import { Hono } from "jsr:@hono/hono@4"; import { encodeBase64Url } from "jsr:@std/encoding@1/base64url"; import { sqlWrapper } from "../db.ts"; import { valkey } from "../valkey.ts"; import { auditWrapper } from "../audit.ts"; import { getAuthenticatedUser, isGlobalAdmin, requireAdmin, } from "../auth-session.ts"; import { adminRateLimiter, getClientIp } from "../middleware.ts"; import { computeJwkThumbprint } from "../http_signatures.ts"; export const adminRoutes = new Hono(); adminRoutes.use("*", requireAdmin); adminRoutes.use("*", adminRateLimiter); // --------------------------------------------------------- // Global Admin APIs (For the Management Console) // --------------------------------------------------------- adminRoutes.get("/audit-logs", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const logs = await sqlWrapper.sql` SELECT a.id, a.action, a.resource, a.details, a.ip_address, a.created_at, u.username as user FROM audit_records a LEFT JOIN users u ON a.user_id = u.id ORDER BY a.created_at DESC LIMIT 100 `; return c.json({ logs }); }); adminRoutes.get("/users", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const users = await sqlWrapper.sql` SELECT id, username, display_name, account_status FROM users ORDER BY username ASC `; return c.json({ users }); }); adminRoutes.post("/users/:id/status", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const targetUserId = c.req.param("id"); const { status } = await c.req.json(); if (!["active", "pending", "suspended"].includes(status)) { return c.json({ error: "Invalid status" }, 400); } const targetUser = await sqlWrapper .sql`UPDATE users SET account_status = ${status} WHERE id = ${targetUserId} RETURNING id` .then((res: any) => res[0]); if (!targetUser) { return c.json({ error: "User not found" }, 404); } auditWrapper.auditLog(auth.userId, "user_status_changed", targetUserId, { newStatus: status, }, getClientIp(c)); return c.json({ success: true }); }); adminRoutes.post("/users/:id/profile", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const targetUserId = c.req.param("id"); const { displayName } = await c.req.json(); const targetUser = await sqlWrapper .sql`UPDATE users SET display_name = ${ displayName?.trim() || null } WHERE id = ${targetUserId} RETURNING id, username, display_name` .then((res: any) => res[0]); if (!targetUser) return c.json({ error: "User not found" }, 404); auditWrapper.auditLog(auth.userId, "user_profile_updated", targetUserId, { display_name: targetUser.display_name, }, getClientIp(c)); return c.json({ success: true, user: targetUser }); }); // --------------------------------------------------------- // Admin Application Registry // --------------------------------------------------------- adminRoutes.get("/apps", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const apps = await sqlWrapper.sql` SELECT a.id, a.name, a.spiffe_id, a.description, a.created_at, COUNT(g.id) AS active_grants_count FROM apps a LEFT JOIN grants g ON a.id = g.app_id GROUP BY a.id, a.name, a.spiffe_id, a.description, a.created_at ORDER BY a.created_at ASC `; return c.json({ apps }); }); adminRoutes.post("/apps", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const { name, spiffeId, description, domain, is_public, bypass_paths, allowed_cidrs, } = await c.req.json(); if (!name || !spiffeId) { return c.json({ error: "Name and SPIFFE ID are required" }, 400); } try { const newApp = await sqlWrapper.sql` INSERT INTO apps (name, spiffe_id, description, domain, is_public, bypass_paths, allowed_cidrs) VALUES (${name.trim()}, ${spiffeId.trim()}, ${ description?.trim() || null }, ${domain?.trim() || null}, ${is_public || false}, ${ bypass_paths || [] }, ${allowed_cidrs || []}) RETURNING id, name, spiffe_id, description, created_at `.then((res: any) => res[0]); auditWrapper.auditLog(auth.userId, "app_registered", newApp.id, { name: newApp.name, spiffe_id: newApp.spiffe_id, }, getClientIp(c)); return c.json({ success: true, app: newApp }); } catch (err: any) { if (err.code === "23505") { return c.json({ error: "An application with this SPIFFE ID already exists", }, 409); } return c.json({ error: "Failed to register application" }, 500); } }); adminRoutes.put("/apps/:id", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const appId = c.req.param("id"); const { name, description, domain, is_public, bypass_paths, allowed_cidrs, } = await c.req.json(); if (!name) { return c.json({ error: "Application name is required" }, 400); } try { const updatedApp = await sqlWrapper.sql` UPDATE apps SET name = ${name.trim()}, description = ${description?.trim() || null}, domain = ${domain?.trim() || null}, is_public = ${is_public || false}, bypass_paths = ${bypass_paths || []}, allowed_cidrs = ${allowed_cidrs || []} WHERE id = ${appId} RETURNING id, name, spiffe_id, description, domain, is_public, bypass_paths, allowed_cidrs `.then((res: any) => res[0]); if (!updatedApp) return c.json({ error: "Application not found" }, 404); auditWrapper.auditLog(auth.userId, "app_updated", updatedApp.id, { name: updatedApp.name, }, getClientIp(c)); return c.json({ success: true, app: updatedApp }); } catch (_err: any) { return c.json({ error: "Failed to update application" }, 500); } }); adminRoutes.delete("/apps/:id", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const appId = c.req.param("id"); const app = await sqlWrapper .sql`DELETE FROM apps WHERE id = ${appId} RETURNING id, name` .then((res: any) => res[0]); if (app) { auditWrapper.auditLog( auth.userId, "app_deleted", appId, { name: app.name }, getClientIp(c), ); return c.json({ success: true }); } return c.json({ error: "Application not found" }, 404); }); // --------------------------------------------------------- // Admin Role Catalog Management // --------------------------------------------------------- adminRoutes.get("/roles", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const appId = c.req.query("appId"); let roles; if (appId) { roles = await sqlWrapper.sql` SELECT r.id, r.name, r.description, r.app_id, r.created_at, a.name AS app_name FROM roles r LEFT JOIN apps a ON r.app_id = a.id WHERE r.app_id IS NULL OR r.app_id = ${appId} ORDER BY r.app_id NULLS FIRST, r.name ASC `; } else { roles = await sqlWrapper.sql` SELECT r.id, r.name, r.description, r.app_id, r.created_at, a.name AS app_name FROM roles r LEFT JOIN apps a ON r.app_id = a.id ORDER BY r.app_id NULLS FIRST, r.name ASC `; } return c.json({ roles }); }); adminRoutes.post("/roles", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const { name, description, appId } = await c.req.json(); if ( !name || typeof name !== "string" || name.trim().length < 2 || name.trim().length > 32 ) { return c.json( { error: "Role name must be between 2 and 32 characters" }, 400, ); } const normalizedName = name.trim().toLowerCase().replace(/[^a-z0-9_-]/g, "_"); let validatedAppId = null; if (appId && typeof appId === "string" && appId.trim()) { const uuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/; if (!uuidRegex.test(appId)) { return c.json({ error: "Invalid App UUID" }, 400); } const appExists = await sqlWrapper .sql`SELECT id, name FROM apps WHERE id = ${appId}` .then((res: any) => res[0]); if (!appExists) { return c.json({ error: "Selected application does not exist" }, 404); } validatedAppId = appId; } try { const newRole = await sqlWrapper.sql` INSERT INTO roles (name, description, app_id) VALUES (${normalizedName}, ${ description?.trim() || null }, ${validatedAppId}) RETURNING id, name, description, app_id, created_at `.then((res: any) => res[0]); auditWrapper.auditLog(auth.userId, "role_created", validatedAppId, { role_name: newRole.name, scope: validatedAppId ? "app-specific" : "global", }, getClientIp(c)); return c.json({ success: true, role: newRole }); } catch (err: any) { if (err.code === "23505") { return c.json({ error: "This role already exists for the selected scope", }, 409); } return c.json({ error: "Failed to create role" }, 500); } }); adminRoutes.put("/roles/:id", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const roleId = c.req.param("id"); const { name, description } = await c.req.json(); if (!name || typeof name !== "string" || name.trim().length < 2) { return c.json({ error: "Role name must be at least 2 characters" }, 400); } const normalizedName = name.trim().toLowerCase().replace(/[^a-z0-9_-]/g, "_"); try { const updatedRole = await sqlWrapper.sql` UPDATE roles SET name = ${normalizedName}, description = ${description?.trim() || null} WHERE id = ${roleId} RETURNING id, name, description, app_id, created_at `.then((res: any) => res[0]); if (!updatedRole) return c.json({ error: "Role not found" }, 404); auditWrapper.auditLog(auth.userId, "role_updated", updatedRole.app_id, { role_name: updatedRole.name, }, getClientIp(c)); return c.json({ success: true, role: updatedRole }); } catch (_err: any) { return c.json({ error: "Failed to update role" }, 500); } }); adminRoutes.delete("/roles/:id", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const roleId = c.req.param("id"); const role = await sqlWrapper .sql`SELECT id, name, app_id FROM roles WHERE id = ${roleId}`.then( (res: any) => res[0], ); if (!role) { return c.json({ error: "Role not found" }, 404); } if (role.name === "admin" && role.app_id === null) { return c.json({ error: "The global 'admin' role cannot be deleted" }, 400); } await sqlWrapper.sql`DELETE FROM roles WHERE id = ${roleId}`; auditWrapper.auditLog( auth.userId, "role_deleted", role.app_id, { role_name: role.name }, getClientIp(c), ); return c.json({ success: true }); }); // --------------------------------------------------------- // Admin Invites / Registration Tokens // --------------------------------------------------------- adminRoutes.get("/invites", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const invites = await sqlWrapper.sql` SELECT i.id, i.code, i.role, i.max_uses, i.uses_count, i.auto_activate, i.expires_at, i.created_at, i.used_at, a.name AS app_name, a.id AS app_id, u.username AS used_by_username FROM invites i LEFT JOIN apps a ON i.app_id = a.id LEFT JOIN users u ON i.used_by = u.id ORDER BY i.created_at DESC `; return c.json({ invites }); }); adminRoutes.post("/invites/create", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const { appId, role, expiresInDays, customCode, usageLimitType, maxUses, autoActivate, } = await c.req.json(); const assignedRole = (typeof role === "string" && role.trim()) ? role.trim() : "user"; let validatedAppId = null; if (appId) { const uuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/; if (typeof appId !== "string" || !uuidRegex.test(appId)) { return c.json({ error: "appId must be a valid UUID string" }, 400); } const appExists = await sqlWrapper .sql`SELECT id FROM apps WHERE id = ${appId}`.then( (res: any) => res[0], ); if (!appExists) { return c.json({ error: "Target application does not exist" }, 404); } validatedAppId = appId; } let parsedMaxUses: number | null = 1; if (usageLimitType === "unlimited") { parsedMaxUses = null; } else if (usageLimitType === "limited") { const n = parseInt(maxUses); parsedMaxUses = (!isNaN(n) && n > 0) ? n : 5; } else { parsedMaxUses = 1; // single-use default } const shouldAutoActivate = autoActivate !== false; const inviteCode = (customCode && typeof customCode === "string" && customCode.trim()) ? customCode.trim() : encodeBase64Url(crypto.getRandomValues(new Uint8Array(24))); const days = Number(expiresInDays) || 7; if (!Number.isInteger(days) || days < 1 || days > 30) { return c.json({ error: "expiresInDays must be an integer between 1 and 30", }, 400); } const expiresAt = new Date(); expiresAt.setDate(expiresAt.getDate() + days); try { await sqlWrapper.sql` INSERT INTO invites (code, app_id, role, created_by, max_uses, uses_count, auto_activate, expires_at) VALUES (${inviteCode}, ${validatedAppId}, ${assignedRole}, ${auth.userId}, ${parsedMaxUses}, 0, ${shouldAutoActivate}, ${expiresAt}) `; } catch (err: any) { if (err.code === "23505") { return c.json({ error: "An invite with this code already exists" }, 409); } return c.json({ error: "Failed to generate invite" }, 500); } auditWrapper.auditLog( auth.userId, "invite_created", validatedAppId, { code: inviteCode, role: assignedRole, max_uses: parsedMaxUses, auto_activate: shouldAutoActivate, expiresInDays: days, }, getClientIp(c), ); return c.json({ success: true, inviteCode, expiresAt, maxUses: parsedMaxUses, autoActivate: shouldAutoActivate, }); }); adminRoutes.get("/invites/:id/redemptions", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const inviteId = c.req.param("id"); const redemptions = await sqlWrapper.sql` SELECT ir.id, ir.redeemed_at, u.id AS user_id, u.username, u.display_name, u.account_status FROM invite_redemptions ir JOIN users u ON ir.user_id = u.id WHERE ir.invite_id = ${inviteId} ORDER BY ir.redeemed_at DESC `; return c.json({ redemptions }); }); adminRoutes.delete("/invites/:id", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const inviteId = c.req.param("id"); const invite = await sqlWrapper .sql`DELETE FROM invites WHERE id = ${inviteId} RETURNING id, code` .then((res: any) => res[0]); if (invite) { auditWrapper.auditLog( auth.userId, "invite_revoked", inviteId, { code: invite.code }, getClientIp(c), ); return c.json({ success: true }); } return c.json({ error: "Invite not found" }, 404); }); // --------------------------------------------------------- // Admin User RBAC Grants Management // --------------------------------------------------------- adminRoutes.get("/users/:id/grants", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const targetUserId = c.req.param("id"); const grants = await sqlWrapper.sql` SELECT g.id, g.app_id, g.role, g.created_at, a.name AS app_name, a.spiffe_id FROM grants g JOIN apps a ON g.app_id = a.id WHERE g.user_id = ${targetUserId} ORDER BY a.name ASC `; return c.json({ grants }); }); adminRoutes.post("/users/:id/grants", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const targetUserId = c.req.param("id"); const { appId, role } = await c.req.json(); if (!appId || !role) { return c.json({ error: "appId and role are required" }, 400); } const app = await sqlWrapper .sql`SELECT id, name FROM apps WHERE id = ${appId}`.then( (res: any) => res[0], ); if (!app) return c.json({ error: "Application not found" }, 404); const targetUser = await sqlWrapper .sql`SELECT id, username FROM users WHERE id = ${targetUserId}`.then( (res: any) => res[0], ); if (!targetUser) return c.json({ error: "User not found" }, 404); await sqlWrapper.sql` INSERT INTO grants (user_id, app_id, role) VALUES (${targetUserId}, ${appId}, ${role}) ON CONFLICT (user_id, app_id) DO UPDATE SET role = ${role} `; auditWrapper.auditLog( auth.userId, "user_grant_assigned", targetUserId, { app_id: appId, app_name: app.name, role }, getClientIp(c), ); return c.json({ success: true }); }); adminRoutes.delete("/users/:id/grants/:appId", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const { id: targetUserId, appId } = c.req.param(); const grant = await sqlWrapper.sql` DELETE FROM grants WHERE user_id = ${targetUserId} AND app_id = ${appId} RETURNING id `.then((res: any) => res[0]); if (grant) { auditWrapper.auditLog( auth.userId, "user_grant_revoked", targetUserId, { app_id: appId }, getClientIp(c), ); return c.json({ success: true }); } return c.json({ error: "Grant not found" }, 404); }); // --------------------------------------------------------- // Admin AAGUID Management // --------------------------------------------------------- adminRoutes.get("/aaguid", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const allowlist = await sqlWrapper .sql`SELECT id, aaguid, description, created_at FROM aaguid_allowlist ORDER BY created_at DESC`; return c.json({ allowlist }); }); adminRoutes.post("/aaguid", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const { aaguid, description } = await c.req.json(); const uuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/i; if (!aaguid || !uuidRegex.test(aaguid)) { return c.json({ error: "Valid AAGUID (UUID) is required" }, 400); } try { await sqlWrapper .sql`INSERT INTO aaguid_allowlist (aaguid, description) VALUES (${aaguid.toLowerCase()}, ${ description || null })`; auditWrapper.auditLog( auth.userId, "aaguid_added", null, { aaguid }, getClientIp(c), ); return c.json({ success: true }); } catch (err: any) { if (err.code === "23505") { return c.json({ error: "AAGUID already exists" }, 409); } return c.json({ error: "Internal server error" }, 500); } }); adminRoutes.delete("/aaguid/:id", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const id = c.req.param("id"); const record = await sqlWrapper .sql`DELETE FROM aaguid_allowlist WHERE id = ${id} RETURNING aaguid` .then((res: any) => res[0]); if (record) { auditWrapper.auditLog( auth.userId, "aaguid_removed", null, { aaguid: record.aaguid }, getClientIp(c), ); } return c.json({ success: true }); }); // --------------------------------------------------------- // Admin HWK (Header Web Key) Management // --------------------------------------------------------- adminRoutes.post("/hwk", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const { jwk, name } = await c.req.json(); if (!jwk || !name || typeof name !== "string") { return c.json({ error: "Missing required fields: jwk, name" }, 400); } if (jwk.kty !== "OKP" || jwk.crv !== "Ed25519" || !jwk.x) { return c.json({ error: "Invalid JWK: Must be an Ed25519 OKP key" }, 400); } try { const fingerprint = await computeJwkThumbprint(jwk); // 1. Dual Storage: PostgreSQL (Durability) await sqlWrapper.sql` INSERT INTO hwk_keys (fingerprint, public_key, name) VALUES (${fingerprint}, ${JSON.stringify(jwk)}, ${name}) `; // 2. Dual Storage: Valkey (O(1) Verification) await valkey.sadd("auth:hwk:fingerprints", fingerprint); auditWrapper.auditLog( auth.userId, "hwk_added", null, { fingerprint, name }, getClientIp(c), ); return c.json({ success: true, fingerprint }, 201); } catch (err: any) { if (err.code === "23505") { return c.json({ error: "This key has already been registered" }, 409); } console.error("Failed to add HWK:", err); return c.json({ error: "Internal server error" }, 500); } }); adminRoutes.delete("/hwk/:fingerprint", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const fingerprint = c.req.param("fingerprint"); // 1. Remove from PostgreSQL const record = await sqlWrapper.sql` DELETE FROM hwk_keys WHERE fingerprint = ${fingerprint} RETURNING id, name `.then((res: any) => res[0]); if (record) { // 2. Remove from Valkey try { await valkey.srem("auth:hwk:fingerprints", fingerprint); } catch (_err) {} auditWrapper.auditLog(auth.userId, "hwk_removed", null, { fingerprint, name: record.name, }, getClientIp(c)); return c.json({ success: true }); } return c.json({ error: "Key not found" }, 404); }); // --------------------------------------------------------- // Global Session and Device Revocation (Admin) // --------------------------------------------------------- adminRoutes.get("/users/:id", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const targetUserId = c.req.param("id"); const user = await sqlWrapper .sql`SELECT id, username, display_name, account_status FROM users WHERE id = ${targetUserId}` .then((res: any) => res[0]); if (!user) return c.json({ error: "User not found" }, 404); const sessions = await sqlWrapper .sql`SELECT id, created_at, expires_at FROM sessions WHERE user_id = ${targetUserId} ORDER BY created_at DESC`; const passkeys = await sqlWrapper .sql`SELECT id, credential_id, counter FROM passkeys WHERE user_id = ${targetUserId}`; return c.json({ user, sessions, passkeys }); }); adminRoutes.delete("/sessions/:id", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const sessionId = c.req.param("id"); const session = await sqlWrapper .sql`DELETE FROM sessions WHERE id = ${sessionId} RETURNING user_id` .then((res: any) => res[0]); if (session) { try { await valkey.del(sessionId); } catch (_err) {} auditWrapper.auditLog( auth.userId, "admin_session_revoked", session.user_id, { revoked_session_id: sessionId, }, getClientIp(c), ); } return c.json({ success: true }); }); adminRoutes.delete("/users/:id/sessions", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const targetUserId = c.req.param("id"); const sessions = await sqlWrapper .sql`DELETE FROM sessions WHERE user_id = ${targetUserId} RETURNING id`; for (const session of sessions) { try { await valkey.del(session.id); } catch (_err) {} } auditWrapper.auditLog( auth.userId, "admin_all_sessions_revoked", targetUserId, null, getClientIp(c), ); return c.json({ success: true }); }); adminRoutes.delete("/users/:userId/passkeys/:passkeyId", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const { userId, passkeyId } = c.req.param(); const passkey = await sqlWrapper .sql`DELETE FROM passkeys WHERE id = ${passkeyId} AND user_id = ${userId} RETURNING id` .then((res: any) => res[0]); if (passkey) { auditWrapper.auditLog(auth.userId, "admin_passkey_revoked", userId, { passkey_id: passkey.id, }, getClientIp(c)); return c.json({ success: true }); } return c.json({ error: "Passkey not found" }, 404); }); // --------------------------------------------------------- // Out-of-Band Account Recovery (Use Case 12) // --------------------------------------------------------- adminRoutes.post("/users/:id/recovery", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const targetUserId = c.req.param("id"); const targetUser = await sqlWrapper .sql`SELECT id FROM users WHERE id = ${targetUserId}` .then((res: any) => res[0]); if (!targetUser) return c.json({ error: "User not found" }, 404); const recoveryCode = encodeBase64Url( crypto.getRandomValues(new Uint8Array(24)), ); const expiresAt = new Date(); expiresAt.setDate(expiresAt.getDate() + 1); await sqlWrapper .sql`INSERT INTO recovery_links (code, user_id, created_by, expires_at) VALUES (${recoveryCode}, ${targetUserId}, ${auth.userId}, ${expiresAt})`; auditWrapper.auditLog( auth.userId, "recovery_link_created", targetUserId, null, getClientIp(c), ); return c.json({ success: true, recoveryCode, expiresAt }); }); adminRoutes.get("/check", async (c) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const isAdmin = await isGlobalAdmin(auth.userId); return c.json({ isAdmin }); });