fix(oidc): local-credential lockout, session hydration, split-origin gaps (codex round 3)
- OIDC-owned accounts can never authenticate locally: the password login rejects auth_provider='oidc' rows outright (generic 401), and the super-admin password reset refuses them with a clear message — previously a reset would have minted a local password bypassing the IdP's MFA/access policies - /auth/session now returns a full adminUser payload (role join) and AdminAuthContext hydrates user state from it: an SSO redirect establishes the session without any login JSON, which left the header identity blank and current-admin form defaults empty - the /sso/login error path redirects absolute to the frontend base (same split-origin reasoning as the callback) - docker-compose.yml passes API_URL through to the backend (production compose uses env_file and needs nothing; dev compose is gitignored) - authSession.symmetry test mock taught the joined admin lookup (leftJoin, prefixed columns, aliases) — the route change made the old mock throw, which read as "table missing, trust token" Tests: new case pins that a known-good password on an OIDC-owned row still gets 401. 14/14 OIDC, 13/13 symmetry.
This commit is contained in:
@@ -459,6 +459,13 @@ async function resetAdminPassword(id, resetById) {
|
||||
throw new NotFoundError('Admin user', id);
|
||||
}
|
||||
|
||||
// OIDC-owned accounts (#798) have no usable local password by design —
|
||||
// minting one here would hand out a login that bypasses the IdP's MFA
|
||||
// and access policies.
|
||||
if (user.auth_provider === 'oidc') {
|
||||
throw new ValidationError('This account is managed by your identity provider (SSO) — reset the password there.');
|
||||
}
|
||||
|
||||
const newPassword = generateReadablePassword();
|
||||
const passwordHash = await bcrypt.hash(newPassword, getBcryptRounds());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user