@vertesia/studio-utils 1.3.0 → 1.4.0-dev.20260615.051508Z

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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/roles/index.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import { type RolePartition } from './classes.js';
2
- export declare const systemPartition: RolePartition;
3
- //# sourceMappingURL=system.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../src/roles/system.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,aAAa,EAAc,MAAM,cAAc,CAAC;AAuMzE,eAAO,MAAM,eAAe,EAAE,aAG7B,CAAC"}
@@ -1,187 +0,0 @@
1
- import { Permission, SystemRoles } from '@vertesia/common';
2
- import { SystemRole } from './classes.js';
3
- class OrgMemberRole extends SystemRole {
4
- constructor(name, permissions) {
5
- super(name, [Permission.account_member, ...permissions]);
6
- }
7
- }
8
- class OwnerRole extends OrgMemberRole {
9
- constructor() {
10
- super(SystemRoles.owner, Object.values(Permission));
11
- }
12
- }
13
- class AdminRole extends OrgMemberRole {
14
- constructor() {
15
- super(SystemRoles.admin, Object.values(Permission));
16
- }
17
- }
18
- class ManagerRole extends OrgMemberRole {
19
- constructor() {
20
- super(SystemRoles.manager, Object.values(Permission));
21
- this.permissions.delete(Permission.account_admin);
22
- this.permissions.delete(Permission.manage_billing);
23
- this.permissions.delete(Permission.audit_read);
24
- this.permissions.delete(Permission.agent_run_read);
25
- this.permissions.delete(Permission.content_read_all);
26
- this.permissions.delete(Permission.content_superadmin);
27
- this.permissions.delete(Permission.workflow_superadmin);
28
- }
29
- }
30
- class DeveloperRole extends OrgMemberRole {
31
- constructor() {
32
- super(SystemRoles.developer, Object.values(Permission));
33
- this.permissions.delete(Permission.account_admin);
34
- this.permissions.delete(Permission.project_admin);
35
- this.permissions.delete(Permission.project_settings_write);
36
- this.permissions.delete(Permission.env_admin);
37
- this.permissions.delete(Permission.manage_billing);
38
- this.permissions.delete(Permission.audit_read);
39
- this.permissions.delete(Permission.agent_run_read);
40
- this.permissions.delete(Permission.content_read_all);
41
- this.permissions.delete(Permission.content_superadmin);
42
- this.permissions.delete(Permission.workflow_superadmin);
43
- }
44
- }
45
- class ApplicationRole extends OrgMemberRole {
46
- constructor() {
47
- super(SystemRoles.application, [
48
- Permission.int_read,
49
- Permission.int_execute,
50
- Permission.int_write,
51
- Permission.run_read,
52
- Permission.content_write,
53
- Permission.content_read,
54
- Permission.content_write,
55
- Permission.content_admin,
56
- Permission.project_admin,
57
- Permission.workflow_run,
58
- Permission.project_settings_write,
59
- Permission.account_write,
60
- ]);
61
- }
62
- }
63
- class AutomationRole extends OrgMemberRole {
64
- constructor() {
65
- super(SystemRoles.automation, [
66
- Permission.content_read,
67
- Permission.content_write,
68
- Permission.content_admin,
69
- Permission.int_read,
70
- Permission.int_execute,
71
- Permission.run_read,
72
- Permission.workflow_run,
73
- Permission.project_integration_read,
74
- ]);
75
- }
76
- }
77
- class ContentProcessorRole extends OrgMemberRole {
78
- constructor() {
79
- super(SystemRoles.content_processor, [
80
- Permission.content_read,
81
- Permission.content_write,
82
- Permission.content_admin,
83
- Permission.content_superadmin,
84
- Permission.int_execute,
85
- Permission.workflow_read,
86
- Permission.workflow_run,
87
- Permission.run_read,
88
- ]);
89
- }
90
- }
91
- class ConsumerRole extends OrgMemberRole {
92
- constructor() {
93
- super(SystemRoles.consumer, [
94
- Permission.content_admin,
95
- Permission.content_read,
96
- Permission.content_write,
97
- Permission.content_delete,
98
- Permission.int_read,
99
- Permission.int_execute,
100
- Permission.run_read,
101
- Permission.workflow_run,
102
- ]);
103
- }
104
- }
105
- class ExecutorRole extends OrgMemberRole {
106
- constructor() {
107
- super(SystemRoles.executor, [Permission.int_execute, Permission.run_read, Permission.workflow_run]);
108
- }
109
- }
110
- class ReaderRole extends OrgMemberRole {
111
- constructor() {
112
- super(SystemRoles.reader, [Permission.int_read, Permission.run_read, Permission.content_read]);
113
- }
114
- }
115
- const READ_ONLY_AUDIT_PERMISSIONS = [
116
- Permission.studio_access,
117
- Permission.account_read,
118
- Permission.project_integration_read,
119
- Permission.api_key_read,
120
- Permission.billing_read,
121
- Permission.audit_read,
122
- Permission.int_read,
123
- Permission.run_read,
124
- Permission.content_read,
125
- Permission.content_read_all,
126
- Permission.task_read,
127
- Permission.workflow_read,
128
- Permission.agent_run_read,
129
- ];
130
- class ReadOnlyAuditRole extends OrgMemberRole {
131
- constructor(name) {
132
- super(name, READ_ONLY_AUDIT_PERMISSIONS);
133
- }
134
- }
135
- class BillingRole extends OrgMemberRole {
136
- constructor() {
137
- super(SystemRoles.billing, [Permission.manage_billing]);
138
- }
139
- }
140
- class AppMemberRole extends OrgMemberRole {
141
- constructor() {
142
- super(SystemRoles.app_member, [
143
- Permission.int_read,
144
- Permission.int_execute,
145
- Permission.int_write,
146
- Permission.run_read,
147
- Permission.content_write,
148
- Permission.content_read,
149
- Permission.content_delete,
150
- Permission.workflow_run,
151
- ]);
152
- }
153
- }
154
- class ContentSuperAdmin extends DeveloperRole {
155
- constructor() {
156
- super();
157
- this.name = SystemRoles.content_superadmin;
158
- this.permissions.add(Permission.content_superadmin);
159
- }
160
- }
161
- // The enum is still named `SystemRoles` (historical); the partition's domain
162
- // is `system` — the foundational built-in roles, distinct from feature domains
163
- // like `content` or `tasks`. Renaming the enum to `SystemRoles` is a separate
164
- // concern to revisit later.
165
- const systemRoles = {
166
- [SystemRoles.owner]: new OwnerRole(),
167
- [SystemRoles.admin]: new AdminRole(),
168
- [SystemRoles.manager]: new ManagerRole(),
169
- [SystemRoles.developer]: new DeveloperRole(),
170
- [SystemRoles.application]: new ApplicationRole(),
171
- [SystemRoles.automation]: new AutomationRole(),
172
- [SystemRoles.content_processor]: new ContentProcessorRole(),
173
- [SystemRoles.consumer]: new ConsumerRole(),
174
- [SystemRoles.executor]: new ExecutorRole(),
175
- [SystemRoles.reader]: new ReaderRole(),
176
- [SystemRoles.auditor]: new ReadOnlyAuditRole(SystemRoles.auditor),
177
- [SystemRoles.support]: new ReadOnlyAuditRole(SystemRoles.support),
178
- [SystemRoles.billing]: new BillingRole(),
179
- [SystemRoles.app_member]: new AppMemberRole(),
180
- [SystemRoles.member]: new OrgMemberRole(SystemRoles.member, []),
181
- [SystemRoles.content_superadmin]: new ContentSuperAdmin(),
182
- };
183
- export const systemPartition = {
184
- domain: 'system',
185
- roles: new Map(Object.entries(systemRoles)),
186
- };
187
- //# sourceMappingURL=system.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/roles/system.ts"],"names":[],"mappings":"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"}
@@ -1,78 +0,0 @@
1
- import type { AbacScope, Permission, RoleDomain } from '@vertesia/common';
2
-
3
- /**
4
- * Class hierarchy and registry-bound interface for the role system. These
5
- * are LOGIC — they have runtime behavior (constructors, instance methods,
6
- * subclass dispatch via `instanceof`). They live in `@vertesia/studio-utils`
7
- * (not common) per the package-layering contract: only types stay in common.
8
- */
9
-
10
- /**
11
- * A role: a named bundle of permissions that ACEs reference by name.
12
- *
13
- * Generic over the permission type so subclasses can tighten it:
14
- * - **System roles** declare `extends Role<Permission>` — construction time
15
- * type-checks against the central `Permission` enum.
16
- * - **ABAC roles** (`AbacRole`) declare `extends Role<string>` — permissions
17
- * are bare verbs (`'read'`, `'write'`, `'delete'`, future domain-specific
18
- * verbs) consumed by the JWT generator to form `{scope}:{verb}` keys in
19
- * `content_security`.
20
- *
21
- * The registry stores `Role` (defaulting to `Role<string>`) — the loose type
22
- * is the lowest common denominator. Tight typing is only enforced at
23
- * declaration sites of the role subclasses.
24
- */
25
- export class Role<PermissionType extends string = string> {
26
- permissions: Set<PermissionType>;
27
- constructor(
28
- public name: string,
29
- permissions: PermissionType[],
30
- public domain: RoleDomain,
31
- ) {
32
- this.permissions = new Set(permissions);
33
- }
34
-
35
- hasPermission(permission: PermissionType) {
36
- return this.permissions.has(permission);
37
- }
38
- }
39
-
40
- /**
41
- * Base class for built-in system roles. Hardcodes `domain: 'system'` and
42
- * specializes `Role<Permission>` so subclasses get compile-time type-checking
43
- * against the central `Permission` enum at construction.
44
- */
45
- export class SystemRole extends Role<Permission> {
46
- constructor(name: string, permissions: Permission[]) {
47
- super(name, permissions, 'system');
48
- }
49
- }
50
-
51
- /**
52
- * A role usable in ContentSet ACEs. Adds `applicableScopes` — the kinds of
53
- * objects the role can be applied to at the ABAC scope level. Inherits
54
- * `Role<string>` because ABAC verbs aren't constrained to the central
55
- * `Permission` enum.
56
- *
57
- * The IAM UI filters via `listAbacRolesForScope` which checks `instanceof AbacRole`.
58
- */
59
- export class AbacRole extends Role<string> {
60
- constructor(
61
- name: string,
62
- permissions: string[],
63
- domain: RoleDomain,
64
- public applicableScopes: readonly AbacScope[],
65
- ) {
66
- super(name, permissions, domain);
67
- }
68
- }
69
-
70
- /**
71
- * A logical bucket of roles owned by a single domain. The registry iterates
72
- * partitions in registration order — first match wins. The `system` partition
73
- * is registered first so domain partitions cannot shadow built-in system roles.
74
- */
75
- export interface RolePartition {
76
- domain: RoleDomain;
77
- roles: Map<string, Role>;
78
- }
@@ -1,46 +0,0 @@
1
- import type { AbacScope, RoleDomain } from '@vertesia/common';
2
- import { AbacRole, type Role, type RolePartition } from './classes.js';
3
-
4
- const ContentRoleDomain: RoleDomain = 'content';
5
-
6
- const APPLICABLE_SCOPES: readonly AbacScope[] = ['document', 'collection'];
7
-
8
- /**
9
- * Names of roles owned by the `content` domain. Apply to ContentSet ACEs
10
- * scoped to either `document` or `collection` — the semantics of "read
11
- * content" are the same for both kinds.
12
- */
13
- export enum ContentRoleNames {
14
- content_reader = 'content_reader',
15
- content_writer = 'content_writer',
16
- content_manager = 'content_manager',
17
- }
18
-
19
- class ContentReaderRole extends AbacRole {
20
- constructor() {
21
- super(ContentRoleNames.content_reader, ['read'], ContentRoleDomain, APPLICABLE_SCOPES);
22
- }
23
- }
24
-
25
- class ContentWriterRole extends AbacRole {
26
- constructor() {
27
- super(ContentRoleNames.content_writer, ['read', 'write'], ContentRoleDomain, APPLICABLE_SCOPES);
28
- }
29
- }
30
-
31
- class ContentManagerRole extends AbacRole {
32
- constructor() {
33
- super(ContentRoleNames.content_manager, ['read', 'write', 'delete'], ContentRoleDomain, APPLICABLE_SCOPES);
34
- }
35
- }
36
-
37
- const contentRoles: Record<ContentRoleNames, Role> = {
38
- [ContentRoleNames.content_reader]: new ContentReaderRole(),
39
- [ContentRoleNames.content_writer]: new ContentWriterRole(),
40
- [ContentRoleNames.content_manager]: new ContentManagerRole(),
41
- };
42
-
43
- export const contentPartition: RolePartition = {
44
- domain: ContentRoleDomain,
45
- roles: new Map(Object.entries(contentRoles)),
46
- };
@@ -1,206 +0,0 @@
1
- import { Permission, SystemRoles } from '@vertesia/common';
2
- import { describe, expect, it } from 'vitest';
3
- import { ContentRoleNames } from './content.js';
4
- import {
5
- AbacRole,
6
- getAllRoleNames,
7
- getPermissionsForRoles,
8
- getRoleByName,
9
- listAbacRolesForScope,
10
- listRoles,
11
- listRolesByDomain,
12
- listSystemRoles,
13
- Role,
14
- RoleList,
15
- SystemRole,
16
- } from './index.js';
17
-
18
- describe('getRoleByName', () => {
19
- it('returns a system role by name', () => {
20
- const role = getRoleByName(SystemRoles.owner);
21
- expect(role).toBeInstanceOf(SystemRole);
22
- expect(role.name).toBe('owner');
23
- expect(role.domain).toBe('system');
24
- });
25
-
26
- it('returns an ABAC role by name', () => {
27
- const role = getRoleByName(ContentRoleNames.content_reader);
28
- expect(role).toBeInstanceOf(AbacRole);
29
- expect(role.name).toBe('content_reader');
30
- expect(role.domain).toBe('content');
31
- });
32
-
33
- it('throws on unknown role', () => {
34
- expect(() => getRoleByName('not_a_real_role')).toThrow(/Role not_a_real_role not found/);
35
- });
36
-
37
- it('queries partitions in registration order — system first', () => {
38
- // System partition is registered before content. Even if a future partition
39
- // declared a role named 'owner', the system one would still win.
40
- const role = getRoleByName(SystemRoles.owner);
41
- expect(role.domain).toBe('system');
42
- });
43
- });
44
-
45
- describe('listRoles', () => {
46
- it('returns every role across all partitions', () => {
47
- const roles = listRoles();
48
- // 16 system roles + 3 content roles
49
- expect(roles).toHaveLength(19);
50
- });
51
-
52
- it('lists system roles before content roles (partition registration order)', () => {
53
- const roles = listRoles();
54
- const systemCount = roles.filter((r) => r.domain === 'system').length;
55
- const contentCount = roles.filter((r) => r.domain === 'content').length;
56
- expect(systemCount).toBe(16);
57
- expect(contentCount).toBe(3);
58
-
59
- // First 16 are system, next 3 are content
60
- for (let i = 0; i < 16; i++) expect(roles[i].domain).toBe('system');
61
- for (let i = 16; i < 19; i++) expect(roles[i].domain).toBe('content');
62
- });
63
- });
64
-
65
- describe('listRolesByDomain', () => {
66
- it('returns only system roles for "system"', () => {
67
- const roles = listRolesByDomain('system');
68
- expect(roles).toHaveLength(16);
69
- expect(roles.every((r) => r.domain === 'system')).toBe(true);
70
- });
71
-
72
- it('returns only content roles for "content"', () => {
73
- const roles = listRolesByDomain('content');
74
- expect(roles).toHaveLength(3);
75
- expect(roles.every((r) => r.domain === 'content')).toBe(true);
76
- });
77
-
78
- it('returns empty for an unregistered domain', () => {
79
- expect(listRolesByDomain('tasks')).toEqual([]);
80
- });
81
- });
82
-
83
- describe('listSystemRoles', () => {
84
- it('returns SystemRole instances', () => {
85
- const roles = listSystemRoles();
86
- expect(roles).toHaveLength(16);
87
- expect(roles.every((r) => r instanceof SystemRole)).toBe(true);
88
- });
89
-
90
- it('excludes ABAC roles', () => {
91
- const roles = listSystemRoles();
92
- expect(roles.some((r) => r instanceof AbacRole)).toBe(false);
93
- });
94
- });
95
-
96
- describe('listAbacRolesForScope', () => {
97
- it('returns content roles for "document" scope', () => {
98
- const roles = listAbacRolesForScope('document');
99
- expect(roles).toHaveLength(3);
100
- expect(roles.map((r) => r.name).sort()).toEqual(['content_manager', 'content_reader', 'content_writer']);
101
- });
102
-
103
- it('returns content roles for "collection" scope (same roles, applicableScopes covers both)', () => {
104
- const roles = listAbacRolesForScope('collection');
105
- expect(roles).toHaveLength(3);
106
- expect(roles.every((r) => r.applicableScopes.includes('collection'))).toBe(true);
107
- });
108
-
109
- it('returns empty for "task" scope (no task partition registered)', () => {
110
- expect(listAbacRolesForScope('task')).toEqual([]);
111
- });
112
-
113
- it('returns AbacRole instances only — no system roles bleed through', () => {
114
- const roles = listAbacRolesForScope('document');
115
- expect(roles.every((r) => r instanceof AbacRole)).toBe(true);
116
- });
117
- });
118
-
119
- describe('getAllRoleNames', () => {
120
- it('returns names of every registered role', () => {
121
- const names = getAllRoleNames();
122
- expect(names).toHaveLength(19);
123
- expect(names).toContain('owner');
124
- expect(names).toContain('content_reader');
125
- });
126
-
127
- it('produces a flat list suited for mongoose enum constraints', () => {
128
- const names = getAllRoleNames();
129
- expect(names.every((n) => typeof n === 'string')).toBe(true);
130
- });
131
- });
132
-
133
- describe('getPermissionsForRoles', () => {
134
- it('merges permissions across multiple roles, deduped', () => {
135
- // content_reader: ['read']
136
- // content_writer: ['read', 'write']
137
- const merged = getPermissionsForRoles([ContentRoleNames.content_reader, ContentRoleNames.content_writer]);
138
- expect(merged.sort()).toEqual(['read', 'write']);
139
- });
140
-
141
- it('returns system Permission values for system roles', () => {
142
- const merged = getPermissionsForRoles([SystemRoles.reader]);
143
- // reader role has: int_read, run_read, content_read + account_member (via OrgMemberRole)
144
- expect(merged).toContain(Permission.int_read);
145
- expect(merged).toContain(Permission.content_read);
146
- expect(merged).toContain(Permission.account_member);
147
- });
148
- });
149
-
150
- describe('Role instances', () => {
151
- it('SystemRole hasPermission for granted Permission', () => {
152
- const owner = getRoleByName(SystemRoles.owner);
153
- expect(owner.hasPermission(Permission.content_read)).toBe(true);
154
- expect(owner.hasPermission(Permission.manage_billing)).toBe(true);
155
- });
156
-
157
- it('SystemRole hasPermission false for arbitrary string', () => {
158
- const reader = getRoleByName(SystemRoles.reader);
159
- expect(reader.hasPermission('not_a_real_perm')).toBe(false);
160
- });
161
-
162
- it('AbacRole carries applicableScopes', () => {
163
- const reader = getRoleByName(ContentRoleNames.content_reader) as AbacRole;
164
- expect(reader.applicableScopes).toEqual(['document', 'collection']);
165
- });
166
-
167
- it('AbacRole permissions are bare verbs, not Permission enum values', () => {
168
- const manager = getRoleByName(ContentRoleNames.content_manager);
169
- expect(Array.from(manager.permissions).sort()).toEqual(['delete', 'read', 'write']);
170
- });
171
- });
172
-
173
- describe('SystemRole vs AbacRole discrimination', () => {
174
- it('SystemRole instanceof Role', () => {
175
- const owner = getRoleByName(SystemRoles.owner);
176
- expect(owner).toBeInstanceOf(Role);
177
- expect(owner).toBeInstanceOf(SystemRole);
178
- expect(owner).not.toBeInstanceOf(AbacRole);
179
- });
180
-
181
- it('AbacRole instanceof Role', () => {
182
- const reader = getRoleByName(ContentRoleNames.content_reader);
183
- expect(reader).toBeInstanceOf(Role);
184
- expect(reader).toBeInstanceOf(AbacRole);
185
- expect(reader).not.toBeInstanceOf(SystemRole);
186
- });
187
- });
188
-
189
- describe('RoleList', () => {
190
- it('fromRoleNames composes a list checkable for permissions', () => {
191
- const list = RoleList.fromRoleNames([SystemRoles.reader, SystemRoles.executor]);
192
- expect(list.hasPermission(Permission.content_read)).toBe(true); // from reader
193
- expect(list.hasPermission(Permission.int_execute)).toBe(true); // from executor
194
- expect(list.hasPermission(Permission.manage_billing)).toBe(false); // neither has it
195
- });
196
-
197
- it('fromRoleName composes a single-role list', () => {
198
- const list = RoleList.fromRoleName(SystemRoles.billing);
199
- expect(list.hasPermission(Permission.manage_billing)).toBe(true);
200
- expect(list.hasPermission(Permission.content_write)).toBe(false);
201
- });
202
-
203
- it('throws on unknown role name', () => {
204
- expect(() => RoleList.fromRoleNames(['not_real'])).toThrow(/Role not_real not found/);
205
- });
206
- });
@@ -1,96 +0,0 @@
1
- import type { AbacScope, RoleDomain } from '@vertesia/common';
2
- import { AbacRole, type Role, type RolePartition, SystemRole } from './classes.js';
3
- import { contentPartition } from './content.js';
4
- import { systemPartition } from './system.js';
5
-
6
- export { AbacRole, Role, type RolePartition, SystemRole } from './classes.js';
7
- export { ContentRoleNames } from './content.js';
8
-
9
- /**
10
- * The ordered partition registry. Partitions are queried in this order — first
11
- * match wins. The `system` partition is registered first so domain-specific
12
- * partitions (added later) cannot shadow built-in system roles.
13
- */
14
- const partitions: RolePartition[] = [systemPartition, contentPartition];
15
-
16
- /** Look up a role by its name across all registered partitions. */
17
- export function getRoleByName(name: string): Role {
18
- for (const partition of partitions) {
19
- const role = partition.roles.get(name);
20
- if (role) return role;
21
- }
22
- throw new Error(`Role ${name} not found`);
23
- }
24
-
25
- /** List every role across all partitions, in partition registration order. */
26
- export function listRoles(): Role[] {
27
- const result: Role[] = [];
28
- for (const partition of partitions) {
29
- for (const role of partition.roles.values()) {
30
- result.push(role);
31
- }
32
- }
33
- return result;
34
- }
35
-
36
- /** Roles owned by a specific domain (e.g. `'system'`, `'content'`). */
37
- export function listRolesByDomain(domain: RoleDomain): Role[] {
38
- const partition = partitions.find((p) => p.domain === domain);
39
- return partition ? Array.from(partition.roles.values()) : [];
40
- }
41
-
42
- /**
43
- * ABAC roles applicable to a given ContentSet scope (e.g. `'document'`,
44
- * `'collection'`). System roles are excluded — they don't carry scope semantics.
45
- */
46
- export function listAbacRolesForScope(scope: AbacScope): AbacRole[] {
47
- return listRoles().filter((r): r is AbacRole => r instanceof AbacRole && r.applicableScopes.includes(scope));
48
- }
49
-
50
- /** Shortcut for the system partition: returns only `SystemRole` instances. */
51
- export function listSystemRoles(): SystemRole[] {
52
- return listRoles().filter((r): r is SystemRole => r instanceof SystemRole);
53
- }
54
-
55
- /** Names of every registered role across all partitions — suited for mongoose schema enum constraints. */
56
- export function getAllRoleNames(): string[] {
57
- return listRoles().map((r) => r.name);
58
- }
59
-
60
- /**
61
- * Merge the permissions granted by a set of roles into a single array.
62
- * Intended for the system-role gating path. For ABAC roles, the bare-verb
63
- * permissions returned here aren't directly meaningful — use the JWT
64
- * `content_security` pathway instead.
65
- */
66
- export function getPermissionsForRoles(roleNames: Iterable<string>): string[] {
67
- const permissions = new Set<string>();
68
- for (const roleName of roleNames) {
69
- const role = getRoleByName(roleName);
70
- for (const permission of role.permissions) {
71
- permissions.add(permission);
72
- }
73
- }
74
- return Array.from(permissions);
75
- }
76
-
77
- /**
78
- * A list of roles with a unified `hasPermission` check across them.
79
- */
80
- export class RoleList {
81
- private constructor(public readonly roles: Role[]) {}
82
-
83
- static fromRoleNames(roleNames: string[]): RoleList {
84
- const roles = roleNames.map((r) => getRoleByName(r));
85
- return new RoleList(roles);
86
- }
87
-
88
- static fromRoleName(roleName: string): RoleList {
89
- const roles = [getRoleByName(roleName)];
90
- return new RoleList(roles);
91
- }
92
-
93
- hasPermission(perm: string): boolean {
94
- return this.roles.some((role) => role.hasPermission(perm));
95
- }
96
- }