feat(auth): add OIDC SSO login

Adds an OpenID Connect relying-party login path (PKCE authorization-code
flow) against a single env-configured identity provider — additive to
password/passkey login by default, with an operator opt-in (OIDC_ONLY,
enforced server-side on every auth route) to disable them entirely.
First-time sign-in auto-provisions or links an account by verified email.

Closes an open redirect in the post-login `next` parameter (both the new
OIDC path and the pre-existing password/passkey flow shared the same
backslash-normalization bypass) by resolving the target through a real
URL parse and comparing origins instead of a prefix check.
This commit is contained in:
Balaji Vijayakumar committed 2026-07-13 16:33:13 +05:30
1 parent 6712619495
commit f815e4a83f
33 files changed
+2202 -95

No files matched your search

+20
View File
@@ -78,6 +78,26 @@
}
]
},
{
"name": "OIDC SSO login",
"description": "Required to enable SSO login against a self-hosted identity provider (Authentik, Keycloak, Authelia, Google Workspace, etc.). App boots without these but the login page's SSO button stays hidden. Register a confidential client with redirect URI ${NEXT_PUBLIC_APP_URL}/api/auth/oidc/callback.",
"required": false,
"allOrNone": true,
"variables": [
{
"name": "OIDC_ISSUER_URL",
"purpose": "OIDC provider issuer URL (discovery doc served at <issuer>/.well-known/openid-configuration)."
},
{
"name": "OIDC_CLIENT_ID",
"purpose": "OIDC confidential client id."
},
{
"name": "OIDC_CLIENT_SECRET",
"purpose": "OIDC confidential client secret."
}
]
},
{
"name": "APNs (iOS push)",
"description": "All four core APNS_* vars together. Missing any disables APNs silently — the v1.4.40 AP-2 gap that motivated this manifest. allOrNone trips the synthetic <all-or-none> required row whenever 1-3 of the 4 are set.",