feat: add superadmin management
This commit is contained in:
49
server/src/routes/admin.ts
Normal file
49
server/src/routes/admin.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import type { FastifyPluginAsync } from 'fastify';
|
||||
import { z } from 'zod';
|
||||
import { pool } from '../db/pool.js';
|
||||
|
||||
const userParamsSchema = z.object({
|
||||
userId: z.string().uuid(),
|
||||
});
|
||||
|
||||
const updateUserSchema = z.object({
|
||||
role: z.enum(['student', 'instructor', 'admin']).optional(),
|
||||
isActive: z.boolean().optional(),
|
||||
}).refine((input) => input.role !== undefined || input.isActive !== undefined, {
|
||||
message: 'Provide at least one field to update',
|
||||
});
|
||||
|
||||
export const adminRoutes: FastifyPluginAsync = async (app) => {
|
||||
const adminAccess = { preHandler: app.requireRoles(['admin']) };
|
||||
|
||||
app.get('/users', adminAccess, async () => {
|
||||
const result = await pool.query(
|
||||
`select id, email, display_name as name, role, is_active as "isActive",
|
||||
created_at as "createdAt"
|
||||
from users
|
||||
order by created_at desc`,
|
||||
);
|
||||
return { data: result.rows };
|
||||
});
|
||||
|
||||
app.patch('/users/:userId', adminAccess, async (request, reply) => {
|
||||
const { userId } = userParamsSchema.parse(request.params);
|
||||
const input = updateUserSchema.parse(request.body);
|
||||
|
||||
if (userId === request.user.id && (input.role !== undefined && input.role !== 'admin' || input.isActive === false)) {
|
||||
return reply.code(400).send({ error: 'You cannot remove your own superadmin access' });
|
||||
}
|
||||
|
||||
const result = await pool.query(
|
||||
`update users
|
||||
set role = coalesce($2::user_role, role),
|
||||
is_active = coalesce($3, is_active)
|
||||
where id = $1
|
||||
returning id, email, display_name as name, role, is_active as "isActive", created_at as "createdAt"`,
|
||||
[userId, input.role ?? null, input.isActive ?? null],
|
||||
);
|
||||
const account = result.rows[0];
|
||||
if (!account) return reply.code(404).send({ error: 'User not found' });
|
||||
return { data: account };
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user