@spinajs/rbac-http-user 2.0.473 → 2.0.474
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/controllers/ActiveRoleController.d.ts +41 -0
- package/lib/cjs/controllers/ActiveRoleController.d.ts.map +1 -0
- package/lib/cjs/controllers/ActiveRoleController.js +135 -0
- package/lib/cjs/controllers/ActiveRoleController.js.map +1 -0
- package/lib/cjs/controllers/ImpersonationController.d.ts +72 -0
- package/lib/cjs/controllers/ImpersonationController.d.ts.map +1 -0
- package/lib/cjs/controllers/ImpersonationController.js +277 -0
- package/lib/cjs/controllers/ImpersonationController.js.map +1 -0
- package/lib/cjs/controllers/LoginController.d.ts +27 -4
- package/lib/cjs/controllers/LoginController.d.ts.map +1 -1
- package/lib/cjs/controllers/LoginController.js +46 -27
- package/lib/cjs/controllers/LoginController.js.map +1 -1
- package/lib/cjs/dto/impersonate-dto.d.ts +24 -0
- package/lib/cjs/dto/impersonate-dto.d.ts.map +1 -0
- package/lib/cjs/dto/impersonate-dto.js +34 -0
- package/lib/cjs/dto/impersonate-dto.js.map +1 -0
- package/lib/cjs/dto/switchRole-dto.d.ts +24 -0
- package/lib/cjs/dto/switchRole-dto.d.ts.map +1 -0
- package/lib/cjs/dto/switchRole-dto.js +34 -0
- package/lib/cjs/dto/switchRole-dto.js.map +1 -0
- package/lib/cjs/handlers/DefaultLogoutHandler.d.ts +14 -0
- package/lib/cjs/handlers/DefaultLogoutHandler.d.ts.map +1 -0
- package/lib/cjs/handlers/DefaultLogoutHandler.js +61 -0
- package/lib/cjs/handlers/DefaultLogoutHandler.js.map +1 -0
- package/lib/cjs/handlers/ImpersonationLogoutHandler.d.ts +18 -0
- package/lib/cjs/handlers/ImpersonationLogoutHandler.d.ts.map +1 -0
- package/lib/cjs/handlers/ImpersonationLogoutHandler.js +66 -0
- package/lib/cjs/handlers/ImpersonationLogoutHandler.js.map +1 -0
- package/lib/cjs/index.d.ts +5 -0
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +5 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/logout.d.ts +51 -0
- package/lib/cjs/logout.d.ts.map +1 -0
- package/lib/cjs/logout.js +29 -0
- package/lib/cjs/logout.js.map +1 -0
- package/lib/mjs/controllers/ActiveRoleController.d.ts +41 -0
- package/lib/mjs/controllers/ActiveRoleController.d.ts.map +1 -0
- package/lib/mjs/controllers/ActiveRoleController.js +132 -0
- package/lib/mjs/controllers/ActiveRoleController.js.map +1 -0
- package/lib/mjs/controllers/ImpersonationController.d.ts +72 -0
- package/lib/mjs/controllers/ImpersonationController.d.ts.map +1 -0
- package/lib/mjs/controllers/ImpersonationController.js +274 -0
- package/lib/mjs/controllers/ImpersonationController.js.map +1 -0
- package/lib/mjs/controllers/LoginController.d.ts +27 -4
- package/lib/mjs/controllers/LoginController.d.ts.map +1 -1
- package/lib/mjs/controllers/LoginController.js +48 -29
- package/lib/mjs/controllers/LoginController.js.map +1 -1
- package/lib/mjs/dto/impersonate-dto.d.ts +24 -0
- package/lib/mjs/dto/impersonate-dto.d.ts.map +1 -0
- package/lib/mjs/dto/impersonate-dto.js +31 -0
- package/lib/mjs/dto/impersonate-dto.js.map +1 -0
- package/lib/mjs/dto/switchRole-dto.d.ts +24 -0
- package/lib/mjs/dto/switchRole-dto.d.ts.map +1 -0
- package/lib/mjs/dto/switchRole-dto.js +31 -0
- package/lib/mjs/dto/switchRole-dto.js.map +1 -0
- package/lib/mjs/handlers/DefaultLogoutHandler.d.ts +14 -0
- package/lib/mjs/handlers/DefaultLogoutHandler.d.ts.map +1 -0
- package/lib/mjs/handlers/DefaultLogoutHandler.js +58 -0
- package/lib/mjs/handlers/DefaultLogoutHandler.js.map +1 -0
- package/lib/mjs/handlers/ImpersonationLogoutHandler.d.ts +18 -0
- package/lib/mjs/handlers/ImpersonationLogoutHandler.d.ts.map +1 -0
- package/lib/mjs/handlers/ImpersonationLogoutHandler.js +63 -0
- package/lib/mjs/handlers/ImpersonationLogoutHandler.js.map +1 -0
- package/lib/mjs/index.d.ts +5 -0
- package/lib/mjs/index.d.ts.map +1 -1
- package/lib/mjs/index.js +5 -0
- package/lib/mjs/index.js.map +1 -1
- package/lib/mjs/logout.d.ts +51 -0
- package/lib/mjs/logout.d.ts.map +1 -0
- package/lib/mjs/logout.js +25 -0
- package/lib/mjs/logout.js.map +1 -0
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +11 -11
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { SwitchRoleDto } from '../dto/switchRole-dto.js';
|
|
2
|
+
import { BaseController, Ok, BadRequestResponse, Unauthorized } from '@spinajs/http';
|
|
3
|
+
import { AccessControl, AuthProvider, PasswordProvider, SessionProvider } from '@spinajs/rbac';
|
|
4
|
+
import type { ISession, User } from '@spinajs/rbac';
|
|
5
|
+
import { IActiveRoleResponse } from '@spinajs/rbac-http';
|
|
6
|
+
/**
|
|
7
|
+
* Active role endpoints.
|
|
8
|
+
* Let users with multiple roles inspect and switch the currently active role.
|
|
9
|
+
* The active role drives all request-bound permission checks; the user's full
|
|
10
|
+
* role list remains available so they can switch back at any time.
|
|
11
|
+
* @tags Authentication
|
|
12
|
+
*/
|
|
13
|
+
export declare class ActiveRoleController extends BaseController {
|
|
14
|
+
protected AC: AccessControl;
|
|
15
|
+
protected AuthProvider: AuthProvider;
|
|
16
|
+
protected PasswordProvider: PasswordProvider;
|
|
17
|
+
protected SessionProvider: SessionProvider;
|
|
18
|
+
protected RolesRequiringPassword: string[];
|
|
19
|
+
/**
|
|
20
|
+
* Get active role
|
|
21
|
+
* Returns the currently active role for the session, all roles the user may switch to,
|
|
22
|
+
* and the RBAC grants resolved for the active role.
|
|
23
|
+
* @security cookieAuth
|
|
24
|
+
* @returns {IActiveRoleResponse}
|
|
25
|
+
* @response 401 No active session
|
|
26
|
+
*/
|
|
27
|
+
getActiveRole(user: User, ActiveRole: string): Promise<Ok<IActiveRoleResponse>>;
|
|
28
|
+
/**
|
|
29
|
+
* Switch active role
|
|
30
|
+
* Switches the active role for the current session. The requested role must be one of
|
|
31
|
+
* the user's assigned roles. If the role is listed in `rbac.roleSwitch.requirePassword`,
|
|
32
|
+
* the user's password must also be provided and is re-verified.
|
|
33
|
+
* @security cookieAuth
|
|
34
|
+
* @returns {IActiveRoleResponse}
|
|
35
|
+
* @response 400 Requested role is not assigned to the user
|
|
36
|
+
* @response 401 Password verification required or failed
|
|
37
|
+
*/
|
|
38
|
+
switchActiveRole(user: User, session: ISession, payload: SwitchRoleDto): Promise<Ok<IActiveRoleResponse> | BadRequestResponse | Unauthorized>;
|
|
39
|
+
protected buildResponse(user: User, activeRole: string): IActiveRoleResponse;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=ActiveRoleController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActiveRoleController.d.ts","sourceRoot":"","sources":["../../../src/controllers/ActiveRoleController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAwB,EAAE,EAAO,kBAAkB,EAAE,YAAY,EAAU,MAAM,eAAe,CAAC;AACxH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAiB,MAAM,eAAe,CAAC;AAC9G,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGpD,OAAO,EAA+E,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEtI;;;;;;GAMG;AACH,qBACa,oBAAqB,SAAQ,cAAc;IAEtD,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAG5B,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC;IAGrC,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAG7C,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAG3C,SAAS,CAAC,sBAAsB,EAAE,MAAM,EAAE,CAAC;IAE3C;;;;;;;OAOG;IAGU,aAAa,CAAiB,IAAI,EAAE,IAAI,EAAiB,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC;IAI3H;;;;;;;;;OASG;IAGU,gBAAgB,CACX,IAAI,EAAE,IAAI,EACP,OAAO,EAAE,QAAQ,EAC5B,OAAO,EAAE,aAAa,GAC7B,OAAO,CAAC,EAAE,CAAC,mBAAmB,CAAC,GAAG,kBAAkB,GAAG,YAAY,CAAC;IAqCvE,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,mBAAmB;CAQ7E"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ActiveRoleController = void 0;
|
|
16
|
+
const switchRole_dto_js_1 = require("../dto/switchRole-dto.js");
|
|
17
|
+
const http_1 = require("@spinajs/http");
|
|
18
|
+
const rbac_1 = require("@spinajs/rbac");
|
|
19
|
+
const di_1 = require("@spinajs/di");
|
|
20
|
+
const configuration_1 = require("@spinajs/configuration");
|
|
21
|
+
const rbac_http_1 = require("@spinajs/rbac-http");
|
|
22
|
+
/**
|
|
23
|
+
* Active role endpoints.
|
|
24
|
+
* Let users with multiple roles inspect and switch the currently active role.
|
|
25
|
+
* The active role drives all request-bound permission checks; the user's full
|
|
26
|
+
* role list remains available so they can switch back at any time.
|
|
27
|
+
* @tags Authentication
|
|
28
|
+
*/
|
|
29
|
+
let ActiveRoleController = class ActiveRoleController extends http_1.BaseController {
|
|
30
|
+
/**
|
|
31
|
+
* Get active role
|
|
32
|
+
* Returns the currently active role for the session, all roles the user may switch to,
|
|
33
|
+
* and the RBAC grants resolved for the active role.
|
|
34
|
+
* @security cookieAuth
|
|
35
|
+
* @returns {IActiveRoleResponse}
|
|
36
|
+
* @response 401 No active session
|
|
37
|
+
*/
|
|
38
|
+
async getActiveRole(user, ActiveRole) {
|
|
39
|
+
return new http_1.Ok(this.buildResponse(user, ActiveRole ?? user.Role?.[0]));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Switch active role
|
|
43
|
+
* Switches the active role for the current session. The requested role must be one of
|
|
44
|
+
* the user's assigned roles. If the role is listed in `rbac.roleSwitch.requirePassword`,
|
|
45
|
+
* the user's password must also be provided and is re-verified.
|
|
46
|
+
* @security cookieAuth
|
|
47
|
+
* @returns {IActiveRoleResponse}
|
|
48
|
+
* @response 400 Requested role is not assigned to the user
|
|
49
|
+
* @response 401 Password verification required or failed
|
|
50
|
+
*/
|
|
51
|
+
async switchActiveRole(user, session, payload) {
|
|
52
|
+
if (!user.Role?.includes(payload.Role)) {
|
|
53
|
+
return new http_1.BadRequestResponse({
|
|
54
|
+
error: {
|
|
55
|
+
code: 'E_ROLE_NOT_ASSIGNED',
|
|
56
|
+
message: `Role '${payload.Role}' is not assigned to user`,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (this.RolesRequiringPassword?.includes(payload.Role)) {
|
|
61
|
+
if (!payload.Password) {
|
|
62
|
+
return new http_1.Unauthorized({
|
|
63
|
+
error: {
|
|
64
|
+
code: 'E_PASSWORD_REQUIRED',
|
|
65
|
+
message: `Password is required to activate role '${payload.Role}'`,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const valid = await this.PasswordProvider.verify(user.Password, payload.Password);
|
|
70
|
+
if (!valid) {
|
|
71
|
+
return new http_1.Unauthorized({
|
|
72
|
+
error: {
|
|
73
|
+
code: 'E_PASSWORD_INVALID',
|
|
74
|
+
message: 'Invalid password',
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
session.Data.set('ActiveRole', payload.Role);
|
|
80
|
+
await this.SessionProvider.save(session);
|
|
81
|
+
return new http_1.Ok(this.buildResponse(user, payload.Role));
|
|
82
|
+
}
|
|
83
|
+
buildResponse(user, activeRole) {
|
|
84
|
+
const grants = activeRole ? (0, rbac_1._unwindGrants)(activeRole, this.AC.getGrants()) : {};
|
|
85
|
+
return {
|
|
86
|
+
ActiveRole: activeRole,
|
|
87
|
+
AvailableRoles: user.Role ?? [],
|
|
88
|
+
Grants: grants,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
exports.ActiveRoleController = ActiveRoleController;
|
|
93
|
+
__decorate([
|
|
94
|
+
(0, di_1.Autoinject)(rbac_1.AccessControl),
|
|
95
|
+
__metadata("design:type", rbac_1.AccessControl)
|
|
96
|
+
], ActiveRoleController.prototype, "AC", void 0);
|
|
97
|
+
__decorate([
|
|
98
|
+
(0, configuration_1.AutoinjectService)('rbac.auth'),
|
|
99
|
+
__metadata("design:type", rbac_1.AuthProvider)
|
|
100
|
+
], ActiveRoleController.prototype, "AuthProvider", void 0);
|
|
101
|
+
__decorate([
|
|
102
|
+
(0, configuration_1.AutoinjectService)('rbac.password'),
|
|
103
|
+
__metadata("design:type", rbac_1.PasswordProvider)
|
|
104
|
+
], ActiveRoleController.prototype, "PasswordProvider", void 0);
|
|
105
|
+
__decorate([
|
|
106
|
+
(0, configuration_1.AutoinjectService)('rbac.session'),
|
|
107
|
+
__metadata("design:type", rbac_1.SessionProvider)
|
|
108
|
+
], ActiveRoleController.prototype, "SessionProvider", void 0);
|
|
109
|
+
__decorate([
|
|
110
|
+
(0, configuration_1.Config)('rbac.roleSwitch.requirePassword', { defaultValue: [] }),
|
|
111
|
+
__metadata("design:type", Array)
|
|
112
|
+
], ActiveRoleController.prototype, "RolesRequiringPassword", void 0);
|
|
113
|
+
__decorate([
|
|
114
|
+
(0, http_1.Get)('active-role'),
|
|
115
|
+
(0, http_1.Policy)(rbac_http_1.LoggedPolicy),
|
|
116
|
+
__param(0, (0, rbac_http_1.User)()),
|
|
117
|
+
__param(1, (0, rbac_http_1.FromSession)()),
|
|
118
|
+
__metadata("design:type", Function),
|
|
119
|
+
__metadata("design:paramtypes", [Function, String]),
|
|
120
|
+
__metadata("design:returntype", Promise)
|
|
121
|
+
], ActiveRoleController.prototype, "getActiveRole", null);
|
|
122
|
+
__decorate([
|
|
123
|
+
(0, http_1.Post)('active-role'),
|
|
124
|
+
(0, http_1.Policy)(rbac_http_1.LoggedPolicy),
|
|
125
|
+
__param(0, (0, rbac_http_1.User)()),
|
|
126
|
+
__param(1, (0, rbac_http_1.Session)()),
|
|
127
|
+
__param(2, (0, http_1.Body)()),
|
|
128
|
+
__metadata("design:type", Function),
|
|
129
|
+
__metadata("design:paramtypes", [Function, Object, switchRole_dto_js_1.SwitchRoleDto]),
|
|
130
|
+
__metadata("design:returntype", Promise)
|
|
131
|
+
], ActiveRoleController.prototype, "switchActiveRole", null);
|
|
132
|
+
exports.ActiveRoleController = ActiveRoleController = __decorate([
|
|
133
|
+
(0, http_1.BasePath)('auth')
|
|
134
|
+
], ActiveRoleController);
|
|
135
|
+
//# sourceMappingURL=ActiveRoleController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActiveRoleController.js","sourceRoot":"","sources":["../../../src/controllers/ActiveRoleController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ImpersonateDto } from '../dto/impersonate-dto.js';
|
|
2
|
+
import { BaseController, Ok, BadRequestResponse, Unauthorized, ForbiddenResponse, Conflict, NotFound } from '@spinajs/http';
|
|
3
|
+
import { AccessControl, PasswordProvider, SessionProvider, User, UserImpersonationStarted, UserImpersonationEnded } from '@spinajs/rbac';
|
|
4
|
+
import type { ISession } from '@spinajs/rbac';
|
|
5
|
+
import { IImpersonationResponse, IImpersonationState, IUserWithGrants } from '@spinajs/rbac-http';
|
|
6
|
+
/**
|
|
7
|
+
* Impersonation endpoints.
|
|
8
|
+
*
|
|
9
|
+
* A user holding `createAny` on the virtual resource `user:impersonate` can
|
|
10
|
+
* temporarily act as another user. While impersonation is active, the session
|
|
11
|
+
* carries both identities — `User` is the target, `Impersonator` is the
|
|
12
|
+
* original. Permission checks therefore "see" the target by default; the
|
|
13
|
+
* original is preserved only for audit and for ending the impersonation.
|
|
14
|
+
*
|
|
15
|
+
* @tags Authentication
|
|
16
|
+
*/
|
|
17
|
+
export declare class ImpersonationController extends BaseController {
|
|
18
|
+
protected AC: AccessControl;
|
|
19
|
+
protected PasswordProvider: PasswordProvider;
|
|
20
|
+
protected SessionProvider: SessionProvider;
|
|
21
|
+
protected RequirePassword: boolean;
|
|
22
|
+
protected ProtectedRoles: string[];
|
|
23
|
+
/**
|
|
24
|
+
* Get impersonation state
|
|
25
|
+
* Returns whether an impersonation is currently active for this session.
|
|
26
|
+
* @security cookieAuth
|
|
27
|
+
* @returns {IImpersonationState}
|
|
28
|
+
* @response 401 No active session
|
|
29
|
+
*/
|
|
30
|
+
getState(Impersonator: string, User: string, ImpersonationStartedAt: string): Promise<Ok<IImpersonationState>>;
|
|
31
|
+
/**
|
|
32
|
+
* Start impersonation
|
|
33
|
+
* Begins impersonating the target user. The caller must have `createAny` on
|
|
34
|
+
* virtual resource `user:impersonate`. The target must not hold any role in
|
|
35
|
+
* `rbac.impersonation.protectedRoles` and must not have effective grants
|
|
36
|
+
* exceeding the caller's. If `rbac.impersonation.requirePassword` is true,
|
|
37
|
+
* the caller's password must be supplied and is verified.
|
|
38
|
+
* @security cookieAuth
|
|
39
|
+
* @returns {IImpersonationResponse}
|
|
40
|
+
* @response 400 Target equals caller or invalid payload
|
|
41
|
+
* @response 401 Password required or invalid
|
|
42
|
+
* @response 403 Caller lacks permission, target is protected, or escalation detected
|
|
43
|
+
* @response 404 Target user not found / inactive / banned / deleted
|
|
44
|
+
* @response 409 An impersonation is already in progress for this session
|
|
45
|
+
*/
|
|
46
|
+
start(caller: User, session: ISession, payload: ImpersonateDto): Promise<Ok<IImpersonationResponse> | BadRequestResponse | Unauthorized | ForbiddenResponse | NotFound | Conflict>;
|
|
47
|
+
/**
|
|
48
|
+
* Stop impersonation
|
|
49
|
+
* Restores the original user's session and returns their login-style payload.
|
|
50
|
+
* @security cookieAuth
|
|
51
|
+
* @returns {IUserWithGrants}
|
|
52
|
+
* @response 400 No impersonation is currently active
|
|
53
|
+
*/
|
|
54
|
+
stop(target: User, session: ISession): Promise<Ok<IUserWithGrants> | BadRequestResponse>;
|
|
55
|
+
/**
|
|
56
|
+
* Emit an impersonation lifecycle event. Wrapped in a protected method so
|
|
57
|
+
* tests can intercept without stubbing module-level ESM bindings.
|
|
58
|
+
*/
|
|
59
|
+
protected emitEvent(event: UserImpersonationStarted | UserImpersonationEnded): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Load the impersonation target (with Metadata so IsBanned works). Extracted
|
|
62
|
+
* as a protected method so tests can stub it without setting up a database.
|
|
63
|
+
*/
|
|
64
|
+
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;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=ImpersonationController.d.ts.map
|
|
@@ -0,0 +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,eAAe,EACf,IAAI,EACJ,wBAAwB,EACxB,sBAAsB,EAGvB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAK9C,OAAO,EAKL,sBAAsB,EACtB,mBAAmB,EACnB,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAI5B;;;;;;;;;;GAUG;AACH,qBACa,uBAAwB,SAAQ,cAAc;IAEzD,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAG5B,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAG7C,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAG3C,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;IAsFD;;;;;;OAMG;IAGU,IAAI,CACC,MAAM,EAAE,IAAI,EACT,OAAO,EAAE,QAAQ,GACnC,OAAO,CAAC,EAAE,CAAC,eAAe,CAAC,GAAG,kBAAkB,CAAC;IA4CpD;;;OAGG;IACH,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,wBAAwB,GAAG,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5F;;;OAGG;IACH,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAI7D;;;OAGG;IACH,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAI/D,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,sBAAsB;CAWzH"}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ImpersonationController = void 0;
|
|
16
|
+
const impersonate_dto_js_1 = require("../dto/impersonate-dto.js");
|
|
17
|
+
const http_1 = require("@spinajs/http");
|
|
18
|
+
const rbac_1 = require("@spinajs/rbac");
|
|
19
|
+
const di_1 = require("@spinajs/di");
|
|
20
|
+
const configuration_1 = require("@spinajs/configuration");
|
|
21
|
+
const queue_1 = require("@spinajs/queue");
|
|
22
|
+
const luxon_1 = require("luxon");
|
|
23
|
+
const rbac_http_1 = require("@spinajs/rbac-http");
|
|
24
|
+
const IMPERSONATE_RESOURCE = 'user:impersonate';
|
|
25
|
+
/**
|
|
26
|
+
* Impersonation endpoints.
|
|
27
|
+
*
|
|
28
|
+
* A user holding `createAny` on the virtual resource `user:impersonate` can
|
|
29
|
+
* temporarily act as another user. While impersonation is active, the session
|
|
30
|
+
* carries both identities — `User` is the target, `Impersonator` is the
|
|
31
|
+
* original. Permission checks therefore "see" the target by default; the
|
|
32
|
+
* original is preserved only for audit and for ending the impersonation.
|
|
33
|
+
*
|
|
34
|
+
* @tags Authentication
|
|
35
|
+
*/
|
|
36
|
+
let ImpersonationController = class ImpersonationController extends http_1.BaseController {
|
|
37
|
+
/**
|
|
38
|
+
* Get impersonation state
|
|
39
|
+
* Returns whether an impersonation is currently active for this session.
|
|
40
|
+
* @security cookieAuth
|
|
41
|
+
* @returns {IImpersonationState}
|
|
42
|
+
* @response 401 No active session
|
|
43
|
+
*/
|
|
44
|
+
async getState(Impersonator, User, ImpersonationStartedAt) {
|
|
45
|
+
if (!Impersonator) {
|
|
46
|
+
return new http_1.Ok({ Active: false });
|
|
47
|
+
}
|
|
48
|
+
return new http_1.Ok({
|
|
49
|
+
Active: true,
|
|
50
|
+
ImpersonatorUuid: Impersonator,
|
|
51
|
+
TargetUuid: User,
|
|
52
|
+
StartedAt: ImpersonationStartedAt,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Start impersonation
|
|
57
|
+
* Begins impersonating the target user. The caller must have `createAny` on
|
|
58
|
+
* virtual resource `user:impersonate`. The target must not hold any role in
|
|
59
|
+
* `rbac.impersonation.protectedRoles` and must not have effective grants
|
|
60
|
+
* exceeding the caller's. If `rbac.impersonation.requirePassword` is true,
|
|
61
|
+
* the caller's password must be supplied and is verified.
|
|
62
|
+
* @security cookieAuth
|
|
63
|
+
* @returns {IImpersonationResponse}
|
|
64
|
+
* @response 400 Target equals caller or invalid payload
|
|
65
|
+
* @response 401 Password required or invalid
|
|
66
|
+
* @response 403 Caller lacks permission, target is protected, or escalation detected
|
|
67
|
+
* @response 404 Target user not found / inactive / banned / deleted
|
|
68
|
+
* @response 409 An impersonation is already in progress for this session
|
|
69
|
+
*/
|
|
70
|
+
async start(caller, session, payload) {
|
|
71
|
+
if (session?.Data.get('Impersonator')) {
|
|
72
|
+
return new http_1.Conflict({
|
|
73
|
+
error: {
|
|
74
|
+
code: 'E_IMPERSONATION_ACTIVE',
|
|
75
|
+
message: 'An impersonation is already in progress. Stop the current one before starting another.',
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (caller.Uuid === payload.TargetUuid) {
|
|
80
|
+
return new http_1.BadRequestResponse({
|
|
81
|
+
error: { code: 'E_SELF_IMPERSONATION', message: 'Cannot impersonate yourself' },
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// Permission to impersonate is itself an RBAC permission honoring ActiveRole.
|
|
85
|
+
const activeRole = session?.Data.get('ActiveRole') ?? caller.Role?.[0];
|
|
86
|
+
const roles = activeRole ? [activeRole] : caller.Role;
|
|
87
|
+
const allowed = this.AC.can(roles).createAny(IMPERSONATE_RESOURCE).granted;
|
|
88
|
+
if (!allowed) {
|
|
89
|
+
return new http_1.ForbiddenResponse({
|
|
90
|
+
error: { code: 'E_IMPERSONATE_FORBIDDEN', message: `Role(s) ${roles} cannot impersonate other users` },
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
const target = await this.loadTarget(payload.TargetUuid);
|
|
94
|
+
if (!target) {
|
|
95
|
+
return new http_1.NotFound({ error: { code: 'E_TARGET_NOT_FOUND', message: 'Target user not found' } });
|
|
96
|
+
}
|
|
97
|
+
if (!target.IsActive || target.IsBanned) {
|
|
98
|
+
return new http_1.NotFound({ error: { code: 'E_TARGET_UNAVAILABLE', message: 'Target user is not available' } });
|
|
99
|
+
}
|
|
100
|
+
const check = (0, rbac_1.canImpersonate)({
|
|
101
|
+
originalRoles: caller.Role,
|
|
102
|
+
targetRoles: target.Role,
|
|
103
|
+
protectedRoles: this.ProtectedRoles ?? [],
|
|
104
|
+
ac: this.AC,
|
|
105
|
+
});
|
|
106
|
+
if (!check.allowed) {
|
|
107
|
+
return new http_1.ForbiddenResponse({
|
|
108
|
+
error: {
|
|
109
|
+
code: check.reason === 'PROTECTED_ROLE' ? 'E_TARGET_PROTECTED' : 'E_PRIVILEGE_ESCALATION',
|
|
110
|
+
message: check.reason === 'PROTECTED_ROLE'
|
|
111
|
+
? `Target has a protected role (${check.detail}) and cannot be impersonated`
|
|
112
|
+
: `Target has a privilege the impersonator lacks (${check.detail})`,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (this.RequirePassword) {
|
|
117
|
+
if (!payload.Password) {
|
|
118
|
+
return new http_1.Unauthorized({
|
|
119
|
+
error: { code: 'E_PASSWORD_REQUIRED', message: 'Password confirmation is required to start impersonation' },
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
const valid = await this.PasswordProvider.verify(caller.Password, payload.Password);
|
|
123
|
+
if (!valid) {
|
|
124
|
+
return new http_1.Unauthorized({ error: { code: 'E_PASSWORD_INVALID', message: 'Invalid password' } });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Persist impersonation state. We keep the impersonator's previous
|
|
128
|
+
// ActiveRole so it can be restored on stop; effective ActiveRole becomes
|
|
129
|
+
// the target's first role.
|
|
130
|
+
const startedAt = luxon_1.DateTime.now().toISO();
|
|
131
|
+
const previousActiveRole = session.Data.get('ActiveRole');
|
|
132
|
+
session.Data.set('Impersonator', caller.Uuid);
|
|
133
|
+
session.Data.set('User', target.Uuid);
|
|
134
|
+
session.Data.set('ImpersonationStartedAt', startedAt);
|
|
135
|
+
if (previousActiveRole !== undefined) {
|
|
136
|
+
session.Data.set('OriginalActiveRole', previousActiveRole);
|
|
137
|
+
}
|
|
138
|
+
const targetActiveRole = target.Role?.[0];
|
|
139
|
+
if (targetActiveRole) {
|
|
140
|
+
session.Data.set('ActiveRole', targetActiveRole);
|
|
141
|
+
}
|
|
142
|
+
await this.SessionProvider.save(session);
|
|
143
|
+
await this.emitEvent(new rbac_1.UserImpersonationStarted(caller, target));
|
|
144
|
+
return new http_1.Ok(this.buildResponse(target, caller, targetActiveRole, startedAt));
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Stop impersonation
|
|
148
|
+
* Restores the original user's session and returns their login-style payload.
|
|
149
|
+
* @security cookieAuth
|
|
150
|
+
* @returns {IUserWithGrants}
|
|
151
|
+
* @response 400 No impersonation is currently active
|
|
152
|
+
*/
|
|
153
|
+
async stop(target, session) {
|
|
154
|
+
const impersonatorUuid = session?.Data.get('Impersonator');
|
|
155
|
+
if (!impersonatorUuid) {
|
|
156
|
+
return new http_1.BadRequestResponse({
|
|
157
|
+
error: { code: 'E_NO_IMPERSONATION', message: 'No impersonation is currently in progress' },
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
const original = await this.loadOriginal(impersonatorUuid);
|
|
161
|
+
if (!original) {
|
|
162
|
+
// Stale session referencing a deleted impersonator — destroy the
|
|
163
|
+
// impersonation block to recover but report an error so the caller
|
|
164
|
+
// can re-authenticate.
|
|
165
|
+
session.Data.delete('Impersonator');
|
|
166
|
+
session.Data.delete('ImpersonationStartedAt');
|
|
167
|
+
session.Data.delete('OriginalActiveRole');
|
|
168
|
+
await this.SessionProvider.save(session);
|
|
169
|
+
return new http_1.BadRequestResponse({
|
|
170
|
+
error: { code: 'E_IMPERSONATOR_GONE', message: 'Original user no longer exists' },
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
// Restore the original session state.
|
|
174
|
+
session.Data.set('User', original.Uuid);
|
|
175
|
+
session.Data.delete('Impersonator');
|
|
176
|
+
session.Data.delete('ImpersonationStartedAt');
|
|
177
|
+
const restoredActiveRole = session.Data.get('OriginalActiveRole') ?? original.Role?.[0];
|
|
178
|
+
if (restoredActiveRole) {
|
|
179
|
+
session.Data.set('ActiveRole', restoredActiveRole);
|
|
180
|
+
}
|
|
181
|
+
session.Data.delete('OriginalActiveRole');
|
|
182
|
+
await this.SessionProvider.save(session);
|
|
183
|
+
await this.emitEvent(new rbac_1.UserImpersonationEnded(original, target));
|
|
184
|
+
const grants = restoredActiveRole ? (0, rbac_1._unwindGrants)(restoredActiveRole, this.AC.getGrants()) : {};
|
|
185
|
+
return new http_1.Ok({
|
|
186
|
+
...original.dehydrateWithRelations({ dateTimeFormat: 'iso' }),
|
|
187
|
+
ActiveRole: restoredActiveRole,
|
|
188
|
+
Grants: grants,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Emit an impersonation lifecycle event. Wrapped in a protected method so
|
|
193
|
+
* tests can intercept without stubbing module-level ESM bindings.
|
|
194
|
+
*/
|
|
195
|
+
emitEvent(event) {
|
|
196
|
+
return (0, queue_1._ev)(event)();
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Load the impersonation target (with Metadata so IsBanned works). Extracted
|
|
200
|
+
* as a protected method so tests can stub it without setting up a database.
|
|
201
|
+
*/
|
|
202
|
+
loadTarget(uuid) {
|
|
203
|
+
return rbac_1.User.query().whereUuid(uuid).populate('Metadata').notDeleted().first();
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Load the original (impersonator) user. Extracted for the same reason as
|
|
207
|
+
* loadTarget — keeps the controller easy to test in isolation.
|
|
208
|
+
*/
|
|
209
|
+
loadOriginal(uuid) {
|
|
210
|
+
return rbac_1.User.getByUuid(uuid);
|
|
211
|
+
}
|
|
212
|
+
buildResponse(target, impersonator, activeRole, startedAt) {
|
|
213
|
+
const grants = activeRole ? (0, rbac_1._unwindGrants)(activeRole, this.AC.getGrants()) : {};
|
|
214
|
+
return {
|
|
215
|
+
User: target.dehydrateWithRelations({ dateTimeFormat: 'iso' }),
|
|
216
|
+
Impersonator: impersonator.dehydrateWithRelations({ dateTimeFormat: 'iso' }),
|
|
217
|
+
ActiveRole: activeRole,
|
|
218
|
+
AvailableRoles: target.Role ?? [],
|
|
219
|
+
Grants: grants,
|
|
220
|
+
StartedAt: startedAt,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
exports.ImpersonationController = ImpersonationController;
|
|
225
|
+
__decorate([
|
|
226
|
+
(0, di_1.Autoinject)(rbac_1.AccessControl),
|
|
227
|
+
__metadata("design:type", rbac_1.AccessControl)
|
|
228
|
+
], ImpersonationController.prototype, "AC", void 0);
|
|
229
|
+
__decorate([
|
|
230
|
+
(0, configuration_1.AutoinjectService)('rbac.password'),
|
|
231
|
+
__metadata("design:type", rbac_1.PasswordProvider)
|
|
232
|
+
], ImpersonationController.prototype, "PasswordProvider", void 0);
|
|
233
|
+
__decorate([
|
|
234
|
+
(0, configuration_1.AutoinjectService)('rbac.session'),
|
|
235
|
+
__metadata("design:type", rbac_1.SessionProvider)
|
|
236
|
+
], ImpersonationController.prototype, "SessionProvider", void 0);
|
|
237
|
+
__decorate([
|
|
238
|
+
(0, configuration_1.Config)('rbac.impersonation.requirePassword', { defaultValue: true }),
|
|
239
|
+
__metadata("design:type", Boolean)
|
|
240
|
+
], ImpersonationController.prototype, "RequirePassword", void 0);
|
|
241
|
+
__decorate([
|
|
242
|
+
(0, configuration_1.Config)('rbac.impersonation.protectedRoles', { defaultValue: ['system'] }),
|
|
243
|
+
__metadata("design:type", Array)
|
|
244
|
+
], ImpersonationController.prototype, "ProtectedRoles", void 0);
|
|
245
|
+
__decorate([
|
|
246
|
+
(0, http_1.Get)('impersonate'),
|
|
247
|
+
(0, http_1.Policy)(rbac_http_1.LoggedPolicy),
|
|
248
|
+
__param(0, (0, rbac_http_1.FromSession)()),
|
|
249
|
+
__param(1, (0, rbac_http_1.FromSession)()),
|
|
250
|
+
__param(2, (0, rbac_http_1.FromSession)()),
|
|
251
|
+
__metadata("design:type", Function),
|
|
252
|
+
__metadata("design:paramtypes", [String, String, String]),
|
|
253
|
+
__metadata("design:returntype", Promise)
|
|
254
|
+
], ImpersonationController.prototype, "getState", null);
|
|
255
|
+
__decorate([
|
|
256
|
+
(0, http_1.Post)('impersonate'),
|
|
257
|
+
(0, http_1.Policy)(rbac_http_1.LoggedPolicy),
|
|
258
|
+
__param(0, (0, rbac_http_1.User)()),
|
|
259
|
+
__param(1, (0, rbac_http_1.Session)()),
|
|
260
|
+
__param(2, (0, http_1.Body)()),
|
|
261
|
+
__metadata("design:type", Function),
|
|
262
|
+
__metadata("design:paramtypes", [rbac_1.User, Object, impersonate_dto_js_1.ImpersonateDto]),
|
|
263
|
+
__metadata("design:returntype", Promise)
|
|
264
|
+
], ImpersonationController.prototype, "start", null);
|
|
265
|
+
__decorate([
|
|
266
|
+
(0, http_1.Del)('impersonate'),
|
|
267
|
+
(0, http_1.Policy)(rbac_http_1.LoggedPolicy),
|
|
268
|
+
__param(0, (0, rbac_http_1.User)()),
|
|
269
|
+
__param(1, (0, rbac_http_1.Session)()),
|
|
270
|
+
__metadata("design:type", Function),
|
|
271
|
+
__metadata("design:paramtypes", [rbac_1.User, Object]),
|
|
272
|
+
__metadata("design:returntype", Promise)
|
|
273
|
+
], ImpersonationController.prototype, "stop", null);
|
|
274
|
+
exports.ImpersonationController = ImpersonationController = __decorate([
|
|
275
|
+
(0, http_1.BasePath)('auth')
|
|
276
|
+
], ImpersonationController);
|
|
277
|
+
//# sourceMappingURL=ImpersonationController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImpersonationController.js","sourceRoot":"","sources":["../../../src/controllers/ImpersonationController.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ import { AuthProvider, SessionProvider, AccessControl } from '@spinajs/rbac';
|
|
|
4
4
|
import { Configuration } from '@spinajs/configuration';
|
|
5
5
|
import { ILoginResponse } from '@spinajs/rbac-http';
|
|
6
6
|
import { User } from '@spinajs/rbac';
|
|
7
|
+
import type { ISession } from '@spinajs/rbac';
|
|
7
8
|
/**
|
|
8
9
|
* Authentication endpoints.
|
|
9
10
|
* Handles user login, logout, and current-session inspection.
|
|
@@ -33,19 +34,41 @@ export declare class LoginController extends BaseController {
|
|
|
33
34
|
/**
|
|
34
35
|
* Logout
|
|
35
36
|
* Destroys the current session identified by the `ssid` cookie and clears the cookie on the client.
|
|
37
|
+
* If an impersonation is active, the session is NOT destroyed — instead the
|
|
38
|
+
* impersonation is ended and the original user resumes their session.
|
|
36
39
|
* Requires the user to be logged in (session exists), but full authorization (2FA) is not required.
|
|
37
40
|
* @security cookieAuth
|
|
38
41
|
* @response 401 No active session
|
|
39
42
|
*/
|
|
40
|
-
logout(ssid: string): Promise<Ok<any>>;
|
|
43
|
+
logout(ssid: string, session: ISession, user: User): Promise<Ok<any>>;
|
|
41
44
|
/**
|
|
42
45
|
* Get current user
|
|
43
|
-
* Returns the user object associated with the current session
|
|
46
|
+
* Returns the user object associated with the current session along with the
|
|
47
|
+
* currently active role and the full list of roles the user may switch to.
|
|
44
48
|
* Requires the user to be logged in (session exists), but full authorization (2FA) is not required.
|
|
45
49
|
* @security cookieAuth
|
|
46
|
-
* @returns {
|
|
50
|
+
* @returns {User} User data from the current session
|
|
47
51
|
* @response 401 No active session
|
|
48
52
|
*/
|
|
49
|
-
whoami(User: User): Promise<Ok<
|
|
53
|
+
whoami(User: User, ActiveRole: string): Promise<Ok<{
|
|
54
|
+
ActiveRole: string;
|
|
55
|
+
AvailableRoles: string[];
|
|
56
|
+
Email: string;
|
|
57
|
+
Password: string;
|
|
58
|
+
Id: number;
|
|
59
|
+
Uuid: string;
|
|
60
|
+
Login: string;
|
|
61
|
+
Role: string[];
|
|
62
|
+
CreatedAt: import("luxon").DateTime;
|
|
63
|
+
RegisteredAt: import("luxon").DateTime;
|
|
64
|
+
DeletedAt: import("luxon").DateTime;
|
|
65
|
+
LastLoginAt: import("luxon").DateTime;
|
|
66
|
+
IsActive: boolean;
|
|
67
|
+
IsGuest: boolean;
|
|
68
|
+
IsBanned: boolean;
|
|
69
|
+
IsDirty: boolean;
|
|
70
|
+
Metadata: Omit<import("@spinajs/orm").ModelDataWithRelationData<import("@spinajs/rbac").UserMetadataBase>, import("@spinajs/orm").ExcludedModelProperties>[];
|
|
71
|
+
PrimaryKeyValue: any;
|
|
72
|
+
}>>;
|
|
50
73
|
}
|
|
51
74
|
//# sourceMappingURL=LoginController.d.ts.map
|
|
@@ -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,EAAe,YAAY,EAAU,MAAM,eAAe,CAAC;AAC5G,OAAO,EAAE,YAAY,EAAE,eAAe,EAAsB,aAAa,EAAiB,MAAM,eAAe,CAAC;AAEhH,OAAO,EAA6B,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAElF,OAAO,
|
|
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,EAAe,YAAY,EAAU,MAAM,eAAe,CAAC;AAC5G,OAAO,EAAE,YAAY,EAAE,eAAe,EAAsB,aAAa,EAAiB,MAAM,eAAe,CAAC;AAEhH,OAAO,EAA6B,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAElF,OAAO,EAA+E,cAAc,EAAmB,MAAM,oBAAoB,CAAC;AAClJ,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI9C;;;;;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,qBAAqB,EAAE,MAAM,CAAC;IAKxC,SAAS,CAAC,oBAAoB,EAAE,OAAO,CAAC;IAMxC,SAAS,CAAC,sBAAsB,EAAE,OAAO,CAAC;IAG1C,SAAS,CAAC,mBAAmB,EAAE,GAAG,CAAC;IAGnC,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC;IAE5B;;;;;;;;;OASG;IAEU,KAAK,CAAiB,MAAM,EAAE,IAAI,EAAgB,IAAI,EAAE,MAAM,EAAU,WAAW,EAAE,YAAY,GAAG,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC;IA+G3J;;;;;;;;OAQG;IAGU,MAAM,CAAe,IAAI,EAAE,MAAM,EAAqB,OAAO,EAAE,QAAQ,EAAkB,IAAI,EAAE,IAAI;IA6BhH;;;;;;;;OAQG;IAGU,MAAM,CAAiB,IAAI,EAAE,IAAI,EAAiB,UAAU,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;CAQlF"}
|