feat(auth): split OIDC_ONLY into granular auth toggles

Replaces the coarse oidc_only + allow_registration settings with four
independent toggles: password_login, password_registration, oidc_login,
oidc_registration. Each can be enabled/disabled individually in
Admin > Settings without affecting the others.

- Add resolveAuthToggles() in authService.ts as the central resolver;
  falls back to legacy oidc_only/allow_registration keys when new keys
  are absent (backward compat)
- OIDC_ONLY env var still works and overrides DB toggles for password_*,
  with a visual lock in the admin UI when active
- Server enforces lockout prevention: cannot disable all login methods
- oidc_login gate added to OIDC /login and /callback routes
- Remove oidc_only toggle from OIDC settings panel; replaced by the
  granular toggles in the Settings tab
- Add 6 new resolveAuthToggles() unit tests; fix AUTH-DB-033 error
  message assertion
- Update OIDC_ONLY descriptions in README, docker-compose, Helm values,
  Unraid template, and .env.example to clarify override semantics

Closes #492
This commit is contained in:
jubnl
2026-04-11 20:21:22 +02:00
parent 2b1889b9a9
commit bfd2553d1e
28 changed files with 439 additions and 76 deletions
+5 -2
View File
@@ -102,13 +102,16 @@ router.get('/oidc', (_req: Request, res: Response) => {
});
router.put('/oidc', (req: Request, res: Response) => {
svc.updateOidcSettings(req.body);
const result = svc.updateOidcSettings(req.body);
if (result.error) {
return res.status(result.status || 400).json({ error: result.error });
}
const authReq = req as AuthRequest;
writeAudit({
userId: authReq.user.id,
action: 'admin.oidc_update',
ip: getClientIp(req),
details: { oidc_only: !!req.body.oidc_only, issuer_set: !!req.body.issuer },
details: { issuer_set: !!req.body.issuer },
});
res.json({ success: true });
});