mirror of
https://github.com/spacebarchat/server.git
synced 2026-03-30 18:15:41 +00:00
fix up searching
This commit is contained in:
@@ -19,10 +19,10 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
|
||||
import { route } from "@spacebar/api";
|
||||
import { Channel, FieldErrors, Message, getPermission } from "@spacebar/util";
|
||||
import { Channel, FieldErrors, Member, Message, Snowflake, getPermission } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { HTTPError } from "lambert-server";
|
||||
import { FindManyOptions, In, Like } from "typeorm";
|
||||
import { Between, FindManyOptions, FindOptionsWhere, In, LessThan, Like, MoreThan } from "typeorm";
|
||||
|
||||
const router: Router = Router({ mergeParams: true });
|
||||
|
||||
@@ -43,16 +43,17 @@ router.get(
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const {
|
||||
channel_id,
|
||||
content,
|
||||
// include_nsfw, // TODO
|
||||
offset,
|
||||
sort_order,
|
||||
// sort_by, // TODO: Handle 'relevance'
|
||||
limit,
|
||||
author_id,
|
||||
max_id,
|
||||
min_id,
|
||||
} = req.query as Record<string, string>;
|
||||
|
||||
const { author_id } = req.query as Record<string, string[] | string>;
|
||||
let { channel_id, mentions } = req.query as Record<string, string[] | string>;
|
||||
const parsedLimit = Number(limit) || 50;
|
||||
if (parsedLimit < 1 || parsedLimit > 100) throw new HTTPError("limit must be between 1 and 100", 422);
|
||||
|
||||
@@ -65,43 +66,98 @@ router.get(
|
||||
},
|
||||
}); // todo this is wrong
|
||||
}
|
||||
|
||||
const permissions = await getPermission(req.user_id, req.params.guild_id as string, channel_id as string | undefined);
|
||||
permissions.hasThrow("VIEW_CHANNEL");
|
||||
if (!permissions.has("READ_MESSAGE_HISTORY")) return res.json({ messages: [], total_results: 0 });
|
||||
if (channel_id) {
|
||||
const ids = new Set(channel_id instanceof Array ? channel_id : [channel_id]);
|
||||
Promise.all(
|
||||
[...ids].map(async (id) => {
|
||||
const permissions = await getPermission(req.user_id, req.params.guild_id as string, id);
|
||||
permissions.hasThrow("VIEW_CHANNEL");
|
||||
if (!permissions.has("READ_MESSAGE_HISTORY")) ids.delete(id);
|
||||
}),
|
||||
);
|
||||
if (ids.size === 0) {
|
||||
res.json({ messages: [], total_results: 0 });
|
||||
} else if (ids.size === 1) {
|
||||
channel_id = [...ids][0];
|
||||
} else {
|
||||
channel_id = [...ids];
|
||||
}
|
||||
} else {
|
||||
const permissions = await getPermission(req.user_id, req.params.guild_id as string);
|
||||
permissions.hasThrow("VIEW_CHANNEL");
|
||||
if (!permissions.has("READ_MESSAGE_HISTORY")) return res.json({ messages: [], total_results: 0 });
|
||||
}
|
||||
const minStamp = min_id ? Snowflake.deconstruct(min_id).timestamp : 0;
|
||||
const maxStamp = max_id ? Snowflake.deconstruct(max_id).timestamp : 0;
|
||||
const where: FindOptionsWhere<Message> = {
|
||||
guild: {
|
||||
id: req.params.guild_id as string,
|
||||
},
|
||||
...(content ? { content: Like(`%${content}%`) } : {}),
|
||||
...(author_id ? (author_id instanceof Array ? { author_id: In(author_id) } : { author_id }) : {}),
|
||||
...(channel_id
|
||||
? channel_id instanceof Array
|
||||
? { channel_id: In(channel_id) }
|
||||
: { channel_id }
|
||||
: {
|
||||
channel_id: In(
|
||||
(
|
||||
await Promise.all(
|
||||
(
|
||||
await Channel.find({
|
||||
where: { guild_id: req.params.guild_id as string },
|
||||
select: { id: true },
|
||||
})
|
||||
).map(async (channel) => {
|
||||
const perm = await getPermission(req.user_id, req.params.guild_id as string, channel.id);
|
||||
return perm.has("VIEW_CHANNEL") && perm.has("READ_MESSAGE_HISTORY") ? channel : undefined;
|
||||
}),
|
||||
)
|
||||
)
|
||||
.filter((_) => _ !== undefined)
|
||||
.map(({ id }) => id),
|
||||
),
|
||||
}),
|
||||
...(minStamp
|
||||
? maxStamp
|
||||
? { timestamp: Between(new Date(minStamp), new Date(maxStamp)) }
|
||||
: { timestamp: MoreThan(new Date(minStamp)) }
|
||||
: maxStamp
|
||||
? { timestamp: LessThan(new Date(maxStamp)) }
|
||||
: {}),
|
||||
};
|
||||
mentions = mentions instanceof Array ? mentions : mentions ? [mentions] : [];
|
||||
let roleids = [] as string[];
|
||||
if (mentions) {
|
||||
const ms = await Member.find({ where: { id: In(mentions), guild_id: req.params.guild_id as string }, relations: ["roles"] });
|
||||
const rSet = new Set<string>();
|
||||
ms.forEach((memb) => {
|
||||
memb.roles.forEach(({ id }) => rSet.add(id));
|
||||
});
|
||||
roleids = [...rSet];
|
||||
}
|
||||
|
||||
const query: FindManyOptions<Message> = {
|
||||
order: {
|
||||
timestamp: sort_order ? (sort_order.toUpperCase() as "ASC" | "DESC") : "DESC",
|
||||
},
|
||||
where: {
|
||||
guild: {
|
||||
id: req.params.guild_id as string,
|
||||
},
|
||||
...(content ? { content: Like(`%${content}%`) } : {}),
|
||||
...(author_id ? { author_id } : {}),
|
||||
...(channel_id
|
||||
? { channel_id }
|
||||
: {
|
||||
channel_id: In(
|
||||
(
|
||||
await Promise.all(
|
||||
(
|
||||
await Channel.find({
|
||||
where: { guild_id: req.params.guild_id as string },
|
||||
select: { id: true },
|
||||
})
|
||||
).map(async (channel) => {
|
||||
const perm = await getPermission(req.user_id, req.params.guild_id as string, channel.id);
|
||||
return perm.has("VIEW_CHANNEL") && perm.has("READ_MESSAGE_HISTORY") ? channel : undefined;
|
||||
}),
|
||||
)
|
||||
)
|
||||
.filter((_) => _ !== undefined)
|
||||
.map(({ id }) => id),
|
||||
),
|
||||
}),
|
||||
},
|
||||
where: mentions.length
|
||||
? [
|
||||
{ ...where, mention_everyone: true },
|
||||
{
|
||||
...where,
|
||||
mentions: {
|
||||
id: In(mentions),
|
||||
},
|
||||
},
|
||||
{
|
||||
...where,
|
||||
mention_roles: {
|
||||
id: In(roleids),
|
||||
},
|
||||
},
|
||||
]
|
||||
: where,
|
||||
relations: { author: true, webhook: true, application: true, mentions: true, mention_roles: true, mention_channels: true, sticker_items: true, attachments: true },
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user