diff --git a/gateway/package-lock.json b/gateway/package-lock.json
index e76bd71c..5190b6b0 100644
--- a/gateway/package-lock.json
+++ b/gateway/package-lock.json
@@ -41,26 +41,30 @@
"hasInstallScript": true,
"license": "GPLV3",
"dependencies": {
- "ajv": "^8.5.0",
+ "ajv": "^8.6.2",
"amqplib": "^0.8.0",
+ "class-validator": "^0.13.1",
"dot-prop": "^6.0.1",
"env-paths": "^2.2.1",
"jsonwebtoken": "^8.5.1",
- "missing-native-js-functions": "^1.2.10",
- "mongodb": "^3.6.9",
- "mongoose": "^5.13.7",
- "mongoose-autopopulate": "^0.12.3",
+ "lambert-server": "^1.2.10",
+ "missing-native-js-functions": "^1.2.11",
"node-fetch": "^2.6.1",
- "typescript": "^4.1.3"
+ "patch-package": "^6.4.7",
+ "pg": "^8.7.1",
+ "reflect-metadata": "^0.1.13",
+ "sqlite3": "^5.0.2",
+ "typeorm": "^0.2.37",
+ "typescript": "^4.3.5",
+ "typescript-json-schema": "^0.50.1"
},
"devDependencies": {
"@types/amqplib": "^0.8.1",
"@types/jsonwebtoken": "^8.5.0",
- "@types/mongodb": "^3.6.9",
"@types/mongoose-autopopulate": "^0.10.1",
- "@types/mongoose-lean-virtuals": "^0.5.1",
"@types/node": "^14.17.9",
- "@types/node-fetch": "^2.5.12"
+ "@types/node-fetch": "^2.5.12",
+ "jest": "^27.0.6"
}
},
"node_modules/@fosscord/util": {
@@ -1927,22 +1931,26 @@
"requires": {
"@types/amqplib": "^0.8.1",
"@types/jsonwebtoken": "^8.5.0",
- "@types/mongodb": "^3.6.9",
"@types/mongoose-autopopulate": "^0.10.1",
- "@types/mongoose-lean-virtuals": "^0.5.1",
"@types/node": "^14.17.9",
"@types/node-fetch": "^2.5.12",
- "ajv": "^8.5.0",
+ "ajv": "^8.6.2",
"amqplib": "^0.8.0",
+ "class-validator": "^0.13.1",
"dot-prop": "^6.0.1",
"env-paths": "^2.2.1",
+ "jest": "^27.0.6",
"jsonwebtoken": "^8.5.1",
- "missing-native-js-functions": "^1.2.10",
- "mongodb": "^3.6.9",
- "mongoose": "^5.13.7",
- "mongoose-autopopulate": "^0.12.3",
+ "lambert-server": "^1.2.10",
+ "missing-native-js-functions": "^1.2.11",
"node-fetch": "^2.6.1",
- "typescript": "^4.1.3"
+ "patch-package": "^6.4.7",
+ "pg": "^8.7.1",
+ "reflect-metadata": "^0.1.13",
+ "sqlite3": "^5.0.2",
+ "typeorm": "^0.2.37",
+ "typescript": "^4.3.5",
+ "typescript-json-schema": "^0.50.1"
}
},
"@types/amqplib": {
diff --git a/gateway/src/Server.ts b/gateway/src/Server.ts
index a50c24a6..944174c7 100644
--- a/gateway/src/Server.ts
+++ b/gateway/src/Server.ts
@@ -1,7 +1,7 @@
import "missing-native-js-functions";
import dotenv from "dotenv";
dotenv.config();
-import { Config, db, initEvent, RabbitMQ } from "@fosscord/util";
+import { closeDatabase, Config, initDatabase, initEvent, RabbitMQ } from "@fosscord/util";
import { Server as WebSocketServer } from "ws";
import { Connection } from "./events/Connection";
import http from "http";
@@ -38,15 +38,8 @@ export class Server {
this.ws.on("error", console.error);
}
- async setupSchema() {
- // TODO: adjust expireAfterSeconds -> lower
- await Promise.all([db.collection("events").createIndex({ created_at: 1 }, { expireAfterSeconds: 60 })]);
- }
-
async start(): Promise<void> {
- // @ts-ignore
- await (db as Promise<Connection>);
- await this.setupSchema();
+ await initDatabase();
await Config.init();
await initEvent();
if (!this.server.listening) {
@@ -56,7 +49,7 @@ export class Server {
}
async stop() {
- await db.close();
+ closeDatabase();
this.server.close();
}
}
diff --git a/gateway/src/listener/listener.ts b/gateway/src/listener/listener.ts
index 633580e3..8fa96555 100644
--- a/gateway/src/listener/listener.ts
+++ b/gateway/src/listener/listener.ts
@@ -1,22 +1,20 @@
import {
- db,
- Event,
User,
getPermission,
Permissions,
Channel,
RabbitMQ,
- EVENT,
listenEvent,
EventOpts,
ListenEventOpts,
+ Member,
} from "@fosscord/util";
import { OPCODES } from "../util/Constants";
import { Send } from "../util/Send";
import WebSocket from "../util/WebSocket";
import "missing-native-js-functions";
-import { ConsumeMessage } from "amqplib";
-import { Channel } from "amqplib";
+import { Channel as AMQChannel } from "amqplib";
+import { In } from "../../../util/node_modules/typeorm";
// TODO: close connection on Invalidated Token
// TODO: check intent
@@ -27,15 +25,16 @@ import { Channel } from "amqplib";
// TODO: use already queried guilds/channels of Identify and don't fetch them again
export async function setupListener(this: WebSocket) {
- const user = await User.findOneOrFail({ id: this.user_id }, { guilds: true });
- const channels = await Channel.find(
- { $or: [{ recipient_ids: this.user_id }, { guild_id: { $in: user.guilds } }] },
- { id: true, permission_overwrites: true }
- );
+ const members = await Member.find({ where: { id: this.user_id } });
+ const guild_ids = members.map((x) => x.guild_id);
+ const user = await User.findOneOrFail({ id: this.user_id });
+ const channels = await Channel.find({
+ where: [{ recipient_ids: this.user_id }, { guild_id: In(guild_ids) }],
+ });
const dm_channels = channels.filter((x) => !x.guild_id);
const guild_channels = channels.filter((x) => x.guild_id);
- const opts: { acknowledge: boolean; channel?: Channel } = { acknowledge: true };
+ const opts: { acknowledge: boolean; channel?: AMQChannel } = { acknowledge: true };
const consumer = consume.bind(this);
if (RabbitMQ.connection) {
@@ -50,7 +49,7 @@ export async function setupListener(this: WebSocket) {
this.events[channel.id] = await listenEvent(channel.id, consumer, opts);
}
- for (const guild of user.guilds) {
+ for (const guild of guild_ids) {
// contains guild and dm channels
getPermission(this.user_id, guild)
diff --git a/gateway/src/opcodes/Identify.ts b/gateway/src/opcodes/Identify.ts
index 644d0984..5be2acce 100644
--- a/gateway/src/opcodes/Identify.ts
+++ b/gateway/src/opcodes/Identify.ts
@@ -42,16 +42,17 @@ export async function onIdentify(this: WebSocket, data: Payload) {
}
}
- const members = await Member.find({ id: this.user_id });
+ const members = await Member.find({ where: { id: this.user_id }, relations: ["guilds"] });
const merged_members = members.map((x: any) => {
const y = { ...x, user_id: x.id };
delete y.settings;
delete y.id;
return [y];
- }) as MemberDocument[][];
+ }) as Member[][];
+ const guilds = members.map((x) => x.guild);
const user_guild_settings_entries = members.map((x) => x.settings);
- const channels = await Channel.find({ recipient_ids: this.user_id });
+ const channels = await Channel.find({ where: { recipient_ids: this.user_id } });
const user = await User.findOneOrFail({ id: this.user_id });
if (!user) return this.close(CLOSECODES.Authentication_failed);
@@ -64,10 +65,6 @@ export async function onIdentify(this: WebSocket, data: Payload) {
bot: user.bot,
};
- const guilds = await Guild.find({ id: { $in: user.guilds } }).populate({
- path: "joined_at",
- match: { id: this.user_id },
- });
const privateUser = {
avatar: user.avatar,
mobile: user.mobile,
@@ -87,6 +84,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
bot: user.bot,
accent_color: user.accent_color || 0,
banner: user.banner,
+ bio: user.bio,
};
const d: ReadyEventData = {
@@ -106,7 +104,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
}),
guild_experiments: [], // TODO
geo_ordered_rtc_regions: [], // TODO
- relationships: user.data.relationships,
+ relationships: user.relationships,
read_state: {
// TODO
entries: [],
@@ -120,7 +118,6 @@ export async function onIdentify(this: WebSocket, data: Payload) {
},
// @ts-ignore
private_channels: channels.map((x): ChannelDocument => {
- x.recipient_ids = x.recipients.map((y: any) => y.id);
delete x.recipients;
return x;
}),
diff --git a/gateway/src/schema/Activity.ts b/gateway/src/schema/Activity.ts
index d7e0a30b..0fd0592f 100644
--- a/gateway/src/schema/Activity.ts
+++ b/gateway/src/schema/Activity.ts
@@ -1,10 +1,47 @@
-import { ActivityBodySchema } from "@fosscord/util";
import { EmojiSchema } from "./Emoji";
export const ActivitySchema = {
afk: Boolean,
status: String,
- $activities: [ActivityBodySchema],
+ $activities: [
+ {
+ name: String,
+ type: Number,
+ $url: String,
+ $created_at: Date,
+ $timestamps: [
+ {
+ $start: Number,
+ $end: Number,
+ },
+ ],
+ $application_id: String,
+ $details: String,
+ $state: String,
+ $emoji: {
+ $name: String,
+ $id: String,
+ $amimated: Boolean,
+ },
+ $party: {
+ $id: String,
+ $size: [Number, Number],
+ },
+ $assets: {
+ $large_image: String,
+ $large_text: String,
+ $small_image: String,
+ $small_text: String,
+ },
+ $secrets: {
+ $join: String,
+ $spectate: String,
+ $match: String,
+ },
+ $instance: Boolean,
+ $flags: BigInt,
+ },
+ ],
$since: Number, // unix time (in milliseconds) of when the client went idle, or null if the client is not idle
};
diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts
index d02cedb4..4900f485 100644
--- a/util/src/entities/Channel.ts
+++ b/util/src/entities/Channel.ts
@@ -25,6 +25,7 @@ export class Channel extends BaseClass {
@Column({ type: "simple-enum", enum: ChannelType })
type: ChannelType;
+ @Column("simple-array")
@RelationId((channel: Channel) => channel.recipients)
recipient_ids: string[];
|