@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,132 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { SwitchRoleDto } from '../dto/switchRole-dto.js';
|
|
14
|
+
import { BaseController, BasePath, Post, Body, Ok, Get, BadRequestResponse, Unauthorized, Policy } from '@spinajs/http';
|
|
15
|
+
import { AccessControl, AuthProvider, PasswordProvider, SessionProvider, _unwindGrants } from '@spinajs/rbac';
|
|
16
|
+
import { Autoinject } from '@spinajs/di';
|
|
17
|
+
import { AutoinjectService, Config } from '@spinajs/configuration';
|
|
18
|
+
import { LoggedPolicy, User as UserRouteArg, Session as SessionRouteArg, FromSession } from '@spinajs/rbac-http';
|
|
19
|
+
/**
|
|
20
|
+
* Active role endpoints.
|
|
21
|
+
* Let users with multiple roles inspect and switch the currently active role.
|
|
22
|
+
* The active role drives all request-bound permission checks; the user's full
|
|
23
|
+
* role list remains available so they can switch back at any time.
|
|
24
|
+
* @tags Authentication
|
|
25
|
+
*/
|
|
26
|
+
let ActiveRoleController = class ActiveRoleController extends BaseController {
|
|
27
|
+
/**
|
|
28
|
+
* Get active role
|
|
29
|
+
* Returns the currently active role for the session, all roles the user may switch to,
|
|
30
|
+
* and the RBAC grants resolved for the active role.
|
|
31
|
+
* @security cookieAuth
|
|
32
|
+
* @returns {IActiveRoleResponse}
|
|
33
|
+
* @response 401 No active session
|
|
34
|
+
*/
|
|
35
|
+
async getActiveRole(user, ActiveRole) {
|
|
36
|
+
return new Ok(this.buildResponse(user, ActiveRole ?? user.Role?.[0]));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Switch active role
|
|
40
|
+
* Switches the active role for the current session. The requested role must be one of
|
|
41
|
+
* the user's assigned roles. If the role is listed in `rbac.roleSwitch.requirePassword`,
|
|
42
|
+
* the user's password must also be provided and is re-verified.
|
|
43
|
+
* @security cookieAuth
|
|
44
|
+
* @returns {IActiveRoleResponse}
|
|
45
|
+
* @response 400 Requested role is not assigned to the user
|
|
46
|
+
* @response 401 Password verification required or failed
|
|
47
|
+
*/
|
|
48
|
+
async switchActiveRole(user, session, payload) {
|
|
49
|
+
if (!user.Role?.includes(payload.Role)) {
|
|
50
|
+
return new BadRequestResponse({
|
|
51
|
+
error: {
|
|
52
|
+
code: 'E_ROLE_NOT_ASSIGNED',
|
|
53
|
+
message: `Role '${payload.Role}' is not assigned to user`,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
if (this.RolesRequiringPassword?.includes(payload.Role)) {
|
|
58
|
+
if (!payload.Password) {
|
|
59
|
+
return new Unauthorized({
|
|
60
|
+
error: {
|
|
61
|
+
code: 'E_PASSWORD_REQUIRED',
|
|
62
|
+
message: `Password is required to activate role '${payload.Role}'`,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
const valid = await this.PasswordProvider.verify(user.Password, payload.Password);
|
|
67
|
+
if (!valid) {
|
|
68
|
+
return new Unauthorized({
|
|
69
|
+
error: {
|
|
70
|
+
code: 'E_PASSWORD_INVALID',
|
|
71
|
+
message: 'Invalid password',
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
session.Data.set('ActiveRole', payload.Role);
|
|
77
|
+
await this.SessionProvider.save(session);
|
|
78
|
+
return new Ok(this.buildResponse(user, payload.Role));
|
|
79
|
+
}
|
|
80
|
+
buildResponse(user, activeRole) {
|
|
81
|
+
const grants = activeRole ? _unwindGrants(activeRole, this.AC.getGrants()) : {};
|
|
82
|
+
return {
|
|
83
|
+
ActiveRole: activeRole,
|
|
84
|
+
AvailableRoles: user.Role ?? [],
|
|
85
|
+
Grants: grants,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
__decorate([
|
|
90
|
+
Autoinject(AccessControl),
|
|
91
|
+
__metadata("design:type", AccessControl)
|
|
92
|
+
], ActiveRoleController.prototype, "AC", void 0);
|
|
93
|
+
__decorate([
|
|
94
|
+
AutoinjectService('rbac.auth'),
|
|
95
|
+
__metadata("design:type", AuthProvider)
|
|
96
|
+
], ActiveRoleController.prototype, "AuthProvider", void 0);
|
|
97
|
+
__decorate([
|
|
98
|
+
AutoinjectService('rbac.password'),
|
|
99
|
+
__metadata("design:type", PasswordProvider)
|
|
100
|
+
], ActiveRoleController.prototype, "PasswordProvider", void 0);
|
|
101
|
+
__decorate([
|
|
102
|
+
AutoinjectService('rbac.session'),
|
|
103
|
+
__metadata("design:type", SessionProvider)
|
|
104
|
+
], ActiveRoleController.prototype, "SessionProvider", void 0);
|
|
105
|
+
__decorate([
|
|
106
|
+
Config('rbac.roleSwitch.requirePassword', { defaultValue: [] }),
|
|
107
|
+
__metadata("design:type", Array)
|
|
108
|
+
], ActiveRoleController.prototype, "RolesRequiringPassword", void 0);
|
|
109
|
+
__decorate([
|
|
110
|
+
Get('active-role'),
|
|
111
|
+
Policy(LoggedPolicy),
|
|
112
|
+
__param(0, UserRouteArg()),
|
|
113
|
+
__param(1, FromSession()),
|
|
114
|
+
__metadata("design:type", Function),
|
|
115
|
+
__metadata("design:paramtypes", [Function, String]),
|
|
116
|
+
__metadata("design:returntype", Promise)
|
|
117
|
+
], ActiveRoleController.prototype, "getActiveRole", null);
|
|
118
|
+
__decorate([
|
|
119
|
+
Post('active-role'),
|
|
120
|
+
Policy(LoggedPolicy),
|
|
121
|
+
__param(0, UserRouteArg()),
|
|
122
|
+
__param(1, SessionRouteArg()),
|
|
123
|
+
__param(2, Body()),
|
|
124
|
+
__metadata("design:type", Function),
|
|
125
|
+
__metadata("design:paramtypes", [Function, Object, SwitchRoleDto]),
|
|
126
|
+
__metadata("design:returntype", Promise)
|
|
127
|
+
], ActiveRoleController.prototype, "switchActiveRole", null);
|
|
128
|
+
ActiveRoleController = __decorate([
|
|
129
|
+
BasePath('auth')
|
|
130
|
+
], ActiveRoleController);
|
|
131
|
+
export { ActiveRoleController };
|
|
132
|
+
//# 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,274 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { ImpersonateDto } from '../dto/impersonate-dto.js';
|
|
14
|
+
import { BaseController, BasePath, Post, Del, Body, Ok, Get, BadRequestResponse, Unauthorized, ForbiddenResponse, Conflict, NotFound, Policy } from '@spinajs/http';
|
|
15
|
+
import { AccessControl, PasswordProvider, SessionProvider, User, UserImpersonationStarted, UserImpersonationEnded, _unwindGrants, canImpersonate, } from '@spinajs/rbac';
|
|
16
|
+
import { Autoinject } from '@spinajs/di';
|
|
17
|
+
import { AutoinjectService, Config } from '@spinajs/configuration';
|
|
18
|
+
import { _ev } from '@spinajs/queue';
|
|
19
|
+
import { DateTime } from 'luxon';
|
|
20
|
+
import { LoggedPolicy, User as UserRouteArg, Session as SessionRouteArg, FromSession, } from '@spinajs/rbac-http';
|
|
21
|
+
const IMPERSONATE_RESOURCE = 'user:impersonate';
|
|
22
|
+
/**
|
|
23
|
+
* Impersonation endpoints.
|
|
24
|
+
*
|
|
25
|
+
* A user holding `createAny` on the virtual resource `user:impersonate` can
|
|
26
|
+
* temporarily act as another user. While impersonation is active, the session
|
|
27
|
+
* carries both identities — `User` is the target, `Impersonator` is the
|
|
28
|
+
* original. Permission checks therefore "see" the target by default; the
|
|
29
|
+
* original is preserved only for audit and for ending the impersonation.
|
|
30
|
+
*
|
|
31
|
+
* @tags Authentication
|
|
32
|
+
*/
|
|
33
|
+
let ImpersonationController = class ImpersonationController extends BaseController {
|
|
34
|
+
/**
|
|
35
|
+
* Get impersonation state
|
|
36
|
+
* Returns whether an impersonation is currently active for this session.
|
|
37
|
+
* @security cookieAuth
|
|
38
|
+
* @returns {IImpersonationState}
|
|
39
|
+
* @response 401 No active session
|
|
40
|
+
*/
|
|
41
|
+
async getState(Impersonator, User, ImpersonationStartedAt) {
|
|
42
|
+
if (!Impersonator) {
|
|
43
|
+
return new Ok({ Active: false });
|
|
44
|
+
}
|
|
45
|
+
return new Ok({
|
|
46
|
+
Active: true,
|
|
47
|
+
ImpersonatorUuid: Impersonator,
|
|
48
|
+
TargetUuid: User,
|
|
49
|
+
StartedAt: ImpersonationStartedAt,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Start impersonation
|
|
54
|
+
* Begins impersonating the target user. The caller must have `createAny` on
|
|
55
|
+
* virtual resource `user:impersonate`. The target must not hold any role in
|
|
56
|
+
* `rbac.impersonation.protectedRoles` and must not have effective grants
|
|
57
|
+
* exceeding the caller's. If `rbac.impersonation.requirePassword` is true,
|
|
58
|
+
* the caller's password must be supplied and is verified.
|
|
59
|
+
* @security cookieAuth
|
|
60
|
+
* @returns {IImpersonationResponse}
|
|
61
|
+
* @response 400 Target equals caller or invalid payload
|
|
62
|
+
* @response 401 Password required or invalid
|
|
63
|
+
* @response 403 Caller lacks permission, target is protected, or escalation detected
|
|
64
|
+
* @response 404 Target user not found / inactive / banned / deleted
|
|
65
|
+
* @response 409 An impersonation is already in progress for this session
|
|
66
|
+
*/
|
|
67
|
+
async start(caller, session, payload) {
|
|
68
|
+
if (session?.Data.get('Impersonator')) {
|
|
69
|
+
return new Conflict({
|
|
70
|
+
error: {
|
|
71
|
+
code: 'E_IMPERSONATION_ACTIVE',
|
|
72
|
+
message: 'An impersonation is already in progress. Stop the current one before starting another.',
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (caller.Uuid === payload.TargetUuid) {
|
|
77
|
+
return new BadRequestResponse({
|
|
78
|
+
error: { code: 'E_SELF_IMPERSONATION', message: 'Cannot impersonate yourself' },
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// Permission to impersonate is itself an RBAC permission honoring ActiveRole.
|
|
82
|
+
const activeRole = session?.Data.get('ActiveRole') ?? caller.Role?.[0];
|
|
83
|
+
const roles = activeRole ? [activeRole] : caller.Role;
|
|
84
|
+
const allowed = this.AC.can(roles).createAny(IMPERSONATE_RESOURCE).granted;
|
|
85
|
+
if (!allowed) {
|
|
86
|
+
return new ForbiddenResponse({
|
|
87
|
+
error: { code: 'E_IMPERSONATE_FORBIDDEN', message: `Role(s) ${roles} cannot impersonate other users` },
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const target = await this.loadTarget(payload.TargetUuid);
|
|
91
|
+
if (!target) {
|
|
92
|
+
return new NotFound({ error: { code: 'E_TARGET_NOT_FOUND', message: 'Target user not found' } });
|
|
93
|
+
}
|
|
94
|
+
if (!target.IsActive || target.IsBanned) {
|
|
95
|
+
return new NotFound({ error: { code: 'E_TARGET_UNAVAILABLE', message: 'Target user is not available' } });
|
|
96
|
+
}
|
|
97
|
+
const check = canImpersonate({
|
|
98
|
+
originalRoles: caller.Role,
|
|
99
|
+
targetRoles: target.Role,
|
|
100
|
+
protectedRoles: this.ProtectedRoles ?? [],
|
|
101
|
+
ac: this.AC,
|
|
102
|
+
});
|
|
103
|
+
if (!check.allowed) {
|
|
104
|
+
return new ForbiddenResponse({
|
|
105
|
+
error: {
|
|
106
|
+
code: check.reason === 'PROTECTED_ROLE' ? 'E_TARGET_PROTECTED' : 'E_PRIVILEGE_ESCALATION',
|
|
107
|
+
message: check.reason === 'PROTECTED_ROLE'
|
|
108
|
+
? `Target has a protected role (${check.detail}) and cannot be impersonated`
|
|
109
|
+
: `Target has a privilege the impersonator lacks (${check.detail})`,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
if (this.RequirePassword) {
|
|
114
|
+
if (!payload.Password) {
|
|
115
|
+
return new Unauthorized({
|
|
116
|
+
error: { code: 'E_PASSWORD_REQUIRED', message: 'Password confirmation is required to start impersonation' },
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
const valid = await this.PasswordProvider.verify(caller.Password, payload.Password);
|
|
120
|
+
if (!valid) {
|
|
121
|
+
return new Unauthorized({ error: { code: 'E_PASSWORD_INVALID', message: 'Invalid password' } });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Persist impersonation state. We keep the impersonator's previous
|
|
125
|
+
// ActiveRole so it can be restored on stop; effective ActiveRole becomes
|
|
126
|
+
// the target's first role.
|
|
127
|
+
const startedAt = DateTime.now().toISO();
|
|
128
|
+
const previousActiveRole = session.Data.get('ActiveRole');
|
|
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);
|
|
140
|
+
await this.emitEvent(new UserImpersonationStarted(caller, target));
|
|
141
|
+
return new Ok(this.buildResponse(target, caller, targetActiveRole, startedAt));
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Stop impersonation
|
|
145
|
+
* Restores the original user's session and returns their login-style payload.
|
|
146
|
+
* @security cookieAuth
|
|
147
|
+
* @returns {IUserWithGrants}
|
|
148
|
+
* @response 400 No impersonation is currently active
|
|
149
|
+
*/
|
|
150
|
+
async stop(target, session) {
|
|
151
|
+
const impersonatorUuid = session?.Data.get('Impersonator');
|
|
152
|
+
if (!impersonatorUuid) {
|
|
153
|
+
return new BadRequestResponse({
|
|
154
|
+
error: { code: 'E_NO_IMPERSONATION', message: 'No impersonation is currently in progress' },
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const original = await this.loadOriginal(impersonatorUuid);
|
|
158
|
+
if (!original) {
|
|
159
|
+
// Stale session referencing a deleted impersonator — destroy the
|
|
160
|
+
// impersonation block to recover but report an error so the caller
|
|
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);
|
|
166
|
+
return new BadRequestResponse({
|
|
167
|
+
error: { code: 'E_IMPERSONATOR_GONE', message: 'Original user no longer exists' },
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
// Restore the original session state.
|
|
171
|
+
session.Data.set('User', original.Uuid);
|
|
172
|
+
session.Data.delete('Impersonator');
|
|
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,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Emit an impersonation lifecycle event. Wrapped in a protected method so
|
|
190
|
+
* tests can intercept without stubbing module-level ESM bindings.
|
|
191
|
+
*/
|
|
192
|
+
emitEvent(event) {
|
|
193
|
+
return _ev(event)();
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Load the impersonation target (with Metadata so IsBanned works). Extracted
|
|
197
|
+
* as a protected method so tests can stub it without setting up a database.
|
|
198
|
+
*/
|
|
199
|
+
loadTarget(uuid) {
|
|
200
|
+
return User.query().whereUuid(uuid).populate('Metadata').notDeleted().first();
|
|
201
|
+
}
|
|
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
|
+
buildResponse(target, impersonator, activeRole, startedAt) {
|
|
210
|
+
const grants = activeRole ? _unwindGrants(activeRole, this.AC.getGrants()) : {};
|
|
211
|
+
return {
|
|
212
|
+
User: target.dehydrateWithRelations({ dateTimeFormat: 'iso' }),
|
|
213
|
+
Impersonator: impersonator.dehydrateWithRelations({ dateTimeFormat: 'iso' }),
|
|
214
|
+
ActiveRole: activeRole,
|
|
215
|
+
AvailableRoles: target.Role ?? [],
|
|
216
|
+
Grants: grants,
|
|
217
|
+
StartedAt: startedAt,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
__decorate([
|
|
222
|
+
Autoinject(AccessControl),
|
|
223
|
+
__metadata("design:type", AccessControl)
|
|
224
|
+
], ImpersonationController.prototype, "AC", void 0);
|
|
225
|
+
__decorate([
|
|
226
|
+
AutoinjectService('rbac.password'),
|
|
227
|
+
__metadata("design:type", PasswordProvider)
|
|
228
|
+
], ImpersonationController.prototype, "PasswordProvider", void 0);
|
|
229
|
+
__decorate([
|
|
230
|
+
AutoinjectService('rbac.session'),
|
|
231
|
+
__metadata("design:type", SessionProvider)
|
|
232
|
+
], ImpersonationController.prototype, "SessionProvider", void 0);
|
|
233
|
+
__decorate([
|
|
234
|
+
Config('rbac.impersonation.requirePassword', { defaultValue: true }),
|
|
235
|
+
__metadata("design:type", Boolean)
|
|
236
|
+
], ImpersonationController.prototype, "RequirePassword", void 0);
|
|
237
|
+
__decorate([
|
|
238
|
+
Config('rbac.impersonation.protectedRoles', { defaultValue: ['system'] }),
|
|
239
|
+
__metadata("design:type", Array)
|
|
240
|
+
], ImpersonationController.prototype, "ProtectedRoles", void 0);
|
|
241
|
+
__decorate([
|
|
242
|
+
Get('impersonate'),
|
|
243
|
+
Policy(LoggedPolicy),
|
|
244
|
+
__param(0, FromSession()),
|
|
245
|
+
__param(1, FromSession()),
|
|
246
|
+
__param(2, FromSession()),
|
|
247
|
+
__metadata("design:type", Function),
|
|
248
|
+
__metadata("design:paramtypes", [String, String, String]),
|
|
249
|
+
__metadata("design:returntype", Promise)
|
|
250
|
+
], ImpersonationController.prototype, "getState", null);
|
|
251
|
+
__decorate([
|
|
252
|
+
Post('impersonate'),
|
|
253
|
+
Policy(LoggedPolicy),
|
|
254
|
+
__param(0, UserRouteArg()),
|
|
255
|
+
__param(1, SessionRouteArg()),
|
|
256
|
+
__param(2, Body()),
|
|
257
|
+
__metadata("design:type", Function),
|
|
258
|
+
__metadata("design:paramtypes", [User, Object, ImpersonateDto]),
|
|
259
|
+
__metadata("design:returntype", Promise)
|
|
260
|
+
], ImpersonationController.prototype, "start", null);
|
|
261
|
+
__decorate([
|
|
262
|
+
Del('impersonate'),
|
|
263
|
+
Policy(LoggedPolicy),
|
|
264
|
+
__param(0, UserRouteArg()),
|
|
265
|
+
__param(1, SessionRouteArg()),
|
|
266
|
+
__metadata("design:type", Function),
|
|
267
|
+
__metadata("design:paramtypes", [User, Object]),
|
|
268
|
+
__metadata("design:returntype", Promise)
|
|
269
|
+
], ImpersonationController.prototype, "stop", null);
|
|
270
|
+
ImpersonationController = __decorate([
|
|
271
|
+
BasePath('auth')
|
|
272
|
+
], ImpersonationController);
|
|
273
|
+
export { ImpersonationController };
|
|
274
|
+
//# sourceMappingURL=ImpersonationController.js.map
|
|
@@ -0,0 +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,eAAe,EACf,IAAI,EACJ,wBAAwB,EACxB,sBAAsB,EACtB,aAAa,EACb,cAAc,GACf,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EACL,YAAY,EACZ,IAAI,IAAI,YAAY,EACpB,OAAO,IAAI,eAAe,EAC1B,WAAW,GAIZ,MAAM,oBAAoB,CAAC;AAE5B,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEhD;;;;;;;;;;GAUG;AAEI,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,cAAc;IAgBzD;;;;;;OAMG;IAGU,AAAN,KAAK,CAAC,QAAQ,CACJ,YAAoB,EACpB,IAAY,EACZ,sBAA8B;QAE7C,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,EAAE,IAAI;YACZ,gBAAgB,EAAE,YAAY;YAC9B,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,sBAAsB;SAClC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;OAcG;IAGU,AAAN,KAAK,CAAC,KAAK,CACA,MAAY,EACT,OAAiB,EAC5B,OAAuB;QAI/B,IAAI,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YACtC,OAAO,IAAI,QAAQ,CAAC;gBAClB,KAAK,EAAE;oBACL,IAAI,EAAE,wBAAwB;oBAC9B,OAAO,EAAE,wFAAwF;iBAClG;aACF,CAAC,CAAC;QACL,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC;YACvC,OAAO,IAAI,kBAAkB,CAAC;gBAC5B,KAAK,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,6BAA6B,EAAE;aAChF,CAAC,CAAC;QACL,CAAC;QAED,8EAA8E;QAC9E,MAAM,UAAU,GAAI,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,CAAwB,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/F,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;QACtD,MAAM,OAAO,GAAI,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAS,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC;QACpF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,iBAAiB,CAAC;gBAC3B,KAAK,EAAE,EAAE,IAAI,EAAE,yBAAyB,EAAE,OAAO,EAAE,WAAW,KAAK,iCAAiC,EAAE;aACvG,CAAC,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,uBAAuB,EAAE,EAAE,CAAC,CAAC;QACnG,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACxC,OAAO,IAAI,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,8BAA8B,EAAE,EAAE,CAAC,CAAC;QAC5G,CAAC;QAED,MAAM,KAAK,GAAG,cAAc,CAAC;YAC3B,aAAa,EAAE,MAAM,CAAC,IAAI;YAC1B,WAAW,EAAE,MAAM,CAAC,IAAI;YACxB,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,EAAE;YACzC,EAAE,EAAE,IAAI,CAAC,EAAE;SACZ,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,IAAI,iBAAiB,CAAC;gBAC3B,KAAK,EAAE;oBACL,IAAI,EAAE,KAAK,CAAC,MAAM,KAAK,gBAAgB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,wBAAwB;oBACzF,OAAO,EAAE,KAAK,CAAC,MAAM,KAAK,gBAAgB;wBACxC,CAAC,CAAC,gCAAgC,KAAK,CAAC,MAAM,8BAA8B;wBAC5E,CAAC,CAAC,kDAAkD,KAAK,CAAC,MAAM,GAAG;iBACtE;aACF,CAAC,CAAC;QACL,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACtB,OAAO,IAAI,YAAY,CAAC;oBACtB,KAAK,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,0DAA0D,EAAE;iBAC5G,CAAC,CAAC;YACL,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;YACpF,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,IAAI,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;YAClG,CAAC;QACH,CAAC;QAED,mEAAmE;QACnE,yEAAyE;QACzE,2BAA2B;QAC3B,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,EAAG,CAAC;QAC1C,MAAM,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAuB,CAAC;QAEhF,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACtC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;QACtD,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,CAAC;QAC7D,CAAC;QACD,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAI,gBAAgB,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAEnE,OAAO,IAAI,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAiB,EAAE,SAAS,CAAC,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;OAMG;IAGU,AAAN,KAAK,CAAC,IAAI,CACC,MAAY,EACT,OAAiB;QAEpC,MAAM,gBAAgB,GAAG,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,CAAuB,CAAC;QACjF,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO,IAAI,kBAAkB,CAAC;gBAC5B,KAAK,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,2CAA2C,EAAE;aAC5F,CAAC,CAAC;QACL,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;QAC3D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,iEAAiE;YACjE,mEAAmE;YACnE,uBAAuB;YACvB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YACpC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;YAC1C,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzC,OAAO,IAAI,kBAAkB,CAAC;gBAC5B,KAAK,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,gCAAgC,EAAE;aAClF,CAAC,CAAC;QACL,CAAC;QAED,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC;QAE9C,MAAM,kBAAkB,GAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAwB,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAChH,IAAI,kBAAkB,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAE1C,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,sBAAsB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;QAEnE,MAAM,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,aAAa,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChG,OAAO,IAAI,EAAE,CAAC;YACZ,GAAI,QAAQ,CAAC,sBAAsB,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,CAAS;YACtE,UAAU,EAAE,kBAAkB;YAC9B,MAAM,EAAE,MAAM;SACI,CAAC,CAAC;IACxB,CAAC;IAED;;;OAGG;IACO,SAAS,CAAC,KAAwD;QAC1E,OAAO,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;IACtB,CAAC;IAED;;;OAGG;IACO,UAAU,CAAC,IAAY;QAC/B,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,UAAU,EAAE,CAAC,KAAK,EAA+B,CAAC;IAC7G,CAAC;IAED;;;OAGG;IACO,YAAY,CAAC,IAAY;QACjC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAA8B,CAAC;IAC3D,CAAC;IAES,aAAa,CAAC,MAAY,EAAE,YAAkB,EAAE,UAAkB,EAAE,SAAiB;QAC7F,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChF,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,sBAAsB,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,CAAQ;YACrE,YAAY,EAAE,YAAY,CAAC,sBAAsB,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,CAAQ;YACnF,UAAU,EAAE,UAAU;YACtB,cAAc,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;YACjC,MAAM,EAAE,MAAM;YACd,SAAS,EAAE,SAAS;SACrB,CAAC;IACJ,CAAC;CACF,CAAA;AA/OW;IADT,UAAU,CAAC,aAAa,CAAC;8BACZ,aAAa;mDAAC;AAGlB;IADT,iBAAiB,CAAC,eAAe,CAAC;8BACP,gBAAgB;iEAAC;AAGnC;IADT,iBAAiB,CAAC,cAAc,CAAC;8BACP,eAAe;gEAAC;AAGjC;IADT,MAAM,CAAC,oCAAoC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;;gEAClC;AAGzB;IADT,MAAM,CAAC,mCAAmC,EAAE,EAAE,YAAY,EAAE,CAAC,QAAQ,CAAa,EAAE,CAAC;;+DACnD;AAWtB;IAFZ,GAAG,CAAC,aAAa,CAAC;IAClB,MAAM,CAAC,YAAY,CAAC;IAElB,WAAA,WAAW,EAAE,CAAA;IACb,WAAA,WAAW,EAAE,CAAA;IACb,WAAA,WAAW,EAAE,CAAA;;;;uDAWf;AAmBY;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;;qCAFiB,IAAI,UAEX,cAAc;;oDAuFhC;AAWY;IAFZ,GAAG,CAAC,aAAa,CAAC;IAClB,MAAM,CAAC,YAAY,CAAC;IAElB,WAAA,YAAY,EAAE,CAAA;IACd,WAAA,eAAe,EAAE,CAAA;;qCADM,IAAI;;mDA4C7B;AA5MU,uBAAuB;IADnC,QAAQ,CAAC,MAAM,CAAC;GACJ,uBAAuB,CAiPnC"}
|
|
@@ -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"}
|