@pcg/auth 1.0.0-alpha.0 → 1.0.0-alpha.2
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 +15 -15
- package/dist/functional-scopes-CsZNJMXW.js +96 -0
- package/dist/functional-scopes-CsZNJMXW.js.map +1 -0
- package/dist/functional-scopes-DygK315q.d.ts +133 -0
- package/dist/functional-scopes-DygK315q.d.ts.map +1 -0
- package/dist/index.d.ts +4 -56
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58 -55
- package/dist/index.js.map +1 -1
- package/dist/scopes.d.ts +2 -0
- package/dist/scopes.js +3 -0
- package/package.json +24 -2
- package/.turbo/turbo-build.log +0 -15
- package/src/index.ts +0 -4
- package/src/permissions/action-scopes.ts +0 -141
- package/src/permissions/helpers.ts +0 -304
- package/src/permissions/index.ts +0 -4
- package/src/permissions/scopes-bulder.ts +0 -99
- package/src/types/permissions.ts +0 -24
- package/src/types/user.ts +0 -33
- package/tests/permissions/__snapshots__/helpers.test.ts.snap +0 -43
- package/tests/permissions/action-scopes.test.ts +0 -111
- package/tests/permissions/helpers.test.ts +0 -169
- package/tests/permissions/helpers.ts +0 -10
- package/tests/permissions/permissions.test.ts +0 -218
- package/tests/permissions/scopes-bulder.test.ts +0 -80
- package/tsconfig.json +0 -9
- package/tsdown.config.ts +0 -11
- package/vitest.config.ts +0 -23
package/README.md
CHANGED
|
@@ -21,14 +21,14 @@ User object `user` must contain `resolvedPemissions` array with array of objects
|
|
|
21
21
|
|
|
22
22
|
```tsx
|
|
23
23
|
user.resolvedPermission = [
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
{
|
|
25
|
+
id: "js:episodes:get",
|
|
26
|
+
scopes: []
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "js:episodes:list",
|
|
30
|
+
scopes: ["published"]
|
|
31
|
+
}
|
|
32
32
|
],
|
|
33
33
|
|
|
34
34
|
```
|
|
@@ -37,8 +37,8 @@ But, is real life we store permissions in database as array of string, like this
|
|
|
37
37
|
|
|
38
38
|
```tsx
|
|
39
39
|
[
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
"js:episodes:get",
|
|
41
|
+
"js:episodes[@published]:list"
|
|
42
42
|
]
|
|
43
43
|
```
|
|
44
44
|
|
|
@@ -48,8 +48,8 @@ Library has special helper, to resolve permissions:
|
|
|
48
48
|
import { resolvePermissions } from '@deep/auth';
|
|
49
49
|
|
|
50
50
|
const permissions = [
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
"js:episodes:get",
|
|
52
|
+
"js:episodes[@published]:list"
|
|
53
53
|
]
|
|
54
54
|
|
|
55
55
|
user.resolvedPermission = resolvePermissions(permissions)
|
|
@@ -66,7 +66,7 @@ import { isGranted, PermissionContext } from '@deep/auth';
|
|
|
66
66
|
const ctx = new PermissionContext();
|
|
67
67
|
|
|
68
68
|
if (filter.published) {
|
|
69
|
-
|
|
69
|
+
ctx.addScope('published');
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
isGranted(user, 'js:episodes:list'); // boolean
|
|
@@ -77,8 +77,8 @@ Otherwise, we can build query based on user rights. In this case, we add system
|
|
|
77
77
|
```tsx
|
|
78
78
|
import { isGranted } from '@deep/auth'
|
|
79
79
|
if(isGranted(user, 'js:roles:get', { scopes: ['system'] })) {
|
|
80
|
-
|
|
80
|
+
where.or.push({
|
|
81
81
|
type: 'system'
|
|
82
82
|
})
|
|
83
83
|
}
|
|
84
|
-
```
|
|
84
|
+
```
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
//#region src/permissions/functional-scopes.ts
|
|
2
|
+
/**
|
|
3
|
+
* Create an ActionScopesArray from individual scope items.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* scopes(org('jsorg:hci'))
|
|
7
|
+
* // => ['org#jsorg:hci']
|
|
8
|
+
*
|
|
9
|
+
* scopes(org('jsorg:hci'), entityId('ep:123'))
|
|
10
|
+
* // => ['org#jsorg:hci', 'id#ep:123']
|
|
11
|
+
*
|
|
12
|
+
* const o = org('jsorg:hci');
|
|
13
|
+
* scopes(o, and(o, 'published'))
|
|
14
|
+
* // => ['org#jsorg:hci', ['org#jsorg:hci', 'published']]
|
|
15
|
+
*/
|
|
16
|
+
function scopes(...items) {
|
|
17
|
+
return items;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create a wildcard scope that matches any permission scope.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* isGranted(user, 'js:core:episodes:list', anyScope())
|
|
24
|
+
*/
|
|
25
|
+
function anyScope() {
|
|
26
|
+
return ["*"];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create an organization scope.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* org('jsorg:hci') // => 'org#jsorg:hci'
|
|
33
|
+
*/
|
|
34
|
+
function org(id$1) {
|
|
35
|
+
return `org#${id$1}`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create an entity id scope.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* id('ep:123') // => 'id#ep:123'
|
|
42
|
+
*/
|
|
43
|
+
function id(entityId) {
|
|
44
|
+
return `id#${entityId}`;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Create a user scope.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* user('hcu:xxx') // => 'user#hcu:xxx'
|
|
51
|
+
*/
|
|
52
|
+
function user(id$1) {
|
|
53
|
+
return `user#${id$1}`;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create a form scope.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* form('contact') // => 'form#contact'
|
|
60
|
+
*/
|
|
61
|
+
function form(id$1) {
|
|
62
|
+
return `form#${id$1}`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a group scope.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* group('hcgrp:ZT9') // => 'grp#hcgrp:ZT9'
|
|
69
|
+
*/
|
|
70
|
+
function group(id$1) {
|
|
71
|
+
return `grp#${id$1}`;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Create a named scope with an optional ID.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* scope('published') // => 'published'
|
|
78
|
+
* scope('orggroup', 'hcgrp:ZT9mt8j9lSR') // => 'orggroup#hcgrp:ZT9mt8j9lSR'
|
|
79
|
+
*/
|
|
80
|
+
function scope(name, id$1) {
|
|
81
|
+
return id$1 ? `${name}#${id$1}` : name;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Combine multiple scopes with AND logic (all must match).
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* and(org('jsorg:hci'), 'published')
|
|
88
|
+
* // => ['org#jsorg:hci', 'published']
|
|
89
|
+
*/
|
|
90
|
+
function and(...items) {
|
|
91
|
+
return items;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
//#endregion
|
|
95
|
+
export { id as a, scopes as c, group as i, user as l, anyScope as n, org as o, form as r, scope as s, and as t };
|
|
96
|
+
//# sourceMappingURL=functional-scopes-CsZNJMXW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functional-scopes-CsZNJMXW.js","names":["id"],"sources":["../src/permissions/functional-scopes.ts"],"sourcesContent":["import { type ActionScopesArray } from './action-scopes.js';\n\nexport type ScopeItem = string | string[];\n\n/**\n * Create an ActionScopesArray from individual scope items.\n *\n * @example\n * scopes(org('jsorg:hci'))\n * // => ['org#jsorg:hci']\n *\n * scopes(org('jsorg:hci'), entityId('ep:123'))\n * // => ['org#jsorg:hci', 'id#ep:123']\n *\n * const o = org('jsorg:hci');\n * scopes(o, and(o, 'published'))\n * // => ['org#jsorg:hci', ['org#jsorg:hci', 'published']]\n */\nexport function scopes(...items: ScopeItem[]): ActionScopesArray {\n return items;\n}\n\n/**\n * Create a wildcard scope that matches any permission scope.\n *\n * @example\n * isGranted(user, 'js:core:episodes:list', anyScope())\n */\nexport function anyScope(): ActionScopesArray {\n return ['*'];\n}\n\n/**\n * Create an organization scope.\n *\n * @example\n * org('jsorg:hci') // => 'org#jsorg:hci'\n */\nexport function org(id: string): string {\n return `org#${id}`;\n}\n\n/**\n * Create an entity id scope.\n *\n * @example\n * id('ep:123') // => 'id#ep:123'\n */\nexport function id(entityId: string): string {\n return `id#${entityId}`;\n}\n\n/**\n * Create a user scope.\n *\n * @example\n * user('hcu:xxx') // => 'user#hcu:xxx'\n */\nexport function user(id: string): string {\n return `user#${id}`;\n}\n\n/**\n * Create a form scope.\n *\n * @example\n * form('contact') // => 'form#contact'\n */\nexport function form(id: string): string {\n return `form#${id}`;\n}\n\n/**\n * Create a group scope.\n *\n * @example\n * group('hcgrp:ZT9') // => 'grp#hcgrp:ZT9'\n */\nexport function group(id: string): string {\n return `grp#${id}`;\n}\n\n/**\n * Create a named scope with an optional ID.\n *\n * @example\n * scope('published') // => 'published'\n * scope('orggroup', 'hcgrp:ZT9mt8j9lSR') // => 'orggroup#hcgrp:ZT9mt8j9lSR'\n */\nexport function scope(name: string, id?: string): string {\n return id ? `${name}#${id}` : name;\n}\n\n/**\n * Combine multiple scopes with AND logic (all must match).\n *\n * @example\n * and(org('jsorg:hci'), 'published')\n * // => ['org#jsorg:hci', 'published']\n */\nexport function and(...items: string[]): string[] {\n return items;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,SAAgB,OAAO,GAAG,OAAuC;AAC/D,QAAO;;;;;;;;AAST,SAAgB,WAA8B;AAC5C,QAAO,CAAC,IAAI;;;;;;;;AASd,SAAgB,IAAI,MAAoB;AACtC,QAAO,OAAOA;;;;;;;;AAShB,SAAgB,GAAG,UAA0B;AAC3C,QAAO,MAAM;;;;;;;;AASf,SAAgB,KAAK,MAAoB;AACvC,QAAO,QAAQA;;;;;;;;AASjB,SAAgB,KAAK,MAAoB;AACvC,QAAO,QAAQA;;;;;;;;AASjB,SAAgB,MAAM,MAAoB;AACxC,QAAO,OAAOA;;;;;;;;;AAUhB,SAAgB,MAAM,MAAc,MAAqB;AACvD,QAAOA,OAAK,GAAG,KAAK,GAAGA,SAAO;;;;;;;;;AAUhC,SAAgB,IAAI,GAAG,OAA2B;AAChD,QAAO"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
//#region src/permissions/action-scopes.d.ts
|
|
2
|
+
type ActionScopesArray = (string | string[])[];
|
|
3
|
+
/**
|
|
4
|
+
* Action scopes are used to describe
|
|
5
|
+
* what scopes are required to execute an action.
|
|
6
|
+
*/
|
|
7
|
+
declare class ActionScopes {
|
|
8
|
+
array: ActionScopesArray;
|
|
9
|
+
anyScope: boolean;
|
|
10
|
+
private idsMap;
|
|
11
|
+
constructor(scopes?: ActionScopesArray);
|
|
12
|
+
/**
|
|
13
|
+
* Set id scope (e.g. 'id#jsu:123')
|
|
14
|
+
* @param id - entity id
|
|
15
|
+
* @returns - this
|
|
16
|
+
* @example
|
|
17
|
+
* scopes.setEntityId('jsu:123')
|
|
18
|
+
*
|
|
19
|
+
* // scopes.getArray() = ['id#jsu:123']
|
|
20
|
+
*/
|
|
21
|
+
setEntityId(id: string): this;
|
|
22
|
+
/**
|
|
23
|
+
* Set scope (e.g. 'org', 'org+review')
|
|
24
|
+
* @param scope - scope name (e.g. 'org', 'org+review')
|
|
25
|
+
* @param id - entity id (e.g. 'jsorg:hci')
|
|
26
|
+
* @returns - this
|
|
27
|
+
* @example
|
|
28
|
+
* scopes.set('my')
|
|
29
|
+
*
|
|
30
|
+
* // scopes.getArray() = ['my']
|
|
31
|
+
*
|
|
32
|
+
* scopes.set('org', 'jsorg:hci')
|
|
33
|
+
*
|
|
34
|
+
* // scopes.getArray() = ['org#jsorg:hci']
|
|
35
|
+
*/
|
|
36
|
+
set(scope: string, id?: string): this;
|
|
37
|
+
has(scope: string): boolean;
|
|
38
|
+
getArray(): ActionScopesArray;
|
|
39
|
+
/**
|
|
40
|
+
* Permission scopes must cover auth scopes determined in auth context.
|
|
41
|
+
* @param permissionScopes
|
|
42
|
+
*/
|
|
43
|
+
canBeExecutedInScopes(permissionScopes: readonly (string | string[])[]): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Resolve presaved scopes
|
|
46
|
+
* @example
|
|
47
|
+
* authCtx.setScope('org', 'jsorg:hci')
|
|
48
|
+
* [org#hci]
|
|
49
|
+
*
|
|
50
|
+
* authCtx.setScope('org+review');
|
|
51
|
+
* [org#hci, [org#hci, review]]
|
|
52
|
+
**/
|
|
53
|
+
private resolveScopeId;
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/permissions/functional-scopes.d.ts
|
|
57
|
+
type ScopeItem = string | string[];
|
|
58
|
+
/**
|
|
59
|
+
* Create an ActionScopesArray from individual scope items.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* scopes(org('jsorg:hci'))
|
|
63
|
+
* // => ['org#jsorg:hci']
|
|
64
|
+
*
|
|
65
|
+
* scopes(org('jsorg:hci'), entityId('ep:123'))
|
|
66
|
+
* // => ['org#jsorg:hci', 'id#ep:123']
|
|
67
|
+
*
|
|
68
|
+
* const o = org('jsorg:hci');
|
|
69
|
+
* scopes(o, and(o, 'published'))
|
|
70
|
+
* // => ['org#jsorg:hci', ['org#jsorg:hci', 'published']]
|
|
71
|
+
*/
|
|
72
|
+
declare function scopes(...items: ScopeItem[]): ActionScopesArray;
|
|
73
|
+
/**
|
|
74
|
+
* Create a wildcard scope that matches any permission scope.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* isGranted(user, 'js:core:episodes:list', anyScope())
|
|
78
|
+
*/
|
|
79
|
+
declare function anyScope(): ActionScopesArray;
|
|
80
|
+
/**
|
|
81
|
+
* Create an organization scope.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* org('jsorg:hci') // => 'org#jsorg:hci'
|
|
85
|
+
*/
|
|
86
|
+
declare function org(id: string): string;
|
|
87
|
+
/**
|
|
88
|
+
* Create an entity id scope.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* id('ep:123') // => 'id#ep:123'
|
|
92
|
+
*/
|
|
93
|
+
declare function id(entityId: string): string;
|
|
94
|
+
/**
|
|
95
|
+
* Create a user scope.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* user('hcu:xxx') // => 'user#hcu:xxx'
|
|
99
|
+
*/
|
|
100
|
+
declare function user(id: string): string;
|
|
101
|
+
/**
|
|
102
|
+
* Create a form scope.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* form('contact') // => 'form#contact'
|
|
106
|
+
*/
|
|
107
|
+
declare function form(id: string): string;
|
|
108
|
+
/**
|
|
109
|
+
* Create a group scope.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* group('hcgrp:ZT9') // => 'grp#hcgrp:ZT9'
|
|
113
|
+
*/
|
|
114
|
+
declare function group(id: string): string;
|
|
115
|
+
/**
|
|
116
|
+
* Create a named scope with an optional ID.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* scope('published') // => 'published'
|
|
120
|
+
* scope('orggroup', 'hcgrp:ZT9mt8j9lSR') // => 'orggroup#hcgrp:ZT9mt8j9lSR'
|
|
121
|
+
*/
|
|
122
|
+
declare function scope(name: string, id?: string): string;
|
|
123
|
+
/**
|
|
124
|
+
* Combine multiple scopes with AND logic (all must match).
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* and(org('jsorg:hci'), 'published')
|
|
128
|
+
* // => ['org#jsorg:hci', 'published']
|
|
129
|
+
*/
|
|
130
|
+
declare function and(...items: string[]): string[];
|
|
131
|
+
//#endregion
|
|
132
|
+
export { group as a, scope as c, ActionScopes as d, ActionScopesArray as f, form as i, scopes as l, and as n, id as o, anyScope as r, org as s, ScopeItem as t, user as u };
|
|
133
|
+
//# sourceMappingURL=functional-scopes-DygK315q.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functional-scopes-DygK315q.d.ts","names":[],"sources":["../src/permissions/action-scopes.ts","../src/permissions/functional-scopes.ts"],"sourcesContent":[],"mappings":";KAAY,iBAAA;AAAZ;AAMA;;;AA6Dc,cA7DD,YAAA,CA6DC;EAAiB,KAAA,EA5Df,iBA4De;;;uBAxDR;ECTX;AAgBZ;AAUA;AAUA;AAUA;AAUA;AAUA;AAUA;AAWA;EAWgB,WAAG,CAAA,EAAA,EAAA,MAAA,CAAA,EAAA,IAAA;;;;;;;;;;;;;;;;;cDjCL;;;;;;;;;;;;;;;;;;;AAnEF,KCEA,SAAA,GDFiB,MAAA,GAAA,MAAA,EAAA;AAM7B;;;;;;;;ACJA;AAgBA;AAUA;AAUA;AAUA;AAUA;AAUgB,iBAlDA,MAAA,CAkDI,GAAA,KAAA,EAlDa,SAkDb,EAAA,CAAA,EAlD2B,iBAkD3B;AAUpB;AAWA;AAWA;;;;iBAxEgB,QAAA,CAAA,GAAY;;;;;;;iBAUZ,GAAA;;;;;;;iBAUA,EAAA;;;;;;;iBAUA,IAAA;;;;;;;iBAUA,IAAA;;;;;;;iBAUA,KAAA;;;;;;;;iBAWA,KAAA;;;;;;;;iBAWA,GAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,59 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Action scopes are used to describe
|
|
5
|
-
* what scopes are required to execute an action.
|
|
6
|
-
*/
|
|
7
|
-
declare class ActionScopes {
|
|
8
|
-
array: ActionScopesArray;
|
|
9
|
-
anyScope: boolean;
|
|
10
|
-
private idsMap;
|
|
11
|
-
constructor(scopes?: ActionScopesArray);
|
|
12
|
-
/**
|
|
13
|
-
* Set id scope (e.g. 'id#jsu:123')
|
|
14
|
-
* @param id - entity id
|
|
15
|
-
* @returns - this
|
|
16
|
-
* @example
|
|
17
|
-
* scopes.setEntityId('jsu:123')
|
|
18
|
-
*
|
|
19
|
-
* // scopes.getArray() = ['id#jsu:123']
|
|
20
|
-
*/
|
|
21
|
-
setEntityId(id: string): this;
|
|
22
|
-
/**
|
|
23
|
-
* Set scope (e.g. 'org', 'org+review')
|
|
24
|
-
* @param scope - scope name (e.g. 'org', 'org+review')
|
|
25
|
-
* @param id - entity id (e.g. 'jsorg:hci')
|
|
26
|
-
* @returns - this
|
|
27
|
-
* @example
|
|
28
|
-
* scopes.set('my')
|
|
29
|
-
*
|
|
30
|
-
* // scopes.getArray() = ['my']
|
|
31
|
-
*
|
|
32
|
-
* scopes.set('org', 'jsorg:hci')
|
|
33
|
-
*
|
|
34
|
-
* // scopes.getArray() = ['org#jsorg:hci']
|
|
35
|
-
*/
|
|
36
|
-
set(scope: string, id?: string): this;
|
|
37
|
-
has(scope: string): boolean;
|
|
38
|
-
getArray(): ActionScopesArray;
|
|
39
|
-
/**
|
|
40
|
-
* Permission scopes must cover auth scopes determined in auth context.
|
|
41
|
-
* @param permissionScopes
|
|
42
|
-
*/
|
|
43
|
-
canBeExecutedInScopes(permissionScopes: readonly (string | string[])[]): boolean;
|
|
44
|
-
/**
|
|
45
|
-
* Resolve presaved scopes
|
|
46
|
-
* @example
|
|
47
|
-
* authCtx.setScope('org', 'jsorg:hci')
|
|
48
|
-
* [org#hci]
|
|
49
|
-
*
|
|
50
|
-
* authCtx.setScope('org+review');
|
|
51
|
-
* [org#hci, [org#hci, review]]
|
|
52
|
-
**/
|
|
53
|
-
private resolveScopeId;
|
|
54
|
-
}
|
|
55
|
-
//#endregion
|
|
1
|
+
import { a as group, c as scope, d as ActionScopes, f as ActionScopesArray, i as form, l as scopes, n as and, o as id, r as anyScope, s as org, t as ScopeItem, u as user } from "./functional-scopes-DygK315q.js";
|
|
2
|
+
|
|
56
3
|
//#region src/types/permissions.d.ts
|
|
4
|
+
|
|
57
5
|
/**
|
|
58
6
|
* Resolved permission string to object with scopes
|
|
59
7
|
* @example
|
|
@@ -242,5 +190,5 @@ declare class ScopesBulder {
|
|
|
242
190
|
replacePrefix(from: string, to: string): void;
|
|
243
191
|
}
|
|
244
192
|
//#endregion
|
|
245
|
-
export { ActionScopes, ActionScopesArray, IUser, ReadonlyResolvedPermission, ResolvedPermission, ResolvedPermissionGroup, ScopesBulder, concatScopes, encodeScopes, injectScopesIntoPermission, isGranted, mergeResolvedPermissions, replaceScope, resolvePermission, resolvePermissionGroup, resolvePermissionGroups, resolvePermissions };
|
|
193
|
+
export { ActionScopes, ActionScopesArray, IUser, ReadonlyResolvedPermission, ResolvedPermission, ResolvedPermissionGroup, ScopeItem, ScopesBulder, and, anyScope, concatScopes, encodeScopes, form, group, id, injectScopesIntoPermission, isGranted, mergeResolvedPermissions, org, replaceScope, resolvePermission, resolvePermissionGroup, resolvePermissionGroups, resolvePermissions, scope, scopes, user };
|
|
246
194
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types/permissions.ts","../src/types/user.ts","../src/permissions/helpers.ts","../src/permissions/scopes-bulder.ts"],"sourcesContent":[],"mappings":";;;;;;;AAKA;AAUA;AAKiB,UAfA,kBAAA,CAe0B;;;;AClB3C;;;;ACoCA;AACQ,UFxBS,uBAAA,CEwBT;EAEQ,EAAA,EAAA,MAAA;EAAoB,MAAA,EAAA,CAAA,MAAA,GAAA,MAAA,EAAA,CAAA,EAAA;;AAgCvB,UFrDI,0BAAA,CE2DhB;EAWY,SAAA,EAAA,EAAA,MAAA;EAqBA,SAAA,MAqBZ,EAAA,SAAA,CAAA,MAAA,GAAA,MAAA,EAAA,CAAA,EAAA;AAUD;;;UD5IiB,KAAA;;ADGjB;AAUA;AAKA;;;;EClBiB,EAAA,EAAA,MAAK;;;;ACoCtB;;;;EAGqD,WAAA,EAAA,SAAA,MAAA,EAAA;EAgCxC;AAiBb;AAqBA;AA+BA;AAkCA;AAiCA;AAaA;AAOA;;;EAE8B,mBAAA,EDxMP,0BCwMO,EAAA;;;;AFlO9B;AAUA;AAKA;;;;AClBA;;;;ACoCA;;;;;AAmCa,cAnCA,SAyCZ,EAAA,CAAA,IAAA,EAxCO,KAwCP,EAAA,UAAA,EAAA,MAAA,EAAA,YAAA,CAAA,EAtCe,iBAsCf,GAtCmC,YAsCnC,EAAA,GAAA,OAAA;AAWY,cAjBA,YA4BZ,EAAA,CAAA,MAAA,EAAA,CAAA,MAAA,GAAA,MAAA,EAAA,CAAA,EAAA,EAAA,GAAA,MAAA;AAUD;AA+BA;AAkCA;AAiCA;AAaA;AAOA;;;;AAE8B,cA7IjB,0BA6IiB,EAAA,CAAA,UAAA,EAAA,MAAA,EAAA,cAAA,EAAA,CAAA,MAAA,GAAA,MAAA,EAAA,CAAA,EAAA,EAAA,GAAA,MAAA;AAmD9B;;;;ACxRA;;;;AAmCyC,cD0E5B,YC1E4B,EAAA,CAAA,GAAA,EAAA,CAAA,MAAA,GAAA,MAAA,EAAA,CAAA,EAAA,EAAA,KAAA,EAAA,CAAA,MAAA,GAAA,MAAA,EAAA,CAAA,EAAA,EAAA,GAAA,IAAA;;;;;;;;;cDyG5B,2CAA0C;;;;;;;;;cAkC1C,+CAEV;;;;;;;;;cA+BU,qDAAiD;;;;;;;;;cAajD,yDAEV;cAKU,mCACH,8BACA,yBAAoB;;;;;;;;;;;cAmDjB;;;;;cCxRA,YAAA;;;EHGI,OAAA,UAAA,CAAA,OAAkB,EGAN,YHAM,CAAA,EGAM,YHAN;EAUlB,KAAA,CAAA,CAAA,EAAA,CAAA,MAAA,GAAA,MAAA,EAAuB,CAAA,EAAA;EAKvB,KAAA,CAAA,CAAA,EGPV,YHOU;;;;AClBjB;;;;ACoCA;;EAGgB,MAAA,CAAA,KAAA,EAAA,MAAA,GAAA,MAAA,EAAA,CAAA,EAAA,IAAA;EAAoB;;AAgCpC;AAiBA;AAqBA;AA+BA;AAkCA;EAiCa,MAAA,CAAA,MAAA,EAAA,CAAA,MAAA,GAGZ,MAAA,EAAA,CAAA,EAAA,GC/KwC,YD4KqB,CAAA,EAAA,IAG7D;EAUY;AAOb;;;;;AAqDA;;;;ECxRa"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { a as id, c as scopes, i as group, l as user, n as anyScope, o as org, r as form, s as scope, t as and } from "./functional-scopes-CsZNJMXW.js";
|
|
2
|
+
|
|
1
3
|
//#region src/permissions/action-scopes.ts
|
|
2
4
|
/**
|
|
3
5
|
* Action scopes are used to describe
|
|
@@ -7,8 +9,8 @@ var ActionScopes = class {
|
|
|
7
9
|
array = [];
|
|
8
10
|
anyScope = false;
|
|
9
11
|
idsMap = /* @__PURE__ */ new Map();
|
|
10
|
-
constructor(scopes) {
|
|
11
|
-
if (scopes) this.array = scopes
|
|
12
|
+
constructor(scopes$1) {
|
|
13
|
+
if (scopes$1) this.array = scopes$1;
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
16
|
* Set id scope (e.g. 'id#jsu:123')
|
|
@@ -19,8 +21,8 @@ var ActionScopes = class {
|
|
|
19
21
|
*
|
|
20
22
|
* // scopes.getArray() = ['id#jsu:123']
|
|
21
23
|
*/
|
|
22
|
-
setEntityId(id) {
|
|
23
|
-
this.set(`id#${id}`);
|
|
24
|
+
setEntityId(id$1) {
|
|
25
|
+
this.set(`id#${id$1}`);
|
|
24
26
|
return this;
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
@@ -37,16 +39,16 @@ var ActionScopes = class {
|
|
|
37
39
|
*
|
|
38
40
|
* // scopes.getArray() = ['org#jsorg:hci']
|
|
39
41
|
*/
|
|
40
|
-
set(scope, id) {
|
|
41
|
-
if (id && /^[A-Za-z_]+$/.test(scope)) this.idsMap.set(scope, id);
|
|
42
|
-
if (scope.includes("+")) {
|
|
43
|
-
const subscopes = scope.split("+");
|
|
42
|
+
set(scope$1, id$1) {
|
|
43
|
+
if (id$1 && /^[A-Za-z_]+$/.test(scope$1)) this.idsMap.set(scope$1, id$1);
|
|
44
|
+
if (scope$1.includes("+")) {
|
|
45
|
+
const subscopes = scope$1.split("+");
|
|
44
46
|
this.array.push(subscopes.map((subscope) => this.resolveScopeId(subscope)));
|
|
45
|
-
} else this.array.push(this.resolveScopeId(scope));
|
|
47
|
+
} else this.array.push(this.resolveScopeId(scope$1));
|
|
46
48
|
return this;
|
|
47
49
|
}
|
|
48
|
-
has(scope) {
|
|
49
|
-
return this.array.includes(scope);
|
|
50
|
+
has(scope$1) {
|
|
51
|
+
return this.array.includes(scope$1);
|
|
50
52
|
}
|
|
51
53
|
getArray() {
|
|
52
54
|
return [...this.array];
|
|
@@ -86,8 +88,9 @@ var ActionScopes = class {
|
|
|
86
88
|
* authCtx.setScope('org+review');
|
|
87
89
|
* [org#hci, [org#hci, review]]
|
|
88
90
|
**/
|
|
89
|
-
resolveScopeId(scope) {
|
|
90
|
-
|
|
91
|
+
resolveScopeId(scope$1) {
|
|
92
|
+
const id$1 = this.idsMap.get(scope$1);
|
|
93
|
+
return id$1 !== void 0 ? `${scope$1}#${id$1}` : scope$1;
|
|
91
94
|
}
|
|
92
95
|
};
|
|
93
96
|
|
|
@@ -100,9 +103,9 @@ var ActionScopes = class {
|
|
|
100
103
|
*
|
|
101
104
|
* scopes.set('my')
|
|
102
105
|
*/
|
|
103
|
-
const normalizeScopes = (scopes) => {
|
|
104
|
-
if (!(scopes instanceof ActionScopes)) return new ActionScopes(scopes);
|
|
105
|
-
return scopes;
|
|
106
|
+
const normalizeScopes = (scopes$1) => {
|
|
107
|
+
if (!(scopes$1 instanceof ActionScopes)) return new ActionScopes(scopes$1);
|
|
108
|
+
return scopes$1;
|
|
106
109
|
};
|
|
107
110
|
/**
|
|
108
111
|
* Check if user has access to permission
|
|
@@ -119,18 +122,18 @@ const normalizeScopes = (scopes) => {
|
|
|
119
122
|
* @param actionScopes - action scopes (e.g. ['org#hcorg:hci'] or ActionScopes instance)
|
|
120
123
|
* @returns - true if user has access to permission
|
|
121
124
|
*/
|
|
122
|
-
const isGranted = (user, permission, actionScopes = []) => {
|
|
125
|
+
const isGranted = (user$1, permission, actionScopes = []) => {
|
|
123
126
|
const [service, module, resource, action] = permission.split(":");
|
|
124
|
-
if (
|
|
125
|
-
const userPermissions = user.resolvedPermissions;
|
|
126
|
-
const scopes = normalizeScopes(actionScopes);
|
|
127
|
-
const permissionCanBeExecutedInScopes = (perm, scopes$
|
|
127
|
+
if (user$1.resolvedPermissions.length === 0) return false;
|
|
128
|
+
const userPermissions = user$1.resolvedPermissions;
|
|
129
|
+
const scopes$1 = normalizeScopes(actionScopes);
|
|
130
|
+
const permissionCanBeExecutedInScopes = (perm, scopes$2) => perm.scopes.length === 0 || scopes$2.canBeExecutedInScopes(perm.scopes);
|
|
128
131
|
const regexp = /* @__PURE__ */ new RegExp(`^(${service}|\\*):(${module}|\\*):(${resource}|\\*):(${action}|\\*)$`);
|
|
129
|
-
if (userPermissions.some((perm) => regexp.test(perm.id) && permissionCanBeExecutedInScopes(perm, scopes))) return true;
|
|
132
|
+
if (userPermissions.some((perm) => regexp.test(perm.id) && permissionCanBeExecutedInScopes(perm, scopes$1))) return true;
|
|
130
133
|
return false;
|
|
131
134
|
};
|
|
132
|
-
const encodeScopes = (scopes) => {
|
|
133
|
-
const scopesString = scopes.map((s) => Array.isArray(s) ? s.join("+") : s).join(",");
|
|
135
|
+
const encodeScopes = (scopes$1) => {
|
|
136
|
+
const scopesString = scopes$1.map((s) => Array.isArray(s) ? s.join("+") : s).join(",");
|
|
134
137
|
return scopesString.length > 0 ? `[${scopesString}]` : "";
|
|
135
138
|
};
|
|
136
139
|
/**
|
|
@@ -143,10 +146,10 @@ const encodeScopes = (scopes) => {
|
|
|
143
146
|
* // js:core:episodes[org,published]:get
|
|
144
147
|
*/
|
|
145
148
|
const injectScopesIntoPermission = (permission, scopesToInject) => {
|
|
146
|
-
const { id, scopes
|
|
147
|
-
const [service, module, resource, action] = id.split(":");
|
|
148
|
-
concatScopes(scopes, scopesToInject);
|
|
149
|
-
return `${service}:${module}:${resource}${encodeScopes(scopes)}:${action}`;
|
|
149
|
+
const { id: id$1, scopes: scopes$1 } = resolvePermission(permission);
|
|
150
|
+
const [service, module, resource, action] = id$1.split(":");
|
|
151
|
+
concatScopes(scopes$1, scopesToInject);
|
|
152
|
+
return `${service}:${module}:${resource}${encodeScopes(scopes$1)}:${action}`;
|
|
150
153
|
};
|
|
151
154
|
/**
|
|
152
155
|
* Concat scopes
|
|
@@ -158,7 +161,7 @@ const injectScopesIntoPermission = (permission, scopesToInject) => {
|
|
|
158
161
|
*/
|
|
159
162
|
const concatScopes = (set, items) => {
|
|
160
163
|
for (const item of items) if (Array.isArray(item)) {
|
|
161
|
-
if (!set.some((scope) => Array.isArray(scope) && scope.length === item.length && scope.every((s) => item.includes(s)))) set.push(item);
|
|
164
|
+
if (!set.some((scope$1) => Array.isArray(scope$1) && scope$1.length === item.length && scope$1.every((s) => item.includes(s)))) set.push(item);
|
|
162
165
|
} else if (!set.includes(item)) set.push(item);
|
|
163
166
|
};
|
|
164
167
|
/**
|
|
@@ -172,13 +175,13 @@ const concatScopes = (set, items) => {
|
|
|
172
175
|
const resolvePermission = (permission) => {
|
|
173
176
|
const matches = /\[(?<scopes>.*?)\]/u.exec(permission);
|
|
174
177
|
if (matches?.[0] && matches.groups?.scopes) {
|
|
175
|
-
const scopes =
|
|
178
|
+
const scopes$1 = matches.groups.scopes.split(",").map((s) => {
|
|
176
179
|
if (s.includes("+")) return s.split("+");
|
|
177
180
|
return s;
|
|
178
181
|
});
|
|
179
182
|
return {
|
|
180
183
|
id: permission.replace(matches[0], ""),
|
|
181
|
-
scopes
|
|
184
|
+
scopes: scopes$1
|
|
182
185
|
};
|
|
183
186
|
}
|
|
184
187
|
return {
|
|
@@ -197,12 +200,12 @@ const resolvePermission = (permission) => {
|
|
|
197
200
|
const resolvePermissions = (permissions) => {
|
|
198
201
|
const resolvedPermissions = [];
|
|
199
202
|
for (const permission of permissions) {
|
|
200
|
-
const { id, scopes } = resolvePermission(permission);
|
|
201
|
-
const currentPermission = resolvedPermissions.find((p) => p.id === id);
|
|
202
|
-
if (currentPermission) concatScopes(currentPermission.scopes, scopes);
|
|
203
|
+
const { id: id$1, scopes: scopes$1 } = resolvePermission(permission);
|
|
204
|
+
const currentPermission = resolvedPermissions.find((p) => p.id === id$1);
|
|
205
|
+
if (currentPermission) concatScopes(currentPermission.scopes, scopes$1);
|
|
203
206
|
else resolvedPermissions.push({
|
|
204
|
-
id,
|
|
205
|
-
scopes
|
|
207
|
+
id: id$1,
|
|
208
|
+
scopes: scopes$1
|
|
206
209
|
});
|
|
207
210
|
}
|
|
208
211
|
return resolvedPermissions;
|
|
@@ -240,11 +243,11 @@ const mergeResolvedPermissions = (array1, array2) => {
|
|
|
240
243
|
});
|
|
241
244
|
continue;
|
|
242
245
|
}
|
|
243
|
-
const scopes = [...rp1.scopes];
|
|
244
|
-
for (const rp2 of rps2) concatScopes(scopes, rp2.scopes);
|
|
246
|
+
const scopes$1 = [...rp1.scopes];
|
|
247
|
+
for (const rp2 of rps2) concatScopes(scopes$1, rp2.scopes);
|
|
245
248
|
result.push({
|
|
246
249
|
id: rp1.id,
|
|
247
|
-
scopes
|
|
250
|
+
scopes: scopes$1
|
|
248
251
|
});
|
|
249
252
|
}
|
|
250
253
|
for (const rp2 of array2) if (!result.some((rp) => rp.id === rp2.id)) result.push(rp2);
|
|
@@ -260,20 +263,20 @@ const mergeResolvedPermissions = (array1, array2) => {
|
|
|
260
263
|
* replaceScope(['org#jsorg:xxx', ['org#jsorg:xxx', 'published']], 'org#jsorg:xxx', 'org#jsorg:hci')
|
|
261
264
|
* // ['org#jsorg:hci', ['org#jsorg:hci', 'published']]
|
|
262
265
|
*/
|
|
263
|
-
const replaceScope = (scopes, from, to) => {
|
|
266
|
+
const replaceScope = (scopes$1, from, to) => {
|
|
264
267
|
const result = [];
|
|
265
|
-
for (const scope of scopes) if (Array.isArray(scope)) result.push(replaceScope(scope, from, to));
|
|
266
|
-
else if (scope === from) if (Array.isArray(to)) result.push(...to);
|
|
268
|
+
for (const scope$1 of scopes$1) if (Array.isArray(scope$1)) result.push(replaceScope(scope$1, from, to));
|
|
269
|
+
else if (scope$1 === from) if (Array.isArray(to)) result.push(...to);
|
|
267
270
|
else result.push(to);
|
|
268
|
-
else result.push(scope);
|
|
271
|
+
else result.push(scope$1);
|
|
269
272
|
return result;
|
|
270
273
|
};
|
|
271
274
|
|
|
272
275
|
//#endregion
|
|
273
276
|
//#region src/permissions/scopes-bulder.ts
|
|
274
277
|
var ScopesBulder = class ScopesBulder {
|
|
275
|
-
constructor(scopes = []) {
|
|
276
|
-
this.scopes = scopes;
|
|
278
|
+
constructor(scopes$1 = []) {
|
|
279
|
+
this.scopes = scopes$1;
|
|
277
280
|
}
|
|
278
281
|
static fromBulder(builder) {
|
|
279
282
|
return new ScopesBulder(builder.scopes.slice());
|
|
@@ -293,8 +296,8 @@ var ScopesBulder = class ScopesBulder {
|
|
|
293
296
|
* append(['org#hci', 'lang#en])
|
|
294
297
|
* // ['org#xxx'] => ['org#xxx', ['org#hci', 'lang#en']]
|
|
295
298
|
*/
|
|
296
|
-
append(scope) {
|
|
297
|
-
this.scopes.push(scope);
|
|
299
|
+
append(scope$1) {
|
|
300
|
+
this.scopes.push(scope$1);
|
|
298
301
|
}
|
|
299
302
|
/**
|
|
300
303
|
* Extend current scopes with the given scopes
|
|
@@ -303,9 +306,9 @@ var ScopesBulder = class ScopesBulder {
|
|
|
303
306
|
* extend(['lang#en', 'lang#de'])
|
|
304
307
|
* // ['published', 'draft'] => ['published', 'draft', 'lang#en', 'lang#de']
|
|
305
308
|
*/
|
|
306
|
-
extend(scopes) {
|
|
307
|
-
if (Array.isArray(scopes)) concatScopes(this.scopes, scopes);
|
|
308
|
-
else if (scopes instanceof ScopesBulder) concatScopes(this.scopes, scopes.scopes);
|
|
309
|
+
extend(scopes$1) {
|
|
310
|
+
if (Array.isArray(scopes$1)) concatScopes(this.scopes, scopes$1);
|
|
311
|
+
else if (scopes$1 instanceof ScopesBulder) concatScopes(this.scopes, scopes$1.scopes);
|
|
309
312
|
}
|
|
310
313
|
/**
|
|
311
314
|
* Join all scopes with the given scope
|
|
@@ -321,8 +324,8 @@ var ScopesBulder = class ScopesBulder {
|
|
|
321
324
|
const scopesToJoin = Array.isArray(scopeOrScopes) ? scopeOrScopes : [scopeOrScopes];
|
|
322
325
|
if (scopesToJoin.length === 0) return;
|
|
323
326
|
const currentScopesCopy = this.build();
|
|
324
|
-
for (const scope of scopesToJoin) {
|
|
325
|
-
const scopeToJoin = Array.isArray(scope) ? scope : [scope];
|
|
327
|
+
for (const scope$1 of scopesToJoin) {
|
|
328
|
+
const scopeToJoin = Array.isArray(scope$1) ? scope$1 : [scope$1];
|
|
326
329
|
for (const s of currentScopesCopy) if (Array.isArray(s)) result.push(pos === "before" ? [...scopeToJoin, ...s] : [...s, ...scopeToJoin]);
|
|
327
330
|
else result.push(pos === "before" ? [...scopeToJoin, s] : [s, ...scopeToJoin]);
|
|
328
331
|
}
|
|
@@ -338,12 +341,12 @@ var ScopesBulder = class ScopesBulder {
|
|
|
338
341
|
*/
|
|
339
342
|
replacePrefix(from, to) {
|
|
340
343
|
const result = [];
|
|
341
|
-
for (const scope of this.scopes) if (Array.isArray(scope)) result.push(scope.map((s) => s.replace(`${from}#`, `${to}#`)));
|
|
342
|
-
else result.push(scope.replace(`${from}#`, `${to}#`));
|
|
344
|
+
for (const scope$1 of this.scopes) if (Array.isArray(scope$1)) result.push(scope$1.map((s) => s.replace(`${from}#`, `${to}#`)));
|
|
345
|
+
else result.push(scope$1.replace(`${from}#`, `${to}#`));
|
|
343
346
|
this.scopes = result;
|
|
344
347
|
}
|
|
345
348
|
};
|
|
346
349
|
|
|
347
350
|
//#endregion
|
|
348
|
-
export { ActionScopes, ScopesBulder, concatScopes, encodeScopes, injectScopesIntoPermission, isGranted, mergeResolvedPermissions, replaceScope, resolvePermission, resolvePermissionGroup, resolvePermissionGroups, resolvePermissions };
|
|
351
|
+
export { ActionScopes, ScopesBulder, and, anyScope, concatScopes, encodeScopes, form, group, id, injectScopesIntoPermission, isGranted, mergeResolvedPermissions, org, replaceScope, resolvePermission, resolvePermissionGroup, resolvePermissionGroups, resolvePermissions, scope, scopes, user };
|
|
349
352
|
//# sourceMappingURL=index.js.map
|