diff options
author | Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> | 2021-09-03 03:37:55 +0200 |
---|---|---|
committer | Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> | 2021-09-03 03:37:55 +0200 |
commit | acb5fba488c6b407450be3fc0981dd897e4dfaef (patch) | |
tree | e652ab2f27f60543c7769ec240ec19ba204568b2 /gateway | |
parent | fix #309 (diff) | |
download | server-acb5fba488c6b407450be3fc0981dd897e4dfaef.tar.xz |
:bug: fix member + member list
Diffstat (limited to 'gateway')
-rw-r--r-- | gateway/src/events/Close.ts | 1 | ||||
-rw-r--r-- | gateway/src/listener/listener.ts | 44 | ||||
-rw-r--r-- | gateway/src/opcodes/Identify.ts | 14 | ||||
-rw-r--r-- | gateway/src/opcodes/LazyRequest.ts | 93 |
4 files changed, 88 insertions, 64 deletions
diff --git a/gateway/src/events/Close.ts b/gateway/src/events/Close.ts index d68fc751..b4fed316 100644 --- a/gateway/src/events/Close.ts +++ b/gateway/src/events/Close.ts @@ -3,6 +3,7 @@ import { Message } from "./Message"; import { Session } from "@fosscord/util"; export async function Close(this: WebSocket, code: number, reason: string) { + console.log("[WebSocket] closed", code, reason); await Session.delete({ session_id: this.session_id }); // @ts-ignore this.off("message", Message); diff --git a/gateway/src/listener/listener.ts b/gateway/src/listener/listener.ts index 67837e8d..0b6fa50c 100644 --- a/gateway/src/listener/listener.ts +++ b/gateway/src/listener/listener.ts @@ -26,15 +26,20 @@ import { Recipient } from "../../../util/dist/entities/Recipient"; // TODO: use already queried guilds/channels of Identify and don't fetch them again export async function setupListener(this: WebSocket) { - const members = await Member.find({ user_id: this.user_id }); + const members = await Member.find({ id: this.user_id }); const guild_ids = members.map((x) => x.guild_id); const user = await User.findOneOrFail({ id: this.user_id }); - const recipients = await Recipient.find({ where: { id: this.user_id }, relations: ["channel"] }); + const recipients = await Recipient.find({ + where: { user_id: this.user_id }, + relations: ["channel"], + }); const channels = await Channel.find({ guild_id: In(guild_ids) }); const dm_channels = recipients.map((x) => x.channel); const guild_channels = channels.filter((x) => x.guild_id); - const opts: { acknowledge: boolean; channel?: AMQChannel } = { acknowledge: true }; + const opts: { acknowledge: boolean; channel?: AMQChannel } = { + acknowledge: true, + }; const consumer = consume.bind(this); if (RabbitMQ.connection) { @@ -58,13 +63,25 @@ export async function setupListener(this: WebSocket) { this.listeners; this.events[guild] = await listenEvent(guild, consumer, opts); - for (const channel of guild_channels.filter((c) => c.guild_id === guild)) { - if (x.overwriteChannel(channel.permission_overwrites).has("VIEW_CHANNEL")) { - this.events[channel.id] = await listenEvent(channel.id, consumer, opts); + for (const channel of guild_channels.filter( + (c) => c.guild_id === guild + )) { + if ( + x + .overwriteChannel(channel.permission_overwrites) + .has("VIEW_CHANNEL") + ) { + this.events[channel.id] = await listenEvent( + channel.id, + consumer, + opts + ); } } }) - .catch((e) => console.log("couldn't get permission for guild " + guild, e)); + .catch((e) => + console.log("couldn't get permission for guild " + guild, e) + ); } this.once("close", () => { @@ -91,7 +108,12 @@ async function consume(this: WebSocket, opts: EventOpts) { opts.cancel(); break; case "CHANNEL_CREATE": - if (!permission.overwriteChannel(data.permission_overwrites).has("VIEW_CHANNEL")) return; + if ( + !permission + .overwriteChannel(data.permission_overwrites) + .has("VIEW_CHANNEL") + ) + return; // TODO: check if user has permission to channel case "GUILD_CREATE": this.events[id] = await listenEvent(id, consumer, listenOpts); @@ -99,7 +121,11 @@ async function consume(this: WebSocket, opts: EventOpts) { case "CHANNEL_UPDATE": const exists = this.events[id]; // @ts-ignore - if (permission.overwriteChannel(data.permission_overwrites).has("VIEW_CHANNEL")) { + if ( + permission + .overwriteChannel(data.permission_overwrites) + .has("VIEW_CHANNEL") + ) { if (exists) break; this.events[id] = await listenEvent(id, consumer, listenOpts); } else { diff --git a/gateway/src/opcodes/Identify.ts b/gateway/src/opcodes/Identify.ts index 73c9a29e..2b2c31c5 100644 --- a/gateway/src/opcodes/Identify.ts +++ b/gateway/src/opcodes/Identify.ts @@ -57,8 +57,16 @@ export async function onIdentify(this: WebSocket, data: Payload) { } const members = await Member.find({ - where: { user_id: this.user_id }, - relations: ["guild", "guild.channels", "guild.emojis", "guild.roles", "guild.stickers", "user", "roles"], + where: { id: this.user_id }, + relations: [ + "guild", + "guild.channels", + "guild.emojis", + "guild.roles", + "guild.stickers", + "user", + "roles", + ], }); const merged_members = members.map((x: any) => { return [x]; @@ -67,7 +75,7 @@ export async function onIdentify(this: WebSocket, data: Payload) { const user_guild_settings_entries = members.map((x) => x.settings); const recipients = await Recipient.find({ - where: { id: this.user_id }, + where: { user_id: this.user_id }, relations: ["channel", "channel.recipients"], }); const channels = recipients.map((x) => x.channel); diff --git a/gateway/src/opcodes/LazyRequest.ts b/gateway/src/opcodes/LazyRequest.ts index 146175b5..e035e6bb 100644 --- a/gateway/src/opcodes/LazyRequest.ts +++ b/gateway/src/opcodes/LazyRequest.ts @@ -1,13 +1,19 @@ -// @ts-nocheck WIP -import { db, getPermission, PublicUserProjection, toObject } from "@fosscord/util"; +import { + getPermission, + Member, + PublicMemberProjection, + PublicUserProjection, + Role, +} from "@fosscord/util"; import { LazyRequest } from "../schema/LazyRequest"; import { OPCODES, Payload } from "../util/Constants"; import { Send } from "../util/Send"; import WebSocket from "../util/WebSocket"; import { check } from "./instanceOf"; +import "missing-native-js-functions"; // TODO: check permission and only show roles/members that have access to this channel -// TODO: config: if want to list all members (even those who are offline) sorted by role, or just those who are online +// TODO: config: to list all members (even those who are offline) sorted by role, or just those who are online // TODO: rewrite typeorm export async function onLazyRequest(this: WebSocket, { d }: Payload) { @@ -18,60 +24,43 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) { const permissions = await getPermission(this.user_id, guild_id); permissions.hasThrow("VIEW_CHANNEL"); - // MongoDB query to retrieve all hoisted roles and join them with the members and users collection - const roles = await db - .collection("roles") - .aggregate([ - { - $match: { - guild_id, - // hoist: true // TODO: also match @everyone role - }, - }, - { $sort: { position: 1 } }, - { - $lookup: { - from: "members", - let: { id: "$id" }, - pipeline: [ - { $match: { $expr: { $in: ["$$id", "$roles"] } } }, - { $limit: 100 }, - { - $lookup: { - from: "users", - let: { user_id: "$id" }, - pipeline: [ - { $match: { $expr: { $eq: ["$id", "$$user_id"] } } }, - { $project: PublicUserProjection }, - ], - as: "user", - }, - }, - { - $unwind: "$user", - }, - ], - as: "members", - }, - }, - ]) - .toArray(); + var members = await Member.find({ + where: { guild_id: guild_id }, + relations: ["roles", "user"], + select: PublicMemberProjection, + }); + + const roles = await Role.find({ + where: { guild_id: guild_id }, + order: { + position: "ASC", + }, + }); - const groups = roles.map((x) => ({ id: x.id === guild_id ? "online" : x.id, count: x.members.length })); - const member_count = roles.reduce((a, b) => b.members.length + a, 0); + const groups = [] as any[]; + var member_count = 0; const items = []; for (const role of roles) { - 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 }); + const [role_members, other_members] = members.partition((m) => + m.roles.find((r) => r.id === role.id) + ); + const group = { + count: role_members.length, + id: role.id === guild_id ? "online" : role.name, + }; + + items.push({ group }); + groups.push(group); + + for (const member of role_members) { + member.roles = member.roles.filter((x) => x.id !== guild_id); + items.push({ + member: { ...member, roles: member.roles.map((x) => x.id) }, + }); } + members = other_members; + member_count += role_members.length; } return Send(this, { |