@arikajs/authorization 0.0.4 → 0.0.5
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/README.md +173 -78
- package/dist/AuthResponse.d.ts +23 -0
- package/dist/AuthResponse.d.ts.map +1 -0
- package/dist/AuthResponse.js +40 -0
- package/dist/AuthResponse.js.map +1 -0
- package/dist/AuthorizationContext.d.ts +31 -0
- package/dist/AuthorizationContext.d.ts.map +1 -0
- package/dist/AuthorizationContext.js +87 -0
- package/dist/AuthorizationContext.js.map +1 -0
- package/dist/AuthorizationManager.d.ts +15 -7
- package/dist/AuthorizationManager.d.ts.map +1 -1
- package/dist/AuthorizationManager.js +46 -12
- package/dist/AuthorizationManager.js.map +1 -1
- package/dist/Exceptions/AuthorizationException.d.ts +2 -1
- package/dist/Exceptions/AuthorizationException.d.ts.map +1 -1
- package/dist/Exceptions/AuthorizationException.js +2 -1
- package/dist/Exceptions/AuthorizationException.js.map +1 -1
- package/dist/Gate.d.ts +39 -3
- package/dist/Gate.d.ts.map +1 -1
- package/dist/Gate.js +121 -14
- package/dist/Gate.js.map +1 -1
- package/dist/Middleware/Authorize.d.ts +5 -4
- package/dist/Middleware/Authorize.d.ts.map +1 -1
- package/dist/Middleware/Authorize.js +24 -6
- package/dist/Middleware/Authorize.js.map +1 -1
- package/dist/PolicyResolver.d.ts +7 -2
- package/dist/PolicyResolver.d.ts.map +1 -1
- package/dist/PolicyResolver.js +26 -4
- package/dist/PolicyResolver.js.map +1 -1
- package/dist/RolePermission.d.ts +36 -0
- package/dist/RolePermission.d.ts.map +1 -0
- package/dist/RolePermission.js +59 -0
- package/dist/RolePermission.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/src/AuthResponse.d.ts +23 -0
- package/dist/src/AuthResponse.d.ts.map +1 -0
- package/dist/src/AuthResponse.js +40 -0
- package/dist/src/AuthResponse.js.map +1 -0
- package/dist/src/AuthorizationContext.d.ts +31 -0
- package/dist/src/AuthorizationContext.d.ts.map +1 -0
- package/dist/src/AuthorizationContext.js +87 -0
- package/dist/src/AuthorizationContext.js.map +1 -0
- package/dist/src/AuthorizationManager.d.ts +25 -0
- package/dist/src/AuthorizationManager.d.ts.map +1 -0
- package/dist/src/AuthorizationManager.js +64 -0
- package/dist/src/AuthorizationManager.js.map +1 -0
- package/dist/src/Contracts/Policy.d.ts +4 -0
- package/dist/src/Contracts/Policy.d.ts.map +1 -0
- package/dist/src/Contracts/Policy.js +3 -0
- package/dist/src/Contracts/Policy.js.map +1 -0
- package/dist/src/Exceptions/AuthorizationException.d.ts +6 -0
- package/dist/src/Exceptions/AuthorizationException.d.ts.map +1 -0
- package/dist/src/Exceptions/AuthorizationException.js +13 -0
- package/dist/src/Exceptions/AuthorizationException.js.map +1 -0
- package/dist/src/Gate.d.ts +76 -0
- package/dist/src/Gate.d.ts.map +1 -0
- package/dist/src/Gate.js +189 -0
- package/dist/src/Gate.js.map +1 -0
- package/dist/src/Middleware/Authorize.d.ts +13 -0
- package/dist/src/Middleware/Authorize.d.ts.map +1 -0
- package/dist/src/Middleware/Authorize.js +51 -0
- package/dist/src/Middleware/Authorize.js.map +1 -0
- package/dist/src/PolicyResolver.d.ts +21 -0
- package/dist/src/PolicyResolver.d.ts.map +1 -0
- package/dist/src/PolicyResolver.js +67 -0
- package/dist/src/PolicyResolver.js.map +1 -0
- package/dist/src/RolePermission.d.ts +36 -0
- package/dist/src/RolePermission.d.ts.map +1 -0
- package/dist/src/RolePermission.js +59 -0
- package/dist/src/RolePermission.js.map +1 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +26 -0
- package/dist/src/index.js.map +1 -0
- package/dist/tests/Authorization.test.d.ts +2 -0
- package/dist/tests/Authorization.test.d.ts.map +1 -0
- package/dist/tests/Authorization.test.js +236 -0
- package/dist/tests/Authorization.test.js.map +1 -0
- package/package.json +44 -42
|
@@ -1,29 +1,63 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AuthorizationManager = void 0;
|
|
4
|
+
const AuthorizationContext_1 = require("./AuthorizationContext");
|
|
4
5
|
class AuthorizationManager {
|
|
5
6
|
constructor(user) {
|
|
6
7
|
this.user = user;
|
|
8
|
+
this.context = new AuthorizationContext_1.AuthorizationContext(user);
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
|
-
*
|
|
11
|
+
* Create a request-scoped authorization context and bind it to the request.
|
|
10
12
|
*/
|
|
13
|
+
static createContext(request) {
|
|
14
|
+
const user = request.user || (request.auth ? null : null);
|
|
15
|
+
const context = new AuthorizationContext_1.AuthorizationContext(user);
|
|
16
|
+
request.can = context.can.bind(context);
|
|
17
|
+
request.cannot = context.cannot.bind(context);
|
|
18
|
+
request.authorize = context.authorize.bind(context);
|
|
19
|
+
return context;
|
|
20
|
+
}
|
|
21
|
+
// ── Delegated checks ────────────────────────────────────────────
|
|
11
22
|
async can(ability, ...args) {
|
|
12
|
-
|
|
13
|
-
return await Gate.forUser(this.user).allows(ability, ...args);
|
|
23
|
+
return await this.context.can(ability, ...args);
|
|
14
24
|
}
|
|
15
|
-
/**
|
|
16
|
-
* Determine if the user cannot perform the given ability.
|
|
17
|
-
*/
|
|
18
25
|
async cannot(ability, ...args) {
|
|
19
|
-
return
|
|
26
|
+
return await this.context.cannot(ability, ...args);
|
|
20
27
|
}
|
|
21
|
-
/**
|
|
22
|
-
* Authorize or throw exception.
|
|
23
|
-
*/
|
|
24
28
|
async authorize(ability, ...args) {
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
return await this.context.authorize(ability, ...args);
|
|
30
|
+
}
|
|
31
|
+
async inspect(ability, ...args) {
|
|
32
|
+
return await this.context.inspect(ability, ...args);
|
|
33
|
+
}
|
|
34
|
+
async any(abilities, ...args) {
|
|
35
|
+
return await this.context.any(abilities, ...args);
|
|
36
|
+
}
|
|
37
|
+
async every(abilities, ...args) {
|
|
38
|
+
return await this.context.every(abilities, ...args);
|
|
39
|
+
}
|
|
40
|
+
async none(abilities, ...args) {
|
|
41
|
+
return await this.context.none(abilities, ...args);
|
|
42
|
+
}
|
|
43
|
+
// ── Role & Permission ───────────────────────────────────────────
|
|
44
|
+
hasRole(role) {
|
|
45
|
+
return this.context.hasRole(role);
|
|
46
|
+
}
|
|
47
|
+
hasAnyRole(roles) {
|
|
48
|
+
return this.context.hasAnyRole(roles);
|
|
49
|
+
}
|
|
50
|
+
hasAllRoles(roles) {
|
|
51
|
+
return this.context.hasAllRoles(roles);
|
|
52
|
+
}
|
|
53
|
+
hasPermission(permission) {
|
|
54
|
+
return this.context.hasPermission(permission);
|
|
55
|
+
}
|
|
56
|
+
hasAnyPermission(permissions) {
|
|
57
|
+
return this.context.hasAnyPermission(permissions);
|
|
58
|
+
}
|
|
59
|
+
hasAllPermissions(permissions) {
|
|
60
|
+
return this.context.hasAllPermissions(permissions);
|
|
27
61
|
}
|
|
28
62
|
}
|
|
29
63
|
exports.AuthorizationManager = AuthorizationManager;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthorizationManager.js","sourceRoot":"","sources":["../src/AuthorizationManager.ts"],"names":[],"mappings":";;;AAAA,MAAa,oBAAoB;
|
|
1
|
+
{"version":3,"file":"AuthorizationManager.js","sourceRoot":"","sources":["../src/AuthorizationManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthorizationException.d.ts","sourceRoot":"","sources":["../../src/Exceptions/AuthorizationException.ts"],"names":[],"mappings":"AAAA,qBAAa,sBAAuB,SAAQ,KAAK;IACtC,UAAU,EAAE,MAAM,CAAO;
|
|
1
|
+
{"version":3,"file":"AuthorizationException.d.ts","sourceRoot":"","sources":["../../src/Exceptions/AuthorizationException.ts"],"names":[],"mappings":"AAAA,qBAAa,sBAAuB,SAAQ,KAAK;IACtC,UAAU,EAAE,MAAM,CAAO;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;gBAEf,OAAO,GAAE,MAAuC,EAAE,IAAI,GAAE,MAAM,GAAG,IAAW;CAK3F"}
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AuthorizationException = void 0;
|
|
4
4
|
class AuthorizationException extends Error {
|
|
5
|
-
constructor(message = 'This action is unauthorized.') {
|
|
5
|
+
constructor(message = 'This action is unauthorized.', code = null) {
|
|
6
6
|
super(message);
|
|
7
7
|
this.statusCode = 403;
|
|
8
8
|
this.name = 'AuthorizationException';
|
|
9
|
+
this.code = code;
|
|
9
10
|
}
|
|
10
11
|
}
|
|
11
12
|
exports.AuthorizationException = AuthorizationException;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthorizationException.js","sourceRoot":"","sources":["../../src/Exceptions/AuthorizationException.ts"],"names":[],"mappings":";;;AAAA,MAAa,sBAAuB,SAAQ,KAAK;
|
|
1
|
+
{"version":3,"file":"AuthorizationException.js","sourceRoot":"","sources":["../../src/Exceptions/AuthorizationException.ts"],"names":[],"mappings":";;;AAAA,MAAa,sBAAuB,SAAQ,KAAK;IAI7C,YAAY,UAAkB,8BAA8B,EAAE,OAAsB,IAAI;QACpF,KAAK,CAAC,OAAO,CAAC,CAAC;QAJZ,eAAU,GAAW,GAAG,CAAC;QAK5B,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;CACJ;AATD,wDASC"}
|
package/dist/Gate.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import { AuthResponse } from './AuthResponse';
|
|
2
|
+
type GateCallback = (user: any, ...args: any[]) => boolean | AuthResponse | Promise<boolean | AuthResponse>;
|
|
3
|
+
type BeforeCallback = (user: any, ability: string, ...args: any[]) => boolean | null | undefined | Promise<boolean | null | undefined>;
|
|
4
|
+
type AfterCallback = (user: any, ability: string, result: boolean, ...args: any[]) => void | Promise<void>;
|
|
2
5
|
export declare class Gate {
|
|
3
6
|
private static abilities;
|
|
4
7
|
private static policyResolver;
|
|
8
|
+
private static beforeCallbacks;
|
|
9
|
+
private static afterCallbacks;
|
|
5
10
|
private static currentUser;
|
|
6
11
|
/**
|
|
7
12
|
* Define a new ability.
|
|
@@ -11,10 +16,27 @@ export declare class Gate {
|
|
|
11
16
|
* Register a policy for a model.
|
|
12
17
|
*/
|
|
13
18
|
static policy(model: any, policy: any): void;
|
|
19
|
+
/**
|
|
20
|
+
* Register a callback to run before all gate checks.
|
|
21
|
+
* Return `true` to allow immediately (super admin bypass).
|
|
22
|
+
* Return `false` to deny immediately.
|
|
23
|
+
* Return `null`/`undefined` to continue to the actual gate check.
|
|
24
|
+
*/
|
|
25
|
+
static before(callback: BeforeCallback): void;
|
|
26
|
+
/**
|
|
27
|
+
* Register a callback to run after all gate checks.
|
|
28
|
+
* Useful for logging, auditing decisions, etc.
|
|
29
|
+
*/
|
|
30
|
+
static after(callback: AfterCallback): void;
|
|
14
31
|
/**
|
|
15
32
|
* Set the current user for authorization checks.
|
|
16
33
|
*/
|
|
17
34
|
static forUser(user: any): typeof Gate;
|
|
35
|
+
/**
|
|
36
|
+
* Determine if the user is authorized for an ability.
|
|
37
|
+
* Returns the AuthResponse for rich deny messages.
|
|
38
|
+
*/
|
|
39
|
+
static inspect(ability: string, ...args: any[]): Promise<AuthResponse>;
|
|
18
40
|
/**
|
|
19
41
|
* Determine if the user is authorized to perform an ability.
|
|
20
42
|
*/
|
|
@@ -24,7 +46,7 @@ export declare class Gate {
|
|
|
24
46
|
*/
|
|
25
47
|
static denies(ability: string, ...args: any[]): Promise<boolean>;
|
|
26
48
|
/**
|
|
27
|
-
* Authorize or throw exception.
|
|
49
|
+
* Authorize or throw exception with optional custom message.
|
|
28
50
|
*/
|
|
29
51
|
static authorize(ability: string, ...args: any[]): Promise<void>;
|
|
30
52
|
/**
|
|
@@ -32,7 +54,21 @@ export declare class Gate {
|
|
|
32
54
|
*/
|
|
33
55
|
static check(ability: string, ...args: any[]): Promise<boolean>;
|
|
34
56
|
/**
|
|
35
|
-
*
|
|
57
|
+
* Check if the user can perform ANY of the given abilities.
|
|
58
|
+
*/
|
|
59
|
+
static any(abilities: string[], ...args: any[]): Promise<boolean>;
|
|
60
|
+
/**
|
|
61
|
+
* Check if the user can perform ALL of the given abilities.
|
|
62
|
+
*/
|
|
63
|
+
static every(abilities: string[], ...args: any[]): Promise<boolean>;
|
|
64
|
+
/**
|
|
65
|
+
* Check if the user can perform NONE of the given abilities.
|
|
66
|
+
*/
|
|
67
|
+
static none(abilities: string[], ...args: any[]): Promise<boolean>;
|
|
68
|
+
private static normalizeResult;
|
|
69
|
+
private static runAfterCallbacks;
|
|
70
|
+
/**
|
|
71
|
+
* Reset all gates, policies, and hooks (useful for testing).
|
|
36
72
|
*/
|
|
37
73
|
static reset(): void;
|
|
38
74
|
}
|
package/dist/Gate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Gate.d.ts","sourceRoot":"","sources":["../src/Gate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Gate.d.ts","sourceRoot":"","sources":["../src/Gate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,GAAG,YAAY,GAAG,OAAO,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;AAC5G,KAAK,cAAc,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AACvI,KAAK,aAAa,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE3G,qBAAa,IAAI;IACb,OAAO,CAAC,MAAM,CAAC,SAAS,CAAwC;IAChE,OAAO,CAAC,MAAM,CAAC,cAAc,CAAwC;IACrE,OAAO,CAAC,MAAM,CAAC,eAAe,CAAwB;IACtD,OAAO,CAAC,MAAM,CAAC,cAAc,CAAuB;IACpD,OAAO,CAAC,MAAM,CAAC,WAAW,CAAa;IAIvC;;OAEG;WACW,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAInE;;OAEG;WACW,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI;IAMnD;;;;;OAKG;WACW,MAAM,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAIpD;;;OAGG;WACW,KAAK,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAMlD;;OAEG;WACW,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,IAAI;IAO7C;;;OAGG;WACiB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAkDnF;;OAEG;WACiB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAK7E;;OAEG;WACiB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAI7E;;OAEG;WACiB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAO7E;;OAEG;WACiB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAM5E;;OAEG;WACiB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAS9E;;OAEG;WACiB,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAShF;;OAEG;WACiB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAW/E,OAAO,CAAC,MAAM,CAAC,eAAe;mBAOT,iBAAiB;IAMtC;;OAEG;WACW,KAAK,IAAI,IAAI;CAO9B"}
|
package/dist/Gate.js
CHANGED
|
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Gate = void 0;
|
|
4
4
|
const PolicyResolver_1 = require("./PolicyResolver");
|
|
5
5
|
const AuthorizationException_1 = require("./Exceptions/AuthorizationException");
|
|
6
|
+
const AuthResponse_1 = require("./AuthResponse");
|
|
6
7
|
class Gate {
|
|
8
|
+
// ── Gate Definitions ────────────────────────────────────────────
|
|
7
9
|
/**
|
|
8
10
|
* Define a new ability.
|
|
9
11
|
*/
|
|
@@ -16,6 +18,24 @@ class Gate {
|
|
|
16
18
|
static policy(model, policy) {
|
|
17
19
|
this.policyResolver.register(model, policy);
|
|
18
20
|
}
|
|
21
|
+
// ── Before / After Hooks ────────────────────────────────────────
|
|
22
|
+
/**
|
|
23
|
+
* Register a callback to run before all gate checks.
|
|
24
|
+
* Return `true` to allow immediately (super admin bypass).
|
|
25
|
+
* Return `false` to deny immediately.
|
|
26
|
+
* Return `null`/`undefined` to continue to the actual gate check.
|
|
27
|
+
*/
|
|
28
|
+
static before(callback) {
|
|
29
|
+
this.beforeCallbacks.push(callback);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Register a callback to run after all gate checks.
|
|
33
|
+
* Useful for logging, auditing decisions, etc.
|
|
34
|
+
*/
|
|
35
|
+
static after(callback) {
|
|
36
|
+
this.afterCallbacks.push(callback);
|
|
37
|
+
}
|
|
38
|
+
// ── User Binding ────────────────────────────────────────────────
|
|
19
39
|
/**
|
|
20
40
|
* Set the current user for authorization checks.
|
|
21
41
|
*/
|
|
@@ -23,28 +43,64 @@ class Gate {
|
|
|
23
43
|
this.currentUser = user;
|
|
24
44
|
return this;
|
|
25
45
|
}
|
|
46
|
+
// ── Single Ability Checks ───────────────────────────────────────
|
|
26
47
|
/**
|
|
27
|
-
* Determine if the user is authorized
|
|
48
|
+
* Determine if the user is authorized for an ability.
|
|
49
|
+
* Returns the AuthResponse for rich deny messages.
|
|
28
50
|
*/
|
|
29
|
-
static async
|
|
30
|
-
// 1.
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
51
|
+
static async inspect(ability, ...args) {
|
|
52
|
+
// 1. Run before hooks
|
|
53
|
+
for (const cb of this.beforeCallbacks) {
|
|
54
|
+
const beforeResult = await cb(this.currentUser, ability, ...args);
|
|
55
|
+
if (beforeResult === true) {
|
|
56
|
+
return AuthResponse_1.AuthResponse.allow();
|
|
57
|
+
}
|
|
58
|
+
if (beforeResult === false) {
|
|
59
|
+
return AuthResponse_1.AuthResponse.deny();
|
|
60
|
+
}
|
|
61
|
+
// null/undefined = continue
|
|
34
62
|
}
|
|
35
|
-
// 2. Check
|
|
63
|
+
// 2. Check policy before() method
|
|
36
64
|
if (args.length > 0) {
|
|
37
65
|
const resource = args[0];
|
|
38
66
|
const policy = this.policyResolver.resolvePolicy(resource);
|
|
39
67
|
if (policy) {
|
|
68
|
+
const instance = this.policyResolver.getInstance(policy);
|
|
69
|
+
if (typeof instance.before === 'function') {
|
|
70
|
+
const policyBefore = await instance.before(this.currentUser, ability, ...args);
|
|
71
|
+
if (policyBefore === true)
|
|
72
|
+
return AuthResponse_1.AuthResponse.allow();
|
|
73
|
+
if (policyBefore === false)
|
|
74
|
+
return AuthResponse_1.AuthResponse.deny();
|
|
75
|
+
}
|
|
40
76
|
const method = this.policyResolver.getPolicyMethod(policy, ability);
|
|
41
77
|
if (method) {
|
|
42
|
-
|
|
78
|
+
const result = await method(this.currentUser, ...args);
|
|
79
|
+
const response = this.normalizeResult(result);
|
|
80
|
+
await this.runAfterCallbacks(ability, response.allowed(), ...args);
|
|
81
|
+
return response;
|
|
43
82
|
}
|
|
44
83
|
}
|
|
45
84
|
}
|
|
46
|
-
// 3.
|
|
47
|
-
|
|
85
|
+
// 3. Check direct gate definition
|
|
86
|
+
if (this.abilities.has(ability)) {
|
|
87
|
+
const callback = this.abilities.get(ability);
|
|
88
|
+
const result = await callback(this.currentUser, ...args);
|
|
89
|
+
const response = this.normalizeResult(result);
|
|
90
|
+
await this.runAfterCallbacks(ability, response.allowed(), ...args);
|
|
91
|
+
return response;
|
|
92
|
+
}
|
|
93
|
+
// 4. Default deny
|
|
94
|
+
const response = AuthResponse_1.AuthResponse.deny();
|
|
95
|
+
await this.runAfterCallbacks(ability, false, ...args);
|
|
96
|
+
return response;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Determine if the user is authorized to perform an ability.
|
|
100
|
+
*/
|
|
101
|
+
static async allows(ability, ...args) {
|
|
102
|
+
const response = await this.inspect(ability, ...args);
|
|
103
|
+
return response.allowed();
|
|
48
104
|
}
|
|
49
105
|
/**
|
|
50
106
|
* Determine if the user is NOT authorized.
|
|
@@ -53,11 +109,12 @@ class Gate {
|
|
|
53
109
|
return !(await this.allows(ability, ...args));
|
|
54
110
|
}
|
|
55
111
|
/**
|
|
56
|
-
* Authorize or throw exception.
|
|
112
|
+
* Authorize or throw exception with optional custom message.
|
|
57
113
|
*/
|
|
58
114
|
static async authorize(ability, ...args) {
|
|
59
|
-
|
|
60
|
-
|
|
115
|
+
const response = await this.inspect(ability, ...args);
|
|
116
|
+
if (response.denied()) {
|
|
117
|
+
throw new AuthorizationException_1.AuthorizationException(response.message() || 'This action is unauthorized.', response.code());
|
|
61
118
|
}
|
|
62
119
|
}
|
|
63
120
|
/**
|
|
@@ -66,17 +123,67 @@ class Gate {
|
|
|
66
123
|
static async check(ability, ...args) {
|
|
67
124
|
return await this.allows(ability, ...args);
|
|
68
125
|
}
|
|
126
|
+
// ── Bulk Ability Checks ─────────────────────────────────────────
|
|
127
|
+
/**
|
|
128
|
+
* Check if the user can perform ANY of the given abilities.
|
|
129
|
+
*/
|
|
130
|
+
static async any(abilities, ...args) {
|
|
131
|
+
for (const ability of abilities) {
|
|
132
|
+
if (await this.allows(ability, ...args)) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Check if the user can perform ALL of the given abilities.
|
|
140
|
+
*/
|
|
141
|
+
static async every(abilities, ...args) {
|
|
142
|
+
for (const ability of abilities) {
|
|
143
|
+
if (!(await this.allows(ability, ...args))) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Check if the user can perform NONE of the given abilities.
|
|
151
|
+
*/
|
|
152
|
+
static async none(abilities, ...args) {
|
|
153
|
+
for (const ability of abilities) {
|
|
154
|
+
if (await this.allows(ability, ...args)) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
// ── Internals ───────────────────────────────────────────────────
|
|
161
|
+
static normalizeResult(result) {
|
|
162
|
+
if (result instanceof AuthResponse_1.AuthResponse) {
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
return result ? AuthResponse_1.AuthResponse.allow() : AuthResponse_1.AuthResponse.deny();
|
|
166
|
+
}
|
|
167
|
+
static async runAfterCallbacks(ability, result, ...args) {
|
|
168
|
+
for (const cb of this.afterCallbacks) {
|
|
169
|
+
await cb(this.currentUser, ability, result, ...args);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
69
172
|
/**
|
|
70
|
-
* Reset all gates and
|
|
173
|
+
* Reset all gates, policies, and hooks (useful for testing).
|
|
71
174
|
*/
|
|
72
175
|
static reset() {
|
|
73
176
|
this.abilities.clear();
|
|
74
177
|
this.policyResolver = new PolicyResolver_1.PolicyResolver();
|
|
178
|
+
this.beforeCallbacks = [];
|
|
179
|
+
this.afterCallbacks = [];
|
|
75
180
|
this.currentUser = null;
|
|
76
181
|
}
|
|
77
182
|
}
|
|
78
183
|
exports.Gate = Gate;
|
|
79
184
|
Gate.abilities = new Map();
|
|
80
185
|
Gate.policyResolver = new PolicyResolver_1.PolicyResolver();
|
|
186
|
+
Gate.beforeCallbacks = [];
|
|
187
|
+
Gate.afterCallbacks = [];
|
|
81
188
|
Gate.currentUser = null;
|
|
82
189
|
//# sourceMappingURL=Gate.js.map
|
package/dist/Gate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Gate.js","sourceRoot":"","sources":["../src/Gate.ts"],"names":[],"mappings":";;;AAAA,qDAAkD;AAClD,gFAA6E;
|
|
1
|
+
{"version":3,"file":"Gate.js","sourceRoot":"","sources":["../src/Gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,10 +2,11 @@ export declare class Authorize {
|
|
|
2
2
|
/**
|
|
3
3
|
* Handle authorization middleware.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* .middleware('can:edit-post') → Gate check
|
|
7
|
+
* .middleware('can:update,post') → Policy check using req[resourceKey]
|
|
8
|
+
* .middleware('role:admin') → Role check
|
|
9
|
+
* .middleware('permission:edit-posts') → Permission check
|
|
9
10
|
*/
|
|
10
11
|
handle(request: any, next: () => Promise<any>, ability: string, resourceKey?: string): Promise<any>;
|
|
11
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Authorize.d.ts","sourceRoot":"","sources":["../../src/Middleware/Authorize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Authorize.d.ts","sourceRoot":"","sources":["../../src/Middleware/Authorize.ts"],"names":[],"mappings":"AAIA,qBAAa,SAAS;IAClB;;;;;;;;OAQG;IACU,MAAM,CACf,OAAO,EAAE,GAAG,EACZ,IAAI,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,EACxB,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,GAAG,CAAC;CAsClB"}
|
|
@@ -3,22 +3,40 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Authorize = void 0;
|
|
4
4
|
const Gate_1 = require("../Gate");
|
|
5
5
|
const AuthorizationException_1 = require("../Exceptions/AuthorizationException");
|
|
6
|
+
const RolePermission_1 = require("../RolePermission");
|
|
6
7
|
class Authorize {
|
|
7
8
|
/**
|
|
8
9
|
* Handle authorization middleware.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* .middleware('can:edit-post') → Gate check
|
|
13
|
+
* .middleware('can:update,post') → Policy check using req[resourceKey]
|
|
14
|
+
* .middleware('role:admin') → Role check
|
|
15
|
+
* .middleware('permission:edit-posts') → Permission check
|
|
14
16
|
*/
|
|
15
17
|
async handle(request, next, ability, resourceKey) {
|
|
16
|
-
const user = request.user;
|
|
18
|
+
const user = request.user || (request.auth && await request.auth.user());
|
|
17
19
|
if (!user) {
|
|
18
20
|
throw new AuthorizationException_1.AuthorizationException('User not authenticated.');
|
|
19
21
|
}
|
|
22
|
+
// Role-based check: 'role:admin' or 'role:admin,editor'
|
|
23
|
+
if (ability.startsWith('role:')) {
|
|
24
|
+
const roles = ability.substring(5).split(',');
|
|
25
|
+
if (!RolePermission_1.RolePermissionMixin.hasAnyRole(user, roles)) {
|
|
26
|
+
throw new AuthorizationException_1.AuthorizationException(`User does not have the required role.`);
|
|
27
|
+
}
|
|
28
|
+
return next();
|
|
29
|
+
}
|
|
30
|
+
// Permission-based check: 'permission:edit-posts'
|
|
31
|
+
if (ability.startsWith('permission:')) {
|
|
32
|
+
const permissions = ability.substring(11).split(',');
|
|
33
|
+
if (!RolePermission_1.RolePermissionMixin.hasAnyPermission(user, permissions)) {
|
|
34
|
+
throw new AuthorizationException_1.AuthorizationException(`User does not have the required permission.`);
|
|
35
|
+
}
|
|
36
|
+
return next();
|
|
37
|
+
}
|
|
38
|
+
// Standard gate/policy check
|
|
20
39
|
Gate_1.Gate.forUser(user);
|
|
21
|
-
// If resourceKey is provided, get resource from request
|
|
22
40
|
const resource = resourceKey ? request[resourceKey] : null;
|
|
23
41
|
if (resource) {
|
|
24
42
|
await Gate_1.Gate.authorize(ability, resource);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Authorize.js","sourceRoot":"","sources":["../../src/Middleware/Authorize.ts"],"names":[],"mappings":";;;AAAA,kCAA+B;AAC/B,iFAA8E;
|
|
1
|
+
{"version":3,"file":"Authorize.js","sourceRoot":"","sources":["../../src/Middleware/Authorize.ts"],"names":[],"mappings":";;;AAAA,kCAA+B;AAC/B,iFAA8E;AAC9E,sDAAwD;AAExD,MAAa,SAAS;IAClB;;;;;;;;OAQG;IACI,KAAK,CAAC,MAAM,CACf,OAAY,EACZ,IAAwB,EACxB,OAAe,EACf,WAAoB;QAEpB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAEzE,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,MAAM,IAAI,+CAAsB,CAAC,yBAAyB,CAAC,CAAC;QAChE,CAAC;QAED,wDAAwD;QACxD,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC9C,IAAI,CAAC,oCAAmB,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;gBAC/C,MAAM,IAAI,+CAAsB,CAAC,uCAAuC,CAAC,CAAC;YAC9E,CAAC;YACD,OAAO,IAAI,EAAE,CAAC;QAClB,CAAC;QAED,kDAAkD;QAClD,IAAI,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACpC,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACrD,IAAI,CAAC,oCAAmB,CAAC,gBAAgB,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;gBAC3D,MAAM,IAAI,+CAAsB,CAAC,6CAA6C,CAAC,CAAC;YACpF,CAAC;YACD,OAAO,IAAI,EAAE,CAAC;QAClB,CAAC;QAED,6BAA6B;QAC7B,WAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEnB,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE3D,IAAI,QAAQ,EAAE,CAAC;YACX,MAAM,WAAI,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACJ,MAAM,WAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;QAED,OAAO,IAAI,EAAE,CAAC;IAClB,CAAC;CACJ;AArDD,8BAqDC"}
|
package/dist/PolicyResolver.d.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
export declare class PolicyResolver {
|
|
2
2
|
private policies;
|
|
3
|
+
private instances;
|
|
3
4
|
/**
|
|
4
5
|
* Register a policy for a given model/class.
|
|
5
6
|
*/
|
|
6
7
|
register(model: any, policy: any): void;
|
|
7
8
|
/**
|
|
8
|
-
* Resolve the policy for a given resource.
|
|
9
|
+
* Resolve the policy class/constructor for a given resource.
|
|
9
10
|
*/
|
|
10
11
|
resolvePolicy(resource: any): any | null;
|
|
11
12
|
/**
|
|
12
|
-
* Get
|
|
13
|
+
* Get or create a cached instance for a policy class.
|
|
14
|
+
*/
|
|
15
|
+
getInstance(policy: any): any;
|
|
16
|
+
/**
|
|
17
|
+
* Get bound policy method for ability.
|
|
13
18
|
*/
|
|
14
19
|
getPolicyMethod(policy: any, ability: string): Function | null;
|
|
15
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PolicyResolver.d.ts","sourceRoot":"","sources":["../src/PolicyResolver.ts"],"names":[],"mappings":"AAEA,qBAAa,cAAc;IACvB,OAAO,CAAC,QAAQ,CAA4B;
|
|
1
|
+
{"version":3,"file":"PolicyResolver.d.ts","sourceRoot":"","sources":["../src/PolicyResolver.ts"],"names":[],"mappings":"AAEA,qBAAa,cAAc;IACvB,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,SAAS,CAA4B;IAE7C;;OAEG;IACI,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI;IAI9C;;OAEG;IACI,aAAa,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,IAAI;IA4B/C;;OAEG;IACI,WAAW,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG;IASpC;;OAEG;IACI,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;CAWxE"}
|
package/dist/PolicyResolver.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.PolicyResolver = void 0;
|
|
|
4
4
|
class PolicyResolver {
|
|
5
5
|
constructor() {
|
|
6
6
|
this.policies = new Map();
|
|
7
|
+
this.instances = new Map();
|
|
7
8
|
}
|
|
8
9
|
/**
|
|
9
10
|
* Register a policy for a given model/class.
|
|
@@ -12,12 +13,12 @@ class PolicyResolver {
|
|
|
12
13
|
this.policies.set(model, policy);
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
|
-
* Resolve the policy for a given resource.
|
|
16
|
+
* Resolve the policy class/constructor for a given resource.
|
|
16
17
|
*/
|
|
17
18
|
resolvePolicy(resource) {
|
|
18
19
|
if (!resource)
|
|
19
20
|
return null;
|
|
20
|
-
// Check
|
|
21
|
+
// Check by constructor
|
|
21
22
|
const constructor = resource.constructor;
|
|
22
23
|
if (constructor && this.policies.has(constructor)) {
|
|
23
24
|
return this.policies.get(constructor);
|
|
@@ -26,15 +27,36 @@ class PolicyResolver {
|
|
|
26
27
|
if (this.policies.has(resource)) {
|
|
27
28
|
return this.policies.get(resource);
|
|
28
29
|
}
|
|
30
|
+
// Auto-discovery by naming convention
|
|
31
|
+
if (constructor && constructor.name) {
|
|
32
|
+
const policyName = `${constructor.name}Policy`;
|
|
33
|
+
for (const [, policy] of this.policies) {
|
|
34
|
+
const pName = typeof policy === 'function' ? policy.name : policy.constructor?.name;
|
|
35
|
+
if (pName === policyName) {
|
|
36
|
+
return policy;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
29
40
|
return null;
|
|
30
41
|
}
|
|
31
42
|
/**
|
|
32
|
-
* Get
|
|
43
|
+
* Get or create a cached instance for a policy class.
|
|
44
|
+
*/
|
|
45
|
+
getInstance(policy) {
|
|
46
|
+
if (typeof policy !== 'function')
|
|
47
|
+
return policy;
|
|
48
|
+
if (!this.instances.has(policy)) {
|
|
49
|
+
this.instances.set(policy, new policy());
|
|
50
|
+
}
|
|
51
|
+
return this.instances.get(policy);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get bound policy method for ability.
|
|
33
55
|
*/
|
|
34
56
|
getPolicyMethod(policy, ability) {
|
|
35
57
|
if (!policy)
|
|
36
58
|
return null;
|
|
37
|
-
const instance =
|
|
59
|
+
const instance = this.getInstance(policy);
|
|
38
60
|
if (typeof instance[ability] === 'function') {
|
|
39
61
|
return instance[ability].bind(instance);
|
|
40
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PolicyResolver.js","sourceRoot":"","sources":["../src/PolicyResolver.ts"],"names":[],"mappings":";;;AAEA,MAAa,cAAc;IAA3B;QACY,aAAQ,GAAkB,IAAI,GAAG,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"PolicyResolver.js","sourceRoot":"","sources":["../src/PolicyResolver.ts"],"names":[],"mappings":";;;AAEA,MAAa,cAAc;IAA3B;QACY,aAAQ,GAAkB,IAAI,GAAG,EAAE,CAAC;QACpC,cAAS,GAAkB,IAAI,GAAG,EAAE,CAAC;IAkEjD,CAAC;IAhEG;;OAEG;IACI,QAAQ,CAAC,KAAU,EAAE,MAAW;QACnC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACI,aAAa,CAAC,QAAa;QAC9B,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE3B,uBAAuB;QACvB,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;QACzC,IAAI,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC1C,CAAC;QAED,gBAAgB;QAChB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;QAED,sCAAsC;QACtC,IAAI,WAAW,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,GAAG,WAAW,CAAC,IAAI,QAAQ,CAAC;YAC/C,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACrC,MAAM,KAAK,GAAG,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC;gBACpF,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;oBACvB,OAAO,MAAM,CAAC;gBAClB,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,WAAW,CAAC,MAAW;QAC1B,IAAI,OAAO,MAAM,KAAK,UAAU;YAAE,OAAO,MAAM,CAAC;QAEhD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACI,eAAe,CAAC,MAAW,EAAE,OAAe;QAC/C,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAEzB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE1C,IAAI,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,UAAU,EAAE,CAAC;YAC1C,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ;AApED,wCAoEC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contracts for entities that have roles and permissions.
|
|
3
|
+
*/
|
|
4
|
+
export interface HasRoles {
|
|
5
|
+
roles?: string[] | {
|
|
6
|
+
name: string;
|
|
7
|
+
}[];
|
|
8
|
+
hasRole(role: string | string[]): boolean;
|
|
9
|
+
hasAnyRole(roles: string[]): boolean;
|
|
10
|
+
hasAllRoles(roles: string[]): boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface HasPermissions {
|
|
13
|
+
permissions?: string[] | {
|
|
14
|
+
name: string;
|
|
15
|
+
}[];
|
|
16
|
+
hasPermission(permission: string): boolean;
|
|
17
|
+
hasAnyPermission(permissions: string[]): boolean;
|
|
18
|
+
hasAllPermissions(permissions: string[]): boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Mixin helper to add Role & Permission checking to any user object.
|
|
22
|
+
* Works with both string arrays and object arrays ({name: string}).
|
|
23
|
+
*/
|
|
24
|
+
export declare class RolePermissionMixin {
|
|
25
|
+
/**
|
|
26
|
+
* Normalize roles/permissions to string arrays.
|
|
27
|
+
*/
|
|
28
|
+
private static normalize;
|
|
29
|
+
static hasRole(user: any, role: string | string[]): boolean;
|
|
30
|
+
static hasAnyRole(user: any, roles: string[]): boolean;
|
|
31
|
+
static hasAllRoles(user: any, roles: string[]): boolean;
|
|
32
|
+
static hasPermission(user: any, permission: string): boolean;
|
|
33
|
+
static hasAnyPermission(user: any, permissions: string[]): boolean;
|
|
34
|
+
static hasAllPermissions(user: any, permissions: string[]): boolean;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=RolePermission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RolePermission.d.ts","sourceRoot":"","sources":["../src/RolePermission.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,QAAQ;IACrB,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;IAC1C,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACrC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;CACzC;AAED,MAAM,WAAW,cAAc;IAC3B,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3C,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACjD,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;CACrD;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAE5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;WAKV,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO;WAQpD,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO;WAK/C,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO;WAKhD,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;WAiBrD,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO;WAI3D,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO;CAG7E"}
|