fix: survive an unconfigured identity provider
Auth.js refuses to build a provider with no issuer, and that refusal takes down the whole auth layer — including reading a session that already exists. A missing or misspelled AUTH_AUTHENTIK_ISSUER would therefore lock everyone out of an otherwise healthy application, and explain itself only as a stack trace in the logs. The provider is now registered only when its three settings are present. Sessions stay readable either way, and the sign-in page says which variables are missing instead of offering a button that fails. Found by the first CI run, which has no .env to inherit from: every signed-in test failed at once, looking exactly like a broken cookie. The local suite had been passing on variables Playwright was quietly inheriting from the development environment — so the E2E server is now given explicit placeholders rather than whatever happens to be around. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012cSY9pVhZmJUKNN7wf1Myd
This commit is contained in:
+19
-1
@@ -19,6 +19,22 @@ import { groupsFromClaim, roleFromGroups, type Role } from './roles';
|
||||
|
||||
const ADMIN_GROUP = process.env.AUTHENTIK_ADMIN_GROUP?.trim() || 'horaires-admins';
|
||||
|
||||
/**
|
||||
* Whether Authentik is configured well enough to sign anyone in.
|
||||
*
|
||||
* Auth.js refuses to build a provider that has no issuer, and that refusal
|
||||
* takes down the whole auth layer — including reading a session that already
|
||||
* exists. A missing or misspelled variable would therefore lock everyone out
|
||||
* of an application that is otherwise perfectly healthy, and say so only as a
|
||||
* stack trace in the logs. Registering the provider only when it can work
|
||||
* keeps sessions readable and lets the sign-in page explain itself.
|
||||
*/
|
||||
export const isAuthentikConfigured = Boolean(
|
||||
process.env.AUTH_AUTHENTIK_ID &&
|
||||
process.env.AUTH_AUTHENTIK_SECRET &&
|
||||
process.env.AUTH_AUTHENTIK_ISSUER,
|
||||
);
|
||||
|
||||
/** Enough to explain a read-only account, not enough to bloat the cookie. */
|
||||
const MAX_REPORTED_GROUPS = 20;
|
||||
|
||||
@@ -45,7 +61,9 @@ declare module '@auth/core/jwt' {
|
||||
}
|
||||
|
||||
const nextAuth = NextAuth({
|
||||
providers: [Authentik({ name: process.env.AUTHENTIK_DISPLAY_NAME?.trim() || 'Loxi' })],
|
||||
providers: isAuthentikConfigured
|
||||
? [Authentik({ name: process.env.AUTHENTIK_DISPLAY_NAME?.trim() || 'Loxi' })]
|
||||
: [],
|
||||
// The application sits behind a reverse proxy; the forwarded host is the
|
||||
// real one.
|
||||
trustHost: true,
|
||||
|
||||
Reference in New Issue
Block a user