feat(19-03): wire /callback link branch, OIDC-guard skip, de-Authelia comments
- /callback: reads signed state, extracts linkUserId, calls linkOidcToUser after OIDC session set; OidcLinkConflictError redirects to /?error=oidc-link-conflict - OIDC guard: oidcAuthMiddleware() factory called once at construction, handler invoked per-request inside skip-when-user-set wrapper (D-03) - middleware.ts: de-Authelia-ize comments — generic OIDC identity provider language (D-06, AUTH-LOCAL-18) - localAuthMiddleware.ts: cast to typeof DEV_USER for ContextVariableMap type compatibility - All 446 tests pass; typecheck clean
This commit is contained in:
@@ -33,6 +33,7 @@ import { eq } from 'drizzle-orm';
|
||||
import { db } from '../db/client.js';
|
||||
import { users } from '../db/schema.js';
|
||||
import { verifyLocalSessionCookie } from './localSession.js';
|
||||
import type { DEV_USER } from './devBypass.js';
|
||||
|
||||
/**
|
||||
* Returns a Hono MiddlewareHandler that:
|
||||
@@ -82,14 +83,15 @@ export function localAuthMiddleware(): MiddlewareHandler {
|
||||
|
||||
// Populate c.get('user') with the same shape as DEV_USER (devBypass.ts ContextVariableMap).
|
||||
// oidcIss/oidcSub: local users have nullable oidcIss/oidcSub — use fallback strings so the
|
||||
// shape matches typeof DEV_USER (all required fields, no undefined in the value object).
|
||||
// shape is compatible with typeof DEV_USER at runtime. Cast required because ContextVariableMap
|
||||
// is narrowed to the const DEV_USER literal type.
|
||||
c.set('user', {
|
||||
id: row.id,
|
||||
oidcIss: row.oidcIss ?? 'local',
|
||||
oidcSub: row.oidcSub ?? String(row.id),
|
||||
displayName: row.displayName ?? null,
|
||||
color: row.color ?? '#4A90D9',
|
||||
});
|
||||
} as typeof DEV_USER);
|
||||
|
||||
await next();
|
||||
};
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* OIDC authentication middleware wiring.
|
||||
*
|
||||
* Configures @hono/oidc-auth for Authelia as the identity provider.
|
||||
* Configures @hono/oidc-auth for the generic OIDC identity provider (D-06).
|
||||
*
|
||||
* Required env vars:
|
||||
* OIDC_AUTH_SECRET — 32+ char random string for JWT cookie signing (T-02-03)
|
||||
* OIDC_ISSUER — Authelia base URL (middleware fetches /.well-known/openid-configuration)
|
||||
* OIDC_CLIENT_ID — registered client ID in Authelia
|
||||
* OIDC_ISSUER — OIDC issuer URL (middleware fetches /.well-known/openid-configuration)
|
||||
* OIDC_CLIENT_ID — registered client ID at the OIDC provider
|
||||
* OIDC_CLIENT_SECRET — PLAIN text secret (NOT the pbkdf2 hash — see Pitfall 7)
|
||||
* OIDC_REDIRECT_URI — https://familysync.<domain>/callback
|
||||
* OIDC_AUTH_EXTERNAL_URL — https://familysync.<domain> — MANDATORY behind Pangolin (Pitfall 1)
|
||||
@@ -30,7 +30,7 @@
|
||||
* Every OIDC_AUTH_REFRESH_INTERVAL (default 15 min) the middleware calls
|
||||
* the token endpoint with the stored refresh token — no iframe required (D-12).
|
||||
* Session lifespan is governed by OIDC_AUTH_EXPIRES (default 1 day) and
|
||||
* Authelia's refresh_token_lifespan.
|
||||
* the OIDC provider's refresh_token_lifespan.
|
||||
*
|
||||
* Scopes: openid, profile, email only — no 'groups' scope (D-11).
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user