External authentication (ADR 0021) built on jose (#188's vetted library) plus fetch — no new dependency enters the supply chain for a security base function. Discovery-configured; ID tokens validate against the IdP's JWKS under an explicit RS256/ES256 allowlist with issuer, audience, expiry and nonce binding. State, nonce and the PKCE verifier travel in a signed HttpOnly Lax cookie keyed by a dedicated HKDF purpose (oidc-state, ADR 0020). Deploy-level configuration (OIDC_ISSUER/CLIENT_ID/CLIENT_SECRET/SCOPES/ PROVIDER_LABEL): who authenticates users is a platform decision. The login page discovers the provider via GET /auth/methods and renders the SSO button (i18n de+en). Identities use the existing slot (provider oidc:<issuer>, subject from the token). First login creates the account just-in-time — ACTIVE and mail-verified only when the IdP asserts a verified address. An existing local account is NEVER adopted silently by e-mail (account-takeover path): login refuses with oidc_link_required and the owner links explicitly via GET /auth/oidc/link (audited auth.identity_linked, catalogue v1.3). Sessions come from the one existing session service. Tests run the full flow against a protocol-faithful fake IdP: PKCE verifier at the token endpoint, JIT creation incl. personal pond, invalid state/nonce/signature/issuer/audience/expiry each rejected, the linking refusal and the explicit link flow. Verified end-to-end against a real Keycloak 26.0 (repeatable procedure documented in security.md §External authentication). Refs #214. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AUtYMxwTCMHG9mVHnwbFg8
88 lines
3.3 KiB
JSON
88 lines
3.3 KiB
JSON
{
|
|
"login": {
|
|
"title": "Sign in",
|
|
"usernameOrEmail": "Username or e-mail",
|
|
"password": "Password",
|
|
"submit": "Sign in",
|
|
"forgot": "Forgot your password?",
|
|
"noAccount": "No account yet?",
|
|
"signupLink": "Register now",
|
|
"resendHint": "Didn't get the confirmation mail?",
|
|
"resendLink": "Send it again"
|
|
},
|
|
"signup": {
|
|
"title": "Create your account",
|
|
"username": "Username",
|
|
"usernameHint": "Letters, digits, hyphens — this is your address inside Dorfteich.",
|
|
"email": "E-mail address",
|
|
"displayName": "Display name",
|
|
"password": "Password",
|
|
"passwordHint": "At least 10 characters. A short sentence works well.",
|
|
"submit": "Register",
|
|
"haveAccount": "Already registered?",
|
|
"loginLink": "Sign in",
|
|
"closed": "Registration is currently closed on this instance.",
|
|
"success": {
|
|
"title": "Check your inbox",
|
|
"body": "We sent a confirmation link to {{email}}. It is valid for 24 hours.",
|
|
"resend": "Send the mail again"
|
|
}
|
|
},
|
|
"verify": {
|
|
"title": "Confirming your e-mail address …",
|
|
"success": {
|
|
"title": "E-mail address confirmed",
|
|
"body": "Your account is active — you can sign in now.",
|
|
"login": "Go to sign-in"
|
|
},
|
|
"error": {
|
|
"title": "This link did not work",
|
|
"resendPrompt": "Enter your e-mail address and we will send a fresh link:",
|
|
"resend": "Send new link"
|
|
},
|
|
"resent": "If the address belongs to an unconfirmed account, a new mail is on its way."
|
|
},
|
|
"forgot": {
|
|
"title": "Reset password",
|
|
"body": "Enter your e-mail address. If an account exists, you will receive a reset link (valid for one hour).",
|
|
"email": "E-mail address",
|
|
"submit": "Send reset link",
|
|
"sent": "Done — check your inbox.",
|
|
"backToLogin": "Back to sign-in"
|
|
},
|
|
"reset": {
|
|
"title": "Set a new password",
|
|
"password": "New password",
|
|
"submit": "Save password",
|
|
"success": {
|
|
"title": "Password saved",
|
|
"body": "All previous sessions were signed out. Sign in with your new password.",
|
|
"login": "Go to sign-in"
|
|
}
|
|
},
|
|
"menu": {
|
|
"settings": "Settings",
|
|
"admin": "Administration",
|
|
"logout": "Sign out",
|
|
"login": "Sign in",
|
|
"signup": "Register"
|
|
},
|
|
"oidc": {
|
|
"signIn": "Sign in with {{provider}}",
|
|
"or": "or",
|
|
"errors": {
|
|
"oidc_failed": "Single sign-on failed. Please try again.",
|
|
"oidc_cancelled": "Single sign-on was cancelled.",
|
|
"oidc_state_invalid": "The sign-on attempt expired. Please try again.",
|
|
"oidc_exchange_failed": "The identity provider rejected the sign-on. Please try again.",
|
|
"oidc_token_invalid": "The identity provider's response could not be verified.",
|
|
"oidc_discovery_failed": "The identity provider is currently unreachable.",
|
|
"oidc_email_missing": "The identity provider did not supply an e-mail address.",
|
|
"oidc_email_unverified": "Your e-mail address is not verified at the identity provider.",
|
|
"oidc_link_required": "An account with this e-mail address already exists. Sign in with your password and link single sign-on in your settings.",
|
|
"oidc_identity_taken": "This single sign-on identity is already linked to another account.",
|
|
"account_disabled": "This account is disabled."
|
|
}
|
|
}
|
|
}
|