mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-30 00:28:02 -04:00
63 lines
2.1 KiB
TypeScript
63 lines
2.1 KiB
TypeScript
import SQL from 'sql-template-strings';
|
|
|
|
import type { UserRow } from '~/server/express/user.ts';
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const query = getQuery(event);
|
|
const checkLocale = query.localeFilter ? global.config.locale : '*';
|
|
|
|
const { isGranted } = await useAuthentication(event);
|
|
if (!isGranted('users', checkLocale) && !isGranted('community', checkLocale)) {
|
|
throw createError({
|
|
status: 401,
|
|
statusMessage: 'Unauthorised',
|
|
});
|
|
}
|
|
|
|
const conditions = [];
|
|
|
|
let sql = SQL`
|
|
SELECT u.id, u.username, u.email, u.roles, u.avatarSource, group_concat(p.locale) AS profiles
|
|
FROM users u
|
|
LEFT JOIN profiles p ON p.userId = u.id
|
|
`;
|
|
|
|
if (typeof query.filter === 'string') {
|
|
conditions.push(SQL`(lower(u.username) LIKE ${`%${query.filter.toLowerCase()}%`} OR lower(u.email) LIKE ${`%${query.filter.toLowerCase()}%`})`);
|
|
}
|
|
if (query.localeFilter) {
|
|
conditions.push(SQL`p.locale=${global.config.locale}`);
|
|
}
|
|
if (query.adminsFilter) {
|
|
conditions.push(SQL`u.roles != ''`);
|
|
}
|
|
|
|
let conditionsSql = SQL``;
|
|
if (conditions.length) {
|
|
let i = 0;
|
|
for (const condition of conditions) {
|
|
conditionsSql = conditionsSql.append(i++ ? SQL` AND ` : SQL` WHERE `).append(condition);
|
|
}
|
|
}
|
|
|
|
sql = sql.append(conditionsSql).append(SQL`
|
|
GROUP BY u.id
|
|
ORDER BY u.id DESC
|
|
LIMIT ${query.limit ? parseInt(query.limit as string) : 100}
|
|
OFFSET ${query.offset ? parseInt(query.offset as string) : 0}
|
|
`);
|
|
|
|
const countSql = SQL`SELECT COUNT(*) AS c FROM (SELECT u.id FROM users u LEFT JOIN profiles p ON p.userId = u.id`.append(conditionsSql).append(' GROUP BY u.id)');
|
|
|
|
const db = useDatabase();
|
|
return {
|
|
count: (await db.get<{ c: number }>(countSql))!.c,
|
|
data: (await db.all<Pick<UserRow, 'id' | 'username' | 'email' | 'roles' | 'avatarSource'> & { profiles: string }>(sql)).map((u) => {
|
|
return {
|
|
...u,
|
|
profiles: u.profiles ? u.profiles.split(',') : [],
|
|
};
|
|
}),
|
|
};
|
|
});
|