feat: Add two-factor authentication via TOTP

Adds TOTP setup with QR code, login challenge, recovery codes and
trusted devices that let a browser skip the second factor for 30
days. Admins can reset another user's second factor by confirming
with their own password.
This commit is contained in:
Daniel Hiller
2026-08-07 20:11:55 +02:00
parent 36aa732fec
commit 2e4904f77d
74 changed files with 4173 additions and 4 deletions
+7
View File
@@ -38,6 +38,12 @@ module.exports.policies = {
'users/update-username': 'is-authenticated',
'users/update-avatar': 'is-authenticated',
'users/create-api-key': ['is-authenticated', 'is-admin'],
'users/setup-totp': 'is-authenticated',
'users/enable-totp': 'is-authenticated',
'users/disable-totp': 'is-authenticated',
'users/regenerate-totp-recovery-codes': 'is-authenticated',
'users/index-trusted-devices': 'is-authenticated',
'users/delete-trusted-device': 'is-authenticated',
'users/delete': ['is-authenticated', 'is-admin'],
'projects/create': ['is-authenticated', 'is-external', 'is-admin-or-project-owner'],
@@ -49,6 +55,7 @@ module.exports.policies = {
'bootstrap/show': true,
'terms/show': true,
'access-tokens/create': true,
'access-tokens/verify-totp': true,
'access-tokens/accept-terms': true,
'access-tokens/revoke-pending-token': true,
};
+7
View File
@@ -117,6 +117,7 @@ module.exports.routes = {
'DELETE /api/webhooks/:id': 'webhooks/delete',
'POST /api/access-tokens': 'access-tokens/create',
'POST /api/access-tokens/verify-totp': 'access-tokens/verify-totp',
'POST /api/access-tokens/accept-terms': 'access-tokens/accept-terms',
'POST /api/access-tokens/revoke-pending-token': 'access-tokens/revoke-pending-token',
'DELETE /api/access-tokens/me': 'access-tokens/delete',
@@ -130,6 +131,12 @@ module.exports.routes = {
'PATCH /api/users/:id/username': 'users/update-username',
'POST /api/users/:id/avatar': 'users/update-avatar',
'POST /api/users/:id/api-key': 'users/create-api-key',
'POST /api/users/:id/totp/setup': 'users/setup-totp',
'POST /api/users/:id/totp/enable': 'users/enable-totp',
'DELETE /api/users/:id/totp': 'users/disable-totp',
'POST /api/users/:id/totp/recovery-codes': 'users/regenerate-totp-recovery-codes',
'GET /api/users/:id/trusted-devices': 'users/index-trusted-devices',
'DELETE /api/users/:id/trusted-devices/:deviceId': 'users/delete-trusted-device',
'DELETE /api/users/:id': 'users/delete',
'GET /api/projects': 'projects/index',