typeorm gateway

This commit is contained in:
Flam3rboy 2021-08-29 00:30:04 +02:00
parent 766dcc24aa
commit 38162b1c20
6 changed files with 85 additions and 50 deletions

View File

@ -41,26 +41,30 @@
"hasInstallScript": true, "hasInstallScript": true,
"license": "GPLV3", "license": "GPLV3",
"dependencies": { "dependencies": {
"ajv": "^8.5.0", "ajv": "^8.6.2",
"amqplib": "^0.8.0", "amqplib": "^0.8.0",
"class-validator": "^0.13.1",
"dot-prop": "^6.0.1", "dot-prop": "^6.0.1",
"env-paths": "^2.2.1", "env-paths": "^2.2.1",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"missing-native-js-functions": "^1.2.10", "lambert-server": "^1.2.10",
"mongodb": "^3.6.9", "missing-native-js-functions": "^1.2.11",
"mongoose": "^5.13.7",
"mongoose-autopopulate": "^0.12.3",
"node-fetch": "^2.6.1", "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": { "devDependencies": {
"@types/amqplib": "^0.8.1", "@types/amqplib": "^0.8.1",
"@types/jsonwebtoken": "^8.5.0", "@types/jsonwebtoken": "^8.5.0",
"@types/mongodb": "^3.6.9",
"@types/mongoose-autopopulate": "^0.10.1", "@types/mongoose-autopopulate": "^0.10.1",
"@types/mongoose-lean-virtuals": "^0.5.1",
"@types/node": "^14.17.9", "@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": { "node_modules/@fosscord/util": {
@ -1927,22 +1931,26 @@
"requires": { "requires": {
"@types/amqplib": "^0.8.1", "@types/amqplib": "^0.8.1",
"@types/jsonwebtoken": "^8.5.0", "@types/jsonwebtoken": "^8.5.0",
"@types/mongodb": "^3.6.9",
"@types/mongoose-autopopulate": "^0.10.1", "@types/mongoose-autopopulate": "^0.10.1",
"@types/mongoose-lean-virtuals": "^0.5.1",
"@types/node": "^14.17.9", "@types/node": "^14.17.9",
"@types/node-fetch": "^2.5.12", "@types/node-fetch": "^2.5.12",
"ajv": "^8.5.0", "ajv": "^8.6.2",
"amqplib": "^0.8.0", "amqplib": "^0.8.0",
"class-validator": "^0.13.1",
"dot-prop": "^6.0.1", "dot-prop": "^6.0.1",
"env-paths": "^2.2.1", "env-paths": "^2.2.1",
"jest": "^27.0.6",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"missing-native-js-functions": "^1.2.10", "lambert-server": "^1.2.10",
"mongodb": "^3.6.9", "missing-native-js-functions": "^1.2.11",
"mongoose": "^5.13.7",
"mongoose-autopopulate": "^0.12.3",
"node-fetch": "^2.6.1", "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": { "@types/amqplib": {

View File

@ -1,7 +1,7 @@
import "missing-native-js-functions"; import "missing-native-js-functions";
import dotenv from "dotenv"; import dotenv from "dotenv";
dotenv.config(); 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 { Server as WebSocketServer } from "ws";
import { Connection } from "./events/Connection"; import { Connection } from "./events/Connection";
import http from "http"; import http from "http";
@ -38,15 +38,8 @@ export class Server {
this.ws.on("error", console.error); 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> { async start(): Promise<void> {
// @ts-ignore await initDatabase();
await (db as Promise<Connection>);
await this.setupSchema();
await Config.init(); await Config.init();
await initEvent(); await initEvent();
if (!this.server.listening) { if (!this.server.listening) {
@ -56,7 +49,7 @@ export class Server {
} }
async stop() { async stop() {
await db.close(); closeDatabase();
this.server.close(); this.server.close();
} }
} }

View File

@ -1,22 +1,20 @@
import { import {
db,
Event,
User, User,
getPermission, getPermission,
Permissions, Permissions,
Channel, Channel,
RabbitMQ, RabbitMQ,
EVENT,
listenEvent, listenEvent,
EventOpts, EventOpts,
ListenEventOpts, ListenEventOpts,
Member,
} from "@fosscord/util"; } from "@fosscord/util";
import { OPCODES } from "../util/Constants"; import { OPCODES } from "../util/Constants";
import { Send } from "../util/Send"; import { Send } from "../util/Send";
import WebSocket from "../util/WebSocket"; import WebSocket from "../util/WebSocket";
import "missing-native-js-functions"; import "missing-native-js-functions";
import { ConsumeMessage } from "amqplib"; import { Channel as AMQChannel } from "amqplib";
import { Channel } from "amqplib"; import { In } from "../../../util/node_modules/typeorm";
// TODO: close connection on Invalidated Token // TODO: close connection on Invalidated Token
// TODO: check intent // 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 // TODO: use already queried guilds/channels of Identify and don't fetch them again
export async function setupListener(this: WebSocket) { export async function setupListener(this: WebSocket) {
const user = await User.findOneOrFail({ id: this.user_id }, { guilds: true }); const members = await Member.find({ where: { id: this.user_id } });
const channels = await Channel.find( const guild_ids = members.map((x) => x.guild_id);
{ $or: [{ recipient_ids: this.user_id }, { guild_id: { $in: user.guilds } }] }, const user = await User.findOneOrFail({ id: this.user_id });
{ id: true, permission_overwrites: true } 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 dm_channels = channels.filter((x) => !x.guild_id);
const guild_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); const consumer = consume.bind(this);
if (RabbitMQ.connection) { if (RabbitMQ.connection) {
@ -50,7 +49,7 @@ export async function setupListener(this: WebSocket) {
this.events[channel.id] = await listenEvent(channel.id, consumer, opts); 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 // contains guild and dm channels
getPermission(this.user_id, guild) getPermission(this.user_id, guild)

View File

@ -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 merged_members = members.map((x: any) => {
const y = { ...x, user_id: x.id }; const y = { ...x, user_id: x.id };
delete y.settings; delete y.settings;
delete y.id; delete y.id;
return [y]; return [y];
}) as MemberDocument[][]; }) as Member[][];
const guilds = members.map((x) => x.guild);
const user_guild_settings_entries = members.map((x) => x.settings); 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 }); const user = await User.findOneOrFail({ id: this.user_id });
if (!user) return this.close(CLOSECODES.Authentication_failed); if (!user) return this.close(CLOSECODES.Authentication_failed);
@ -64,10 +65,6 @@ export async function onIdentify(this: WebSocket, data: Payload) {
bot: user.bot, bot: user.bot,
}; };
const guilds = await Guild.find({ id: { $in: user.guilds } }).populate({
path: "joined_at",
match: { id: this.user_id },
});
const privateUser = { const privateUser = {
avatar: user.avatar, avatar: user.avatar,
mobile: user.mobile, mobile: user.mobile,
@ -87,6 +84,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
bot: user.bot, bot: user.bot,
accent_color: user.accent_color || 0, accent_color: user.accent_color || 0,
banner: user.banner, banner: user.banner,
bio: user.bio,
}; };
const d: ReadyEventData = { const d: ReadyEventData = {
@ -106,7 +104,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
}), }),
guild_experiments: [], // TODO guild_experiments: [], // TODO
geo_ordered_rtc_regions: [], // TODO geo_ordered_rtc_regions: [], // TODO
relationships: user.data.relationships, relationships: user.relationships,
read_state: { read_state: {
// TODO // TODO
entries: [], entries: [],
@ -120,7 +118,6 @@ export async function onIdentify(this: WebSocket, data: Payload) {
}, },
// @ts-ignore // @ts-ignore
private_channels: channels.map((x): ChannelDocument => { private_channels: channels.map((x): ChannelDocument => {
x.recipient_ids = x.recipients.map((y: any) => y.id);
delete x.recipients; delete x.recipients;
return x; return x;
}), }),

View File

@ -1,10 +1,47 @@
import { ActivityBodySchema } from "@fosscord/util";
import { EmojiSchema } from "./Emoji"; import { EmojiSchema } from "./Emoji";
export const ActivitySchema = { export const ActivitySchema = {
afk: Boolean, afk: Boolean,
status: String, 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 $since: Number, // unix time (in milliseconds) of when the client went idle, or null if the client is not idle
}; };

View File

@ -25,6 +25,7 @@ export class Channel extends BaseClass {
@Column({ type: "simple-enum", enum: ChannelType }) @Column({ type: "simple-enum", enum: ChannelType })
type: ChannelType; type: ChannelType;
@Column("simple-array")
@RelationId((channel: Channel) => channel.recipients) @RelationId((channel: Channel) => channel.recipients)
recipient_ids: string[]; recipient_ids: string[];