diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..0224de64 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +MONGO_URL=mongodb://localhost/fosscord +PORT=3002 +PRODUCTION=TRUE +THREADS=# automatically use all available cores, only available if production = true \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index ade7c416..b2329233 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,12 @@ FROM node:lts-alpine WORKDIR /usr/src/fosscord-gateway -COPY . . +COPY package.json . RUN apk --no-cache --virtual build-dependencies add \ python \ make \ g++ RUN npm install RUN apk del build-dependencies +COPY . . EXPOSE 3002 CMD ["npm", "start"] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c9428dd1..c18abf32 100644 Binary files a/package-lock.json and b/package-lock.json differ diff --git a/package.json b/package.json index e98a04d3..c5f3df24 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "author": "Fosscord", "license": "ISC", "dependencies": { - "@fosscord/server-util": "^1.2.6", + "@fosscord/server-util": "^1.3.7", + "ajv": "^8.5.0", "dotenv": "^8.2.0", "jsonwebtoken": "^8.5.1", "lambert-server": "^1.1.7", diff --git a/src/Server.ts b/src/Server.ts index 46ff56a3..2f72cc00 100644 --- a/src/Server.ts +++ b/src/Server.ts @@ -1,10 +1,9 @@ import "missing-native-js-functions"; import dotenv from "dotenv"; dotenv.config(); -import { db } from "@fosscord/server-util"; +import { Config, db } from "@fosscord/server-util"; import { Server as WebSocketServer } from "ws"; import { Connection } from "./events/Connection"; -import Config from "./util/Config"; // TODO: only listen/start the server if everything got initalized // https://www.npmjs.com/package/ws use "External HTTP/S server" and listen manually at the end of listen() @@ -37,8 +36,8 @@ export class Server { // @ts-ignore await (db as Promise); await this.setupSchema(); - console.log("[DB] connected"); await Config.init(); + console.log("[DB] connected"); console.log(`[Gateway] online on 0.0.0.0:${port}`); } } diff --git a/src/opcodes/Identify.ts b/src/opcodes/Identify.ts index f31eebfe..0ddc58d1 100644 --- a/src/opcodes/Identify.ts +++ b/src/opcodes/Identify.ts @@ -11,6 +11,7 @@ import { UserModel, toObject, EVENTEnum, + Config, } from "@fosscord/server-util"; import { setupListener } from "../listener/listener"; import { IdentifySchema } from "../schema/Identify"; @@ -29,7 +30,8 @@ export async function onIdentify(this: WebSocket, data: Payload) { const identify: IdentifySchema = data.d; try { - var decoded = await checkToken(identify.token); // will throw an error if invalid + const { jwtSecret } = Config.get().security; + var decoded = await checkToken(identify.token, jwtSecret); // will throw an error if invalid } catch (error) { console.error("invalid token", error); return this.close(CLOSECODES.Authentication_failed); diff --git a/src/opcodes/LazyRequest.ts b/src/opcodes/LazyRequest.ts index 8b97e84a..8a7bb8c4 100644 --- a/src/opcodes/LazyRequest.ts +++ b/src/opcodes/LazyRequest.ts @@ -70,15 +70,16 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) { const items = []; for (const role of roles) { - items.push({ - group: { - count: role.members.length, - id: role.id, - }, - }); - for (const member of role.members) { - items.push({ member }); - } + items.push({ + group: { + count: role.members.length, + id: role.id === guild_id ? "online" : role.name + } + }); + for (const member of role.members) { + member.roles.remove(guild_id); + items.push({ member }); + } } return Send(this, { @@ -90,7 +91,7 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) { { range: [0, 99], op: "SYNC", - items: items, + items, }, ], online_count: member_count, // TODO count online count diff --git a/src/util/Config.ts b/src/util/Config.ts index eee20e1d..9ceb8cd5 100644 --- a/src/util/Config.ts +++ b/src/util/Config.ts @@ -1,21 +1,41 @@ +// @ts-nocheck import { Config } from "@fosscord/server-util"; - -export default { - init() { - return Config.init({ gateway: DefaultOptions }); - }, - get() { - return Config.getAll().gateway; - }, - set(val: any) { - return Config.setAll({ gateway: val }); - }, - getAll: Config.getAll, - setAll: Config.setAll, -}; +import { getConfigPathForFile } from "@fosscord/server-util/dist/util/Config"; +import Ajv, { JSONSchemaType } from "ajv"; export interface DefaultOptions { endpoint?: string; + security: { + jwtSecret: string; + }; } -export const DefaultOptions: DefaultOptions = {}; +const schema: JSONSchemaType = { + type: "object", + properties: { + endpoint: { + type: "string", + nullable: true, + }, + security: { + type: "object", + properties: { + jwtSecret: { + type: "string", + }, + }, + required: ["jwtSecret"], + }, + }, + required: ["security"], +}; + +const ajv = new Ajv(); +const validator = ajv.compile(schema); + +const configPath = getConfigPathForFile("fosscord", "gateway", ".json"); +export const gatewayConfig = new Config({ + path: configPath, + schemaValidator: validator, + schema: schema, +});