Merge pull request #1408 from MathMan05/removeStupidPolies

This commit is contained in:
Madeline
2025-11-29 09:39:02 +11:00
committed by GitHub
32 changed files with 179 additions and 816 deletions
@@ -29,6 +29,7 @@ import {
MessageReactionRemoveEmojiEvent,
MessageReactionRemoveEvent,
User,
arrayRemove,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
@@ -112,7 +113,7 @@ router.delete(
const already_added = message.reactions.find((x) => (x.emoji.id === emoji.id && emoji.id) || x.emoji.name === emoji.name);
if (!already_added) throw new HTTPError("Reaction not found", 404);
message.reactions.remove(already_added);
arrayRemove(message.reactions, already_added);
await Promise.all([
message.save(),
@@ -283,7 +284,7 @@ router.delete(
already_added.count--;
if (already_added.count <= 0) message.reactions.remove(already_added);
if (already_added.count <= 0) arrayRemove(message.reactions, already_added);
else already_added.user_ids.splice(already_added.user_ids.indexOf(user_id), 1);
await message.save();
@@ -340,7 +341,7 @@ router.delete(
already_added.count--;
if (already_added.count <= 0) message.reactions.remove(already_added);
if (already_added.count <= 0) arrayRemove(message.reactions, already_added);
else already_added.user_ids.splice(already_added.user_ids.indexOf(user_id), 1);
await message.save();
@@ -41,6 +41,7 @@ import {
Snowflake,
uploadFile,
User,
stringGlobToRegexp,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
@@ -244,24 +245,28 @@ router.get(
return x;
});
await ret
.filter((x: MessageCreateSchema) => x.interaction_metadata && !x.interaction_metadata.user)
.forEachAsync(async (x: MessageCreateSchema) => {
x.interaction_metadata!.user = x.interaction!.user = await User.findOneOrFail({ where: { id: (x as Message).interaction_metadata!.user_id } });
});
await Promise.all(
ret
.filter((x: MessageCreateSchema) => x.interaction_metadata && !x.interaction_metadata.user)
.map(async (x: MessageCreateSchema) => {
x.interaction_metadata!.user = x.interaction!.user = await User.findOneOrFail({ where: { id: (x as Message).interaction_metadata!.user_id } });
}),
);
// polyfill message references for old messages
await ret
.filter((msg) => msg.message_reference && !msg.referenced_message?.id)
.forEachAsync(async (msg) => {
const whereOptions: { id: string; guild_id?: string; channel_id?: string } = {
id: msg.message_reference!.message_id,
};
if (msg.message_reference!.guild_id) whereOptions.guild_id = msg.message_reference!.guild_id;
if (msg.message_reference!.channel_id) whereOptions.channel_id = msg.message_reference!.channel_id;
await Promise.all(
ret
.filter((msg) => msg.message_reference && !msg.referenced_message?.id)
.map(async (msg) => {
const whereOptions: { id: string; guild_id?: string; channel_id?: string } = {
id: msg.message_reference!.message_id,
};
if (msg.message_reference!.guild_id) whereOptions.guild_id = msg.message_reference!.guild_id;
if (msg.message_reference!.channel_id) whereOptions.channel_id = msg.message_reference!.channel_id;
msg.referenced_message = await Message.findOne({ where: whereOptions, relations: ["author", "mentions", "mention_roles", "mention_channels"] });
});
msg.referenced_message = await Message.findOne({ where: whereOptions, relations: ["author", "mentions", "mention_roles", "mention_channels"] });
}),
);
return res.json(ret);
},
@@ -449,8 +454,8 @@ router.post(
if (rule.trigger_type == AutomodTriggerTypes.CUSTOM_WORDS) {
const triggerMeta = rule.trigger_metadata as AutomodCustomWordsRule;
const regexes = triggerMeta.regex_patterns.map((x) => new RegExp(x, "i")).concat(triggerMeta.keyword_filter.map((k) => k.globToRegexp("i")));
const allowedRegexes = triggerMeta.allow_list.map((k) => k.globToRegexp("i"));
const regexes = triggerMeta.regex_patterns.map((x) => new RegExp(x, "i")).concat(triggerMeta.keyword_filter.map((k) => stringGlobToRegexp(k, "i")));
const allowedRegexes = triggerMeta.allow_list.map((k) => stringGlobToRegexp(k, "i"));
const matches = regexes
.map((r) => message.content!.match(r))
@@ -17,15 +17,7 @@
*/
import { route } from "@spacebar/api";
import {
Channel,
ChannelRecipientAddEvent,
DiscordApiErrors,
DmChannelDTO,
emitEvent,
Recipient,
User,
} from "@spacebar/util";
import { Channel, ChannelRecipientAddEvent, DiscordApiErrors, DmChannelDTO, emitEvent, Recipient, User } from "@spacebar/util";
import { Request, Response, Router } from "express";
import { ChannelType, PublicUserProjection } from "@spacebar/schemas";
@@ -47,24 +39,16 @@ router.put(
});
if (channel.type !== ChannelType.GROUP_DM) {
const recipients = [
...(channel.recipients?.map((r) => r.user_id) || []),
user_id,
].distinct();
const recipients = [...new Set([...(channel.recipients?.map((r) => r.user_id) || []), user_id])];
const new_channel = await Channel.createDMChannel(
recipients,
req.user_id,
);
const new_channel = await Channel.createDMChannel(recipients, req.user_id);
return res.status(201).json(new_channel);
} else {
if (channel.recipients?.map((r) => r.user_id).includes(user_id)) {
throw DiscordApiErrors.INVALID_RECIPIENT; //TODO is this the right error?
}
channel.recipients?.push(
Recipient.create({ channel_id: channel_id, user_id: user_id }),
);
channel.recipients?.push(Recipient.create({ channel_id: channel_id, user_id: user_id }));
await channel.save();
await emitEvent({
@@ -103,13 +87,7 @@ router.delete(
where: { id: channel_id },
relations: ["recipients"],
});
if (
!(
channel.type === ChannelType.GROUP_DM &&
(channel.owner_id === req.user_id || user_id === req.user_id)
)
)
throw DiscordApiErrors.MISSING_PERMISSIONS;
if (!(channel.type === ChannelType.GROUP_DM && (channel.owner_id === req.user_id || user_id === req.user_id))) throw DiscordApiErrors.MISSING_PERMISSIONS;
if (!channel.recipients?.map((r) => r.user_id).includes(user_id)) {
throw DiscordApiErrors.INVALID_RECIPIENT; //TODO is this the right error?
+7 -5
View File
@@ -40,11 +40,13 @@ router.get(
relations: PublicInviteRelation,
});
await invites
.filter((i) => i.isExpired())
.forEachAsync(async (i) => {
await Invite.delete({ code: i.code });
});
await Promise.all(
invites
.filter((i) => i.isExpired())
.map(async (i) => {
await Invite.delete({ code: i.code });
}),
);
return res.json(invites.filter((i) => !i.isExpired()));
},
@@ -17,45 +17,30 @@
*/
import { Router, Request, Response } from "express";
import { DiscordApiErrors, Member } from "@spacebar/util";
import { DiscordApiErrors, Member, arrayPartition } from "@spacebar/util";
import { route } from "@spacebar/api";
const router = Router({ mergeParams: true });
router.patch(
"/",
route({ permission: "MANAGE_ROLES" }),
async (req: Request, res: Response) => {
// Payload is JSON containing a list of member_ids, the new list of members to have the role
const { guild_id, role_id } = req.params;
const { member_ids } = req.body;
router.patch("/", route({ permission: "MANAGE_ROLES" }), async (req: Request, res: Response) => {
// Payload is JSON containing a list of member_ids, the new list of members to have the role
const { guild_id, role_id } = req.params;
const { member_ids } = req.body;
// don't mess with @everyone
if (role_id == guild_id) throw DiscordApiErrors.INVALID_ROLE;
// don't mess with @everyone
if (role_id == guild_id) throw DiscordApiErrors.INVALID_ROLE;
const members = await Member.find({
where: { guild_id },
relations: ["roles"],
});
const members = await Member.find({
where: { guild_id },
relations: ["roles"],
});
const [add, remove] = members.partition(
(member) =>
member_ids.includes(member.id) &&
!member.roles.map((role) => role.id).includes(role_id),
);
const [add, remove] = arrayPartition(members, (member) => member_ids.includes(member.id) && !member.roles.map((role) => role.id).includes(role_id));
// TODO (erkin): have a bulk add/remove function that adds the roles in a single txn
await Promise.all([
...add.map((member) =>
Member.addRole(member.id, guild_id, role_id),
),
...remove.map((member) =>
Member.removeRole(member.id, guild_id, role_id),
),
]);
// TODO (erkin): have a bulk add/remove function that adds the roles in a single txn
await Promise.all([...add.map((member) => Member.addRole(member.id, guild_id, role_id)), ...remove.map((member) => Member.removeRole(member.id, guild_id, role_id))]);
res.sendStatus(204);
},
);
res.sendStatus(204);
});
export default router;
+2 -2
View File
@@ -19,7 +19,7 @@
import { route } from "@spacebar/api";
import { Config, Message, User } from "@spacebar/util";
import { Request, Response, Router } from "express";
import { DmMessagesResponseSchema } from "@spacebar/schemas"
import { DmMessagesResponseSchema } from "@spacebar/schemas";
const router = Router({ mergeParams: true });
router.get(
@@ -42,7 +42,7 @@ router.get(
await Message.find({
where: { channel_id: channel?.id },
order: { timestamp: "DESC" },
take: Math.clamp(req.query.limit ? Number(req.query.limit) : 50, 1, Config.get().limits.message.maxPreloadCount),
take: Math.min(Math.max(req.query.limit ? Number(req.query.limit) : 50, 1), Config.get().limits.message.maxPreloadCount),
})
).filter((x) => x !== null) as Message[];
+26 -74
View File
@@ -19,7 +19,7 @@
import { route } from "@spacebar/api";
import { Snowflake, User, Message, Member, Channel, Permissions, timePromise, NewUrlUserSignatureData, Stopwatch, Attachment } from "@spacebar/util";
import { Request, Response, Router } from "express";
import { In, LessThan } from "typeorm";
import { In, LessThan, FindOptionsWhere } from "typeorm";
const router: Router = Router({ mergeParams: true });
@@ -70,7 +70,7 @@ router.get(
const channels = await Channel.find({
where: {
guild_id: In(memberships.map((m) => m.guild_id).distinct()),
guild_id: In(memberships.map((m) => m.guild_id)),
},
select: { id: true, guild_id: true, permission_overwrites: true },
});
@@ -78,7 +78,7 @@ router.get(
const visibleChannels = channels.filter((c) => {
const member = memberships.find((m) => m.guild_id === c.guild_id)!;
return Permissions.finalPermission({
user: { id: member.id, roles: member.roles.map((r) => r.id).distinct(), communication_disabled_until: member.communication_disabled_until, flags: 0 },
user: { id: member.id, roles: member.roles.map((r) => r.id), communication_disabled_until: member.communication_disabled_until, flags: 0 },
guild: { id: member.guild.id, owner_id: member.guild.owner_id!, roles: member.roles },
channel: c,
}).has("VIEW_CHANNEL");
@@ -90,81 +90,32 @@ router.get(
return acc;
}, [] as Snowflake[]);
const [
{ result: userMentions, elapsed: userMentionQueryTime },
{ result: roleMentions, elapsed: roleMentionQueryTime },
{ result: everyoneMentions, elapsed: everyoneMentionQueryTime },
] = await Promise.all([
await timePromise(() =>
Message.find({
where: {
channel_id: In(visibleChannelIds),
mentions: { id: user.id },
...(before === undefined ? {} : { id: LessThan(before) }),
},
select: {
id: true,
timestamp: true,
},
order: {
timestamp: "DESC",
},
take: limit,
}),
),
await timePromise(() =>
!roles
? Promise.resolve([])
: Message.find({
where: {
channel_id: In(visibleChannelIds),
mention_roles: { id: In(ownedMentionableRoleIds) },
...(before === undefined ? {} : { id: LessThan(before) }),
},
select: {
id: true,
timestamp: true,
},
order: {
timestamp: "DESC",
},
take: limit,
}),
),
await timePromise(() =>
!everyone
? Promise.resolve([])
: Message.find({
where: {
channel_id: In(visibleChannelIds),
mention_everyone: true,
...(before === undefined ? {} : { id: LessThan(before) }),
},
select: {
id: true,
timestamp: true,
},
order: {
timestamp: "DESC",
},
take: limit,
}),
),
]);
const allMentions = [...userMentions, ...roleMentions, ...everyoneMentions];
console.log(
`[Inbox/mentions] User ${user.id} query results: totalRecs=${allMentions.length} | user=${userMentions.length} (took ${userMentionQueryTime.totalMilliseconds}ms), role=${roleMentions.length} (took ${roleMentionQueryTime.totalMilliseconds}ms), everyone=${everyoneMentions.length} (took ${everyoneMentionQueryTime.totalMilliseconds}ms)`,
);
const messageIdsToReturn = allMentions
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())
.distinctBy((m) => m.id)
.slice(0, limit);
const whereQuery: FindOptionsWhere<Message>[] = [
{
channel_id: In(visibleChannelIds),
mentions: { id: user.id },
id: before ? LessThan(before) : undefined,
},
];
if (everyone) {
whereQuery.push({
channel_id: In(visibleChannelIds),
mention_everyone: true,
id: before ? LessThan(before) : undefined,
});
}
if (roles) {
whereQuery.push({
channel_id: In(visibleChannelIds),
mention_roles: { id: In(ownedMentionableRoleIds) },
id: before ? LessThan(before) : undefined,
});
}
const sw = Stopwatch.startNew();
const finalMessages = (
await Message.find({
where: { id: In(messageIdsToReturn.map((m) => m.id)) },
where: whereQuery,
order: { timestamp: "DESC" },
relations: [
"author",
@@ -185,6 +136,7 @@ router.get(
"referenced_message.sticker_items",
"referenced_message.attachments",
],
take: limit,
})
).map((m) => {
return {
+5 -8
View File
@@ -19,7 +19,7 @@
import { route } from "@spacebar/api";
import { User, UserSettings } from "@spacebar/util";
import { Request, Response, Router } from "express";
import { UserSettingsUpdateSchema, UserSettingsSchema } from "@spacebar/schemas"
import { UserSettingsUpdateSchema, UserSettingsSchema } from "@spacebar/schemas";
const router = Router({ mergeParams: true });
@@ -36,7 +36,7 @@ router.get(
},
}),
async (req: Request, res: Response) => {
const settings = await UserSettings.getOrDefault(req.user_id)
const settings = await UserSettings.getOrDefault(req.user_id);
return res.json(settings);
},
);
@@ -67,13 +67,10 @@ router.patch(
relations: ["settings"],
});
if (!user.settings)
user.settings = UserSettings.create(body as UserSettingsUpdateSchema);
else
user.settings.assign(body);
if (!user.settings) user.settings = UserSettings.create<UserSettings>(body);
else user.settings.assign(body);
if (body.guild_folders)
user.settings.guild_folders = body.guild_folders;
if (body.guild_folders) user.settings.guild_folders = body.guild_folders;
await user.settings.save();
await user.save();