mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 14:32:03 +00:00
fix(auth): harden the OIDC token path and state-cookie lifecycle
Token verification: jwtVerify now carries a closed asymmetric algorithm allowlist (RS256/PS256/ES256/EdDSA — an HMAC alg would let anyone with the client secret forge identities) and a 60 s clock tolerance for the usual self-host drift between IdP and app box. The JWKS fetch — jose's own, outside safeFetch by design — is disciplined instead by pinning the jwks_uri host to the configured issuer's host byte-exact and passing the same 15 s timeout safeFetch defaults to. requirePublicHost stays deliberately unused on this surface: LAN/Tailscale-only IdPs are a legitimate topology and the issuer is operator config, not user input. Discovery: the issuer comparison now tolerates exactly one trailing slash on either side (a recurring IdP/operator mismatch); token verification still matches the provider-sent issuer byte-exact. State cookie: the cookie is set under Path=/api/auth/oidc but was deleted without a path — RFC 6265 keys cookies by (name, domain, path), so the deletion never matched and the single-use blob survived its whole TTL. Every delete now repeats the exact path, via a shared constant. Also: the IdP error code recorded in the wide event is whitelisted against the closed OAuth error-code set (unknown values collapse to "other"); the status route drops an unreachable try/catch and a duplicated annotate; the passkey conditional-UI autofill stays unarmed under OIDC_ONLY (passkey login is a server-enforced dead end there); env-manifest gains the three optional OIDC_* tuning vars; the env example notes why the issuer should be HTTPS.
This commit is contained in:
1 parent
9b8b31c864
commit
7592c73947
10 files changed
+252
-32
No files matched your search
@@ -98,6 +98,25 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OIDC SSO options",
|
||||
"description": "Optional tuning for an enabled OIDC provider. Each stands alone (deliberately NOT allOrNone — any subset is valid) and each has a safe default when unset.",
|
||||
"required": false,
|
||||
"variables": [
|
||||
{
|
||||
"name": "OIDC_SCOPES",
|
||||
"purpose": "Space-separated scopes requested at authorization. Default: \"openid email profile\"."
|
||||
},
|
||||
{
|
||||
"name": "OIDC_BUTTON_LABEL",
|
||||
"purpose": "Label on the login page's SSO button. Default: \"Single Sign-On\"."
|
||||
},
|
||||
{
|
||||
"name": "OIDC_ONLY",
|
||||
"purpose": "\"true\" disables password/passkey login server-side (only effective when the OIDC provider group is fully configured). Default: additive login. Locks the native iOS app out of sign-in."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"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.",
|
||||
|
||||
Reference in new issue
Block a user