/** * authMode.ts — GET /api/auth/mode pre-auth endpoint (AUTH-LOCAL-05). * * Returns { localEnabled: boolean, oidcEnabled: boolean } reflecting the current * authentication configuration. This endpoint is intentionally reachable before * authentication (same pre-auth pattern as GET /api/setup/status). * * Mount in index.ts BEFORE devAuthBypass and OIDC guard: * app.route('/api/auth', authModeRouter); ← pre-auth * * Response contract: * - localEnabled: always true — local auth is the default, always available (D-01). * - oidcEnabled: true when OIDC_ISSUER env var is set, OR when app_config has * an oidc_issuer row (supports wizard-configured OIDC before container restart). * * No auth gate, no isSetupLocked() check — the PWA fetches this on app load before * knowing if the user is authenticated. */ import { Hono } from 'hono'; import { eq } from 'drizzle-orm'; import { db } from '../db/client.js'; import { appConfig } from '../db/schema.js'; export const authModeRouter = new Hono(); /** * GET / (mounted as /api/auth, so effective path is GET /api/auth/mode) * * Checks OIDC_ISSUER env var first (process.env is cheapest); falls back to * app_config DB row if env var is absent (wizard-configured OIDC). */ authModeRouter.get('/mode', async (c) => { // localEnabled: always true (D-01) // oidcEnabled: env var first, then app_config fallback const issuerFromEnv = process.env.OIDC_ISSUER; let oidcEnabled = Boolean(issuerFromEnv); if (!oidcEnabled) { // Check app_config for oidc_issuer (wizard-written, pre-restart-fallback pattern from middleware.ts) const [row] = await db .select({ value: appConfig.value }) .from(appConfig) .where(eq(appConfig.key, 'oidc_issuer')) .limit(1); oidcEnabled = Boolean(row?.value); } return c.json({ localEnabled: true, oidcEnabled }); });