@spinajs/rbac-http-user 2.0.486 → 2.0.487
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/config/rbac-http.d.ts +0 -15
- package/lib/cjs/config/rbac-http.d.ts.map +1 -1
- package/lib/cjs/config/rbac-http.js +6 -16
- package/lib/cjs/config/rbac-http.js.map +1 -1
- package/lib/cjs/controllers/ActiveRoleController.d.ts +2 -1
- package/lib/cjs/controllers/ActiveRoleController.d.ts.map +1 -1
- package/lib/cjs/controllers/ActiveRoleController.js +7 -17
- package/lib/cjs/controllers/ActiveRoleController.js.map +1 -1
- package/lib/cjs/controllers/ImpersonationController.d.ts +7 -9
- package/lib/cjs/controllers/ImpersonationController.d.ts.map +1 -1
- package/lib/cjs/controllers/ImpersonationController.js +31 -56
- package/lib/cjs/controllers/ImpersonationController.js.map +1 -1
- package/lib/cjs/controllers/LoginController.d.ts +10 -3
- package/lib/cjs/controllers/LoginController.d.ts.map +1 -1
- package/lib/cjs/controllers/LoginController.js +39 -40
- package/lib/cjs/controllers/LoginController.js.map +1 -1
- package/lib/cjs/controllers/PasswordResetController.d.ts +54 -0
- package/lib/cjs/controllers/PasswordResetController.d.ts.map +1 -0
- package/lib/cjs/controllers/PasswordResetController.js +129 -0
- package/lib/cjs/controllers/PasswordResetController.js.map +1 -0
- package/lib/cjs/controllers/SessionsController.d.ts +65 -0
- package/lib/cjs/controllers/SessionsController.d.ts.map +1 -0
- package/lib/cjs/controllers/SessionsController.js +143 -0
- package/lib/cjs/controllers/SessionsController.js.map +1 -0
- package/lib/cjs/controllers/TwoFactorAuthController.d.ts +24 -23
- package/lib/cjs/controllers/TwoFactorAuthController.d.ts.map +1 -1
- package/lib/cjs/controllers/TwoFactorAuthController.js +39 -72
- package/lib/cjs/controllers/TwoFactorAuthController.js.map +1 -1
- package/lib/cjs/controllers/TwoFactorAuthUserController.d.ts +98 -0
- package/lib/cjs/controllers/TwoFactorAuthUserController.d.ts.map +1 -0
- package/lib/cjs/controllers/TwoFactorAuthUserController.js +195 -0
- package/lib/cjs/controllers/TwoFactorAuthUserController.js.map +1 -0
- package/lib/cjs/controllers/UserController.d.ts +10 -7
- package/lib/cjs/controllers/UserController.d.ts.map +1 -1
- package/lib/cjs/controllers/UserController.js +56 -58
- package/lib/cjs/controllers/UserController.js.map +1 -1
- package/lib/cjs/controllers/UserMetadataController.d.ts +6 -12
- package/lib/cjs/controllers/UserMetadataController.d.ts.map +1 -1
- package/lib/cjs/controllers/UserMetadataController.js +23 -72
- package/lib/cjs/controllers/UserMetadataController.js.map +1 -1
- package/lib/cjs/dto/confirm-password-dto.d.ts +23 -0
- package/lib/cjs/dto/confirm-password-dto.d.ts.map +1 -0
- package/lib/cjs/dto/{restore-password-dto.js → confirm-password-dto.js} +16 -12
- package/lib/cjs/dto/confirm-password-dto.js.map +1 -0
- package/lib/cjs/dto/password-reset-dto.d.ts +58 -0
- package/lib/cjs/dto/password-reset-dto.d.ts.map +1 -0
- package/lib/cjs/dto/password-reset-dto.js +57 -0
- package/lib/cjs/dto/password-reset-dto.js.map +1 -0
- package/lib/cjs/handlers/DefaultLogoutHandler.d.ts +4 -1
- package/lib/cjs/handlers/DefaultLogoutHandler.d.ts.map +1 -1
- package/lib/cjs/handlers/DefaultLogoutHandler.js +20 -13
- package/lib/cjs/handlers/DefaultLogoutHandler.js.map +1 -1
- package/lib/cjs/handlers/ImpersonationLogoutHandler.d.ts +4 -7
- package/lib/cjs/handlers/ImpersonationLogoutHandler.d.ts.map +1 -1
- package/lib/cjs/handlers/ImpersonationLogoutHandler.js +30 -31
- package/lib/cjs/handlers/ImpersonationLogoutHandler.js.map +1 -1
- package/lib/cjs/index.d.ts +20 -0
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +22 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/logout.d.ts +7 -0
- package/lib/cjs/logout.d.ts.map +1 -1
- package/lib/cjs/logout.js.map +1 -1
- package/lib/cjs/policies/2FaPolicy.d.ts +21 -1
- package/lib/cjs/policies/2FaPolicy.d.ts.map +1 -1
- package/lib/cjs/policies/2FaPolicy.js +31 -7
- package/lib/cjs/policies/2FaPolicy.js.map +1 -1
- package/lib/cjs/services/ImpersonationService.d.ts +90 -0
- package/lib/cjs/services/ImpersonationService.d.ts.map +1 -0
- package/lib/cjs/services/ImpersonationService.js +147 -0
- package/lib/cjs/services/ImpersonationService.js.map +1 -0
- package/lib/cjs/services/SessionCookies.d.ts +41 -0
- package/lib/cjs/services/SessionCookies.d.ts.map +1 -0
- package/lib/cjs/services/SessionCookies.js +62 -0
- package/lib/cjs/services/SessionCookies.js.map +1 -0
- package/lib/cjs/services/UserMetadataService.d.ts +53 -0
- package/lib/cjs/services/UserMetadataService.d.ts.map +1 -0
- package/lib/cjs/services/UserMetadataService.js +94 -0
- package/lib/cjs/services/UserMetadataService.js.map +1 -0
- package/lib/cjs/services/grants.d.ts +29 -0
- package/lib/cjs/services/grants.d.ts.map +1 -0
- package/lib/cjs/services/grants.js +43 -0
- package/lib/cjs/services/grants.js.map +1 -0
- package/lib/mjs/config/rbac-http.d.ts +0 -15
- package/lib/mjs/config/rbac-http.d.ts.map +1 -1
- package/lib/mjs/config/rbac-http.js +6 -16
- package/lib/mjs/config/rbac-http.js.map +1 -1
- package/lib/mjs/controllers/ActiveRoleController.d.ts +2 -1
- package/lib/mjs/controllers/ActiveRoleController.d.ts.map +1 -1
- package/lib/mjs/controllers/ActiveRoleController.js +8 -18
- package/lib/mjs/controllers/ActiveRoleController.js.map +1 -1
- package/lib/mjs/controllers/ImpersonationController.d.ts +7 -9
- package/lib/mjs/controllers/ImpersonationController.d.ts.map +1 -1
- package/lib/mjs/controllers/ImpersonationController.js +32 -57
- package/lib/mjs/controllers/ImpersonationController.js.map +1 -1
- package/lib/mjs/controllers/LoginController.d.ts +10 -3
- package/lib/mjs/controllers/LoginController.d.ts.map +1 -1
- package/lib/mjs/controllers/LoginController.js +42 -43
- package/lib/mjs/controllers/LoginController.js.map +1 -1
- package/lib/mjs/controllers/PasswordResetController.d.ts +54 -0
- package/lib/mjs/controllers/PasswordResetController.d.ts.map +1 -0
- package/lib/mjs/controllers/PasswordResetController.js +126 -0
- package/lib/mjs/controllers/PasswordResetController.js.map +1 -0
- package/lib/mjs/controllers/SessionsController.d.ts +65 -0
- package/lib/mjs/controllers/SessionsController.d.ts.map +1 -0
- package/lib/mjs/controllers/SessionsController.js +140 -0
- package/lib/mjs/controllers/SessionsController.js.map +1 -0
- package/lib/mjs/controllers/TwoFactorAuthController.d.ts +24 -23
- package/lib/mjs/controllers/TwoFactorAuthController.d.ts.map +1 -1
- package/lib/mjs/controllers/TwoFactorAuthController.js +43 -76
- package/lib/mjs/controllers/TwoFactorAuthController.js.map +1 -1
- package/lib/mjs/controllers/TwoFactorAuthUserController.d.ts +98 -0
- package/lib/mjs/controllers/TwoFactorAuthUserController.d.ts.map +1 -0
- package/lib/mjs/controllers/TwoFactorAuthUserController.js +192 -0
- package/lib/mjs/controllers/TwoFactorAuthUserController.js.map +1 -0
- package/lib/mjs/controllers/UserController.d.ts +10 -7
- package/lib/mjs/controllers/UserController.d.ts.map +1 -1
- package/lib/mjs/controllers/UserController.js +59 -28
- package/lib/mjs/controllers/UserController.js.map +1 -1
- package/lib/mjs/controllers/UserMetadataController.d.ts +6 -12
- package/lib/mjs/controllers/UserMetadataController.d.ts.map +1 -1
- package/lib/mjs/controllers/UserMetadataController.js +23 -72
- package/lib/mjs/controllers/UserMetadataController.js.map +1 -1
- package/lib/mjs/dto/confirm-password-dto.d.ts +23 -0
- package/lib/mjs/dto/confirm-password-dto.d.ts.map +1 -0
- package/lib/mjs/dto/{user-dto.js → confirm-password-dto.js} +15 -10
- package/lib/mjs/dto/confirm-password-dto.js.map +1 -0
- package/lib/mjs/dto/password-reset-dto.d.ts +58 -0
- package/lib/mjs/dto/password-reset-dto.d.ts.map +1 -0
- package/lib/mjs/dto/password-reset-dto.js +54 -0
- package/lib/mjs/dto/password-reset-dto.js.map +1 -0
- package/lib/mjs/handlers/DefaultLogoutHandler.d.ts +4 -1
- package/lib/mjs/handlers/DefaultLogoutHandler.d.ts.map +1 -1
- package/lib/mjs/handlers/DefaultLogoutHandler.js +23 -16
- package/lib/mjs/handlers/DefaultLogoutHandler.js.map +1 -1
- package/lib/mjs/handlers/ImpersonationLogoutHandler.d.ts +4 -7
- package/lib/mjs/handlers/ImpersonationLogoutHandler.d.ts.map +1 -1
- package/lib/mjs/handlers/ImpersonationLogoutHandler.js +31 -32
- package/lib/mjs/handlers/ImpersonationLogoutHandler.js.map +1 -1
- package/lib/mjs/index.d.ts +20 -0
- package/lib/mjs/index.d.ts.map +1 -1
- package/lib/mjs/index.js +22 -0
- package/lib/mjs/index.js.map +1 -1
- package/lib/mjs/logout.d.ts +7 -0
- package/lib/mjs/logout.d.ts.map +1 -1
- package/lib/mjs/logout.js.map +1 -1
- package/lib/mjs/policies/2FaPolicy.d.ts +21 -1
- package/lib/mjs/policies/2FaPolicy.d.ts.map +1 -1
- package/lib/mjs/policies/2FaPolicy.js +29 -6
- package/lib/mjs/policies/2FaPolicy.js.map +1 -1
- package/lib/mjs/services/ImpersonationService.d.ts +90 -0
- package/lib/mjs/services/ImpersonationService.d.ts.map +1 -0
- package/lib/mjs/services/ImpersonationService.js +144 -0
- package/lib/mjs/services/ImpersonationService.js.map +1 -0
- package/lib/mjs/services/SessionCookies.d.ts +41 -0
- package/lib/mjs/services/SessionCookies.d.ts.map +1 -0
- package/lib/mjs/services/SessionCookies.js +59 -0
- package/lib/mjs/services/SessionCookies.js.map +1 -0
- package/lib/mjs/services/UserMetadataService.d.ts +53 -0
- package/lib/mjs/services/UserMetadataService.d.ts.map +1 -0
- package/lib/mjs/services/UserMetadataService.js +91 -0
- package/lib/mjs/services/UserMetadataService.js.map +1 -0
- package/lib/mjs/services/grants.d.ts +29 -0
- package/lib/mjs/services/grants.d.ts.map +1 -0
- package/lib/mjs/services/grants.js +38 -0
- package/lib/mjs/services/grants.js.map +1 -0
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +17 -11
- package/lib/cjs/controllers/AuthController.d.ts +0 -1
- package/lib/cjs/controllers/AuthController.d.ts.map +0 -1
- package/lib/cjs/controllers/AuthController.js +0 -211
- package/lib/cjs/controllers/AuthController.js.map +0 -1
- package/lib/cjs/controllers/FederatedLoginController.d.ts +0 -1
- package/lib/cjs/controllers/FederatedLoginController.d.ts.map +0 -1
- package/lib/cjs/controllers/FederatedLoginController.js +0 -38
- package/lib/cjs/controllers/FederatedLoginController.js.map +0 -1
- package/lib/cjs/dto/login-dto.d.ts +0 -17
- package/lib/cjs/dto/login-dto.d.ts.map +0 -1
- package/lib/cjs/dto/login-dto.js +0 -33
- package/lib/cjs/dto/login-dto.js.map +0 -1
- package/lib/cjs/dto/restore-password-dto.d.ts +0 -24
- package/lib/cjs/dto/restore-password-dto.d.ts.map +0 -1
- package/lib/cjs/dto/restore-password-dto.js.map +0 -1
- package/lib/cjs/dto/user-dto.d.ts +0 -22
- package/lib/cjs/dto/user-dto.d.ts.map +0 -1
- package/lib/cjs/dto/user-dto.js +0 -33
- package/lib/cjs/dto/user-dto.js.map +0 -1
- package/lib/cjs/fingerprint/FingerprintJs.d.ts +0 -1
- package/lib/cjs/fingerprint/FingerprintJs.d.ts.map +0 -1
- package/lib/cjs/fingerprint/FingerprintJs.js +0 -5
- package/lib/cjs/fingerprint/FingerprintJs.js.map +0 -1
- package/lib/cjs/middlewares/AttributeFilter.d.ts +0 -11
- package/lib/cjs/middlewares/AttributeFilter.d.ts.map +0 -1
- package/lib/cjs/middlewares/AttributeFilter.js +0 -19
- package/lib/cjs/middlewares/AttributeFilter.js.map +0 -1
- package/lib/cjs/policies/AllowFederatedLoginPolicy.d.ts +0 -7
- package/lib/cjs/policies/AllowFederatedLoginPolicy.d.ts.map +0 -1
- package/lib/cjs/policies/AllowFederatedLoginPolicy.js +0 -32
- package/lib/cjs/policies/AllowFederatedLoginPolicy.js.map +0 -1
- package/lib/cjs/policies/CaptchaPolicy.d.ts +0 -1
- package/lib/cjs/policies/CaptchaPolicy.d.ts.map +0 -1
- package/lib/cjs/policies/CaptchaPolicy.js +0 -1
- package/lib/cjs/policies/CaptchaPolicy.js.map +0 -1
- package/lib/mjs/controllers/AuthController.d.ts +0 -2
- package/lib/mjs/controllers/AuthController.d.ts.map +0 -1
- package/lib/mjs/controllers/AuthController.js +0 -212
- package/lib/mjs/controllers/AuthController.js.map +0 -1
- package/lib/mjs/controllers/FederatedLoginController.d.ts +0 -2
- package/lib/mjs/controllers/FederatedLoginController.d.ts.map +0 -1
- package/lib/mjs/controllers/FederatedLoginController.js +0 -39
- package/lib/mjs/controllers/FederatedLoginController.js.map +0 -1
- package/lib/mjs/dto/login-dto.d.ts +0 -17
- package/lib/mjs/dto/login-dto.d.ts.map +0 -1
- package/lib/mjs/dto/login-dto.js +0 -30
- package/lib/mjs/dto/login-dto.js.map +0 -1
- package/lib/mjs/dto/restore-password-dto.d.ts +0 -24
- package/lib/mjs/dto/restore-password-dto.d.ts.map +0 -1
- package/lib/mjs/dto/restore-password-dto.js +0 -31
- package/lib/mjs/dto/restore-password-dto.js.map +0 -1
- package/lib/mjs/dto/user-dto.d.ts +0 -22
- package/lib/mjs/dto/user-dto.d.ts.map +0 -1
- package/lib/mjs/dto/user-dto.js.map +0 -1
- package/lib/mjs/fingerprint/FingerprintJs.d.ts +0 -2
- package/lib/mjs/fingerprint/FingerprintJs.d.ts.map +0 -1
- package/lib/mjs/fingerprint/FingerprintJs.js +0 -6
- package/lib/mjs/fingerprint/FingerprintJs.js.map +0 -1
- package/lib/mjs/middlewares/AttributeFilter.d.ts +0 -11
- package/lib/mjs/middlewares/AttributeFilter.d.ts.map +0 -1
- package/lib/mjs/middlewares/AttributeFilter.js +0 -15
- package/lib/mjs/middlewares/AttributeFilter.js.map +0 -1
- package/lib/mjs/policies/AllowFederatedLoginPolicy.d.ts +0 -7
- package/lib/mjs/policies/AllowFederatedLoginPolicy.d.ts.map +0 -1
- package/lib/mjs/policies/AllowFederatedLoginPolicy.js +0 -28
- package/lib/mjs/policies/AllowFederatedLoginPolicy.js.map +0 -1
- package/lib/mjs/policies/CaptchaPolicy.d.ts +0 -2
- package/lib/mjs/policies/CaptchaPolicy.d.ts.map +0 -1
- package/lib/mjs/policies/CaptchaPolicy.js +0 -2
- package/lib/mjs/policies/CaptchaPolicy.js.map +0 -1
|
@@ -1,41 +1,42 @@
|
|
|
1
1
|
import { TokenDto } from './../dto/token-dto.js';
|
|
2
2
|
import { BaseController, Ok, ForbiddenResponse } from '@spinajs/http';
|
|
3
3
|
import { ISession, SessionProvider, User as UserModel, AccessControl } from '@spinajs/rbac';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { IEnable2faResponse, IUserWithGrants } from '@spinajs/rbac-http';
|
|
5
|
+
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
6
6
|
/**
|
|
7
|
-
* Two-factor authentication
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* Two-factor authentication during login.
|
|
8
|
+
*
|
|
9
|
+
* These routes serve the narrow window between a successful password check and
|
|
10
|
+
* full authorization: the session is `Logged` but not `Authorized` and carries
|
|
11
|
+
* the `TwoFactorAuth` marker. Both class policies must hold, so the window
|
|
12
|
+
* closes the moment verification succeeds.
|
|
13
|
+
*
|
|
14
|
+
* Managing a TOTP device outside that window — enrolling for the first time, or
|
|
15
|
+
* turning 2FA off — lives on {@link TwoFactorAuthUserController} under
|
|
16
|
+
* `/user/2fa`, where the caller is fully authorized. Notably there is no
|
|
17
|
+
* "disable" here on purpose: a session that has not yet proven possession of
|
|
18
|
+
* the second factor must not be able to remove it, which would reduce the whole
|
|
19
|
+
* scheme to the password alone.
|
|
20
|
+
*
|
|
12
21
|
* @tags Two-Factor Authentication
|
|
13
22
|
*/
|
|
14
23
|
export declare class TwoFactorAuthController extends BaseController {
|
|
15
|
-
protected Queue: QueueService;
|
|
16
24
|
protected SessionProvider: SessionProvider;
|
|
17
|
-
protected
|
|
25
|
+
protected SessionCookies: SessionCookieFactory;
|
|
18
26
|
protected AC: AccessControl;
|
|
19
27
|
/**
|
|
20
|
-
*
|
|
21
|
-
* Generates a TOTP secret for
|
|
22
|
-
*
|
|
28
|
+
* Set up two-factor authentication during login
|
|
29
|
+
* Generates a TOTP secret for a user who must enrol before continuing — the state
|
|
30
|
+
* signalled by `TwoFactorInitRequired` at login when `rbac.twoFactorAuth.forceUser`
|
|
31
|
+
* is on. Returns the OTP provisioning URI to scan with an authenticator app; the
|
|
32
|
+
* caller then confirms with `POST /auth/2fa/verify`.
|
|
23
33
|
* @security cookieAuth
|
|
24
34
|
* @returns {IEnable2faResponse} OTP provisioning URI to scan with an authenticator app
|
|
25
35
|
* @response 400 Two-factor authentication is already enabled for this user
|
|
26
36
|
* @response 401 Unauthorized — valid session required
|
|
37
|
+
* @response 403 Session is not awaiting two-factor enrolment
|
|
27
38
|
*/
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Disable two-factor authentication
|
|
31
|
-
* Removes the TOTP secret and disables 2FA for the authenticated user.
|
|
32
|
-
* Throws if 2FA is not currently enabled for the user.
|
|
33
|
-
* @security cookieAuth
|
|
34
|
-
* @response 200 Two-factor authentication disabled successfully
|
|
35
|
-
* @response 400 Two-factor authentication is not enabled for this user
|
|
36
|
-
* @response 401 Unauthorized — valid session required
|
|
37
|
-
*/
|
|
38
|
-
disable2Fa(user: UserModel): Promise<Ok<any>>;
|
|
39
|
+
setup2fa(user: UserModel): Promise<Ok<IEnable2faResponse>>;
|
|
39
40
|
/**
|
|
40
41
|
* Verify TOTP token
|
|
41
42
|
* Validates the provided TOTP token against the user's 2FA secret. On success, marks the session
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TwoFactorAuthController.d.ts","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"TwoFactorAuthController.d.ts","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAY,EAAE,EAAQ,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,IAAI,SAAS,EAAE,aAAa,EAAqB,MAAM,eAAe,CAAC;AAO/G,OAAO,EAA6B,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAIpG,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAGrE;;;;;;;;;;;;;;;;GAgBG;AACH,qBAGa,uBAAwB,SAAQ,cAAc;IAEzD,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAG3C,SAAS,CAAC,cAAc,EAAE,oBAAoB,CAAC;IAG/C,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAE5B;;;;;;;;;;;OAWG;IAEU,QAAQ,CAAS,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC;IAW/E;;;;;;;;OAQG;IAEU,WAAW,CAAS,MAAM,EAAE,SAAS,EAAU,KAAK,EAAE,QAAQ,EAAa,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,eAAe,CAAC,GAAG,iBAAiB,CAAC;IAyC5J;;;;OAIG;IACH,SAAS,CAAC,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG9E"}
|
|
@@ -21,54 +21,51 @@ const http_2 = require("@spinajs/http");
|
|
|
21
21
|
const _2FaPolicy_js_1 = require("../policies/2FaPolicy.js");
|
|
22
22
|
const configuration_1 = require("@spinajs/configuration");
|
|
23
23
|
const di_1 = require("@spinajs/di");
|
|
24
|
-
const queue_1 = require("@spinajs/queue");
|
|
25
24
|
const rbac_http_2 = require("@spinajs/rbac-http");
|
|
26
|
-
const _2fa_js_1 = require("
|
|
27
|
-
const _2fa_js_2 = require("../actions/2fa.js");
|
|
25
|
+
const _2fa_js_1 = require("../actions/2fa.js");
|
|
28
26
|
const exceptions_1 = require("@spinajs/exceptions");
|
|
27
|
+
const Default2FaToken_js_1 = require("../2fa/Default2FaToken.js");
|
|
28
|
+
const SessionCookies_js_1 = require("../services/SessionCookies.js");
|
|
29
|
+
const grants_js_1 = require("../services/grants.js");
|
|
29
30
|
/**
|
|
30
|
-
* Two-factor authentication
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
31
|
+
* Two-factor authentication during login.
|
|
32
|
+
*
|
|
33
|
+
* These routes serve the narrow window between a successful password check and
|
|
34
|
+
* full authorization: the session is `Logged` but not `Authorized` and carries
|
|
35
|
+
* the `TwoFactorAuth` marker. Both class policies must hold, so the window
|
|
36
|
+
* closes the moment verification succeeds.
|
|
37
|
+
*
|
|
38
|
+
* Managing a TOTP device outside that window — enrolling for the first time, or
|
|
39
|
+
* turning 2FA off — lives on {@link TwoFactorAuthUserController} under
|
|
40
|
+
* `/user/2fa`, where the caller is fully authorized. Notably there is no
|
|
41
|
+
* "disable" here on purpose: a session that has not yet proven possession of
|
|
42
|
+
* the second factor must not be able to remove it, which would reduce the whole
|
|
43
|
+
* scheme to the password alone.
|
|
44
|
+
*
|
|
35
45
|
* @tags Two-Factor Authentication
|
|
36
46
|
*/
|
|
37
47
|
let TwoFactorAuthController = class TwoFactorAuthController extends http_1.BaseController {
|
|
38
48
|
/**
|
|
39
|
-
*
|
|
40
|
-
* Generates a TOTP secret for
|
|
41
|
-
*
|
|
49
|
+
* Set up two-factor authentication during login
|
|
50
|
+
* Generates a TOTP secret for a user who must enrol before continuing — the state
|
|
51
|
+
* signalled by `TwoFactorInitRequired` at login when `rbac.twoFactorAuth.forceUser`
|
|
52
|
+
* is on. Returns the OTP provisioning URI to scan with an authenticator app; the
|
|
53
|
+
* caller then confirms with `POST /auth/2fa/verify`.
|
|
42
54
|
* @security cookieAuth
|
|
43
55
|
* @returns {IEnable2faResponse} OTP provisioning URI to scan with an authenticator app
|
|
44
56
|
* @response 400 Two-factor authentication is already enabled for this user
|
|
45
57
|
* @response 401 Unauthorized — valid session required
|
|
58
|
+
* @response 403 Session is not awaiting two-factor enrolment
|
|
46
59
|
*/
|
|
47
|
-
async
|
|
48
|
-
if (user.Metadata[
|
|
60
|
+
async setup2fa(user) {
|
|
61
|
+
if (user.Metadata[Default2FaToken_js_1.TWO_FA_METATADATA_KEYS.ENABLED]) {
|
|
49
62
|
throw new exceptions_1.InvalidOperation(`User ${user.Uuid} already has 2fa enabled`);
|
|
50
63
|
}
|
|
51
|
-
const result = await (0,
|
|
64
|
+
const result = await (0, _2fa_js_1.enableUser2Fa)(user);
|
|
52
65
|
return new http_1.Ok({
|
|
53
|
-
otp: result
|
|
66
|
+
otp: result,
|
|
54
67
|
});
|
|
55
68
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Disable two-factor authentication
|
|
58
|
-
* Removes the TOTP secret and disables 2FA for the authenticated user.
|
|
59
|
-
* Throws if 2FA is not currently enabled for the user.
|
|
60
|
-
* @security cookieAuth
|
|
61
|
-
* @response 200 Two-factor authentication disabled successfully
|
|
62
|
-
* @response 400 Two-factor authentication is not enabled for this user
|
|
63
|
-
* @response 401 Unauthorized — valid session required
|
|
64
|
-
*/
|
|
65
|
-
async disable2Fa(user) {
|
|
66
|
-
if (!user.Metadata['2fa:enabled']) {
|
|
67
|
-
throw new exceptions_1.InvalidOperation(`User ${user.Uuid} already has 2fa disabled`);
|
|
68
|
-
}
|
|
69
|
-
await (0, _2fa_js_1.disableUser2Fa)(user);
|
|
70
|
-
return new http_1.Ok();
|
|
71
|
-
}
|
|
72
69
|
/**
|
|
73
70
|
* Verify TOTP token
|
|
74
71
|
* Validates the provided TOTP token against the user's 2FA secret. On success, marks the session
|
|
@@ -89,41 +86,22 @@ let TwoFactorAuthController = class TwoFactorAuthController extends http_1.BaseC
|
|
|
89
86
|
// id to defend against session fixation and reset the ssid cookie.
|
|
90
87
|
const regenerated = await (0, rbac_1.regenerateSession)(this.SessionProvider, session);
|
|
91
88
|
this._log.trace('User logged in, 2fa authorized', {
|
|
92
|
-
Uuid: logged.Uuid
|
|
89
|
+
Uuid: logged.Uuid,
|
|
93
90
|
});
|
|
94
91
|
// Mirror the login response shape: resolve grants for the session's
|
|
95
92
|
// active role (falling back to the first role) and include ActiveRole,
|
|
96
93
|
// instead of flattening every role with no ActiveRole reported.
|
|
97
|
-
const activeRole =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
...logged.dehydrateWithRelations({
|
|
101
|
-
dateTimeFormat: "iso"
|
|
102
|
-
}),
|
|
103
|
-
Role: logged.Role,
|
|
104
|
-
ActiveRole: activeRole,
|
|
105
|
-
Grants: combinedGrants,
|
|
106
|
-
}, {
|
|
107
|
-
Coockies: [
|
|
108
|
-
{
|
|
109
|
-
Name: 'ssid',
|
|
110
|
-
Value: regenerated.SessionId,
|
|
111
|
-
Options: {
|
|
112
|
-
signed: true,
|
|
113
|
-
httpOnly: true,
|
|
114
|
-
maxAge: (0, rbac_1.sessionCookieMaxAge)(regenerated),
|
|
115
|
-
...this.SessionCookieConfig,
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
],
|
|
94
|
+
const activeRole = (0, grants_js_1.activeRoleOf)(logged, session);
|
|
95
|
+
return new http_1.Ok((0, grants_js_1.buildUserWithGrants)(logged, activeRole, this.AC), {
|
|
96
|
+
Coockies: [this.SessionCookies.issue(regenerated)],
|
|
119
97
|
});
|
|
120
98
|
}
|
|
121
99
|
catch (err) {
|
|
122
100
|
if (err instanceof Error) {
|
|
123
|
-
this._log.error(err,
|
|
101
|
+
this._log.error(err, '2fa verification failed');
|
|
124
102
|
}
|
|
125
103
|
else {
|
|
126
|
-
this._log.error(
|
|
104
|
+
this._log.error('2fa verification failed', { error: err });
|
|
127
105
|
}
|
|
128
106
|
return new http_1.ForbiddenResponse({
|
|
129
107
|
error: {
|
|
@@ -143,36 +121,25 @@ let TwoFactorAuthController = class TwoFactorAuthController extends http_1.BaseC
|
|
|
143
121
|
}
|
|
144
122
|
};
|
|
145
123
|
exports.TwoFactorAuthController = TwoFactorAuthController;
|
|
146
|
-
__decorate([
|
|
147
|
-
(0, di_1.Autoinject)(queue_1.QueueService),
|
|
148
|
-
__metadata("design:type", queue_1.QueueService)
|
|
149
|
-
], TwoFactorAuthController.prototype, "Queue", void 0);
|
|
150
124
|
__decorate([
|
|
151
125
|
(0, configuration_1.AutoinjectService)('rbac.session'),
|
|
152
126
|
__metadata("design:type", rbac_1.SessionProvider)
|
|
153
127
|
], TwoFactorAuthController.prototype, "SessionProvider", void 0);
|
|
154
128
|
__decorate([
|
|
155
|
-
(0,
|
|
156
|
-
__metadata("design:type",
|
|
157
|
-
], TwoFactorAuthController.prototype, "
|
|
129
|
+
(0, di_1.Autoinject)(SessionCookies_js_1.SessionCookieFactory),
|
|
130
|
+
__metadata("design:type", SessionCookies_js_1.SessionCookieFactory)
|
|
131
|
+
], TwoFactorAuthController.prototype, "SessionCookies", void 0);
|
|
158
132
|
__decorate([
|
|
159
133
|
(0, di_1.Autoinject)(rbac_1.AccessControl),
|
|
160
134
|
__metadata("design:type", rbac_1.AccessControl)
|
|
161
135
|
], TwoFactorAuthController.prototype, "AC", void 0);
|
|
162
136
|
__decorate([
|
|
163
|
-
(0, http_1.
|
|
164
|
-
__param(0, (0, rbac_http_2.User)()),
|
|
165
|
-
__metadata("design:type", Function),
|
|
166
|
-
__metadata("design:paramtypes", [rbac_1.User]),
|
|
167
|
-
__metadata("design:returntype", Promise)
|
|
168
|
-
], TwoFactorAuthController.prototype, "enable2fa", null);
|
|
169
|
-
__decorate([
|
|
170
|
-
(0, http_1.Get)('2fa/disable'),
|
|
137
|
+
(0, http_1.Post)('2fa/setup'),
|
|
171
138
|
__param(0, (0, rbac_http_2.User)()),
|
|
172
139
|
__metadata("design:type", Function),
|
|
173
140
|
__metadata("design:paramtypes", [rbac_1.User]),
|
|
174
141
|
__metadata("design:returntype", Promise)
|
|
175
|
-
], TwoFactorAuthController.prototype, "
|
|
142
|
+
], TwoFactorAuthController.prototype, "setup2fa", null);
|
|
176
143
|
__decorate([
|
|
177
144
|
(0, http_1.Post)('2fa/verify'),
|
|
178
145
|
__param(0, (0, rbac_http_2.User)()),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TwoFactorAuthController.js","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,wDAAiD;AACjD,
|
|
1
|
+
{"version":3,"file":"TwoFactorAuthController.js","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { BaseController, Ok, Unauthorized } from '@spinajs/http';
|
|
2
|
+
import { PasswordProvider, SessionProvider, User as UserModel } from '@spinajs/rbac';
|
|
3
|
+
import type { ISession } from '@spinajs/rbac';
|
|
4
|
+
import { IEnable2faResponse } from '@spinajs/rbac-http';
|
|
5
|
+
import { ConfirmPasswordDto } from '../dto/confirm-password-dto.js';
|
|
6
|
+
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
7
|
+
/** Whether the authenticated user currently has a TOTP device enrolled. */
|
|
8
|
+
export interface ITwoFactorStatus {
|
|
9
|
+
Enabled: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Self-service two-factor authentication.
|
|
13
|
+
*
|
|
14
|
+
* Enrolling and unenrolling a TOTP device for one's own account, from a fully
|
|
15
|
+
* authorized session. These operations were previously only reachable from the
|
|
16
|
+
* login-time 2FA window, whose policies (`TwoFacRouteEnabled` +
|
|
17
|
+
* `NotAuthorizedPolicy`) exclude an authorized session by construction — so a
|
|
18
|
+
* normal logged-in user could neither enrol nor unenrol, and the only ways in
|
|
19
|
+
* were the CLI command or an administrator's 2FA reset.
|
|
20
|
+
*
|
|
21
|
+
* Both mutations re-verify the account password. A stolen session cookie must
|
|
22
|
+
* not be enough to attach an attacker-controlled authenticator or to strip the
|
|
23
|
+
* second factor off the account.
|
|
24
|
+
*
|
|
25
|
+
* @tags Two-Factor Authentication
|
|
26
|
+
*/
|
|
27
|
+
export declare class TwoFactorAuthUserController extends BaseController {
|
|
28
|
+
protected PasswordProvider: PasswordProvider;
|
|
29
|
+
protected SessionProvider: SessionProvider;
|
|
30
|
+
protected SessionCookies: SessionCookieFactory;
|
|
31
|
+
/**
|
|
32
|
+
* Get own two-factor status
|
|
33
|
+
* Reports whether the authenticated user currently has a TOTP device enrolled.
|
|
34
|
+
* @security cookieAuth
|
|
35
|
+
* @returns {ITwoFactorStatus} Current enrolment state
|
|
36
|
+
* @response 401 Unauthorized — valid session required
|
|
37
|
+
* @response 403 Forbidden — insufficient permissions
|
|
38
|
+
*/
|
|
39
|
+
status(user: UserModel): Promise<Ok<ITwoFactorStatus>>;
|
|
40
|
+
/**
|
|
41
|
+
* Enable own two-factor authentication
|
|
42
|
+
* Generates a TOTP secret for the authenticated user and returns the OTP provisioning
|
|
43
|
+
* URI to scan with an authenticator app. Requires the account password to be re-entered.
|
|
44
|
+
* @security cookieAuth
|
|
45
|
+
* @returns {IEnable2faResponse} OTP provisioning URI to scan with an authenticator app
|
|
46
|
+
* @response 400 Two-factor authentication is already enabled for this user
|
|
47
|
+
* @response 401 Unauthorized — valid session required, or password invalid
|
|
48
|
+
* @response 403 Forbidden — insufficient permissions
|
|
49
|
+
*/
|
|
50
|
+
enable(user: UserModel, confirmation: ConfirmPasswordDto, session: ISession): Promise<Ok<IEnable2faResponse> | Unauthorized>;
|
|
51
|
+
/**
|
|
52
|
+
* Disable own two-factor authentication
|
|
53
|
+
* Removes the TOTP secret and disables 2FA for the authenticated user.
|
|
54
|
+
* Requires the account password to be re-entered.
|
|
55
|
+
* @security cookieAuth
|
|
56
|
+
* @response 200 Two-factor authentication disabled successfully
|
|
57
|
+
* @response 400 Two-factor authentication is not enabled for this user
|
|
58
|
+
* @response 401 Unauthorized — valid session required, or password invalid
|
|
59
|
+
* @response 403 Forbidden — insufficient permissions
|
|
60
|
+
*/
|
|
61
|
+
disable(user: UserModel, confirmation: ConfirmPasswordDto, session: ISession): Promise<Ok | Unauthorized>;
|
|
62
|
+
/**
|
|
63
|
+
* Rotates the session id after the account's authentication requirements
|
|
64
|
+
* changed, and returns the response options carrying the new cookie.
|
|
65
|
+
*
|
|
66
|
+
* Attaching or removing a second factor changes what the session is worth. A
|
|
67
|
+
* session id that was observed before the change must not keep working after
|
|
68
|
+
* it.
|
|
69
|
+
*
|
|
70
|
+
* @param session - the caller's current session
|
|
71
|
+
*/
|
|
72
|
+
protected rotate(session: ISession): Promise<{
|
|
73
|
+
Headers: {
|
|
74
|
+
Name: string;
|
|
75
|
+
Value: string;
|
|
76
|
+
}[];
|
|
77
|
+
Coockies?: undefined;
|
|
78
|
+
} | {
|
|
79
|
+
Coockies: import("../services/SessionCookies.js").ISessionCookie[];
|
|
80
|
+
Headers: {
|
|
81
|
+
Name: string;
|
|
82
|
+
Value: string;
|
|
83
|
+
}[];
|
|
84
|
+
}>;
|
|
85
|
+
/**
|
|
86
|
+
* Generate and store the TOTP secret, returning the provisioning URI. Wraps
|
|
87
|
+
* the module-level action so tests can stub it without a TOTP/DB setup.
|
|
88
|
+
*/
|
|
89
|
+
protected enrol(user: UserModel): Promise<unknown>;
|
|
90
|
+
/** Clear the TOTP secret. Wrapped for the same reason as {@link enrol}. */
|
|
91
|
+
protected unenrol(user: UserModel): Promise<unknown>;
|
|
92
|
+
/**
|
|
93
|
+
* Re-verify the account password. Returns `true` on success, or the
|
|
94
|
+
* Unauthorized response to hand back to the caller.
|
|
95
|
+
*/
|
|
96
|
+
protected confirmPassword(user: UserModel, password: string): Promise<true | Unauthorized>;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=TwoFactorAuthUserController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TwoFactorAuthUserController.d.ts","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthUserController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAuB,EAAE,EAAgB,YAAY,EAAE,MAAM,eAAe,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,IAAI,IAAI,SAAS,EAAqB,MAAM,eAAe,CAAC;AACxG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAoB,kBAAkB,EAA0D,MAAM,oBAAoB,CAAC;AAGlI,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAIrE,2EAA2E;AAC3E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAIa,2BAA4B,SAAQ,cAAc;IAE7D,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAG7C,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAG3C,SAAS,CAAC,cAAc,EAAE,oBAAoB,CAAC;IAE/C;;;;;;;OAOG;IAGU,MAAM,CAAS,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAI3E;;;;;;;;;OASG;IAGU,MAAM,CAAS,IAAI,EAAE,SAAS,EAAU,YAAY,EAAE,kBAAkB,EAAqB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,kBAAkB,CAAC,GAAG,YAAY,CAAC;IAoB5K;;;;;;;;;OASG;IAGU,OAAO,CAAS,IAAI,EAAE,SAAS,EAAU,YAAY,EAAE,kBAAkB,EAAqB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,GAAG,YAAY,CAAC;IAczJ;;;;;;;;;OASG;cACa,MAAM,CAAC,OAAO,EAAE,QAAQ;;;;;;;;;;;;;IAaxC;;;OAGG;IACH,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlD,2EAA2E;IAC3E,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAIpD;;;OAGG;cACa,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC;CAajG"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.TwoFactorAuthUserController = void 0;
|
|
16
|
+
const http_1 = require("@spinajs/http");
|
|
17
|
+
const rbac_1 = require("@spinajs/rbac");
|
|
18
|
+
const di_1 = require("@spinajs/di");
|
|
19
|
+
const configuration_1 = require("@spinajs/configuration");
|
|
20
|
+
const rbac_http_1 = require("@spinajs/rbac-http");
|
|
21
|
+
const exceptions_1 = require("@spinajs/exceptions");
|
|
22
|
+
const _2FaPolicy_js_1 = require("../policies/2FaPolicy.js");
|
|
23
|
+
const confirm_password_dto_js_1 = require("../dto/confirm-password-dto.js");
|
|
24
|
+
const SessionCookies_js_1 = require("../services/SessionCookies.js");
|
|
25
|
+
const _2fa_js_1 = require("../actions/2fa.js");
|
|
26
|
+
const Default2FaToken_js_1 = require("../2fa/Default2FaToken.js");
|
|
27
|
+
/**
|
|
28
|
+
* Self-service two-factor authentication.
|
|
29
|
+
*
|
|
30
|
+
* Enrolling and unenrolling a TOTP device for one's own account, from a fully
|
|
31
|
+
* authorized session. These operations were previously only reachable from the
|
|
32
|
+
* login-time 2FA window, whose policies (`TwoFacRouteEnabled` +
|
|
33
|
+
* `NotAuthorizedPolicy`) exclude an authorized session by construction — so a
|
|
34
|
+
* normal logged-in user could neither enrol nor unenrol, and the only ways in
|
|
35
|
+
* were the CLI command or an administrator's 2FA reset.
|
|
36
|
+
*
|
|
37
|
+
* Both mutations re-verify the account password. A stolen session cookie must
|
|
38
|
+
* not be enough to attach an attacker-controlled authenticator or to strip the
|
|
39
|
+
* second factor off the account.
|
|
40
|
+
*
|
|
41
|
+
* @tags Two-Factor Authentication
|
|
42
|
+
*/
|
|
43
|
+
let TwoFactorAuthUserController = class TwoFactorAuthUserController extends http_1.BaseController {
|
|
44
|
+
/**
|
|
45
|
+
* Get own two-factor status
|
|
46
|
+
* Reports whether the authenticated user currently has a TOTP device enrolled.
|
|
47
|
+
* @security cookieAuth
|
|
48
|
+
* @returns {ITwoFactorStatus} Current enrolment state
|
|
49
|
+
* @response 401 Unauthorized — valid session required
|
|
50
|
+
* @response 403 Forbidden — insufficient permissions
|
|
51
|
+
*/
|
|
52
|
+
async status(user) {
|
|
53
|
+
return new http_1.Ok({ Enabled: Boolean(user.Metadata[Default2FaToken_js_1.TWO_FA_METATADATA_KEYS.ENABLED]) });
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Enable own two-factor authentication
|
|
57
|
+
* Generates a TOTP secret for the authenticated user and returns the OTP provisioning
|
|
58
|
+
* URI to scan with an authenticator app. Requires the account password to be re-entered.
|
|
59
|
+
* @security cookieAuth
|
|
60
|
+
* @returns {IEnable2faResponse} OTP provisioning URI to scan with an authenticator app
|
|
61
|
+
* @response 400 Two-factor authentication is already enabled for this user
|
|
62
|
+
* @response 401 Unauthorized — valid session required, or password invalid
|
|
63
|
+
* @response 403 Forbidden — insufficient permissions
|
|
64
|
+
*/
|
|
65
|
+
async enable(user, confirmation, session) {
|
|
66
|
+
if (user.Metadata[Default2FaToken_js_1.TWO_FA_METATADATA_KEYS.ENABLED]) {
|
|
67
|
+
throw new exceptions_1.InvalidOperation(`User ${user.Uuid} already has 2fa enabled`);
|
|
68
|
+
}
|
|
69
|
+
const confirmed = await this.confirmPassword(user, confirmation.Password);
|
|
70
|
+
if (confirmed !== true) {
|
|
71
|
+
return confirmed;
|
|
72
|
+
}
|
|
73
|
+
// NOTE: enrolment takes effect immediately — the secret is stored and
|
|
74
|
+
// `2fa:enabled` is set before the user has proven they scanned it. That is
|
|
75
|
+
// the same contract the login-time setup route follows, and it is what the
|
|
76
|
+
// login check reads. A user who never scans the returned URI locks
|
|
77
|
+
// themselves out and needs an administrator 2FA reset to recover.
|
|
78
|
+
const result = await this.enrol(user);
|
|
79
|
+
return new http_1.Ok({ otp: result }, await this.rotate(session));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Disable own two-factor authentication
|
|
83
|
+
* Removes the TOTP secret and disables 2FA for the authenticated user.
|
|
84
|
+
* Requires the account password to be re-entered.
|
|
85
|
+
* @security cookieAuth
|
|
86
|
+
* @response 200 Two-factor authentication disabled successfully
|
|
87
|
+
* @response 400 Two-factor authentication is not enabled for this user
|
|
88
|
+
* @response 401 Unauthorized — valid session required, or password invalid
|
|
89
|
+
* @response 403 Forbidden — insufficient permissions
|
|
90
|
+
*/
|
|
91
|
+
async disable(user, confirmation, session) {
|
|
92
|
+
if (!user.Metadata[Default2FaToken_js_1.TWO_FA_METATADATA_KEYS.ENABLED]) {
|
|
93
|
+
throw new exceptions_1.InvalidOperation(`User ${user.Uuid} already has 2fa disabled`);
|
|
94
|
+
}
|
|
95
|
+
const confirmed = await this.confirmPassword(user, confirmation.Password);
|
|
96
|
+
if (confirmed !== true) {
|
|
97
|
+
return confirmed;
|
|
98
|
+
}
|
|
99
|
+
await this.unenrol(user);
|
|
100
|
+
return new http_1.Ok(null, await this.rotate(session));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Rotates the session id after the account's authentication requirements
|
|
104
|
+
* changed, and returns the response options carrying the new cookie.
|
|
105
|
+
*
|
|
106
|
+
* Attaching or removing a second factor changes what the session is worth. A
|
|
107
|
+
* session id that was observed before the change must not keep working after
|
|
108
|
+
* it.
|
|
109
|
+
*
|
|
110
|
+
* @param session - the caller's current session
|
|
111
|
+
*/
|
|
112
|
+
async rotate(session) {
|
|
113
|
+
if (!session) {
|
|
114
|
+
return { Headers: [{ Name: 'Cache-Control', Value: 'no-store' }] };
|
|
115
|
+
}
|
|
116
|
+
const regenerated = await (0, rbac_1.regenerateSession)(this.SessionProvider, session);
|
|
117
|
+
return {
|
|
118
|
+
Coockies: [this.SessionCookies.issue(regenerated)],
|
|
119
|
+
Headers: [{ Name: 'Cache-Control', Value: 'no-store' }],
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Generate and store the TOTP secret, returning the provisioning URI. Wraps
|
|
124
|
+
* the module-level action so tests can stub it without a TOTP/DB setup.
|
|
125
|
+
*/
|
|
126
|
+
enrol(user) {
|
|
127
|
+
return (0, _2fa_js_1.enableUser2Fa)(user);
|
|
128
|
+
}
|
|
129
|
+
/** Clear the TOTP secret. Wrapped for the same reason as {@link enrol}. */
|
|
130
|
+
unenrol(user) {
|
|
131
|
+
return (0, _2fa_js_1.disableUser2Fa)(user);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Re-verify the account password. Returns `true` on success, or the
|
|
135
|
+
* Unauthorized response to hand back to the caller.
|
|
136
|
+
*/
|
|
137
|
+
async confirmPassword(user, password) {
|
|
138
|
+
const valid = await this.PasswordProvider.verify(user.Password, password);
|
|
139
|
+
if (!valid) {
|
|
140
|
+
this._log.warn(`2fa change rejected for ${user.Uuid}: password confirmation failed`);
|
|
141
|
+
return new http_1.Unauthorized({
|
|
142
|
+
error: { code: 'E_PASSWORD_INVALID', message: 'Invalid password' },
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
exports.TwoFactorAuthUserController = TwoFactorAuthUserController;
|
|
149
|
+
__decorate([
|
|
150
|
+
(0, configuration_1.AutoinjectService)('rbac.password'),
|
|
151
|
+
__metadata("design:type", rbac_1.PasswordProvider)
|
|
152
|
+
], TwoFactorAuthUserController.prototype, "PasswordProvider", void 0);
|
|
153
|
+
__decorate([
|
|
154
|
+
(0, configuration_1.AutoinjectService)('rbac.session'),
|
|
155
|
+
__metadata("design:type", rbac_1.SessionProvider)
|
|
156
|
+
], TwoFactorAuthUserController.prototype, "SessionProvider", void 0);
|
|
157
|
+
__decorate([
|
|
158
|
+
(0, di_1.Autoinject)(SessionCookies_js_1.SessionCookieFactory),
|
|
159
|
+
__metadata("design:type", SessionCookies_js_1.SessionCookieFactory)
|
|
160
|
+
], TwoFactorAuthUserController.prototype, "SessionCookies", void 0);
|
|
161
|
+
__decorate([
|
|
162
|
+
(0, http_1.Get)('2fa'),
|
|
163
|
+
(0, rbac_http_1.Permission)(['readOwn']),
|
|
164
|
+
__param(0, (0, rbac_http_1.User)()),
|
|
165
|
+
__metadata("design:type", Function),
|
|
166
|
+
__metadata("design:paramtypes", [rbac_1.User]),
|
|
167
|
+
__metadata("design:returntype", Promise)
|
|
168
|
+
], TwoFactorAuthUserController.prototype, "status", null);
|
|
169
|
+
__decorate([
|
|
170
|
+
(0, http_1.Post)('2fa/enable'),
|
|
171
|
+
(0, rbac_http_1.Permission)(['updateOwn']),
|
|
172
|
+
__param(0, (0, rbac_http_1.User)()),
|
|
173
|
+
__param(1, (0, http_1.Body)()),
|
|
174
|
+
__param(2, (0, rbac_http_1.Session)()),
|
|
175
|
+
__metadata("design:type", Function),
|
|
176
|
+
__metadata("design:paramtypes", [rbac_1.User, confirm_password_dto_js_1.ConfirmPasswordDto, Object]),
|
|
177
|
+
__metadata("design:returntype", Promise)
|
|
178
|
+
], TwoFactorAuthUserController.prototype, "enable", null);
|
|
179
|
+
__decorate([
|
|
180
|
+
(0, http_1.Post)('2fa/disable'),
|
|
181
|
+
(0, rbac_http_1.Permission)(['updateOwn']),
|
|
182
|
+
__param(0, (0, rbac_http_1.User)()),
|
|
183
|
+
__param(1, (0, http_1.Body)()),
|
|
184
|
+
__param(2, (0, rbac_http_1.Session)()),
|
|
185
|
+
__metadata("design:type", Function),
|
|
186
|
+
__metadata("design:paramtypes", [rbac_1.User, confirm_password_dto_js_1.ConfirmPasswordDto, Object]),
|
|
187
|
+
__metadata("design:returntype", Promise)
|
|
188
|
+
], TwoFactorAuthUserController.prototype, "disable", null);
|
|
189
|
+
exports.TwoFactorAuthUserController = TwoFactorAuthUserController = __decorate([
|
|
190
|
+
(0, http_1.BasePath)('user'),
|
|
191
|
+
(0, rbac_http_1.Resource)('user'),
|
|
192
|
+
(0, http_1.Policy)(rbac_http_1.AuthorizedPolicy),
|
|
193
|
+
(0, http_1.Policy)(_2FaPolicy_js_1.TwoFactorAuthEnabled)
|
|
194
|
+
], TwoFactorAuthUserController);
|
|
195
|
+
//# sourceMappingURL=TwoFactorAuthUserController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TwoFactorAuthUserController.js","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthUserController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { PasswordDto } from '../dto/password-dto.js';
|
|
2
2
|
import { User as UserModel, PasswordProvider, SessionProvider, AccessControl } from '@spinajs/rbac';
|
|
3
|
+
import type { ISession } from '@spinajs/rbac';
|
|
3
4
|
import { BaseController, Ok } from '@spinajs/http';
|
|
4
5
|
import { IGrantsMap } from '@spinajs/rbac-http';
|
|
6
|
+
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
5
7
|
/**
|
|
6
8
|
* Current user profile management.
|
|
7
9
|
* Allows an authenticated user to read and modify their own account — refresh profile data,
|
|
@@ -10,9 +12,9 @@ import { IGrantsMap } from '@spinajs/rbac-http';
|
|
|
10
12
|
*/
|
|
11
13
|
export declare class UserController extends BaseController {
|
|
12
14
|
protected PasswordProvider: PasswordProvider;
|
|
13
|
-
protected CoockieSecret: string;
|
|
14
15
|
protected SessionProvider: SessionProvider;
|
|
15
16
|
protected AC: AccessControl;
|
|
17
|
+
protected SessionCookies: SessionCookieFactory;
|
|
16
18
|
/**
|
|
17
19
|
* Refresh current user profile
|
|
18
20
|
* Reloads the authenticated user's record from the database (including metadata) and
|
|
@@ -22,17 +24,18 @@ export declare class UserController extends BaseController {
|
|
|
22
24
|
* @response 401 Unauthorized — valid session required
|
|
23
25
|
* @response 403 Forbidden — insufficient permissions
|
|
24
26
|
*/
|
|
25
|
-
refresh(user: UserModel, ssid: string): Promise<Ok<import("@spinajs/orm").
|
|
27
|
+
refresh(user: UserModel, ssid: string): Promise<Ok<import("@spinajs/orm").ModelDataWithRelationData<UserModel>>>;
|
|
26
28
|
/**
|
|
27
29
|
* Get current user grants
|
|
28
|
-
* Returns the flattened RBAC grants for the authenticated user
|
|
29
|
-
* the
|
|
30
|
+
* Returns the flattened RBAC grants in effect for the authenticated user — those of
|
|
31
|
+
* the session's active role, resolved through its inheritance chain. Switching the
|
|
32
|
+
* active role (`POST /auth/active-role`) changes what this returns.
|
|
30
33
|
* @security cookieAuth
|
|
31
|
-
* @returns {IGrantsMap}
|
|
34
|
+
* @returns {IGrantsMap} RBAC grants map for the active role: resource → action → permission descriptor
|
|
32
35
|
* @response 401 Unauthorized — valid session required
|
|
33
36
|
* @response 403 Forbidden — insufficient permissions
|
|
34
37
|
*/
|
|
35
|
-
getGrants(user: UserModel): Promise<Ok<IGrantsMap>>;
|
|
38
|
+
getGrants(user: UserModel, session: ISession): Promise<Ok<IGrantsMap>>;
|
|
36
39
|
/**
|
|
37
40
|
* Change own password
|
|
38
41
|
* Changes the authenticated user's password. Requires the current (old) password for verification.
|
|
@@ -42,6 +45,6 @@ export declare class UserController extends BaseController {
|
|
|
42
45
|
* @response 401 Unauthorized — valid session required
|
|
43
46
|
* @response 403 Forbidden — insufficient permissions
|
|
44
47
|
*/
|
|
45
|
-
newPassword(user: UserModel, pwd: PasswordDto): Promise<Ok<
|
|
48
|
+
newPassword(user: UserModel, pwd: PasswordDto, session: ISession): Promise<Ok<null>>;
|
|
46
49
|
}
|
|
47
50
|
//# sourceMappingURL=UserController.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserController.d.ts","sourceRoot":"","sources":["../../../src/controllers/UserController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,gBAAgB,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"UserController.d.ts","sourceRoot":"","sources":["../../../src/controllers/UserController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAA8C,aAAa,EAAE,MAAM,eAAe,CAAC;AAChJ,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAiB,EAAE,EAAuB,MAAM,eAAe,CAAC;AAIvF,OAAO,EAAgD,UAAU,EAAyD,MAAM,oBAAoB,CAAC;AAGrJ,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAIrE;;;;;GAKG;AACH,qBAGa,cAAe,SAAQ,cAAc;IAEhD,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAG7C,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAG3C,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAG5B,SAAS,CAAC,cAAc,EAAE,oBAAoB,CAAC;IAE/C;;;;;;;;OAQG;IAGU,OAAO,CAAS,IAAI,EAAE,SAAS,EAAkB,IAAI,EAAE,MAAM;IA0B1E;;;;;;;;;OASG;IAGU,SAAS,CAAS,IAAI,EAAE,SAAS,EAAqB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IAS9G;;;;;;;;OAQG;IAGU,WAAW,CAAS,IAAI,EAAE,SAAS,EAAU,GAAG,EAAE,WAAW,EAAqB,OAAO,EAAE,QAAQ;CAwCjH"}
|