summary refs log tree commit diff
path: root/gateway
diff options
context:
space:
mode:
authorFlam3rboy <34555296+Flam3rboy@users.noreply.github.com>2021-09-03 03:37:55 +0200
committerFlam3rboy <34555296+Flam3rboy@users.noreply.github.com>2021-09-03 03:37:55 +0200
commit36fe0ec0c8022cbbde23eb87ca00906629255de6 (patch)
tree43dba167ea6e790ac271b05710c41a539a0fd0d3 /gateway
parentfix #309 (diff)
downloadserver-36fe0ec0c8022cbbde23eb87ca00906629255de6.tar.xz
:bug: fix member + member list
Diffstat (limited to 'gateway')
-rw-r--r--gateway/src/events/Close.ts1
-rw-r--r--gateway/src/listener/listener.ts44
-rw-r--r--gateway/src/opcodes/Identify.ts14
-rw-r--r--gateway/src/opcodes/LazyRequest.ts93
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, {