@spinajs/rbac-http-user 2.0.502 → 2.0.504
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/2fa/Default2FaToken.d.ts +8 -0
- package/lib/cjs/2fa/Default2FaToken.d.ts.map +1 -1
- package/lib/cjs/2fa/Default2FaToken.js +25 -3
- package/lib/cjs/2fa/Default2FaToken.js.map +1 -1
- package/lib/cjs/actions/2fa.d.ts +22 -3
- package/lib/cjs/actions/2fa.d.ts.map +1 -1
- package/lib/cjs/actions/2fa.js +44 -3
- package/lib/cjs/actions/2fa.js.map +1 -1
- package/lib/cjs/config/rbac-http.d.ts.map +1 -1
- package/lib/cjs/config/rbac-http.js +6 -0
- package/lib/cjs/config/rbac-http.js.map +1 -1
- package/lib/cjs/controllers/LoginController.d.ts.map +1 -1
- package/lib/cjs/controllers/LoginController.js +10 -1
- package/lib/cjs/controllers/LoginController.js.map +1 -1
- package/lib/cjs/controllers/TwoFactorAuthController.d.ts +20 -1
- package/lib/cjs/controllers/TwoFactorAuthController.d.ts.map +1 -1
- package/lib/cjs/controllers/TwoFactorAuthController.js +45 -2
- package/lib/cjs/controllers/TwoFactorAuthController.js.map +1 -1
- package/lib/cjs/controllers/TwoFactorAuthUserController.d.ts +83 -4
- package/lib/cjs/controllers/TwoFactorAuthUserController.d.ts.map +1 -1
- package/lib/cjs/controllers/TwoFactorAuthUserController.js +156 -12
- package/lib/cjs/controllers/TwoFactorAuthUserController.js.map +1 -1
- package/lib/cjs/policies/2FaPolicy.d.ts.map +1 -1
- package/lib/cjs/policies/2FaPolicy.js +27 -6
- package/lib/cjs/policies/2FaPolicy.js.map +1 -1
- package/lib/mjs/2fa/Default2FaToken.d.ts +8 -0
- package/lib/mjs/2fa/Default2FaToken.d.ts.map +1 -1
- package/lib/mjs/2fa/Default2FaToken.js +25 -3
- package/lib/mjs/2fa/Default2FaToken.js.map +1 -1
- package/lib/mjs/actions/2fa.d.ts +22 -3
- package/lib/mjs/actions/2fa.d.ts.map +1 -1
- package/lib/mjs/actions/2fa.js +41 -3
- package/lib/mjs/actions/2fa.js.map +1 -1
- package/lib/mjs/config/rbac-http.d.ts.map +1 -1
- package/lib/mjs/config/rbac-http.js +6 -0
- package/lib/mjs/config/rbac-http.js.map +1 -1
- package/lib/mjs/controllers/LoginController.d.ts.map +1 -1
- package/lib/mjs/controllers/LoginController.js +10 -1
- package/lib/mjs/controllers/LoginController.js.map +1 -1
- package/lib/mjs/controllers/TwoFactorAuthController.d.ts +20 -1
- package/lib/mjs/controllers/TwoFactorAuthController.d.ts.map +1 -1
- package/lib/mjs/controllers/TwoFactorAuthController.js +48 -5
- package/lib/mjs/controllers/TwoFactorAuthController.js.map +1 -1
- package/lib/mjs/controllers/TwoFactorAuthUserController.d.ts +83 -4
- package/lib/mjs/controllers/TwoFactorAuthUserController.d.ts.map +1 -1
- package/lib/mjs/controllers/TwoFactorAuthUserController.js +160 -16
- package/lib/mjs/controllers/TwoFactorAuthUserController.js.map +1 -1
- package/lib/mjs/policies/2FaPolicy.d.ts.map +1 -1
- package/lib/mjs/policies/2FaPolicy.js +26 -5
- package/lib/mjs/policies/2FaPolicy.js.map +1 -1
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +15 -15
|
@@ -14,6 +14,14 @@ export declare class Default2FaToken extends TwoFactorAuthProvider {
|
|
|
14
14
|
execute(_: User): Promise<void>;
|
|
15
15
|
verifyToken(token: string, user: User): Promise<boolean>;
|
|
16
16
|
disable(user: User): Promise<void>;
|
|
17
|
+
beginEnrolment(user: User): Promise<any>;
|
|
18
|
+
activate(user: User): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Enrol and switch on in one step. This is what the CLI command, the
|
|
21
|
+
* administrator reset and user seeding use — they hand the secret to an
|
|
22
|
+
* operator rather than to the account owner, so there is nobody to confirm
|
|
23
|
+
* possession with.
|
|
24
|
+
*/
|
|
17
25
|
initialize(user: User): Promise<any>;
|
|
18
26
|
getOtpAuthUrl(user: User): Promise<string | null>;
|
|
19
27
|
isEnabled(user: User): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Default2FaToken.d.ts","sourceRoot":"","sources":["../../../src/2fa/Default2FaToken.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,OAAO,EAAE,GAAG,EAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAI3D,oBAAY,sBAAsB;IAC9B,KAAK,cAAc;IACnB,OAAO,gBAAgB;IACvB,GAAG,YAAY;CAClB;AAED,qBACa,eAAgB,SAAQ,qBAAqB;IAEtD,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC;IAGtB,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB,cAEC;IAED,OAAO,CAAC,OAAO;IAYR,OAAO,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrC;IAEY,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAcpE;IAEY,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAY9C;IAEY,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"Default2FaToken.d.ts","sourceRoot":"","sources":["../../../src/2fa/Default2FaToken.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,OAAO,EAAE,GAAG,EAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAI3D,oBAAY,sBAAsB;IAC9B,KAAK,cAAc;IACnB,OAAO,gBAAgB;IACvB,GAAG,YAAY;CAClB;AAED,qBACa,eAAgB,SAAQ,qBAAqB;IAEtD,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC;IAGtB,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB,cAEC;IAED,OAAO,CAAC,OAAO;IAYR,OAAO,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrC;IAEY,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAcpE;IAEY,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAY9C;IAEY,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAwBpD;IAEY,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAc/C;IAED;;;;;OAKG;IACU,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAKhD;IAEY,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAU7D;IAEY,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAGnD;IAEY,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAGvD;CACJ"}
|
|
@@ -96,17 +96,16 @@ let Default2FaToken = class Default2FaToken extends rbac_http_1.TwoFactorAuthPro
|
|
|
96
96
|
},
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
|
-
async
|
|
99
|
+
async beginEnrolment(user) {
|
|
100
100
|
if (user.Metadata[TWO_FA_METATADATA_KEYS.ENABLED]) {
|
|
101
101
|
throw new exceptions_1.InvalidOperation(`user ${user.Uuid} alread have enabled 2f, disable it first.`);
|
|
102
102
|
}
|
|
103
103
|
const secret = new OTPAuth.Secret({ size: this.Config.secretSize });
|
|
104
104
|
const totp = this._getOTP(user, secret.base32);
|
|
105
105
|
user.Metadata[TWO_FA_METATADATA_KEYS.TOKEN] = secret.base32;
|
|
106
|
-
user.Metadata[TWO_FA_METATADATA_KEYS.ENABLED] = true;
|
|
107
106
|
user.Metadata[TWO_FA_METATADATA_KEYS.OTP] = totp.toString();
|
|
108
107
|
await user.Metadata.update();
|
|
109
|
-
this.Log.trace(`2fa
|
|
108
|
+
this.Log.trace(`2fa enrolment started for user ${user.Uuid}`, {
|
|
110
109
|
user: {
|
|
111
110
|
Uuid: user.Uuid
|
|
112
111
|
},
|
|
@@ -116,6 +115,29 @@ let Default2FaToken = class Default2FaToken extends rbac_http_1.TwoFactorAuthPro
|
|
|
116
115
|
*/
|
|
117
116
|
return totp.toString();
|
|
118
117
|
}
|
|
118
|
+
async activate(user) {
|
|
119
|
+
if (!user.Metadata[TWO_FA_METATADATA_KEYS.TOKEN]) {
|
|
120
|
+
throw new exceptions_1.InvalidOperation(`user ${user.Uuid} has no 2fa secret to activate`);
|
|
121
|
+
}
|
|
122
|
+
user.Metadata[TWO_FA_METATADATA_KEYS.ENABLED] = true;
|
|
123
|
+
await user.Metadata.update();
|
|
124
|
+
this.Log.trace(`2fa activated for user ${user.Uuid}`, {
|
|
125
|
+
user: {
|
|
126
|
+
Uuid: user.Uuid
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Enrol and switch on in one step. This is what the CLI command, the
|
|
132
|
+
* administrator reset and user seeding use — they hand the secret to an
|
|
133
|
+
* operator rather than to the account owner, so there is nobody to confirm
|
|
134
|
+
* possession with.
|
|
135
|
+
*/
|
|
136
|
+
async initialize(user) {
|
|
137
|
+
const otp = await this.beginEnrolment(user);
|
|
138
|
+
await this.activate(user);
|
|
139
|
+
return otp;
|
|
140
|
+
}
|
|
119
141
|
async getOtpAuthUrl(user) {
|
|
120
142
|
const token = user.Metadata[TWO_FA_METATADATA_KEYS.TOKEN];
|
|
121
143
|
if (!token) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Default2FaToken.js","sourceRoot":"","sources":["../../../src/2fa/Default2FaToken.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oCAAyC;AAEzC,0DAAgD;AAChD,sCAA2C;AAC3C,kDAA2D;AAC3D,MAAY,OAAO,oCAAgB;AACnC,oDAAkE;AAElE,IAAY,sBAIX;AAJD,WAAY,sBAAsB;IAC9B,6CAAmB,CAAA;IACnB,iDAAuB,CAAA;IACvB,yCAAe,CAAA;AACnB,CAAC,EAJW,sBAAsB,aAAtB,sBAAsB,GAAtB,sBAAsB,QAIjC;AAGM,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,iCAAqB;IAOtD;QACI,KAAK,EAAE,CAAC;IACZ,CAAC;IAEO,OAAO,CAAC,IAAU,EAAE,MAAc;QACtC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YACpB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;YAC1B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;YAChC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;YAC1B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;YAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;SAC5C,CAAC,CAAC;IAEP,CAAC;IAEM,OAAO,CAAC,CAAO;QAClB,yDAAyD;QACzD,gCAAgC;QAChC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,KAAa,EAAE,IAAU;QAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAE/D,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,MAAM,IAAI,sBAAS,CAAC,kDAAkD,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACvF,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC3B,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;SAC7B,CAAC,CAAC;QAEH,OAAO,QAAQ,KAAK,IAAI,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,IAAU;QAE3B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAC3D,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAGvD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,8BAA8B,IAAI,CAAC,IAAI,EAAE,EAAE;YACtD,IAAI,EAAE;gBACF,IAAI,EAAE,IAAI,CAAC,IAAI;aAClB;SACJ,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"Default2FaToken.js","sourceRoot":"","sources":["../../../src/2fa/Default2FaToken.ts"],"names":[],"mappings":"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"}
|
package/lib/cjs/actions/2fa.d.ts
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
import { User } from '@spinajs/rbac';
|
|
2
2
|
/**
|
|
3
|
-
* NOTE for
|
|
4
|
-
*
|
|
3
|
+
* NOTE for enableUser2Fa: the event must be emitted for the USER, not for
|
|
4
|
+
* whatever the provider call returned ( `initialize()` returns the otpauth
|
|
5
5
|
* url ). `_user_ev` reads `Uuid` off its argument, so it is bound to `u`
|
|
6
|
-
* explicitly
|
|
6
|
+
* explicitly via `_tap`, which fires the event as a side effect while passing
|
|
7
|
+
* the provider result through untouched as the chain's result.
|
|
7
8
|
*/
|
|
8
9
|
export declare function enableUser2Fa(identifier: number | string | User): Promise<unknown>;
|
|
10
|
+
/**
|
|
11
|
+
* Hand the user a secret without switching 2fa on. No event is emitted: an
|
|
12
|
+
* enrolment nobody confirmed is not a fact about the account, and consumers
|
|
13
|
+
* listening for User2FaEnabled would otherwise fire on an abandoned attempt.
|
|
14
|
+
*/
|
|
15
|
+
export declare function beginUser2FaEnrolment(identifier: number | string | User): Promise<unknown>;
|
|
16
|
+
/**
|
|
17
|
+
* Switch 2fa on for an account whose code was already verified by the caller.
|
|
18
|
+
* The login-window flow needs this split: `auth2Fa` has already checked the
|
|
19
|
+
* code and emitted User2FaPassed by the time the session is authorized.
|
|
20
|
+
*/
|
|
21
|
+
export declare function activateUser2Fa(identifier: number | string | User): Promise<unknown>;
|
|
22
|
+
/**
|
|
23
|
+
* Complete an enrolment started by `beginUser2FaEnrolment`: verify the code
|
|
24
|
+
* against the stored secret, then switch 2fa on. Throws Unauthorized when the
|
|
25
|
+
* code does not match, leaving the enrolment pending so the user can retry.
|
|
26
|
+
*/
|
|
27
|
+
export declare function confirmUser2Fa(identifier: number | string | User, token: string): Promise<unknown>;
|
|
9
28
|
export declare function disableUser2Fa(identifier: number | string | User): Promise<unknown>;
|
|
10
29
|
export declare function resetUser2Fa(identifier: number | string | User): Promise<unknown>;
|
|
11
30
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"2fa.d.ts","sourceRoot":"","sources":["../../../src/actions/2fa.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAyD,MAAM,eAAe,CAAC;AAa5F
|
|
1
|
+
{"version":3,"file":"2fa.d.ts","sourceRoot":"","sources":["../../../src/actions/2fa.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAyD,MAAM,eAAe,CAAC;AAa5F;;;;;;GAMG;AAEH,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,oBAYrE;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,oBAU7E;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,oBAWvE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,oBAqBrF;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,oBAWtE;AAED,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,oBAiBpE;AAED;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,oBA8B9E"}
|
package/lib/cjs/actions/2fa.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.enableUser2Fa = enableUser2Fa;
|
|
4
|
+
exports.beginUser2FaEnrolment = beginUser2FaEnrolment;
|
|
5
|
+
exports.activateUser2Fa = activateUser2Fa;
|
|
6
|
+
exports.confirmUser2Fa = confirmUser2Fa;
|
|
4
7
|
exports.disableUser2Fa = disableUser2Fa;
|
|
5
8
|
exports.resetUser2Fa = resetUser2Fa;
|
|
6
9
|
exports.auth2Fa = auth2Fa;
|
|
@@ -15,10 +18,11 @@ const rbac_http_1 = require("@spinajs/rbac-http");
|
|
|
15
18
|
const User2FaReset_js_1 = require("../events/User2FaReset.js");
|
|
16
19
|
const User2FaDisabled_js_1 = require("../events/User2FaDisabled.js");
|
|
17
20
|
/**
|
|
18
|
-
* NOTE for
|
|
19
|
-
*
|
|
21
|
+
* NOTE for enableUser2Fa: the event must be emitted for the USER, not for
|
|
22
|
+
* whatever the provider call returned ( `initialize()` returns the otpauth
|
|
20
23
|
* url ). `_user_ev` reads `Uuid` off its argument, so it is bound to `u`
|
|
21
|
-
* explicitly
|
|
24
|
+
* explicitly via `_tap`, which fires the event as a side effect while passing
|
|
25
|
+
* the provider result through untouched as the chain's result.
|
|
22
26
|
*/
|
|
23
27
|
async function enableUser2Fa(identifier) {
|
|
24
28
|
return (0, util_1._chain)((0, rbac_1._user_unsafe)(identifier), (u) => {
|
|
@@ -27,6 +31,43 @@ async function enableUser2Fa(identifier) {
|
|
|
27
31
|
(0, util_1._tap)(async () => (0, rbac_1._user_ev)(User2FaEnabled_js_1.User2FaEnabled)(u)));
|
|
28
32
|
});
|
|
29
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Hand the user a secret without switching 2fa on. No event is emitted: an
|
|
36
|
+
* enrolment nobody confirmed is not a fact about the account, and consumers
|
|
37
|
+
* listening for User2FaEnabled would otherwise fire on an abandoned attempt.
|
|
38
|
+
*/
|
|
39
|
+
async function beginUser2FaEnrolment(identifier) {
|
|
40
|
+
return (0, util_1._chain)((0, rbac_1._user_unsafe)(identifier), (u) => {
|
|
41
|
+
return (0, util_1._chain)((0, configuration_1._service)('rbac.twoFactorAuth', rbac_http_1.TwoFactorAuthProvider), async (twoFa) => twoFa.beginEnrolment(u));
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Switch 2fa on for an account whose code was already verified by the caller.
|
|
46
|
+
* The login-window flow needs this split: `auth2Fa` has already checked the
|
|
47
|
+
* code and emitted User2FaPassed by the time the session is authorized.
|
|
48
|
+
*/
|
|
49
|
+
async function activateUser2Fa(identifier) {
|
|
50
|
+
return (0, util_1._chain)((0, rbac_1._user_unsafe)(identifier), (u) => {
|
|
51
|
+
return (0, util_1._chain)((0, configuration_1._service)('rbac.twoFactorAuth', rbac_http_1.TwoFactorAuthProvider), async (twoFa) => twoFa.activate(u), () => (0, rbac_1._user_ev)(User2FaEnabled_js_1.User2FaEnabled)(u));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Complete an enrolment started by `beginUser2FaEnrolment`: verify the code
|
|
56
|
+
* against the stored secret, then switch 2fa on. Throws Unauthorized when the
|
|
57
|
+
* code does not match, leaving the enrolment pending so the user can retry.
|
|
58
|
+
*/
|
|
59
|
+
async function confirmUser2Fa(identifier, token) {
|
|
60
|
+
token = (0, util_1._check_arg)((0, util_1._trim)(), (0, util_1._non_empty)())(token, 'token');
|
|
61
|
+
return (0, util_1._chain)((0, rbac_1._user_unsafe)(identifier), (u) => {
|
|
62
|
+
return (0, util_1._chain)((0, configuration_1._service)('rbac.twoFactorAuth', rbac_http_1.TwoFactorAuthProvider), (0, util_1._either)((twoFa) => twoFa.verifyToken(token, u),
|
|
63
|
+
// Delegates to `activateUser2Fa`, which re-resolves the provider
|
|
64
|
+
// itself. It is shared with the login-window flow, where the
|
|
65
|
+
// code is already verified by the time activation is needed.
|
|
66
|
+
() => activateUser2Fa(u), () => {
|
|
67
|
+
throw new http_1.Unauthorized('2fa confirmation failed');
|
|
68
|
+
}));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
30
71
|
async function disableUser2Fa(identifier) {
|
|
31
72
|
return (0, util_1._chain)((0, rbac_1._user_unsafe)(identifier), (u) => {
|
|
32
73
|
return (0, util_1._chain)((0, configuration_1._service)('rbac.twoFactorAuth', rbac_http_1.TwoFactorAuthProvider), async (twoFa) => twoFa.disable(u), () => (0, rbac_1._user_ev)(User2FaDisabled_js_1.User2FaDisabled)(u));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"2fa.js","sourceRoot":"","sources":["../../../src/actions/2fa.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"2fa.js","sourceRoot":"","sources":["../../../src/actions/2fa.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rbac-http.d.ts","sourceRoot":"","sources":["../../../src/config/rbac-http.ts"],"names":[],"mappings":"AAQA,QAAA,MAAM,QAAQ;IACZ,MAAM;QACJ,IAAI;YACF,WAAW;YACX,GAAG;;;IAGP,KAAK;QACH,OAAO;YACL,eAAe;gBAAI,UAAU;;YAC7B,cAAc;gBAAI,UAAU;;YAC5B,aAAa;gBAAI,UAAU;;YAC3B,YAAY;gBAAI,UAAU;;;;IAG9B,IAAI;QACF,OAAO;YACL;;eAEG;YACH,MAAM;YAEN;;eAEG;YACH,SAAS;YACT,MAAM;YACN,MAAM;YACN,MAAM;;QAER,aAAa;YACX,OAAO;
|
|
1
|
+
{"version":3,"file":"rbac-http.d.ts","sourceRoot":"","sources":["../../../src/config/rbac-http.ts"],"names":[],"mappings":"AAQA,QAAA,MAAM,QAAQ;IACZ,MAAM;QACJ,IAAI;YACF,WAAW;YACX,GAAG;;;IAGP,KAAK;QACH,OAAO;YACL,eAAe;gBAAI,UAAU;;YAC7B,cAAc;gBAAI,UAAU;;YAC5B,aAAa;gBAAI,UAAU;;YAC3B,YAAY;gBAAI,UAAU;;;;IAG9B,IAAI;QACF,OAAO;YACL;;eAEG;YACH,MAAM;YAEN;;eAEG;YACH,SAAS;YACT,MAAM;YACN,MAAM;YACN,MAAM;;QAER,aAAa;YACX,OAAO;YAQP,SAAS;YACT,OAAO;;QAMT,QAAQ;YAIN;;eAEG;YACH,kBAAkB;;;IAGtB,IAAI;CAKL,CAAC;eAEa,QAAQ"}
|
|
@@ -36,6 +36,12 @@ const rbacHttp = {
|
|
|
36
36
|
},
|
|
37
37
|
twoFactorAuth: {
|
|
38
38
|
enabled: true,
|
|
39
|
+
// `POST /user/2fa/reset` relies on this flag to recover an account that
|
|
40
|
+
// was left password-only after a reset was abandoned before the new
|
|
41
|
+
// secret was confirmed (see the docblock on `reset` in
|
|
42
|
+
// TwoFactorAuthUserController) — with it `false`, as it defaults here,
|
|
43
|
+
// that downgrade is silent and permanent for any consumer of this
|
|
44
|
+
// package that does not override it.
|
|
39
45
|
forceUser: false,
|
|
40
46
|
service: 'Default2FaToken',
|
|
41
47
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rbac-http.js","sourceRoot":"","sources":["../../../src/config/rbac-http.ts"],"names":[],"mappings":";;AAAA,+BAAgD;AAEhD,SAAS,GAAG,CAAC,IAAY;IACvB,MAAM,UAAU,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;IACjD,OAAO,IAAA,cAAO,EAAC,IAAA,gBAAS,EAAC,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3K,CAAC;AAGD,MAAM,QAAQ,GAAG;IACf,MAAM,EAAE;QACN,IAAI,EAAE;YACJ,WAAW,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACjC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;SAClB;KACF;IACD,KAAK,EAAE;QACL,OAAO,EAAE;YACP,eAAe,EAAE,EAAE,UAAU,EAAE,uBAAuB,EAAE;YACxD,cAAc,EAAE,EAAE,UAAU,EAAE,uBAAuB,EAAE;YACvD,aAAa,EAAE,EAAE,UAAU,EAAE,uBAAuB,EAAE;YACtD,YAAY,EAAE,EAAE,UAAU,EAAE,uBAAuB,EAAE;SACtD;KACF;IACD,IAAI,EAAE;QACJ,OAAO,EAAE;YACP;;eAEG;YACH,MAAM,EAAE,SAAS;YAEjB;;eAEG;YACH,SAAS,EAAE,MAAM;YACjB,MAAM,EAAE,CAAC;YACT,MAAM,EAAE,EAAE;YACV,MAAM,EAAE,CAAC;SACV;QACD,aAAa,EAAE;YACb,OAAO,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"rbac-http.js","sourceRoot":"","sources":["../../../src/config/rbac-http.ts"],"names":[],"mappings":";;AAAA,+BAAgD;AAEhD,SAAS,GAAG,CAAC,IAAY;IACvB,MAAM,UAAU,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;IACjD,OAAO,IAAA,cAAO,EAAC,IAAA,gBAAS,EAAC,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3K,CAAC;AAGD,MAAM,QAAQ,GAAG;IACf,MAAM,EAAE;QACN,IAAI,EAAE;YACJ,WAAW,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACjC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;SAClB;KACF;IACD,KAAK,EAAE;QACL,OAAO,EAAE;YACP,eAAe,EAAE,EAAE,UAAU,EAAE,uBAAuB,EAAE;YACxD,cAAc,EAAE,EAAE,UAAU,EAAE,uBAAuB,EAAE;YACvD,aAAa,EAAE,EAAE,UAAU,EAAE,uBAAuB,EAAE;YACtD,YAAY,EAAE,EAAE,UAAU,EAAE,uBAAuB,EAAE;SACtD;KACF;IACD,IAAI,EAAE;QACJ,OAAO,EAAE;YACP;;eAEG;YACH,MAAM,EAAE,SAAS;YAEjB;;eAEG;YACH,SAAS,EAAE,MAAM;YACjB,MAAM,EAAE,CAAC;YACT,MAAM,EAAE,EAAE;YACV,MAAM,EAAE,CAAC;SACV;QACD,aAAa,EAAE;YACb,OAAO,EAAE,IAAI;YAEb,wEAAwE;YACxE,oEAAoE;YACpE,uDAAuD;YACvD,uEAAuE;YACvE,kEAAkE;YAClE,qCAAqC;YACrC,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,iBAAiB;SAC3B;QACD,sEAAsE;QACtE,0EAA0E;QAC1E,sEAAsE;QACtE,yCAAyC;QACzC,QAAQ,EAAE;YACR,qFAAqF;YACrF,4EAA4E;YAE5E;;eAEG;YACH,kBAAkB,EAAE,CAAC;SACtB;KACF;IACD,IAAI,EAAE;IACJ,iBAAiB;IACjB,+CAA+C;IAC/C,KAAK;KACN;CACF,CAAC;kBAEa,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoginController.d.ts","sourceRoot":"","sources":["../../../src/controllers/LoginController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAwB,EAAE,EAAO,YAAY,EAAU,MAAM,eAAe,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,eAAe,EAAsB,aAAa,EAA0C,MAAM,eAAe,CAAC;AAGzI,OAAO,EAA6B,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAElF,OAAO,EAA0F,cAAc,EAAE,eAAe,EAAuB,MAAM,oBAAoB,CAAC;AAClL,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAKrE;;;;;GAKG;AACH,qBACa,eAAgB,SAAQ,cAAc;IAEjD,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;IAGvC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC;IAGrC,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAK3C,SAAS,CAAC,oBAAoB,EAAE,OAAO,CAAC;IAMxC,SAAS,CAAC,sBAAsB,EAAE,OAAO,CAAC;IAG1C,SAAS,CAAC,cAAc,EAAE,oBAAoB,CAAC;IAG/C,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAE5B;;;;;;;;;OASG;IAGU,KAAK,CAAiB,MAAM,EAAE,IAAI,EAAe,IAAI,EAAE,MAAM,EAAU,WAAW,EAAE,YAAY,GAAG,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"LoginController.d.ts","sourceRoot":"","sources":["../../../src/controllers/LoginController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAwB,EAAE,EAAO,YAAY,EAAU,MAAM,eAAe,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,eAAe,EAAsB,aAAa,EAA0C,MAAM,eAAe,CAAC;AAGzI,OAAO,EAA6B,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAElF,OAAO,EAA0F,cAAc,EAAE,eAAe,EAAuB,MAAM,oBAAoB,CAAC;AAClL,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAKrE;;;;;GAKG;AACH,qBACa,eAAgB,SAAQ,cAAc;IAEjD,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;IAGvC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC;IAGrC,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAK3C,SAAS,CAAC,oBAAoB,EAAE,OAAO,CAAC;IAMxC,SAAS,CAAC,sBAAsB,EAAE,OAAO,CAAC;IAG1C,SAAS,CAAC,cAAc,EAAE,oBAAoB,CAAC;IAG/C,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAE5B;;;;;;;;;OASG;IAGU,KAAK,CAAiB,MAAM,EAAE,IAAI,EAAe,IAAI,EAAE,MAAM,EAAU,WAAW,EAAE,YAAY,GAAG,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC,CAqHzJ;IAED;;;;;;;;;;;;OAYG;IAGU,MAAM,CAAc,IAAI,EAAE,MAAM,EAAqB,OAAO,EAAE,QAAQ,EAAkB,IAAI,EAAE,IAAI,oBA8B9G;IAED;;;;;;;;;OASG;IAGU,MAAM,CAAiB,IAAI,EAAE,IAAI,EAAiB,UAAU,EAAE,MAAM,EAAqB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAmBrJ;CACF"}
|
|
@@ -66,7 +66,16 @@ let LoginController = class LoginController extends http_1.BaseController {
|
|
|
66
66
|
session.Data.set('Logged', true);
|
|
67
67
|
session.UserId = user.Id;
|
|
68
68
|
const twoFaEnabledForUser = Boolean(user.Metadata[Default2FaToken_js_1.TWO_FA_METATADATA_KEYS.ENABLED]);
|
|
69
|
-
|
|
69
|
+
// `forceUser` alone used to be enough to park the user in
|
|
70
|
+
// TwoFactorInitRequired. But every mutating `/user/2fa*` and
|
|
71
|
+
// `/auth/2fa/setup` handler now calls `assertSystemEnabled()` and throws
|
|
72
|
+
// 403 when `rbac.twoFactorAuth.enabled` is off — so a user forced into
|
|
73
|
+
// this branch while the system switch is off would have no route back
|
|
74
|
+
// out: setup2fa can no longer both enrol AND activate them. The
|
|
75
|
+
// system-wide switch has to gate this branch too, or every user without
|
|
76
|
+
// 2FA is locked out of the product the moment forceUser is on and the
|
|
77
|
+
// switch is off.
|
|
78
|
+
if (this.TwoFactorAuthEnabled && this.TwoFactorAuthForceUser && !twoFaEnabledForUser) {
|
|
70
79
|
this._log.trace('User logged in, 2fa init required', {
|
|
71
80
|
Uuid: user.Uuid
|
|
72
81
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoginController.js","sourceRoot":"","sources":["../../../src/controllers/LoginController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,8DAAuD;AACvD,wCAAoG;AACpG,wCAAyI;AACzI,oDAAiE;AACjE,oCAA6C;AAC7C,0DAAkF;AAElF,kDAAkL;AAClL,wCAAqC;AAErC,4CAA6D;AAC7D,qEAAqE;AACrE,qDAA4D;AAC5D,kEAAmE;AAGnE;;;;;GAKG;AAEI,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,qBAAc;IA2BjD;;;;;;;;;OASG;IAGU,AAAN,KAAK,CAAC,KAAK,CAAiB,MAAY,EAAe,IAAY,EAAU,WAAyB;QAC3G,IAAI,CAAC;YAEH,0DAA0D;YAC1D,2BAA2B;YAC3B,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC1C,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,IAAA,YAAK,EAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;YAClE,MAAM,OAAO,GAAG,IAAI,kBAAW,EAAE,CAAC;YAElC,IAAI,MAAsB,CAAC;YAE3B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAEpC,8DAA8D;YAC9D,oEAAoE;YACpE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAClC,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;YAC7C,CAAC;YAED,8BAA8B;YAC9B,sEAAsE;YACtE,+EAA+E;YAC/E,yDAAyD;YACzD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACjC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;YAEzB,MAAM,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,2CAAsB,CAAC,OAAO,CAAC,CAAC,CAAC;YAEnF,IAAI,IAAI,CAAC,sBAAsB,IAAI,CAAC,mBAAmB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"LoginController.js","sourceRoot":"","sources":["../../../src/controllers/LoginController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
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 { IEnable2faResponse, IUserWithGrants } from '@spinajs/rbac-http';
|
|
4
|
+
import { IEnable2faResponse, IUserWithGrants, TwoFactorAuthConfig } from '@spinajs/rbac-http';
|
|
5
5
|
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
6
6
|
/**
|
|
7
7
|
* Two-factor authentication during login.
|
|
@@ -24,6 +24,7 @@ export declare class TwoFactorAuthController extends BaseController {
|
|
|
24
24
|
protected SessionProvider: SessionProvider;
|
|
25
25
|
protected SessionCookies: SessionCookieFactory;
|
|
26
26
|
protected AC: AccessControl;
|
|
27
|
+
protected TwoFactorConfig: TwoFactorAuthConfig;
|
|
27
28
|
/**
|
|
28
29
|
* Set up two-factor authentication during login
|
|
29
30
|
* Generates a TOTP secret for a user who must enrol before continuing — the state
|
|
@@ -53,5 +54,23 @@ export declare class TwoFactorAuthController extends BaseController {
|
|
|
53
54
|
* verification without a TOTP/DB setup.
|
|
54
55
|
*/
|
|
55
56
|
protected verifyTwoFactorToken(user: UserModel, token: string): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Store the TOTP secret without switching 2fa on. Wrapped in a protected
|
|
59
|
+
* method for the same reason as {@link verifyTwoFactorToken}.
|
|
60
|
+
*/
|
|
61
|
+
protected enrol(user: UserModel): Promise<unknown>;
|
|
62
|
+
/** Switch 2fa on for an account whose secret was just verified. */
|
|
63
|
+
protected activateEnrolment(user: UserModel): Promise<unknown>;
|
|
64
|
+
/**
|
|
65
|
+
* Refuse to start enrolment while 2FA is switched off system-wide.
|
|
66
|
+
*
|
|
67
|
+
* `TwoFacRouteEnabled` cannot do this job here either: @spinajs/http merges
|
|
68
|
+
* a route's policies into one gate that passes when ANY of them resolves,
|
|
69
|
+
* and this controller also carries `NotAuthorizedPolicy`, which succeeds
|
|
70
|
+
* for exactly the callers these routes serve — so `TwoFacRouteEnabled`
|
|
71
|
+
* rejecting cannot stop them. The check has to live where it cannot be
|
|
72
|
+
* short-circuited.
|
|
73
|
+
*/
|
|
74
|
+
protected assertSystemEnabled(): void;
|
|
56
75
|
}
|
|
57
76
|
//# sourceMappingURL=TwoFactorAuthController.d.ts.map
|
|
@@ -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,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;
|
|
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,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAIzH,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;IAG5B,SAAS,CAAC,eAAe,EAAE,mBAAmB,CAAC;IAE/C;;;;;;;;;;;OAWG;IAEU,QAAQ,CAAS,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAgB9E;IAED;;;;;;;;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,CA8C3J;IAED;;;;OAIG;IACH,SAAS,CAAC,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;IAED;;;OAGG;IACH,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAEjD;IAED,mEAAmE;IACnE,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAE7D;IAED;;;;;;;;;OASG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI,CAMpC;CACF"}
|
|
@@ -58,10 +58,15 @@ let TwoFactorAuthController = class TwoFactorAuthController extends http_1.BaseC
|
|
|
58
58
|
* @response 403 Session is not awaiting two-factor enrolment
|
|
59
59
|
*/
|
|
60
60
|
async setup2fa(user) {
|
|
61
|
+
this.assertSystemEnabled();
|
|
61
62
|
if (user.Metadata[Default2FaToken_js_1.TWO_FA_METATADATA_KEYS.ENABLED]) {
|
|
62
|
-
throw new exceptions_1.
|
|
63
|
+
throw new exceptions_1.BadRequest(`User ${user.Uuid} already has 2fa enabled`);
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
+
// Re-running setup on an account that already started enrolling is allowed:
|
|
66
|
+
// it replaces an unconfirmed secret, which is exactly how a user who lost
|
|
67
|
+
// the QR gets a new one. There is nothing to steal — the caller could reach
|
|
68
|
+
// the same state from scratch.
|
|
69
|
+
const result = await this.enrol(user);
|
|
65
70
|
return new http_1.Ok({
|
|
66
71
|
otp: result,
|
|
67
72
|
});
|
|
@@ -78,6 +83,12 @@ let TwoFactorAuthController = class TwoFactorAuthController extends http_1.BaseC
|
|
|
78
83
|
async verifyToken(logged, token, session) {
|
|
79
84
|
try {
|
|
80
85
|
await this.verifyTwoFactorToken(logged, token.Token);
|
|
86
|
+
// A pending enrolment (secret stored, `2fa:enabled` unset) becomes real
|
|
87
|
+
// here and nowhere else — this is the first moment the user has proven
|
|
88
|
+
// possession of the device.
|
|
89
|
+
if (!logged.Metadata[Default2FaToken_js_1.TWO_FA_METATADATA_KEYS.ENABLED]) {
|
|
90
|
+
await this.activateEnrolment(logged);
|
|
91
|
+
}
|
|
81
92
|
// 2fa complete, mark as authorized
|
|
82
93
|
// fron now on user is considered authorized
|
|
83
94
|
session.Data.set('Authorized', true);
|
|
@@ -119,6 +130,34 @@ let TwoFactorAuthController = class TwoFactorAuthController extends http_1.BaseC
|
|
|
119
130
|
verifyTwoFactorToken(user, token) {
|
|
120
131
|
return (0, _2fa_js_1.auth2Fa)(user, token);
|
|
121
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Store the TOTP secret without switching 2fa on. Wrapped in a protected
|
|
135
|
+
* method for the same reason as {@link verifyTwoFactorToken}.
|
|
136
|
+
*/
|
|
137
|
+
enrol(user) {
|
|
138
|
+
return (0, _2fa_js_1.beginUser2FaEnrolment)(user);
|
|
139
|
+
}
|
|
140
|
+
/** Switch 2fa on for an account whose secret was just verified. */
|
|
141
|
+
activateEnrolment(user) {
|
|
142
|
+
return (0, _2fa_js_1.activateUser2Fa)(user);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Refuse to start enrolment while 2FA is switched off system-wide.
|
|
146
|
+
*
|
|
147
|
+
* `TwoFacRouteEnabled` cannot do this job here either: @spinajs/http merges
|
|
148
|
+
* a route's policies into one gate that passes when ANY of them resolves,
|
|
149
|
+
* and this controller also carries `NotAuthorizedPolicy`, which succeeds
|
|
150
|
+
* for exactly the callers these routes serve — so `TwoFacRouteEnabled`
|
|
151
|
+
* rejecting cannot stop them. The check has to live where it cannot be
|
|
152
|
+
* short-circuited.
|
|
153
|
+
*/
|
|
154
|
+
assertSystemEnabled() {
|
|
155
|
+
if (this.TwoFactorConfig?.enabled === false) {
|
|
156
|
+
throw Object.assign(new exceptions_1.Forbidden('2 factor auth is not enabled'), {
|
|
157
|
+
error: { code: 'E_2FA_SYSTEM_DISABLED', message: '2 factor auth is not enabled' },
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
122
161
|
};
|
|
123
162
|
exports.TwoFactorAuthController = TwoFactorAuthController;
|
|
124
163
|
__decorate([
|
|
@@ -133,6 +172,10 @@ __decorate([
|
|
|
133
172
|
(0, di_1.Autoinject)(rbac_1.AccessControl),
|
|
134
173
|
__metadata("design:type", rbac_1.AccessControl)
|
|
135
174
|
], TwoFactorAuthController.prototype, "AC", void 0);
|
|
175
|
+
__decorate([
|
|
176
|
+
(0, configuration_1.Config)('rbac.twoFactorAuth'),
|
|
177
|
+
__metadata("design:type", Object)
|
|
178
|
+
], TwoFactorAuthController.prototype, "TwoFactorConfig", void 0);
|
|
136
179
|
__decorate([
|
|
137
180
|
(0, http_1.Post)('2fa/setup'),
|
|
138
181
|
__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,wCAAsF;AACtF,wCAA+G;AAC/G,kDAA6C;AAC7C,wCAA6C;AAE7C,4DAA8D;AAC9D,
|
|
1
|
+
{"version":3,"file":"TwoFactorAuthController.js","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,26 @@
|
|
|
1
|
-
import { BaseController, Ok, Unauthorized } from '@spinajs/http';
|
|
1
|
+
import { BaseController, ForbiddenResponse, Ok, Unauthorized } from '@spinajs/http';
|
|
2
2
|
import { PasswordProvider, SessionProvider, User as UserModel } from '@spinajs/rbac';
|
|
3
3
|
import type { ISession } from '@spinajs/rbac';
|
|
4
|
-
import { IEnable2faResponse } from '@spinajs/rbac-http';
|
|
4
|
+
import { IEnable2faResponse, TwoFactorAuthConfig } from '@spinajs/rbac-http';
|
|
5
5
|
import { ConfirmPasswordDto } from '../dto/confirm-password-dto.js';
|
|
6
|
+
import { TokenDto } from '../dto/token-dto.js';
|
|
6
7
|
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
7
8
|
/** Whether the authenticated user currently has a TOTP device enrolled. */
|
|
8
9
|
export interface ITwoFactorStatus {
|
|
9
10
|
Enabled: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* A secret was issued but never confirmed. The account is not protected — the
|
|
13
|
+
* distinction exists so the UI can say "you started this" rather than
|
|
14
|
+
* "you have no 2fa".
|
|
15
|
+
*/
|
|
16
|
+
Pending: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Whether 2FA is switched on system-wide (`rbac.twoFactorAuth.enabled`). The
|
|
19
|
+
* frontend hides its 2FA controls when this is false; it is reported here
|
|
20
|
+
* rather than signalled by an error because the guarding policy cannot
|
|
21
|
+
* reject an authorized caller.
|
|
22
|
+
*/
|
|
23
|
+
SystemEnabled: boolean;
|
|
10
24
|
}
|
|
11
25
|
/**
|
|
12
26
|
* Self-service two-factor authentication.
|
|
@@ -22,12 +36,24 @@ export interface ITwoFactorStatus {
|
|
|
22
36
|
* not be enough to attach an attacker-controlled authenticator or to strip the
|
|
23
37
|
* second factor off the account.
|
|
24
38
|
*
|
|
39
|
+
* `TwoFactorAuthEnabled` stays on the class as the guard for callers it is
|
|
40
|
+
* able to reject, but it cannot block an authorized caller here:
|
|
41
|
+
* `@spinajs/http` merges every policy on a route into ONE gate that lets the
|
|
42
|
+
* route run when ANY policy resolves, and `AuthorizedPolicy` below resolves
|
|
43
|
+
* for any logged-in caller — so once a session is authorized, that policy
|
|
44
|
+
* alone is enough to pass the gate regardless of what `TwoFactorAuthEnabled`
|
|
45
|
+
* decides. That is why the system-wide switch (`rbac.twoFactorAuth.enabled`)
|
|
46
|
+
* is *also* enforced directly in the mutating handlers, via
|
|
47
|
+
* {@link assertSystemEnabled}, which is the check that actually matters for
|
|
48
|
+
* an authorized caller.
|
|
49
|
+
*
|
|
25
50
|
* @tags Two-Factor Settings
|
|
26
51
|
*/
|
|
27
52
|
export declare class TwoFactorAuthUserController extends BaseController {
|
|
28
53
|
protected PasswordProvider: PasswordProvider;
|
|
29
54
|
protected SessionProvider: SessionProvider;
|
|
30
55
|
protected SessionCookies: SessionCookieFactory;
|
|
56
|
+
protected TwoFactorConfig: TwoFactorAuthConfig;
|
|
31
57
|
/**
|
|
32
58
|
* Get own two-factor status
|
|
33
59
|
* Reports whether the authenticated user currently has a TOTP device enrolled.
|
|
@@ -41,6 +67,8 @@ export declare class TwoFactorAuthUserController extends BaseController {
|
|
|
41
67
|
* Enable own two-factor authentication
|
|
42
68
|
* Generates a TOTP secret for the authenticated user and returns the OTP provisioning
|
|
43
69
|
* URI to scan with an authenticator app. Requires the account password to be re-entered.
|
|
70
|
+
* 2FA stays off until the new code is confirmed with `POST /user/2fa/confirm` — a caller
|
|
71
|
+
* that stops after this call leaves the account unprotected, believing it is enrolled.
|
|
44
72
|
* @security cookieAuth
|
|
45
73
|
* @returns {IEnable2faResponse} OTP provisioning URI to scan with an authenticator app
|
|
46
74
|
* @response 400 Two-factor authentication is already enabled for this user
|
|
@@ -48,6 +76,17 @@ export declare class TwoFactorAuthUserController extends BaseController {
|
|
|
48
76
|
* @response 403 Forbidden — insufficient permissions
|
|
49
77
|
*/
|
|
50
78
|
enable(user: UserModel, confirmation: ConfirmPasswordDto, session: ISession): Promise<Ok<IEnable2faResponse> | Unauthorized>;
|
|
79
|
+
/**
|
|
80
|
+
* Confirm own two-factor enrolment
|
|
81
|
+
* Verifies a code generated from the secret handed out by `POST /user/2fa/enable`
|
|
82
|
+
* or `POST /user/2fa/reset`, and only then switches 2FA on.
|
|
83
|
+
* @security cookieAuth
|
|
84
|
+
* @response 200 Two-factor authentication is now active
|
|
85
|
+
* @response 400 There is no pending enrolment to confirm
|
|
86
|
+
* @response 401 Unauthorized — valid session required
|
|
87
|
+
* @response 403 Invalid or expired TOTP code
|
|
88
|
+
*/
|
|
89
|
+
confirm(user: UserModel, token: TokenDto, session: ISession): Promise<Ok | ForbiddenResponse>;
|
|
51
90
|
/**
|
|
52
91
|
* Disable own two-factor authentication
|
|
53
92
|
* Removes the TOTP secret and disables 2FA for the authenticated user.
|
|
@@ -59,6 +98,43 @@ export declare class TwoFactorAuthUserController extends BaseController {
|
|
|
59
98
|
* @response 403 Forbidden — insufficient permissions
|
|
60
99
|
*/
|
|
61
100
|
disable(user: UserModel, confirmation: ConfirmPasswordDto, session: ISession): Promise<Ok | Unauthorized>;
|
|
101
|
+
/**
|
|
102
|
+
* Reset own two-factor authentication
|
|
103
|
+
* Removes the current TOTP device and issues a new secret in a single request,
|
|
104
|
+
* returning the provisioning URI to scan. 2FA stays off until the new code is
|
|
105
|
+
* confirmed with `POST /user/2fa/confirm`. Requires the account password.
|
|
106
|
+
*
|
|
107
|
+
* Folding disable-then-enable into one request removes the client-side gap
|
|
108
|
+
* where abandoning the flow between the two calls could strand the account
|
|
109
|
+
* without a second factor. It does not remove the server-side one: if
|
|
110
|
+
* `enrol` fails after `unenrol` already removed the old device, the account
|
|
111
|
+
* is left with no device at all — there is nothing to roll back to, since
|
|
112
|
+
* the old secret is already gone. That leaves the account in the ordinary
|
|
113
|
+
* `none` state, which every route here already handles: `GET /user/2fa`
|
|
114
|
+
* reports it and `POST /user/2fa/enable` starts a fresh enrolment.
|
|
115
|
+
*
|
|
116
|
+
* A caller who abandons before confirming is left password-only — the same
|
|
117
|
+
* gap as `enable`. The only built-in recovery is `rbac.twoFactorAuth.forceUser`
|
|
118
|
+
* pushing the account back through enrolment at next login, and this package's
|
|
119
|
+
* own default for that flag is `false` (see `src/config/rbac-http.ts`), so a
|
|
120
|
+
* consumer that has not set it will see the downgrade become silent and
|
|
121
|
+
* permanent rather than recovered.
|
|
122
|
+
* @security cookieAuth
|
|
123
|
+
* @returns {IEnable2faResponse} OTP provisioning URI to scan with an authenticator app
|
|
124
|
+
* @response 400 There is no two-factor device to reset
|
|
125
|
+
* @response 401 Unauthorized — valid session required, or password invalid
|
|
126
|
+
* @response 403 Forbidden — insufficient permissions
|
|
127
|
+
*/
|
|
128
|
+
reset(user: UserModel, confirmation: ConfirmPasswordDto, session: ISession): Promise<Ok<IEnable2faResponse> | Unauthorized>;
|
|
129
|
+
/**
|
|
130
|
+
* Refuse a mutation while 2FA is switched off system-wide.
|
|
131
|
+
*
|
|
132
|
+
* The `TwoFactorAuthEnabled` policy cannot do this job: @spinajs/http merges
|
|
133
|
+
* a route's policies into one gate that passes when ANY of them resolves, and
|
|
134
|
+
* these routes also carry AuthorizedPolicy, which succeeds for every
|
|
135
|
+
* logged-in caller. The check has to live where it cannot be short-circuited.
|
|
136
|
+
*/
|
|
137
|
+
protected assertSystemEnabled(): void;
|
|
62
138
|
/**
|
|
63
139
|
* Rotates the session id after the account's authentication requirements
|
|
64
140
|
* changed, and returns the response options carrying the new cookie.
|
|
@@ -83,10 +159,13 @@ export declare class TwoFactorAuthUserController extends BaseController {
|
|
|
83
159
|
}[];
|
|
84
160
|
}>;
|
|
85
161
|
/**
|
|
86
|
-
*
|
|
87
|
-
* the module-level action so tests can stub it without a
|
|
162
|
+
* Store the TOTP secret and return the provisioning URI, leaving 2fa off until
|
|
163
|
+
* confirmed. Wraps the module-level action so tests can stub it without a
|
|
164
|
+
* TOTP/DB setup.
|
|
88
165
|
*/
|
|
89
166
|
protected enrol(user: UserModel): Promise<unknown>;
|
|
167
|
+
/** Verify a code against the pending secret and switch 2fa on. */
|
|
168
|
+
protected confirmEnrolment(user: UserModel, token: string): Promise<unknown>;
|
|
90
169
|
/** Clear the TOTP secret. Wrapped for the same reason as {@link enrol}. */
|
|
91
170
|
protected unenrol(user: UserModel): Promise<unknown>;
|
|
92
171
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TwoFactorAuthUserController.d.ts","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthUserController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"TwoFactorAuthUserController.d.ts","sourceRoot":"","sources":["../../../src/controllers/TwoFactorAuthUserController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAkB,iBAAiB,EAAO,EAAE,EAAgB,YAAY,EAAE,MAAM,eAAe,CAAC;AACvH,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,EAAoD,mBAAmB,EAAQ,MAAM,oBAAoB,CAAC;AAEvJ,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAKrE,2EAA2E;AAC3E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IAEjB;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;;;OAKG;IACH,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;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;IAG/C,SAAS,CAAC,eAAe,EAAE,mBAAmB,CAAC;IAE/C;;;;;;;OAOG;IAGU,MAAM,CAAS,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAQ1E;IAED;;;;;;;;;;;OAWG;IAGU,MAAM,CAAS,IAAI,EAAE,SAAS,EAAU,YAAY,EAAE,kBAAkB,EAAqB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,kBAAkB,CAAC,GAAG,YAAY,CAAC,CAmB3K;IAED;;;;;;;;;OASG;IAGU,OAAO,CAAS,IAAI,EAAE,SAAS,EAAU,KAAK,EAAE,QAAQ,EAAqB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,GAAG,iBAAiB,CAAC,CAiC5I;IAED;;;;;;;;;OASG;IAGU,OAAO,CAAS,IAAI,EAAE,SAAS,EAAU,YAAY,EAAE,kBAAkB,EAAqB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,GAAG,YAAY,CAAC,CAcxJ;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IAGU,KAAK,CAAS,IAAI,EAAE,SAAS,EAAU,YAAY,EAAE,kBAAkB,EAAqB,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,kBAAkB,CAAC,GAAG,YAAY,CAAC,CAgB1K;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI,CAMpC;IAED;;;;;;;;;OASG;IACH,UAAgB,MAAM,CAAC,OAAO,EAAE,QAAQ;;;;;;;;;;;;OAWvC;IAED;;;;OAIG;IACH,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAEjD;IAED,kEAAkE;IAClE,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE3E;IAED,2EAA2E;IAC3E,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAEnD;IAED;;;OAGG;IACH,UAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC,CAY/F;CACF"}
|