@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
|
@@ -12,10 +12,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
12
12
|
};
|
|
13
13
|
import { SwitchRoleDto } from '../dto/switchRole-dto.js';
|
|
14
14
|
import { BaseController, BasePath, Post, Body, Ok, Get, BadRequestResponse, Unauthorized, Policy } from '@spinajs/http';
|
|
15
|
-
import { AccessControl, AuthProvider, PasswordProvider, SessionProvider,
|
|
15
|
+
import { AccessControl, AuthProvider, PasswordProvider, SessionProvider, regenerateSession } from '@spinajs/rbac';
|
|
16
16
|
import { Autoinject } from '@spinajs/di';
|
|
17
17
|
import { AutoinjectService, Config } from '@spinajs/configuration';
|
|
18
18
|
import { LoggedPolicy, User as UserRouteArg, Session as SessionRouteArg, FromSession } from '@spinajs/rbac-http';
|
|
19
|
+
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
20
|
+
import { grantsFor } from '../services/grants.js';
|
|
19
21
|
/**
|
|
20
22
|
* Active role endpoints.
|
|
21
23
|
* Let users with multiple roles inspect and switch the currently active role.
|
|
@@ -78,25 +80,13 @@ let ActiveRoleController = class ActiveRoleController extends BaseController {
|
|
|
78
80
|
// fixation, and reset the ssid cookie to the new id.
|
|
79
81
|
const regenerated = await regenerateSession(this.SessionProvider, session);
|
|
80
82
|
return new Ok(this.buildResponse(payload.Role), {
|
|
81
|
-
Coockies: [
|
|
82
|
-
{
|
|
83
|
-
Name: 'ssid',
|
|
84
|
-
Value: regenerated.SessionId,
|
|
85
|
-
Options: {
|
|
86
|
-
signed: true,
|
|
87
|
-
httpOnly: true,
|
|
88
|
-
maxAge: sessionCookieMaxAge(regenerated),
|
|
89
|
-
...this.SessionCookieConfig,
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
],
|
|
83
|
+
Coockies: [this.SessionCookies.issue(regenerated)],
|
|
93
84
|
});
|
|
94
85
|
}
|
|
95
86
|
buildResponse(activeRole) {
|
|
96
|
-
const grants = activeRole ? _unwindGrants(activeRole, this.AC.getGrants()) : {};
|
|
97
87
|
return {
|
|
98
88
|
ActiveRole: activeRole,
|
|
99
|
-
Grants:
|
|
89
|
+
Grants: grantsFor(this.AC, activeRole),
|
|
100
90
|
};
|
|
101
91
|
}
|
|
102
92
|
};
|
|
@@ -121,9 +111,9 @@ __decorate([
|
|
|
121
111
|
__metadata("design:type", Array)
|
|
122
112
|
], ActiveRoleController.prototype, "RolesRequiringPassword", void 0);
|
|
123
113
|
__decorate([
|
|
124
|
-
|
|
125
|
-
__metadata("design:type",
|
|
126
|
-
], ActiveRoleController.prototype, "
|
|
114
|
+
Autoinject(SessionCookieFactory),
|
|
115
|
+
__metadata("design:type", SessionCookieFactory)
|
|
116
|
+
], ActiveRoleController.prototype, "SessionCookies", void 0);
|
|
127
117
|
__decorate([
|
|
128
118
|
Get('active-role'),
|
|
129
119
|
Policy(LoggedPolicy),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActiveRoleController.js","sourceRoot":"","sources":["../../../src/controllers/ActiveRoleController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACxH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"ActiveRoleController.js","sourceRoot":"","sources":["../../../src/controllers/ActiveRoleController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACxH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,IAAI,IAAI,YAAY,EAAE,OAAO,IAAI,eAAe,EAAE,WAAW,EAAuB,MAAM,oBAAoB,CAAC;AACtI,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;GAMG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,cAAc;IAmBtD;;;;;;;OAOG;IAGU,AAAN,KAAK,CAAC,aAAa,CAAiB,IAAU,EAAiB,UAAkB;QACtF,OAAO,IAAI,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;IAED;;;;;;;;;OASG;IAGU,AAAN,KAAK,CAAC,gBAAgB,CACX,IAAU,EACP,OAAiB,EAC5B,OAAsB;QAE9B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,kBAAkB,CAAC;gBAC5B,KAAK,EAAE;oBACL,IAAI,EAAE,qBAAqB;oBAC3B,OAAO,EAAE,SAAS,OAAO,CAAC,IAAI,2BAA2B;iBAC1D;aACF,CAAC,CAAC;QACL,CAAC;QAED,IAAI,IAAI,CAAC,sBAAsB,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACtB,OAAO,IAAI,YAAY,CAAC;oBACtB,KAAK,EAAE;wBACL,IAAI,EAAE,qBAAqB;wBAC3B,OAAO,EAAE,0CAA0C,OAAO,CAAC,IAAI,GAAG;qBACnE;iBACF,CAAC,CAAC;YACL,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;YAClF,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,IAAI,YAAY,CAAC;oBACtB,KAAK,EAAE;wBACL,IAAI,EAAE,oBAAoB;wBAC1B,OAAO,EAAE,kBAAkB;qBAC5B;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAE7C,4EAA4E;QAC5E,qDAAqD;QACrD,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAE3E,OAAO,IAAI,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YAC9C,QAAQ,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;SACnD,CAAC,CAAC;IACL,CAAC;IAES,aAAa,CAAC,UAAkB;QACxC,OAAO;YACL,UAAU,EAAE,UAAU;YACtB,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC;SACvC,CAAC;IACJ,CAAC;CACF,CAAA;AA/FW;IADT,UAAU,CAAC,aAAa,CAAC;8BACZ,aAAa;gDAAC;AAGlB;IADT,iBAAiB,CAAC,WAAW,CAAC;8BACP,YAAY;0DAAC;AAG3B;IADT,iBAAiB,CAAC,eAAe,CAAC;8BACP,gBAAgB;8DAAC;AAGnC;IADT,iBAAiB,CAAC,cAAc,CAAC;8BACP,eAAe;6DAAC;AAGjC;IADT,MAAM,CAAC,iCAAiC,EAAE,EAAE,YAAY,EAAE,EAAc,EAAE,CAAC;;oEACjC;AAGjC;IADT,UAAU,CAAC,oBAAoB,CAAC;8BACP,oBAAoB;4DAAC;AAYlC;IAFZ,GAAG,CAAC,aAAa,CAAC;IAClB,MAAM,CAAC,YAAY,CAAC;IACO,WAAA,YAAY,EAAE,CAAA;IAAc,WAAA,WAAW,EAAE,CAAA;;;;yDAEpE;AAcY;IAFZ,IAAI,CAAC,aAAa,CAAC;IACnB,MAAM,CAAC,YAAY,CAAC;IAElB,WAAA,YAAY,EAAE,CAAA;IACd,WAAA,eAAe,EAAE,CAAA;IACjB,WAAA,IAAI,EAAE,CAAA;;uDAAU,aAAa;;4DAyC/B;AAzFU,oBAAoB;IADhC,QAAQ,CAAC,MAAM,CAAC;GACJ,oBAAoB,CAiGhC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { ImpersonateDto } from '../dto/impersonate-dto.js';
|
|
2
2
|
import { BaseController, Ok, BadRequestResponse, Unauthorized, ForbiddenResponse, Conflict, NotFound } from '@spinajs/http';
|
|
3
|
-
import { AccessControl, PasswordProvider,
|
|
3
|
+
import { AccessControl, PasswordProvider, User, UserImpersonationStarted } from '@spinajs/rbac';
|
|
4
4
|
import type { ISession } from '@spinajs/rbac';
|
|
5
5
|
import { IImpersonationResponse, IImpersonationState, IUserWithGrants } from '@spinajs/rbac-http';
|
|
6
|
+
import { ImpersonationService } from '../services/ImpersonationService.js';
|
|
7
|
+
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
6
8
|
/**
|
|
7
9
|
* Impersonation endpoints.
|
|
8
10
|
*
|
|
@@ -17,7 +19,8 @@ import { IImpersonationResponse, IImpersonationState, IUserWithGrants } from '@s
|
|
|
17
19
|
export declare class ImpersonationController extends BaseController {
|
|
18
20
|
protected AC: AccessControl;
|
|
19
21
|
protected PasswordProvider: PasswordProvider;
|
|
20
|
-
protected
|
|
22
|
+
protected Impersonation: ImpersonationService;
|
|
23
|
+
protected SessionCookies: SessionCookieFactory;
|
|
21
24
|
protected RequirePassword: boolean;
|
|
22
25
|
protected ProtectedRoles: string[];
|
|
23
26
|
/**
|
|
@@ -56,17 +59,12 @@ export declare class ImpersonationController extends BaseController {
|
|
|
56
59
|
* Emit an impersonation lifecycle event. Wrapped in a protected method so
|
|
57
60
|
* tests can intercept without stubbing module-level ESM bindings.
|
|
58
61
|
*/
|
|
59
|
-
protected emitEvent(event: UserImpersonationStarted
|
|
62
|
+
protected emitEvent(event: UserImpersonationStarted): Promise<void>;
|
|
60
63
|
/**
|
|
61
64
|
* Load the impersonation target (with Metadata so IsBanned works). Extracted
|
|
62
65
|
* as a protected method so tests can stub it without setting up a database.
|
|
63
66
|
*/
|
|
64
67
|
protected loadTarget(uuid: string): Promise<User | undefined>;
|
|
65
|
-
|
|
66
|
-
* Load the original (impersonator) user. Extracted for the same reason as
|
|
67
|
-
* loadTarget — keeps the controller easy to test in isolation.
|
|
68
|
-
*/
|
|
69
|
-
protected loadOriginal(uuid: string): Promise<User | undefined>;
|
|
70
|
-
protected buildResponse(target: User, impersonator: User, activeRole: string, startedAt: string): IImpersonationResponse;
|
|
68
|
+
protected buildResponse(target: User, impersonator: User, activeRole: string | undefined, startedAt: string): IImpersonationResponse;
|
|
71
69
|
}
|
|
72
70
|
//# sourceMappingURL=ImpersonationController.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImpersonationController.d.ts","sourceRoot":"","sources":["../../../src/controllers/ImpersonationController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAA6B,EAAE,EAAO,kBAAkB,EAAE,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,EAAU,MAAM,eAAe,CAAC;AACpK,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,
|
|
1
|
+
{"version":3,"file":"ImpersonationController.d.ts","sourceRoot":"","sources":["../../../src/controllers/ImpersonationController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAA6B,EAAE,EAAO,kBAAkB,EAAE,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,EAAU,MAAM,eAAe,CAAC;AACpK,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,IAAI,EACJ,wBAAwB,EAEzB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAK9C,OAAO,EAKL,sBAAsB,EACtB,mBAAmB,EACnB,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAKrE;;;;;;;;;;GAUG;AACH,qBACa,uBAAwB,SAAQ,cAAc;IAEzD,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAG5B,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAG7C,SAAS,CAAC,aAAa,EAAE,oBAAoB,CAAC;IAG9C,SAAS,CAAC,cAAc,EAAE,oBAAoB,CAAC;IAG/C,SAAS,CAAC,eAAe,EAAE,OAAO,CAAC;IAGnC,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;IAEnC;;;;;;OAMG;IAGU,QAAQ,CACJ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,sBAAsB,EAAE,MAAM,GAC5C,OAAO,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC;IAYnC;;;;;;;;;;;;;;OAcG;IAGU,KAAK,CACA,MAAM,EAAE,IAAI,EACT,OAAO,EAAE,QAAQ,EAC5B,OAAO,EAAE,cAAc,GAC9B,OAAO,CACR,EAAE,CAAC,sBAAsB,CAAC,GAAG,kBAAkB,GAAG,YAAY,GAAG,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CACzG;IA+ED;;;;;;OAMG;IAGU,IAAI,CACC,MAAM,EAAE,IAAI,EACT,OAAO,EAAE,QAAQ,GACnC,OAAO,CAAC,EAAE,CAAC,eAAe,CAAC,GAAG,kBAAkB,CAAC;IAwBpD;;;OAGG;IACH,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAInE;;;OAGG;IACH,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAI7D,SAAS,CAAC,aAAa,CACrB,MAAM,EAAE,IAAI,EACZ,YAAY,EAAE,IAAI,EAClB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE,MAAM,GAChB,sBAAsB;CAS1B"}
|
|
@@ -12,12 +12,15 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
12
12
|
};
|
|
13
13
|
import { ImpersonateDto } from '../dto/impersonate-dto.js';
|
|
14
14
|
import { BaseController, BasePath, Post, Del, Body, Ok, Get, BadRequestResponse, Unauthorized, ForbiddenResponse, Conflict, NotFound, Policy } from '@spinajs/http';
|
|
15
|
-
import { AccessControl, PasswordProvider,
|
|
15
|
+
import { AccessControl, PasswordProvider, User, UserImpersonationStarted, canImpersonate, } from '@spinajs/rbac';
|
|
16
16
|
import { Autoinject } from '@spinajs/di';
|
|
17
17
|
import { AutoinjectService, Config } from '@spinajs/configuration';
|
|
18
18
|
import { _ev } from '@spinajs/queue';
|
|
19
19
|
import { DateTime } from 'luxon';
|
|
20
20
|
import { LoggedPolicy, User as UserRouteArg, Session as SessionRouteArg, FromSession, } from '@spinajs/rbac-http';
|
|
21
|
+
import { ImpersonationService } from '../services/ImpersonationService.js';
|
|
22
|
+
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
23
|
+
import { buildUserWithGrants, grantsFor } from '../services/grants.js';
|
|
21
24
|
const IMPERSONATE_RESOURCE = 'user:impersonate';
|
|
22
25
|
/**
|
|
23
26
|
* Impersonation endpoints.
|
|
@@ -65,7 +68,7 @@ let ImpersonationController = class ImpersonationController extends BaseControll
|
|
|
65
68
|
* @response 409 An impersonation is already in progress for this session
|
|
66
69
|
*/
|
|
67
70
|
async start(caller, session, payload) {
|
|
68
|
-
if (
|
|
71
|
+
if (this.Impersonation.isActive(session)) {
|
|
69
72
|
return new Conflict({
|
|
70
73
|
error: {
|
|
71
74
|
code: 'E_IMPERSONATION_ACTIVE',
|
|
@@ -121,24 +124,18 @@ let ImpersonationController = class ImpersonationController extends BaseControll
|
|
|
121
124
|
return new Unauthorized({ error: { code: 'E_PASSWORD_INVALID', message: 'Invalid password' } });
|
|
122
125
|
}
|
|
123
126
|
}
|
|
124
|
-
// Persist impersonation state.
|
|
125
|
-
// ActiveRole so it can be restored on stop; effective ActiveRole
|
|
126
|
-
// the target's first role.
|
|
127
|
+
// Persist impersonation state. The service keeps the impersonator's
|
|
128
|
+
// previous ActiveRole so it can be restored on stop; effective ActiveRole
|
|
129
|
+
// becomes the target's first role.
|
|
127
130
|
const startedAt = DateTime.now().toISO();
|
|
128
|
-
const
|
|
129
|
-
session.Data.set('Impersonator', caller.Uuid);
|
|
130
|
-
session.Data.set('User', target.Uuid);
|
|
131
|
-
session.Data.set('ImpersonationStartedAt', startedAt);
|
|
132
|
-
if (previousActiveRole !== undefined) {
|
|
133
|
-
session.Data.set('OriginalActiveRole', previousActiveRole);
|
|
134
|
-
}
|
|
135
|
-
const targetActiveRole = target.Role?.[0];
|
|
136
|
-
if (targetActiveRole) {
|
|
137
|
-
session.Data.set('ActiveRole', targetActiveRole);
|
|
138
|
-
}
|
|
139
|
-
await this.SessionProvider.save(session);
|
|
131
|
+
const { Session: regenerated, ActiveRole: targetActiveRole } = await this.Impersonation.start(session, caller, target, startedAt);
|
|
140
132
|
await this.emitEvent(new UserImpersonationStarted(caller, target));
|
|
141
|
-
|
|
133
|
+
// The session id changed with the identity — hand the client the new one or
|
|
134
|
+
// its next request arrives with a session that no longer exists.
|
|
135
|
+
return new Ok(this.buildResponse(target, caller, targetActiveRole, startedAt), {
|
|
136
|
+
Coockies: [this.SessionCookies.issue(regenerated)],
|
|
137
|
+
Headers: [{ Name: 'Cache-Control', Value: 'no-store' }],
|
|
138
|
+
});
|
|
142
139
|
}
|
|
143
140
|
/**
|
|
144
141
|
* Stop impersonation
|
|
@@ -148,41 +145,23 @@ let ImpersonationController = class ImpersonationController extends BaseControll
|
|
|
148
145
|
* @response 400 No impersonation is currently active
|
|
149
146
|
*/
|
|
150
147
|
async stop(target, session) {
|
|
151
|
-
const
|
|
152
|
-
if (
|
|
148
|
+
const result = await this.Impersonation.revert(session, target);
|
|
149
|
+
if (result.Status === 'not-impersonating') {
|
|
153
150
|
return new BadRequestResponse({
|
|
154
151
|
error: { code: 'E_NO_IMPERSONATION', message: 'No impersonation is currently in progress' },
|
|
155
152
|
});
|
|
156
153
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
//
|
|
160
|
-
//
|
|
161
|
-
// can re-authenticate.
|
|
162
|
-
session.Data.delete('Impersonator');
|
|
163
|
-
session.Data.delete('ImpersonationStartedAt');
|
|
164
|
-
session.Data.delete('OriginalActiveRole');
|
|
165
|
-
await this.SessionProvider.save(session);
|
|
154
|
+
if (result.Status === 'impersonator-gone') {
|
|
155
|
+
// Stale session referencing a deleted impersonator. The service already
|
|
156
|
+
// cleared the impersonation block to recover; report an error so the
|
|
157
|
+
// caller can re-authenticate.
|
|
166
158
|
return new BadRequestResponse({
|
|
167
159
|
error: { code: 'E_IMPERSONATOR_GONE', message: 'Original user no longer exists' },
|
|
168
160
|
});
|
|
169
161
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
session.Data.delete('ImpersonationStartedAt');
|
|
174
|
-
const restoredActiveRole = session.Data.get('OriginalActiveRole') ?? original.Role?.[0];
|
|
175
|
-
if (restoredActiveRole) {
|
|
176
|
-
session.Data.set('ActiveRole', restoredActiveRole);
|
|
177
|
-
}
|
|
178
|
-
session.Data.delete('OriginalActiveRole');
|
|
179
|
-
await this.SessionProvider.save(session);
|
|
180
|
-
await this.emitEvent(new UserImpersonationEnded(original, target));
|
|
181
|
-
const grants = restoredActiveRole ? _unwindGrants(restoredActiveRole, this.AC.getGrants()) : {};
|
|
182
|
-
return new Ok({
|
|
183
|
-
...original.dehydrateWithRelations({ dateTimeFormat: 'iso' }),
|
|
184
|
-
ActiveRole: restoredActiveRole,
|
|
185
|
-
Grants: grants,
|
|
162
|
+
return new Ok(buildUserWithGrants(result.Original, result.ActiveRole, this.AC), {
|
|
163
|
+
Coockies: [this.SessionCookies.issue(result.Session)],
|
|
164
|
+
Headers: [{ Name: 'Cache-Control', Value: 'no-store' }],
|
|
186
165
|
});
|
|
187
166
|
}
|
|
188
167
|
/**
|
|
@@ -199,20 +178,12 @@ let ImpersonationController = class ImpersonationController extends BaseControll
|
|
|
199
178
|
loadTarget(uuid) {
|
|
200
179
|
return User.query().whereUuid(uuid).populate('Metadata').notDeleted().first();
|
|
201
180
|
}
|
|
202
|
-
/**
|
|
203
|
-
* Load the original (impersonator) user. Extracted for the same reason as
|
|
204
|
-
* loadTarget — keeps the controller easy to test in isolation.
|
|
205
|
-
*/
|
|
206
|
-
loadOriginal(uuid) {
|
|
207
|
-
return User.getByUuid(uuid);
|
|
208
|
-
}
|
|
209
181
|
buildResponse(target, impersonator, activeRole, startedAt) {
|
|
210
|
-
const grants = activeRole ? _unwindGrants(activeRole, this.AC.getGrants()) : {};
|
|
211
182
|
return {
|
|
212
183
|
User: target.dehydrateWithRelations({ dateTimeFormat: 'iso' }),
|
|
213
184
|
Impersonator: impersonator.dehydrateWithRelations({ dateTimeFormat: 'iso' }),
|
|
214
185
|
ActiveRole: activeRole,
|
|
215
|
-
Grants:
|
|
186
|
+
Grants: grantsFor(this.AC, activeRole),
|
|
216
187
|
StartedAt: startedAt,
|
|
217
188
|
};
|
|
218
189
|
}
|
|
@@ -226,9 +197,13 @@ __decorate([
|
|
|
226
197
|
__metadata("design:type", PasswordProvider)
|
|
227
198
|
], ImpersonationController.prototype, "PasswordProvider", void 0);
|
|
228
199
|
__decorate([
|
|
229
|
-
|
|
230
|
-
__metadata("design:type",
|
|
231
|
-
], ImpersonationController.prototype, "
|
|
200
|
+
Autoinject(ImpersonationService),
|
|
201
|
+
__metadata("design:type", ImpersonationService)
|
|
202
|
+
], ImpersonationController.prototype, "Impersonation", void 0);
|
|
203
|
+
__decorate([
|
|
204
|
+
Autoinject(SessionCookieFactory),
|
|
205
|
+
__metadata("design:type", SessionCookieFactory)
|
|
206
|
+
], ImpersonationController.prototype, "SessionCookies", void 0);
|
|
232
207
|
__decorate([
|
|
233
208
|
Config('rbac.impersonation.requirePassword', { defaultValue: true }),
|
|
234
209
|
__metadata("design:type", Boolean)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImpersonationController.js","sourceRoot":"","sources":["../../../src/controllers/ImpersonationController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,kBAAkB,EAAE,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACpK,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,
|
|
1
|
+
{"version":3,"file":"ImpersonationController.js","sourceRoot":"","sources":["../../../src/controllers/ImpersonationController.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import { Configuration } from '@spinajs/configuration';
|
|
|
5
5
|
import { ILoginResponse } from '@spinajs/rbac-http';
|
|
6
6
|
import { User } from '@spinajs/rbac';
|
|
7
7
|
import type { ISession } from '@spinajs/rbac';
|
|
8
|
+
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
8
9
|
/**
|
|
9
10
|
* Authentication endpoints.
|
|
10
11
|
* Handles user login, logout, and current-session inspection.
|
|
@@ -17,7 +18,7 @@ export declare class LoginController extends BaseController {
|
|
|
17
18
|
protected SessionProvider: SessionProvider;
|
|
18
19
|
protected TwoFactorAuthEnabled: boolean;
|
|
19
20
|
protected TwoFactorAuthForceUser: boolean;
|
|
20
|
-
protected
|
|
21
|
+
protected SessionCookies: SessionCookieFactory;
|
|
21
22
|
protected AC: AccessControl;
|
|
22
23
|
/**
|
|
23
24
|
* Login
|
|
@@ -36,6 +37,10 @@ export declare class LoginController extends BaseController {
|
|
|
36
37
|
* If an impersonation is active, the session is NOT destroyed — instead the
|
|
37
38
|
* impersonation is ended and the original user resumes their session.
|
|
38
39
|
* Requires the user to be logged in (session exists), but full authorization (2FA) is not required.
|
|
40
|
+
*
|
|
41
|
+
* POST, not GET: under `SameSite=Lax` a cookie rides a top-level cross-site
|
|
42
|
+
* GET, so a third-party page could log any visitor out simply by linking to
|
|
43
|
+
* this route.
|
|
39
44
|
* @security cookieAuth
|
|
40
45
|
* @response 401 No active session
|
|
41
46
|
*/
|
|
@@ -43,14 +48,16 @@ export declare class LoginController extends BaseController {
|
|
|
43
48
|
/**
|
|
44
49
|
* Get current user
|
|
45
50
|
* Returns the user object associated with the current session along with the
|
|
46
|
-
* currently active role
|
|
51
|
+
* currently active role and whether the session has completed 2FA (when
|
|
52
|
+
* required). Roles the user may switch to are listed in Role.
|
|
47
53
|
* Requires the user to be logged in (session exists), but full authorization (2FA) is not required.
|
|
48
54
|
* @security cookieAuth
|
|
49
55
|
* @returns {User} User data from the current session
|
|
50
56
|
* @response 401 No active session
|
|
51
57
|
*/
|
|
52
|
-
whoami(User: User, ActiveRole: string): Promise<Ok<{
|
|
58
|
+
whoami(User: User, ActiveRole: string, session: ISession): Promise<Ok<{
|
|
53
59
|
ActiveRole: string;
|
|
60
|
+
Authorized: {};
|
|
54
61
|
Email: string;
|
|
55
62
|
Password: string;
|
|
56
63
|
Id: number;
|
|
@@ -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,
|
|
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,EAAuB,MAAM,oBAAoB,CAAC;AACjK,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;IA8G1J;;;;;;;;;;;;OAYG;IAGU,MAAM,CAAc,IAAI,EAAE,MAAM,EAAqB,OAAO,EAAE,QAAQ,EAAkB,IAAI,EAAE,IAAI;IAgC/G;;;;;;;;;OASG;IAGU,MAAM,CAAiB,IAAI,EAAE,IAAI,EAAiB,UAAU,EAAE,MAAM,EAAqB,OAAO,EAAE,QAAQ;;;;;;;;;;;;;;;;;;;;;CAQxH"}
|
|
@@ -11,14 +11,17 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
11
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
12
|
};
|
|
13
13
|
import { UserLoginDto } from '../dto/userLogin-dto.js';
|
|
14
|
-
import { BaseController, BasePath, Post, Body, Ok, Get,
|
|
15
|
-
import { AuthProvider, SessionProvider, login, UserSession, AccessControl,
|
|
14
|
+
import { BaseController, BasePath, Post, Body, Ok, Get, Unauthorized, Policy } from '@spinajs/http';
|
|
15
|
+
import { AuthProvider, SessionProvider, login, UserSession, AccessControl, AthenticationErrorCodes, hashSessionId } from '@spinajs/rbac';
|
|
16
16
|
import { ErrorCode, InvalidArgument } from '@spinajs/exceptions';
|
|
17
17
|
import { Autoinject, DI } from '@spinajs/di';
|
|
18
18
|
import { AutoinjectService, Config, Configuration } from '@spinajs/configuration';
|
|
19
|
-
import { LoggedPolicy, User as UserRouteArg, Session as SessionRouteArg, FromSession, SkipModelPermission } from '@spinajs/rbac-http';
|
|
19
|
+
import { LoggedPolicy, User as UserRouteArg, Session as SessionRouteArg, SessionId, FromSession, SkipModelPermission } from '@spinajs/rbac-http';
|
|
20
20
|
import { User } from '@spinajs/rbac';
|
|
21
21
|
import { LogoutHandler } from '../logout.js';
|
|
22
|
+
import { SessionCookieFactory } from '../services/SessionCookies.js';
|
|
23
|
+
import { buildUserWithGrants } from '../services/grants.js';
|
|
24
|
+
import { TWO_FA_METATADATA_KEYS } from '../2fa/Default2FaToken.js';
|
|
22
25
|
/**
|
|
23
26
|
* Authentication endpoints.
|
|
24
27
|
* Handles user login, logout, and current-session inspection.
|
|
@@ -59,7 +62,8 @@ let LoginController = class LoginController extends BaseController {
|
|
|
59
62
|
// user is automatically authorized at login
|
|
60
63
|
session.Data.set('Logged', true);
|
|
61
64
|
session.UserId = user.Id;
|
|
62
|
-
|
|
65
|
+
const twoFaEnabledForUser = Boolean(user.Metadata[TWO_FA_METATADATA_KEYS.ENABLED]);
|
|
66
|
+
if (this.TwoFactorAuthForceUser && !twoFaEnabledForUser) {
|
|
63
67
|
this._log.trace('User logged in, 2fa init required', {
|
|
64
68
|
Uuid: user.Uuid
|
|
65
69
|
});
|
|
@@ -67,7 +71,7 @@ let LoginController = class LoginController extends BaseController {
|
|
|
67
71
|
session.Data.set('TwoFactorAuth', true);
|
|
68
72
|
result = { TwoFactorInitRequired: true };
|
|
69
73
|
}
|
|
70
|
-
else if (this.TwoFactorAuthEnabled &&
|
|
74
|
+
else if (this.TwoFactorAuthEnabled && twoFaEnabledForUser) {
|
|
71
75
|
this._log.trace('User logged in, 2fa required', {
|
|
72
76
|
Uuid: user.Uuid
|
|
73
77
|
});
|
|
@@ -77,40 +81,25 @@ let LoginController = class LoginController extends BaseController {
|
|
|
77
81
|
}
|
|
78
82
|
else {
|
|
79
83
|
session.Data.set('Authorized', true);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
result = {
|
|
85
|
-
...user.dehydrateWithRelations({ dateTimeFormat: "iso" }),
|
|
86
|
-
Role: user.Role, // temp fix for role grants, as dehydrateWithRelations returns string of roles, not array
|
|
87
|
-
ActiveRole: activeRole,
|
|
88
|
-
Grants: combinedGrants,
|
|
89
|
-
};
|
|
84
|
+
this._log.trace('User logged in, no 2fa required', {
|
|
85
|
+
Uuid: user.Uuid
|
|
86
|
+
});
|
|
87
|
+
result = buildUserWithGrants(user, activeRole, this.AC);
|
|
90
88
|
}
|
|
91
|
-
this._log.trace('User logged in, no 2fa required', {
|
|
92
|
-
Uuid: user.Uuid
|
|
93
|
-
});
|
|
94
89
|
// save() schedules the session's initial expiration via the configured
|
|
95
90
|
// strategy; the cookie maxAge is then derived from that real expiry (B1),
|
|
96
91
|
// no longer the bogus `expiration * 1000` (~2 min) value.
|
|
97
92
|
await this.SessionProvider.save(session);
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
signed: true,
|
|
104
|
-
httpOnly: true,
|
|
105
|
-
// cookie lifetime tracks the session's real expiration
|
|
106
|
-
maxAge: sessionCookieMaxAge(session),
|
|
107
|
-
// any optional cookie options / override default ones
|
|
108
|
-
...this.SessionCookieConfig
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
];
|
|
93
|
+
this._log.info(`Session created`, {
|
|
94
|
+
// never the raw id — a log file must not be a bag of live credentials
|
|
95
|
+
Session: hashSessionId(session.SessionId),
|
|
96
|
+
User: user.Uuid,
|
|
97
|
+
});
|
|
112
98
|
return new Ok(result, {
|
|
113
|
-
Coockies:
|
|
99
|
+
Coockies: [this.SessionCookies.issue(session)],
|
|
100
|
+
// The response carries the session id in a Set-Cookie and the user's
|
|
101
|
+
// own data in the body. Neither may be written to any cache.
|
|
102
|
+
Headers: [{ Name: 'Cache-Control', Value: 'no-store' }],
|
|
114
103
|
});
|
|
115
104
|
}
|
|
116
105
|
catch (err) {
|
|
@@ -142,6 +131,10 @@ let LoginController = class LoginController extends BaseController {
|
|
|
142
131
|
* If an impersonation is active, the session is NOT destroyed — instead the
|
|
143
132
|
* impersonation is ended and the original user resumes their session.
|
|
144
133
|
* Requires the user to be logged in (session exists), but full authorization (2FA) is not required.
|
|
134
|
+
*
|
|
135
|
+
* POST, not GET: under `SameSite=Lax` a cookie rides a top-level cross-site
|
|
136
|
+
* GET, so a third-party page could log any visitor out simply by linking to
|
|
137
|
+
* this route.
|
|
145
138
|
* @security cookieAuth
|
|
146
139
|
* @response 401 No active session
|
|
147
140
|
*/
|
|
@@ -163,7 +156,10 @@ let LoginController = class LoginController extends BaseController {
|
|
|
163
156
|
for (const handler of sorted) {
|
|
164
157
|
const result = await handler.handle(ctx);
|
|
165
158
|
if (result) {
|
|
166
|
-
return new Ok(result.Body ?? null, {
|
|
159
|
+
return new Ok(result.Body ?? null, {
|
|
160
|
+
Coockies: result.Cookies ?? [],
|
|
161
|
+
Headers: result.Headers ?? [],
|
|
162
|
+
});
|
|
167
163
|
}
|
|
168
164
|
}
|
|
169
165
|
// No handler claimed the request — should not happen as long as the
|
|
@@ -173,16 +169,18 @@ let LoginController = class LoginController extends BaseController {
|
|
|
173
169
|
/**
|
|
174
170
|
* Get current user
|
|
175
171
|
* Returns the user object associated with the current session along with the
|
|
176
|
-
* currently active role
|
|
172
|
+
* currently active role and whether the session has completed 2FA (when
|
|
173
|
+
* required). Roles the user may switch to are listed in Role.
|
|
177
174
|
* Requires the user to be logged in (session exists), but full authorization (2FA) is not required.
|
|
178
175
|
* @security cookieAuth
|
|
179
176
|
* @returns {User} User data from the current session
|
|
180
177
|
* @response 401 No active session
|
|
181
178
|
*/
|
|
182
|
-
async whoami(User, ActiveRole) {
|
|
179
|
+
async whoami(User, ActiveRole, session) {
|
|
183
180
|
return new Ok({
|
|
184
181
|
...User.dehydrateWithRelations({ dateTimeFormat: 'iso' }),
|
|
185
182
|
ActiveRole: ActiveRole ?? User.Role?.[0],
|
|
183
|
+
Authorized: session.Data.get('Authorized') ?? true,
|
|
186
184
|
});
|
|
187
185
|
}
|
|
188
186
|
};
|
|
@@ -211,9 +209,9 @@ __decorate([
|
|
|
211
209
|
__metadata("design:type", Boolean)
|
|
212
210
|
], LoginController.prototype, "TwoFactorAuthForceUser", void 0);
|
|
213
211
|
__decorate([
|
|
214
|
-
|
|
215
|
-
__metadata("design:type",
|
|
216
|
-
], LoginController.prototype, "
|
|
212
|
+
Autoinject(SessionCookieFactory),
|
|
213
|
+
__metadata("design:type", SessionCookieFactory)
|
|
214
|
+
], LoginController.prototype, "SessionCookies", void 0);
|
|
217
215
|
__decorate([
|
|
218
216
|
Autoinject(AccessControl),
|
|
219
217
|
__metadata("design:type", AccessControl)
|
|
@@ -222,16 +220,16 @@ __decorate([
|
|
|
222
220
|
Post(),
|
|
223
221
|
SkipModelPermission(),
|
|
224
222
|
__param(0, UserRouteArg()),
|
|
225
|
-
__param(1,
|
|
223
|
+
__param(1, SessionId()),
|
|
226
224
|
__param(2, Body()),
|
|
227
225
|
__metadata("design:type", Function),
|
|
228
226
|
__metadata("design:paramtypes", [User, String, UserLoginDto]),
|
|
229
227
|
__metadata("design:returntype", Promise)
|
|
230
228
|
], LoginController.prototype, "login", null);
|
|
231
229
|
__decorate([
|
|
232
|
-
|
|
230
|
+
Post(),
|
|
233
231
|
Policy(LoggedPolicy),
|
|
234
|
-
__param(0,
|
|
232
|
+
__param(0, SessionId()),
|
|
235
233
|
__param(1, SessionRouteArg()),
|
|
236
234
|
__param(2, UserRouteArg()),
|
|
237
235
|
__metadata("design:type", Function),
|
|
@@ -243,8 +241,9 @@ __decorate([
|
|
|
243
241
|
Policy(LoggedPolicy),
|
|
244
242
|
__param(0, UserRouteArg()),
|
|
245
243
|
__param(1, FromSession()),
|
|
244
|
+
__param(2, SessionRouteArg()),
|
|
246
245
|
__metadata("design:type", Function),
|
|
247
|
-
__metadata("design:paramtypes", [User, String]),
|
|
246
|
+
__metadata("design:paramtypes", [User, String, Object]),
|
|
248
247
|
__metadata("design:returntype", Promise)
|
|
249
248
|
], LoginController.prototype, "whoami", null);
|
|
250
249
|
LoginController = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoginController.js","sourceRoot":"","sources":["../../../src/controllers/LoginController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"LoginController.js","sourceRoot":"","sources":["../../../src/controllers/LoginController.ts"],"names":[],"mappings":"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"}
|