import type { Context } from "jsr:@hono/hono@4"; import { getClientIp, getCookieDomain, isIpAllowed, isPathBypassed, isSafeRedirectUrl, } from "./forward_auth.ts"; import { type AppRecord, type AuthenticatedUser, extractAllSessionIds, getAppByHost, getAuthenticatedUser, getUserGrant, isGlobalAdmin, } from "./session_resolver.ts"; // Re-export for backward compatibility export { type AppRecord, type AuthenticatedUser, extractAllSessionIds, getAppByHost, getAuthenticatedUser, getClientIp, getCookieDomain, getUserGrant, isGlobalAdmin, isIpAllowed, isPathBypassed, isSafeRedirectUrl, }; /** * Evaluates if the current user's capabilities satisfy the required scope. * If !auth.isAgent, primary sessions inherit full capabilities (returns true). * If auth.isAgent, checks if customScopes contains the requiredScope or '*'. */ export function hasScope( auth: AuthenticatedUser, requiredScope: string, ): boolean { if (!auth.isAgent) return true; if (!Array.isArray(auth.customScopes)) return false; return auth.customScopes.includes("*") || auth.customScopes.includes(requiredScope); } /** * Helper to check if the session itself is authorized as an admin. */ export async function isSessionAdmin( auth: AuthenticatedUser, ): Promise { const globalAdmin = await isGlobalAdmin(auth.userId); if (!globalAdmin) return false; if (!auth.isAgent) return true; return Array.isArray(auth.customScopes) && auth.customScopes.includes("*"); } /** * Hono Middleware: Blocks access if the session is a delegated agent session. */ export async function requirePrimarySession( c: Context, next: () => Promise, ) { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); if (auth.isAgent) { return c.json({ error: "Forbidden: Primary session required" }, 403); } await next(); } /** * Hono Middleware Factory: Requires a specific scope. */ export function requireScope(scope: string) { return async (c: Context, next: () => Promise) => { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); if (!hasScope(auth, scope)) { return c.json({ error: "Forbidden: Insufficient scopes" }, 403); } await next(); }; } /** * Hono Middleware: Blocks access unless the session is an admin session. */ export async function requireAdmin(c: Context, next: () => Promise) { const auth = await getAuthenticatedUser(c); if (!auth) return c.json({ error: "Unauthorized" }, 401); const isAdmin = await isSessionAdmin(auth); if (!isAdmin) { return c.json({ error: "Forbidden: Global admin access required" }, 403); } await next(); }