import type { PageServerLoad, Actions } from './$types'; import { db } from '$lib/server/db'; import { users } from '$lib/server/schema'; import { error, fail } from '@sveltejs/kit'; import { hasPermission } from '$lib/roles'; import type { Role } from '$lib/roles'; import { eq, desc, count } from 'drizzle-orm'; import { logAudit } from '$lib/server/audit'; import { sendRegistrationApproved, sendRegistrationDenied } from '$lib/server/email'; export const load: PageServerLoad = async ({ locals }) => { if (!hasPermission(locals.user!.role as Role, 'users')) error(403, 'You do not have permission to manage users'); const userList = await db .select({ id: users.id, name: users.name, email: users.email, role: users.role, active: users.active, createdAt: users.createdAt }) .from(users) .orderBy(desc(users.createdAt)); const [pendingRow] = await db.select({ total: count() }).from(users).where(eq(users.active, false)); const pendingCount = pendingRow?.total ?? 0; return { users: userList, pendingCount }; }; export const actions: Actions = { approve: async ({ request, locals }) => { if (!hasPermission(locals.user!.role as Role, 'users')) error(403, 'Access denied'); const fd = await request.formData(); const userId = parseInt(fd.get('userId')?.toString() ?? '', 10); const role = fd.get('role')?.toString() ?? 'viewer'; if (isNaN(userId)) return fail(400, { error: 'Invalid user ID' }); const validRoles = ['sysadmin', 'director', 'foster_coordinator', 'volunteer_manager', 'vet_liaison', 'content_editor', 'applications_manager', 'viewer', 'foster']; if (!validRoles.includes(role)) return fail(400, { error: 'Invalid role' }); const [user] = await db.select({ id: users.id, name: users.name, email: users.email }).from(users).where(eq(users.id, userId)).limit(1); if (!user) return fail(404, { error: 'User not found' }); await db.update(users).set({ active: true, role: role as typeof users.role.enumValues[number] }).where(eq(users.id, userId)); await logAudit({ userId: locals.user!.id, action: 'approve_user', entity: 'user', entityId: userId, diff: { role } }); try { await sendRegistrationApproved(process.env.ORG_NAME ?? 'Rescue', user.email, user.name, `${process.env.SITE_URL ?? ''}/login`); } catch { /* noop */ } return { success: true, action: 'approve' }; }, deny: async ({ request, locals }) => { if (!hasPermission(locals.user!.role as Role, 'users')) error(403, 'Access denied'); const fd = await request.formData(); const userId = parseInt(fd.get('userId')?.toString() ?? '', 10); if (isNaN(userId)) return fail(400, { error: 'Invalid user ID' }); const [user] = await db.select({ id: users.id, name: users.name, email: users.email, active: users.active }).from(users).where(eq(users.id, userId)).limit(1); if (!user) return fail(404, { error: 'User not found' }); if (user.active) return fail(400, { error: 'Cannot deny an active user. Use the edit page to deactivate.' }); await db.delete(users).where(eq(users.id, userId)); await logAudit({ userId: locals.user!.id, action: 'deny_user', entity: 'user', entityId: userId }); try { await sendRegistrationDenied(process.env.ORG_NAME ?? 'Rescue', user.email, user.name); } catch { /* noop */ } return { success: true, action: 'deny' }; } };