@contractspec/lib.identity-rbac 1.56.1 → 1.58.0
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/dist/browser/contracts/index.js +1045 -0
- package/dist/browser/contracts/organization.js +655 -0
- package/dist/browser/contracts/rbac.js +599 -0
- package/dist/browser/contracts/user.js +235 -0
- package/dist/browser/entities/index.js +464 -0
- package/dist/browser/entities/organization.js +150 -0
- package/dist/browser/entities/rbac.js +124 -0
- package/dist/browser/entities/user.js +168 -0
- package/dist/browser/events.js +374 -0
- package/dist/browser/identity-rbac.capability.js +28 -0
- package/dist/browser/identity-rbac.feature.js +67 -0
- package/dist/browser/index.js +2099 -0
- package/dist/browser/policies/engine.js +154 -0
- package/dist/browser/policies/index.js +154 -0
- package/dist/contracts/index.d.ts +4 -4
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +1045 -4
- package/dist/contracts/organization.d.ts +758 -764
- package/dist/contracts/organization.d.ts.map +1 -1
- package/dist/contracts/organization.js +653 -602
- package/dist/contracts/rbac.d.ts +517 -523
- package/dist/contracts/rbac.d.ts.map +1 -1
- package/dist/contracts/rbac.js +597 -481
- package/dist/contracts/user.d.ts +513 -519
- package/dist/contracts/user.d.ts.map +1 -1
- package/dist/contracts/user.js +222 -319
- package/dist/entities/index.d.ts +164 -169
- package/dist/entities/index.d.ts.map +1 -1
- package/dist/entities/index.js +462 -33
- package/dist/entities/organization.d.ts +58 -63
- package/dist/entities/organization.d.ts.map +1 -1
- package/dist/entities/organization.js +145 -145
- package/dist/entities/rbac.d.ts +62 -67
- package/dist/entities/rbac.d.ts.map +1 -1
- package/dist/entities/rbac.js +119 -132
- package/dist/entities/user.d.ts +66 -71
- package/dist/entities/user.d.ts.map +1 -1
- package/dist/entities/user.js +164 -189
- package/dist/events.d.ts +537 -543
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +343 -651
- package/dist/identity-rbac.capability.d.ts +2 -7
- package/dist/identity-rbac.capability.d.ts.map +1 -1
- package/dist/identity-rbac.capability.js +29 -29
- package/dist/identity-rbac.feature.d.ts +1 -7
- package/dist/identity-rbac.feature.d.ts.map +1 -1
- package/dist/identity-rbac.feature.js +66 -193
- package/dist/index.d.ts +6 -12
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2100 -14
- package/dist/node/contracts/index.js +1045 -0
- package/dist/node/contracts/organization.js +655 -0
- package/dist/node/contracts/rbac.js +599 -0
- package/dist/node/contracts/user.js +235 -0
- package/dist/node/entities/index.js +464 -0
- package/dist/node/entities/organization.js +150 -0
- package/dist/node/entities/rbac.js +124 -0
- package/dist/node/entities/user.js +168 -0
- package/dist/node/events.js +374 -0
- package/dist/node/identity-rbac.capability.js +28 -0
- package/dist/node/identity-rbac.feature.js +67 -0
- package/dist/node/index.js +2099 -0
- package/dist/node/policies/engine.js +154 -0
- package/dist/node/policies/index.js +154 -0
- package/dist/policies/engine.d.ts +98 -101
- package/dist/policies/engine.d.ts.map +1 -1
- package/dist/policies/engine.js +151 -164
- package/dist/policies/index.d.ts +2 -2
- package/dist/policies/index.d.ts.map +1 -0
- package/dist/policies/index.js +154 -2
- package/package.json +149 -40
- package/dist/contracts/organization.js.map +0 -1
- package/dist/contracts/rbac.js.map +0 -1
- package/dist/contracts/user.js.map +0 -1
- package/dist/entities/index.js.map +0 -1
- package/dist/entities/organization.js.map +0 -1
- package/dist/entities/rbac.js.map +0 -1
- package/dist/entities/user.js.map +0 -1
- package/dist/events.js.map +0 -1
- package/dist/identity-rbac.capability.js.map +0 -1
- package/dist/identity-rbac.feature.js.map +0 -1
- package/dist/policies/engine.js.map +0 -1
package/dist/policies/engine.js
CHANGED
|
@@ -1,168 +1,155 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
ADMIN_ACCESS: "admin.access",
|
|
39
|
-
ADMIN_IMPERSONATE: "admin.impersonate"
|
|
1
|
+
// @bun
|
|
2
|
+
// src/policies/engine.ts
|
|
3
|
+
var Permission = {
|
|
4
|
+
USER_CREATE: "user.create",
|
|
5
|
+
USER_READ: "user.read",
|
|
6
|
+
USER_UPDATE: "user.update",
|
|
7
|
+
USER_DELETE: "user.delete",
|
|
8
|
+
USER_LIST: "user.list",
|
|
9
|
+
USER_MANAGE: "user.manage",
|
|
10
|
+
ORG_CREATE: "org.create",
|
|
11
|
+
ORG_READ: "org.read",
|
|
12
|
+
ORG_UPDATE: "org.update",
|
|
13
|
+
ORG_DELETE: "org.delete",
|
|
14
|
+
ORG_LIST: "org.list",
|
|
15
|
+
MEMBER_INVITE: "member.invite",
|
|
16
|
+
MEMBER_REMOVE: "member.remove",
|
|
17
|
+
MEMBER_UPDATE_ROLE: "member.update_role",
|
|
18
|
+
MEMBER_LIST: "member.list",
|
|
19
|
+
MANAGE_MEMBERS: "org.manage_members",
|
|
20
|
+
TEAM_CREATE: "team.create",
|
|
21
|
+
TEAM_UPDATE: "team.update",
|
|
22
|
+
TEAM_DELETE: "team.delete",
|
|
23
|
+
TEAM_MANAGE: "team.manage",
|
|
24
|
+
ROLE_CREATE: "role.create",
|
|
25
|
+
ROLE_UPDATE: "role.update",
|
|
26
|
+
ROLE_DELETE: "role.delete",
|
|
27
|
+
ROLE_ASSIGN: "role.assign",
|
|
28
|
+
ROLE_REVOKE: "role.revoke",
|
|
29
|
+
BILLING_VIEW: "billing.view",
|
|
30
|
+
BILLING_MANAGE: "billing.manage",
|
|
31
|
+
PROJECT_CREATE: "project.create",
|
|
32
|
+
PROJECT_READ: "project.read",
|
|
33
|
+
PROJECT_UPDATE: "project.update",
|
|
34
|
+
PROJECT_DELETE: "project.delete",
|
|
35
|
+
PROJECT_MANAGE: "project.manage",
|
|
36
|
+
ADMIN_ACCESS: "admin.access",
|
|
37
|
+
ADMIN_IMPERSONATE: "admin.impersonate"
|
|
40
38
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
Permission.PROJECT_READ
|
|
94
|
-
]
|
|
95
|
-
}
|
|
39
|
+
var StandardRole = {
|
|
40
|
+
OWNER: {
|
|
41
|
+
name: "owner",
|
|
42
|
+
description: "Organization owner with full access",
|
|
43
|
+
permissions: Object.values(Permission)
|
|
44
|
+
},
|
|
45
|
+
ADMIN: {
|
|
46
|
+
name: "admin",
|
|
47
|
+
description: "Administrator with most permissions",
|
|
48
|
+
permissions: [
|
|
49
|
+
Permission.USER_READ,
|
|
50
|
+
Permission.USER_LIST,
|
|
51
|
+
Permission.ORG_READ,
|
|
52
|
+
Permission.ORG_UPDATE,
|
|
53
|
+
Permission.MEMBER_INVITE,
|
|
54
|
+
Permission.MEMBER_REMOVE,
|
|
55
|
+
Permission.MEMBER_UPDATE_ROLE,
|
|
56
|
+
Permission.MEMBER_LIST,
|
|
57
|
+
Permission.MANAGE_MEMBERS,
|
|
58
|
+
Permission.TEAM_CREATE,
|
|
59
|
+
Permission.TEAM_UPDATE,
|
|
60
|
+
Permission.TEAM_DELETE,
|
|
61
|
+
Permission.TEAM_MANAGE,
|
|
62
|
+
Permission.PROJECT_CREATE,
|
|
63
|
+
Permission.PROJECT_READ,
|
|
64
|
+
Permission.PROJECT_UPDATE,
|
|
65
|
+
Permission.PROJECT_DELETE,
|
|
66
|
+
Permission.PROJECT_MANAGE,
|
|
67
|
+
Permission.BILLING_VIEW
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
MEMBER: {
|
|
71
|
+
name: "member",
|
|
72
|
+
description: "Regular organization member",
|
|
73
|
+
permissions: [
|
|
74
|
+
Permission.USER_READ,
|
|
75
|
+
Permission.ORG_READ,
|
|
76
|
+
Permission.MEMBER_LIST,
|
|
77
|
+
Permission.PROJECT_READ,
|
|
78
|
+
Permission.PROJECT_CREATE
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
VIEWER: {
|
|
82
|
+
name: "viewer",
|
|
83
|
+
description: "Read-only access",
|
|
84
|
+
permissions: [
|
|
85
|
+
Permission.USER_READ,
|
|
86
|
+
Permission.ORG_READ,
|
|
87
|
+
Permission.MEMBER_LIST,
|
|
88
|
+
Permission.PROJECT_READ
|
|
89
|
+
]
|
|
90
|
+
}
|
|
96
91
|
};
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
* Check if user has all of the specified permissions.
|
|
153
|
-
*/
|
|
154
|
-
async hasAllPermissions(userId, orgId, permissions, bindings) {
|
|
155
|
-
const { permissions: userPerms } = await this.getPermissions(userId, orgId, bindings);
|
|
156
|
-
return permissions.every((p) => userPerms.has(p));
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
/**
|
|
160
|
-
* Create a new RBAC policy engine instance.
|
|
161
|
-
*/
|
|
92
|
+
|
|
93
|
+
class RBACPolicyEngine {
|
|
94
|
+
roleCache = new Map;
|
|
95
|
+
bindingCache = new Map;
|
|
96
|
+
async checkPermission(input, bindings) {
|
|
97
|
+
const { userId, orgId, permission } = input;
|
|
98
|
+
const now = new Date;
|
|
99
|
+
const userBindings = bindings.filter((b) => b.targetType === "user" && b.targetId === userId);
|
|
100
|
+
const orgBindings = orgId ? bindings.filter((b) => b.targetType === "organization" && b.targetId === orgId) : [];
|
|
101
|
+
const allBindings = [...userBindings, ...orgBindings];
|
|
102
|
+
const activeBindings = allBindings.filter((b) => !b.expiresAt || b.expiresAt > now);
|
|
103
|
+
if (activeBindings.length === 0) {
|
|
104
|
+
return {
|
|
105
|
+
allowed: false,
|
|
106
|
+
reason: "No active role bindings found"
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
for (const binding of activeBindings) {
|
|
110
|
+
if (binding.role.permissions.includes(permission)) {
|
|
111
|
+
return {
|
|
112
|
+
allowed: true,
|
|
113
|
+
matchedRole: binding.role.name
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
allowed: false,
|
|
119
|
+
reason: `No role grants the "${permission}" permission`
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
async getPermissions(userId, orgId, bindings) {
|
|
123
|
+
const now = new Date;
|
|
124
|
+
const userBindings = bindings.filter((b) => b.targetType === "user" && b.targetId === userId);
|
|
125
|
+
const orgBindings = orgId ? bindings.filter((b) => b.targetType === "organization" && b.targetId === orgId) : [];
|
|
126
|
+
const allBindings = [...userBindings, ...orgBindings];
|
|
127
|
+
const activeBindings = allBindings.filter((b) => !b.expiresAt || b.expiresAt > now);
|
|
128
|
+
const permissions = new Set;
|
|
129
|
+
const roles = [];
|
|
130
|
+
for (const binding of activeBindings) {
|
|
131
|
+
roles.push(binding.role);
|
|
132
|
+
for (const perm of binding.role.permissions) {
|
|
133
|
+
permissions.add(perm);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return { permissions, roles };
|
|
137
|
+
}
|
|
138
|
+
async hasAnyPermission(userId, orgId, permissions, bindings) {
|
|
139
|
+
const { permissions: userPerms } = await this.getPermissions(userId, orgId, bindings);
|
|
140
|
+
return permissions.some((p) => userPerms.has(p));
|
|
141
|
+
}
|
|
142
|
+
async hasAllPermissions(userId, orgId, permissions, bindings) {
|
|
143
|
+
const { permissions: userPerms } = await this.getPermissions(userId, orgId, bindings);
|
|
144
|
+
return permissions.every((p) => userPerms.has(p));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
162
147
|
function createRBACEngine() {
|
|
163
|
-
|
|
148
|
+
return new RBACPolicyEngine;
|
|
164
149
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
150
|
+
export {
|
|
151
|
+
createRBACEngine,
|
|
152
|
+
StandardRole,
|
|
153
|
+
RBACPolicyEngine,
|
|
154
|
+
Permission
|
|
155
|
+
};
|
package/dist/policies/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export { Permission, StandardRole, RBACPolicyEngine, createRBACEngine, type PermissionKey, type PermissionCheckInput, type PermissionCheckResult, type RoleWithPermissions, type PolicyBindingForEval, } from './engine';
|
|
2
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/policies/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,UAAU,CAAC"}
|
package/dist/policies/index.js
CHANGED
|
@@ -1,3 +1,155 @@
|
|
|
1
|
-
|
|
1
|
+
// @bun
|
|
2
|
+
// src/policies/engine.ts
|
|
3
|
+
var Permission = {
|
|
4
|
+
USER_CREATE: "user.create",
|
|
5
|
+
USER_READ: "user.read",
|
|
6
|
+
USER_UPDATE: "user.update",
|
|
7
|
+
USER_DELETE: "user.delete",
|
|
8
|
+
USER_LIST: "user.list",
|
|
9
|
+
USER_MANAGE: "user.manage",
|
|
10
|
+
ORG_CREATE: "org.create",
|
|
11
|
+
ORG_READ: "org.read",
|
|
12
|
+
ORG_UPDATE: "org.update",
|
|
13
|
+
ORG_DELETE: "org.delete",
|
|
14
|
+
ORG_LIST: "org.list",
|
|
15
|
+
MEMBER_INVITE: "member.invite",
|
|
16
|
+
MEMBER_REMOVE: "member.remove",
|
|
17
|
+
MEMBER_UPDATE_ROLE: "member.update_role",
|
|
18
|
+
MEMBER_LIST: "member.list",
|
|
19
|
+
MANAGE_MEMBERS: "org.manage_members",
|
|
20
|
+
TEAM_CREATE: "team.create",
|
|
21
|
+
TEAM_UPDATE: "team.update",
|
|
22
|
+
TEAM_DELETE: "team.delete",
|
|
23
|
+
TEAM_MANAGE: "team.manage",
|
|
24
|
+
ROLE_CREATE: "role.create",
|
|
25
|
+
ROLE_UPDATE: "role.update",
|
|
26
|
+
ROLE_DELETE: "role.delete",
|
|
27
|
+
ROLE_ASSIGN: "role.assign",
|
|
28
|
+
ROLE_REVOKE: "role.revoke",
|
|
29
|
+
BILLING_VIEW: "billing.view",
|
|
30
|
+
BILLING_MANAGE: "billing.manage",
|
|
31
|
+
PROJECT_CREATE: "project.create",
|
|
32
|
+
PROJECT_READ: "project.read",
|
|
33
|
+
PROJECT_UPDATE: "project.update",
|
|
34
|
+
PROJECT_DELETE: "project.delete",
|
|
35
|
+
PROJECT_MANAGE: "project.manage",
|
|
36
|
+
ADMIN_ACCESS: "admin.access",
|
|
37
|
+
ADMIN_IMPERSONATE: "admin.impersonate"
|
|
38
|
+
};
|
|
39
|
+
var StandardRole = {
|
|
40
|
+
OWNER: {
|
|
41
|
+
name: "owner",
|
|
42
|
+
description: "Organization owner with full access",
|
|
43
|
+
permissions: Object.values(Permission)
|
|
44
|
+
},
|
|
45
|
+
ADMIN: {
|
|
46
|
+
name: "admin",
|
|
47
|
+
description: "Administrator with most permissions",
|
|
48
|
+
permissions: [
|
|
49
|
+
Permission.USER_READ,
|
|
50
|
+
Permission.USER_LIST,
|
|
51
|
+
Permission.ORG_READ,
|
|
52
|
+
Permission.ORG_UPDATE,
|
|
53
|
+
Permission.MEMBER_INVITE,
|
|
54
|
+
Permission.MEMBER_REMOVE,
|
|
55
|
+
Permission.MEMBER_UPDATE_ROLE,
|
|
56
|
+
Permission.MEMBER_LIST,
|
|
57
|
+
Permission.MANAGE_MEMBERS,
|
|
58
|
+
Permission.TEAM_CREATE,
|
|
59
|
+
Permission.TEAM_UPDATE,
|
|
60
|
+
Permission.TEAM_DELETE,
|
|
61
|
+
Permission.TEAM_MANAGE,
|
|
62
|
+
Permission.PROJECT_CREATE,
|
|
63
|
+
Permission.PROJECT_READ,
|
|
64
|
+
Permission.PROJECT_UPDATE,
|
|
65
|
+
Permission.PROJECT_DELETE,
|
|
66
|
+
Permission.PROJECT_MANAGE,
|
|
67
|
+
Permission.BILLING_VIEW
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
MEMBER: {
|
|
71
|
+
name: "member",
|
|
72
|
+
description: "Regular organization member",
|
|
73
|
+
permissions: [
|
|
74
|
+
Permission.USER_READ,
|
|
75
|
+
Permission.ORG_READ,
|
|
76
|
+
Permission.MEMBER_LIST,
|
|
77
|
+
Permission.PROJECT_READ,
|
|
78
|
+
Permission.PROJECT_CREATE
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
VIEWER: {
|
|
82
|
+
name: "viewer",
|
|
83
|
+
description: "Read-only access",
|
|
84
|
+
permissions: [
|
|
85
|
+
Permission.USER_READ,
|
|
86
|
+
Permission.ORG_READ,
|
|
87
|
+
Permission.MEMBER_LIST,
|
|
88
|
+
Permission.PROJECT_READ
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
};
|
|
2
92
|
|
|
3
|
-
|
|
93
|
+
class RBACPolicyEngine {
|
|
94
|
+
roleCache = new Map;
|
|
95
|
+
bindingCache = new Map;
|
|
96
|
+
async checkPermission(input, bindings) {
|
|
97
|
+
const { userId, orgId, permission } = input;
|
|
98
|
+
const now = new Date;
|
|
99
|
+
const userBindings = bindings.filter((b) => b.targetType === "user" && b.targetId === userId);
|
|
100
|
+
const orgBindings = orgId ? bindings.filter((b) => b.targetType === "organization" && b.targetId === orgId) : [];
|
|
101
|
+
const allBindings = [...userBindings, ...orgBindings];
|
|
102
|
+
const activeBindings = allBindings.filter((b) => !b.expiresAt || b.expiresAt > now);
|
|
103
|
+
if (activeBindings.length === 0) {
|
|
104
|
+
return {
|
|
105
|
+
allowed: false,
|
|
106
|
+
reason: "No active role bindings found"
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
for (const binding of activeBindings) {
|
|
110
|
+
if (binding.role.permissions.includes(permission)) {
|
|
111
|
+
return {
|
|
112
|
+
allowed: true,
|
|
113
|
+
matchedRole: binding.role.name
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
allowed: false,
|
|
119
|
+
reason: `No role grants the "${permission}" permission`
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
async getPermissions(userId, orgId, bindings) {
|
|
123
|
+
const now = new Date;
|
|
124
|
+
const userBindings = bindings.filter((b) => b.targetType === "user" && b.targetId === userId);
|
|
125
|
+
const orgBindings = orgId ? bindings.filter((b) => b.targetType === "organization" && b.targetId === orgId) : [];
|
|
126
|
+
const allBindings = [...userBindings, ...orgBindings];
|
|
127
|
+
const activeBindings = allBindings.filter((b) => !b.expiresAt || b.expiresAt > now);
|
|
128
|
+
const permissions = new Set;
|
|
129
|
+
const roles = [];
|
|
130
|
+
for (const binding of activeBindings) {
|
|
131
|
+
roles.push(binding.role);
|
|
132
|
+
for (const perm of binding.role.permissions) {
|
|
133
|
+
permissions.add(perm);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return { permissions, roles };
|
|
137
|
+
}
|
|
138
|
+
async hasAnyPermission(userId, orgId, permissions, bindings) {
|
|
139
|
+
const { permissions: userPerms } = await this.getPermissions(userId, orgId, bindings);
|
|
140
|
+
return permissions.some((p) => userPerms.has(p));
|
|
141
|
+
}
|
|
142
|
+
async hasAllPermissions(userId, orgId, permissions, bindings) {
|
|
143
|
+
const { permissions: userPerms } = await this.getPermissions(userId, orgId, bindings);
|
|
144
|
+
return permissions.every((p) => userPerms.has(p));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function createRBACEngine() {
|
|
148
|
+
return new RBACPolicyEngine;
|
|
149
|
+
}
|
|
150
|
+
export {
|
|
151
|
+
createRBACEngine,
|
|
152
|
+
StandardRole,
|
|
153
|
+
RBACPolicyEngine,
|
|
154
|
+
Permission
|
|
155
|
+
};
|