mirror of
https://github.com/spacebarchat/server.git
synced 2026-05-24 23:26:05 +00:00
Merge pull request #1408 from MathMan05/removeStupidPolies
This commit is contained in:
@@ -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?
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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[];
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user