feat(19-03): implement localAuthMiddleware, GET /api/auth/mode, and pre-auth route mounts
- localAuthMiddleware: cookie→c.set('user') with Pitfall-1 guard (no-set on no-cookie path)
- authMode: GET /api/auth/mode pre-auth endpoint (localEnabled:true, oidcEnabled from env+config)
- localAuth: POST /api/auth/local/login (rate-limit + timing-safe), logout routes
- index.ts: mount authModeRouter + localAuthRouter pre-auth; localAuthMiddleware after devAuthBypass; OIDC guard wrapped skip-when-user-set
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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 });
|
||||
});
|
||||
Reference in New Issue
Block a user