refactor(api): extract adminGuard + add user-management contracts

This commit is contained in:
Bas van Rossem
2026-06-24 22:42:35 +02:00
parent 4463a2e41a
commit a32406de69
3 changed files with 29 additions and 8 deletions

View File

@@ -1,4 +1,4 @@
import type { Context } from 'hono';
import type { Context, MiddlewareHandler } from 'hono';
import { auth } from '../auth';
export interface SessionUser {
@@ -16,3 +16,11 @@ export async function getSessionUser(c: Context): Promise<SessionUser | null> {
export function isAdmin(u: SessionUser | null): boolean {
return u?.role === 'admin';
}
// Reusable gate for the whole /api/admin/* surface: 401 if unauthenticated, 403 if not an admin.
export const adminGuard: MiddlewareHandler = async (c, next) => {
const u = await getSessionUser(c);
if (!u) return c.json({ error: 'Unauthorized' }, 401);
if (!isAdmin(u)) return c.json({ error: 'Forbidden' }, 403);
await next();
};

View File

@@ -3,7 +3,7 @@ import { and, asc, desc, eq, gte, lte, type SQL } from 'drizzle-orm';
import { AdminUpdateSessionInput, CreateManualSessionInput, InsoleType } from '@solelog/shared';
import { db } from '../db/client';
import { activities, user, workSessions } from '../db/schema';
import { getSessionUser, isAdmin } from '../lib/require-user';
import { adminGuard } from '../lib/require-user';
import { toWorkSession } from '../lib/work-session';
import { buildSessionsCsv } from '../lib/csv';
@@ -59,12 +59,7 @@ function buildSessionFilters(q: ReportQuery): SQL[] {
export const adminRoutes = new Hono();
// Gate the whole /api/admin/* surface to admins.
adminRoutes.use('/api/admin/*', async (c, next) => {
const sessionUser = await getSessionUser(c);
if (!sessionUser) return c.json({ error: 'Unauthorized' }, 401);
if (!isAdmin(sessionUser)) return c.json({ error: 'Forbidden' }, 403);
await next();
});
adminRoutes.use('/api/admin/*', adminGuard);
const baseSelect = {
session: workSessions,