43 lines
1.6 KiB
TypeScript
43 lines
1.6 KiB
TypeScript
import { asc, eq, max, sql } from 'drizzle-orm';
|
|
import { accounts, sessions, users } from '~~/drizzle/schema';
|
|
import { db } from '~~/server/lib/db';
|
|
|
|
/**
|
|
* Every account of the instance, for the admin user list.
|
|
*
|
|
* Only what is needed to manage accounts is returned. Chats, agents, files and
|
|
* API keys of other users are never part of this.
|
|
*/
|
|
export default defineEventHandler(async (event) => {
|
|
await protectAdminRoute(event);
|
|
|
|
const rows = await db
|
|
.select({
|
|
id: users.id,
|
|
name: users.name,
|
|
email: users.email,
|
|
image: users.image,
|
|
role: users.role,
|
|
banned: users.banned,
|
|
twoFactorEnabled: users.twoFactorEnabled,
|
|
createdAt: users.createdAt,
|
|
// sessions are touched as they are used, the newest one is the
|
|
// closest thing there is to a last seen time
|
|
lastActiveAt: max(sessions.updatedAt),
|
|
// no password yet: created by an admin and still waiting for its
|
|
// owner to open the setup link
|
|
pending: sql<boolean>`not exists (select 1 from ${accounts} where ${accounts.userId} = ${users.id} and ${accounts.providerId} = 'credential')`,
|
|
})
|
|
.from(users)
|
|
.leftJoin(sessions, eq(sessions.userId, users.id))
|
|
.groupBy(users.id)
|
|
.orderBy(asc(users.createdAt));
|
|
|
|
return rows.map((row) => ({
|
|
...row,
|
|
role: row.role === 'admin' ? 'admin' as const : 'user' as const,
|
|
banned: !!row.banned,
|
|
twoFactorEnabled: !!row.twoFactorEnabled,
|
|
}));
|
|
});
|