mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 14:40:52 +00:00
feat(auth): pin OIDC accounts to their (issuer, sub) identity
An OIDC login now resolves the account by the durable (issuer, sub) pair instead of the email claim. First contact stamps the pair — by auto-provision or a one-time link against an existing account matched by verified email — and every later login matches on it alone, so an IdP-side email change refreshes the display email but can never re-point the login at a different account. An email that matches an account already bound to a different identity is rejected and audited (auth.oidc.link_conflict), never silently re-bound. The email gate tightens with it: linking and provisioning now require an explicit email_verified: true — an absent claim is a reject (oidc_email_unverified) rather than a benefit of the doubt, since an IdP that does not assert verification cannot anchor the account match. Provisioned accounts get a lowercased email and the same server-default timezone resolution the register route uses. Migration 0240 adds the nullable users.oidc_issuer / users.oidc_sub columns with a composite unique index.
This commit is contained in:
1 parent
f815e4a83f
commit
fa326c398a
11 files changed
+348
-141
No files matched your search
@@ -39,6 +39,8 @@ export default function LoginPage() {
|
||||
const key: Record<string, string> = {
|
||||
oidc_denied: "auth.oidc.errorDenied",
|
||||
oidc_no_email: "auth.oidc.errorNoEmail",
|
||||
oidc_email_unverified: "auth.oidc.errorEmailUnverified",
|
||||
oidc_identity_conflict: "auth.oidc.errorIdentityConflict",
|
||||
oidc_registration_disabled: "auth.oidc.errorRegistrationDisabled",
|
||||
};
|
||||
return t(key[oidcError] ?? "auth.oidc.errorFailed");
|
||||
|
||||
Reference in new issue
Block a user