@lightdash/common 0.1937.0 → 0.1937.1

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.
Files changed (129) hide show
  1. package/dist/cjs/authorization/index.d.ts +8 -4
  2. package/dist/cjs/authorization/index.d.ts.map +1 -1
  3. package/dist/cjs/authorization/index.js +26 -3
  4. package/dist/cjs/authorization/index.js.map +1 -1
  5. package/dist/cjs/authorization/index.mock.d.ts +2 -0
  6. package/dist/cjs/authorization/index.mock.d.ts.map +1 -1
  7. package/dist/cjs/authorization/index.mock.js +2 -0
  8. package/dist/cjs/authorization/index.mock.js.map +1 -1
  9. package/dist/cjs/authorization/organizationMemberAbility.mock.d.ts.map +1 -1
  10. package/dist/cjs/authorization/organizationMemberAbility.mock.js +1 -0
  11. package/dist/cjs/authorization/organizationMemberAbility.mock.js.map +1 -1
  12. package/dist/cjs/authorization/parseScopes.d.ts +3 -2
  13. package/dist/cjs/authorization/parseScopes.d.ts.map +1 -1
  14. package/dist/cjs/authorization/parseScopes.js +17 -8
  15. package/dist/cjs/authorization/parseScopes.js.map +1 -1
  16. package/dist/cjs/authorization/parseScopes.test.js +9 -14
  17. package/dist/cjs/authorization/parseScopes.test.js.map +1 -1
  18. package/dist/cjs/authorization/projectMemberAbility.mock.d.ts.map +1 -1
  19. package/dist/cjs/authorization/projectMemberAbility.mock.js +1 -0
  20. package/dist/cjs/authorization/projectMemberAbility.mock.js.map +1 -1
  21. package/dist/cjs/authorization/roleToScopeMapping.d.ts +19 -0
  22. package/dist/cjs/authorization/roleToScopeMapping.d.ts.map +1 -0
  23. package/dist/cjs/authorization/roleToScopeMapping.js +163 -0
  24. package/dist/cjs/authorization/roleToScopeMapping.js.map +1 -0
  25. package/dist/cjs/authorization/roleToScopeMapping.test.d.ts +2 -0
  26. package/dist/cjs/authorization/roleToScopeMapping.test.d.ts.map +1 -0
  27. package/dist/cjs/authorization/roleToScopeMapping.test.js +549 -0
  28. package/dist/cjs/authorization/roleToScopeMapping.test.js.map +1 -0
  29. package/dist/cjs/authorization/roleToScopeMapping.testUtils.d.ts +1393 -0
  30. package/dist/cjs/authorization/roleToScopeMapping.testUtils.d.ts.map +1 -0
  31. package/dist/cjs/authorization/roleToScopeMapping.testUtils.js +329 -0
  32. package/dist/cjs/authorization/roleToScopeMapping.testUtils.js.map +1 -0
  33. package/dist/cjs/authorization/scopeAbilityBuilder.d.ts +14 -8
  34. package/dist/cjs/authorization/scopeAbilityBuilder.d.ts.map +1 -1
  35. package/dist/cjs/authorization/scopeAbilityBuilder.js +7 -7
  36. package/dist/cjs/authorization/scopeAbilityBuilder.js.map +1 -1
  37. package/dist/cjs/authorization/scopeAbilityBuilder.test.js +258 -185
  38. package/dist/cjs/authorization/scopeAbilityBuilder.test.js.map +1 -1
  39. package/dist/cjs/authorization/scopes.d.ts.map +1 -1
  40. package/dist/cjs/authorization/scopes.js +132 -187
  41. package/dist/cjs/authorization/scopes.js.map +1 -1
  42. package/dist/cjs/types/organizationMemberProfile.d.ts +1 -0
  43. package/dist/cjs/types/organizationMemberProfile.d.ts.map +1 -1
  44. package/dist/cjs/types/organizationMemberProfile.js.map +1 -1
  45. package/dist/cjs/types/projectMemberProfile.d.ts +1 -0
  46. package/dist/cjs/types/projectMemberProfile.d.ts.map +1 -1
  47. package/dist/cjs/types/scopes.d.ts +19 -9
  48. package/dist/cjs/types/scopes.d.ts.map +1 -1
  49. package/dist/cjs/types/user.d.ts +1 -0
  50. package/dist/cjs/types/user.d.ts.map +1 -1
  51. package/dist/cjs/types/user.js.map +1 -1
  52. package/dist/esm/authorization/index.d.ts +8 -4
  53. package/dist/esm/authorization/index.d.ts.map +1 -1
  54. package/dist/esm/authorization/index.js +26 -3
  55. package/dist/esm/authorization/index.js.map +1 -1
  56. package/dist/esm/authorization/index.mock.d.ts +2 -0
  57. package/dist/esm/authorization/index.mock.d.ts.map +1 -1
  58. package/dist/esm/authorization/index.mock.js +2 -0
  59. package/dist/esm/authorization/index.mock.js.map +1 -1
  60. package/dist/esm/authorization/organizationMemberAbility.mock.d.ts.map +1 -1
  61. package/dist/esm/authorization/organizationMemberAbility.mock.js +1 -0
  62. package/dist/esm/authorization/organizationMemberAbility.mock.js.map +1 -1
  63. package/dist/esm/authorization/parseScopes.d.ts +3 -2
  64. package/dist/esm/authorization/parseScopes.d.ts.map +1 -1
  65. package/dist/esm/authorization/parseScopes.js +15 -7
  66. package/dist/esm/authorization/parseScopes.js.map +1 -1
  67. package/dist/esm/authorization/parseScopes.test.js +9 -14
  68. package/dist/esm/authorization/parseScopes.test.js.map +1 -1
  69. package/dist/esm/authorization/projectMemberAbility.mock.d.ts.map +1 -1
  70. package/dist/esm/authorization/projectMemberAbility.mock.js +1 -0
  71. package/dist/esm/authorization/projectMemberAbility.mock.js.map +1 -1
  72. package/dist/esm/authorization/roleToScopeMapping.d.ts +19 -0
  73. package/dist/esm/authorization/roleToScopeMapping.d.ts.map +1 -0
  74. package/dist/esm/authorization/roleToScopeMapping.js +157 -0
  75. package/dist/esm/authorization/roleToScopeMapping.js.map +1 -0
  76. package/dist/esm/authorization/roleToScopeMapping.test.d.ts +2 -0
  77. package/dist/esm/authorization/roleToScopeMapping.test.d.ts.map +1 -0
  78. package/dist/esm/authorization/roleToScopeMapping.test.js +547 -0
  79. package/dist/esm/authorization/roleToScopeMapping.test.js.map +1 -0
  80. package/dist/esm/authorization/roleToScopeMapping.testUtils.d.ts +1393 -0
  81. package/dist/esm/authorization/roleToScopeMapping.testUtils.d.ts.map +1 -0
  82. package/dist/esm/authorization/roleToScopeMapping.testUtils.js +319 -0
  83. package/dist/esm/authorization/roleToScopeMapping.testUtils.js.map +1 -0
  84. package/dist/esm/authorization/scopeAbilityBuilder.d.ts +14 -8
  85. package/dist/esm/authorization/scopeAbilityBuilder.d.ts.map +1 -1
  86. package/dist/esm/authorization/scopeAbilityBuilder.js +7 -7
  87. package/dist/esm/authorization/scopeAbilityBuilder.js.map +1 -1
  88. package/dist/esm/authorization/scopeAbilityBuilder.test.js +259 -186
  89. package/dist/esm/authorization/scopeAbilityBuilder.test.js.map +1 -1
  90. package/dist/esm/authorization/scopes.d.ts.map +1 -1
  91. package/dist/esm/authorization/scopes.js +132 -187
  92. package/dist/esm/authorization/scopes.js.map +1 -1
  93. package/dist/esm/types/organizationMemberProfile.d.ts +1 -0
  94. package/dist/esm/types/organizationMemberProfile.d.ts.map +1 -1
  95. package/dist/esm/types/organizationMemberProfile.js.map +1 -1
  96. package/dist/esm/types/projectMemberProfile.d.ts +1 -0
  97. package/dist/esm/types/projectMemberProfile.d.ts.map +1 -1
  98. package/dist/esm/types/scopes.d.ts +19 -9
  99. package/dist/esm/types/scopes.d.ts.map +1 -1
  100. package/dist/esm/types/user.d.ts +1 -0
  101. package/dist/esm/types/user.d.ts.map +1 -1
  102. package/dist/esm/types/user.js.map +1 -1
  103. package/dist/tsconfig.types.tsbuildinfo +1 -1
  104. package/dist/types/authorization/index.d.ts +8 -4
  105. package/dist/types/authorization/index.d.ts.map +1 -1
  106. package/dist/types/authorization/index.mock.d.ts +2 -0
  107. package/dist/types/authorization/index.mock.d.ts.map +1 -1
  108. package/dist/types/authorization/organizationMemberAbility.mock.d.ts.map +1 -1
  109. package/dist/types/authorization/parseScopes.d.ts +3 -2
  110. package/dist/types/authorization/parseScopes.d.ts.map +1 -1
  111. package/dist/types/authorization/projectMemberAbility.mock.d.ts.map +1 -1
  112. package/dist/types/authorization/roleToScopeMapping.d.ts +19 -0
  113. package/dist/types/authorization/roleToScopeMapping.d.ts.map +1 -0
  114. package/dist/types/authorization/roleToScopeMapping.test.d.ts +2 -0
  115. package/dist/types/authorization/roleToScopeMapping.test.d.ts.map +1 -0
  116. package/dist/types/authorization/roleToScopeMapping.testUtils.d.ts +1393 -0
  117. package/dist/types/authorization/roleToScopeMapping.testUtils.d.ts.map +1 -0
  118. package/dist/types/authorization/scopeAbilityBuilder.d.ts +14 -8
  119. package/dist/types/authorization/scopeAbilityBuilder.d.ts.map +1 -1
  120. package/dist/types/authorization/scopes.d.ts.map +1 -1
  121. package/dist/types/types/organizationMemberProfile.d.ts +1 -0
  122. package/dist/types/types/organizationMemberProfile.d.ts.map +1 -1
  123. package/dist/types/types/projectMemberProfile.d.ts +1 -0
  124. package/dist/types/types/projectMemberProfile.d.ts.map +1 -1
  125. package/dist/types/types/scopes.d.ts +19 -9
  126. package/dist/types/types/scopes.d.ts.map +1 -1
  127. package/dist/types/types/user.d.ts +1 -0
  128. package/dist/types/types/user.d.ts.map +1 -1
  129. package/package.json +1 -1
@@ -0,0 +1,549 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /* eslint-disable no-console */
4
+ const ability_1 = require("@casl/ability");
5
+ const organizationMemberProfile_1 = require("../types/organizationMemberProfile");
6
+ const projectMemberRole_1 = require("../types/projectMemberRole");
7
+ const index_1 = require("./index");
8
+ const projectMemberAbility_1 = require("./projectMemberAbility");
9
+ const projectMemberAbility_mock_1 = require("./projectMemberAbility.mock");
10
+ const roleToScopeMapping_1 = require("./roleToScopeMapping");
11
+ const roleToScopeMapping_testUtils_1 = require("./roleToScopeMapping.testUtils");
12
+ const scopeAbilityBuilder_1 = require("./scopeAbilityBuilder");
13
+ describe('roleToScopeMapping', () => {
14
+ describe('getScopesForRole', () => {
15
+ it('should return scopes for viewer role', () => {
16
+ const scopes = (0, roleToScopeMapping_1.getScopesForRole)(projectMemberRole_1.ProjectMemberRole.VIEWER);
17
+ expect(scopes).toContain('view:Dashboard');
18
+ expect(scopes).toContain('view:SavedChart');
19
+ expect(scopes).toContain('view:Space');
20
+ expect(scopes).toContain('view:Project');
21
+ });
22
+ it('should include inherited scopes for editor role', () => {
23
+ const scopes = (0, roleToScopeMapping_1.getScopesForRole)(projectMemberRole_1.ProjectMemberRole.EDITOR);
24
+ // Should have viewer scopes
25
+ expect(scopes).toContain('view:Dashboard');
26
+ expect(scopes).toContain('view:SavedChart');
27
+ // Should have interactive viewer scopes
28
+ expect(scopes).toContain('view:UnderlyingData');
29
+ expect(scopes).toContain('manage:Explore');
30
+ // Should have editor-specific scopes
31
+ expect(scopes).toContain('create:Space');
32
+ expect(scopes).toContain('manage:DashboardComments');
33
+ expect(scopes).toContain('manage:ScheduledDeliveries');
34
+ });
35
+ it('should have more scopes for higher roles', () => {
36
+ const viewerScopes = (0, roleToScopeMapping_1.getScopesForRole)(projectMemberRole_1.ProjectMemberRole.VIEWER);
37
+ const editorScopes = (0, roleToScopeMapping_1.getScopesForRole)(projectMemberRole_1.ProjectMemberRole.EDITOR);
38
+ const adminScopes = (0, roleToScopeMapping_1.getScopesForRole)(projectMemberRole_1.ProjectMemberRole.ADMIN);
39
+ expect(editorScopes.length).toBeGreaterThan(viewerScopes.length);
40
+ expect(adminScopes.length).toBeGreaterThan(editorScopes.length);
41
+ });
42
+ });
43
+ describe('getIncrementalScopesForRole', () => {
44
+ it('should return all scopes for viewer (base role)', () => {
45
+ const incrementalScopes = (0, roleToScopeMapping_1.getIncrementalScopesForRole)(projectMemberRole_1.ProjectMemberRole.VIEWER);
46
+ const allScopes = (0, roleToScopeMapping_1.getScopesForRole)(projectMemberRole_1.ProjectMemberRole.VIEWER);
47
+ expect(incrementalScopes.sort()).toEqual(allScopes.sort());
48
+ });
49
+ it('should return only new scopes for editor role', () => {
50
+ const incrementalScopes = (0, roleToScopeMapping_1.getIncrementalScopesForRole)(projectMemberRole_1.ProjectMemberRole.EDITOR);
51
+ const interactiveViewerScopes = (0, roleToScopeMapping_1.getScopesForRole)(projectMemberRole_1.ProjectMemberRole.INTERACTIVE_VIEWER);
52
+ // Should not contain any interactive viewer scopes
53
+ incrementalScopes.forEach((scope) => {
54
+ expect(interactiveViewerScopes).not.toContain(scope);
55
+ });
56
+ // Should contain editor-specific scopes
57
+ expect(incrementalScopes).toContain('create:Space');
58
+ expect(incrementalScopes).toContain('manage:DashboardComments');
59
+ expect(incrementalScopes).toContain('manage:ScheduledDeliveries');
60
+ });
61
+ });
62
+ describe('validateRoleInheritance', () => {
63
+ it('should validate that roles properly inherit permissions', () => {
64
+ const validation = (0, roleToScopeMapping_testUtils_1.validateRoleInheritance)();
65
+ if (!validation.valid) {
66
+ console.debug('Validation errors:', validation.errors);
67
+ }
68
+ expect(validation.valid).toBe(true);
69
+ expect(validation.errors).toHaveLength(0);
70
+ });
71
+ });
72
+ describe('debugRoleScopeMapping', () => {
73
+ it('should not throw when debugging editor role', () => {
74
+ expect(() => {
75
+ (0, roleToScopeMapping_testUtils_1.debugRoleScopeMapping)(projectMemberRole_1.ProjectMemberRole.EDITOR);
76
+ }).not.toThrow();
77
+ });
78
+ });
79
+ describe('AbilityBuilderCompatibility', () => { });
80
+ describe('Ability builder compatibility', () => {
81
+ it('should build equivalent abilities using scopes vs role-based builder', () => {
82
+ // Build ability using the old role-based system
83
+ const roleBuilder = new ability_1.AbilityBuilder(ability_1.Ability);
84
+ projectMemberAbility_1.projectMemberAbilities[projectMemberRole_1.ProjectMemberRole.EDITOR](projectMemberAbility_mock_1.PROJECT_EDITOR, roleBuilder);
85
+ const roleAbility = roleBuilder.build();
86
+ // Define scopes that should be equivalent to an editor role
87
+ // Based on projectMemberAbility.ts, an editor can:
88
+ // - Do everything interactive_viewer can do (view content, export, create deliveries)
89
+ // - Create spaces
90
+ // - Manage non-private spaces, jobs, pinned items, scheduled deliveries, dashboard comments, tags
91
+ // NOTE: Adding manage:Project to enable managing non-private spaces
92
+ const editorScopes = [
93
+ // Interactive viewer scopes (inherited)
94
+ 'view:Dashboard',
95
+ 'view:SavedChart',
96
+ 'view:Space',
97
+ 'view:Project',
98
+ 'create:ScheduledDeliveries',
99
+ 'view:Job',
100
+ 'create:Job',
101
+ 'manage:Explore',
102
+ 'create:DashboardComments',
103
+ // Editor-specific scopes
104
+ 'create:Space',
105
+ 'manage:Space',
106
+ 'manage:Project', // Required for managing non-private spaces
107
+ 'manage:Job',
108
+ 'manage:PinnedItems',
109
+ 'manage:ScheduledDeliveries',
110
+ 'manage:DashboardComments',
111
+ 'manage:Tags',
112
+ ];
113
+ // Build ability using the new scope-based system
114
+ const scopeBuilder = new ability_1.AbilityBuilder(ability_1.Ability);
115
+ (0, scopeAbilityBuilder_1.buildAbilityFromScopes)({
116
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
117
+ userUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.userUuid,
118
+ scopes: editorScopes,
119
+ isEnterprise: false,
120
+ organizationRole: 'editor',
121
+ permissionsConfig: {
122
+ pat: {
123
+ enabled: false,
124
+ allowedOrgRoles: [],
125
+ },
126
+ },
127
+ }, scopeBuilder);
128
+ const scopeAbility = scopeBuilder.build();
129
+ // Test cases that should be equivalent for both abilities
130
+ const testCases = [
131
+ // View permissions (inherited from interactive_viewer)
132
+ {
133
+ action: 'view',
134
+ subject: 'Dashboard',
135
+ resource: {
136
+ organizationUuid: 'org-uuid-test',
137
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
138
+ isPrivate: false,
139
+ },
140
+ },
141
+ {
142
+ action: 'view',
143
+ subject: 'SavedChart',
144
+ resource: {
145
+ organizationUuid: 'org-uuid-test',
146
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
147
+ isPrivate: false,
148
+ },
149
+ },
150
+ {
151
+ action: 'view',
152
+ subject: 'Space',
153
+ resource: {
154
+ organizationUuid: 'org-uuid-test',
155
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
156
+ isPrivate: false,
157
+ },
158
+ },
159
+ // Create permissions (editor-specific)
160
+ {
161
+ action: 'create',
162
+ subject: 'Space',
163
+ resource: {
164
+ organizationUuid: 'org-uuid-test',
165
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
166
+ },
167
+ },
168
+ // Manage permissions (editor-specific)
169
+ {
170
+ action: 'manage',
171
+ subject: 'Space',
172
+ resource: {
173
+ organizationUuid: 'org-uuid-test',
174
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
175
+ isPrivate: false,
176
+ },
177
+ },
178
+ {
179
+ action: 'manage',
180
+ subject: 'Job',
181
+ resource: {},
182
+ },
183
+ {
184
+ action: 'manage',
185
+ subject: 'PinnedItems',
186
+ resource: {
187
+ organizationUuid: 'org-uuid-test',
188
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
189
+ },
190
+ },
191
+ {
192
+ action: 'manage',
193
+ subject: 'ScheduledDeliveries',
194
+ resource: {
195
+ organizationUuid: 'org-uuid-test',
196
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
197
+ },
198
+ },
199
+ {
200
+ action: 'manage',
201
+ subject: 'DashboardComments',
202
+ resource: {
203
+ organizationUuid: 'org-uuid-test',
204
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
205
+ },
206
+ },
207
+ {
208
+ action: 'manage',
209
+ subject: 'Tags',
210
+ resource: {
211
+ organizationUuid: 'org-uuid-test',
212
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
213
+ },
214
+ },
215
+ ];
216
+ // Verify that both ability builders produce the same results
217
+ testCases.forEach(({ action, subject: subjectType, resource }) => {
218
+ const subjectWithResource = (0, ability_1.subject)(subjectType, resource);
219
+ const roleResult = roleAbility.can(action, subjectWithResource);
220
+ const scopeResult = scopeAbility.can(action, subjectWithResource);
221
+ expect(scopeResult).toBe(roleResult);
222
+ });
223
+ });
224
+ it('should deny the same permissions for both abilities', () => {
225
+ // Build abilities
226
+ const roleBuilder = new ability_1.AbilityBuilder(ability_1.Ability);
227
+ projectMemberAbility_1.projectMemberAbilities[projectMemberRole_1.ProjectMemberRole.EDITOR](projectMemberAbility_mock_1.PROJECT_EDITOR, roleBuilder);
228
+ const roleAbility = roleBuilder.build();
229
+ const editorScopes = [
230
+ 'view:Dashboard',
231
+ 'view:SavedChart',
232
+ 'view:Space',
233
+ 'view:Project',
234
+ 'create:ScheduledDeliveries',
235
+ 'view:Job',
236
+ 'create:Job',
237
+ 'manage:Explore',
238
+ 'create:DashboardComments',
239
+ 'create:Space',
240
+ 'manage:Job',
241
+ 'manage:PinnedItems',
242
+ 'manage:ScheduledDeliveries',
243
+ 'manage:DashboardComments',
244
+ 'manage:Tags',
245
+ ];
246
+ const scopeBuilder = new ability_1.AbilityBuilder(ability_1.Ability);
247
+ (0, scopeAbilityBuilder_1.buildAbilityFromScopes)({
248
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
249
+ userUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.userUuid,
250
+ scopes: editorScopes,
251
+ isEnterprise: false,
252
+ organizationRole: 'editor',
253
+ permissionsConfig: {
254
+ pat: {
255
+ enabled: false,
256
+ allowedOrgRoles: [],
257
+ },
258
+ },
259
+ }, scopeBuilder);
260
+ const scopeAbility = scopeBuilder.build();
261
+ // Test cases that should be denied for both abilities (editor limitations)
262
+ const deniedTestCases = [
263
+ // Cannot manage project (developer+ only)
264
+ {
265
+ action: 'manage',
266
+ subject: 'Project',
267
+ resource: { projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid },
268
+ },
269
+ // Cannot manage validations (developer+ only)
270
+ {
271
+ action: 'manage',
272
+ subject: 'Validation',
273
+ resource: { projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid },
274
+ },
275
+ // Cannot manage virtual views (developer+ only)
276
+ {
277
+ action: 'manage',
278
+ subject: 'VirtualView',
279
+ resource: { projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid },
280
+ },
281
+ ];
282
+ // Verify that both ability builders deny the same permissions
283
+ deniedTestCases.forEach(({ action, subject: subjectType, resource }) => {
284
+ const subjectWithResource = (0, ability_1.subject)(subjectType, resource);
285
+ const roleResult = roleAbility.can(action, subjectWithResource);
286
+ const scopeResult = scopeAbility.can(action, subjectWithResource);
287
+ expect(scopeResult).toBe(roleResult);
288
+ expect(roleResult).toBe(false); // Ensure they're both false
289
+ });
290
+ });
291
+ });
292
+ describe('Convert all project member roles to scopes', () => {
293
+ const testCases = [
294
+ {
295
+ action: 'view',
296
+ subject: 'Dashboard',
297
+ resource: {
298
+ organizationUuid: 'org-uuid-test',
299
+ projectUuid: 'test-project-uuid',
300
+ isPrivate: false,
301
+ },
302
+ },
303
+ {
304
+ action: 'create',
305
+ subject: 'Space',
306
+ resource: {
307
+ organizationUuid: 'org-uuid-test',
308
+ projectUuid: 'test-project-uuid',
309
+ },
310
+ },
311
+ {
312
+ action: 'manage',
313
+ subject: 'Space',
314
+ resource: {
315
+ organizationUuid: 'org-uuid-test',
316
+ projectUuid: 'test-project-uuid',
317
+ isPrivate: false,
318
+ },
319
+ },
320
+ {
321
+ action: 'manage',
322
+ subject: 'Project',
323
+ resource: { projectUuid: 'test-project-uuid' },
324
+ },
325
+ {
326
+ action: 'view',
327
+ subject: 'Analytics',
328
+ resource: { projectUuid: 'test-project-uuid' },
329
+ },
330
+ ];
331
+ const roles = [
332
+ projectMemberRole_1.ProjectMemberRole.VIEWER,
333
+ projectMemberRole_1.ProjectMemberRole.INTERACTIVE_VIEWER,
334
+ projectMemberRole_1.ProjectMemberRole.EDITOR,
335
+ projectMemberRole_1.ProjectMemberRole.DEVELOPER,
336
+ projectMemberRole_1.ProjectMemberRole.ADMIN,
337
+ ];
338
+ roles.forEach((role) => {
339
+ it(`should have equivalent CASL abilities for ${role} role`, () => {
340
+ // Build role-based ability
341
+ const roleBuilder = new ability_1.AbilityBuilder(ability_1.Ability);
342
+ const testMember = {
343
+ role,
344
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
345
+ userUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.userUuid,
346
+ };
347
+ projectMemberAbility_1.projectMemberAbilities[role](testMember, roleBuilder);
348
+ const roleAbility = roleBuilder.build();
349
+ // Build scope-based ability
350
+ const scopes = (0, roleToScopeMapping_1.getNonEnterpriseScopesForRole)(role);
351
+ const scopeBuilder = new ability_1.AbilityBuilder(ability_1.Ability);
352
+ (0, scopeAbilityBuilder_1.buildAbilityFromScopes)({
353
+ projectUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.projectUuid,
354
+ userUuid: projectMemberAbility_mock_1.PROJECT_EDITOR.userUuid,
355
+ scopes,
356
+ isEnterprise: false,
357
+ organizationRole: 'editor',
358
+ permissionsConfig: {
359
+ pat: {
360
+ enabled: false,
361
+ allowedOrgRoles: [],
362
+ },
363
+ },
364
+ }, scopeBuilder);
365
+ const scopeAbility = scopeBuilder.build();
366
+ // Test key permissions for each role - assert strict equivalence
367
+ testCases.forEach((testCase) => {
368
+ const subjectWithResource = (0, ability_1.subject)(testCase.subject, testCase.resource);
369
+ const roleResult = roleAbility.can(testCase.action, subjectWithResource);
370
+ const scopeResult = scopeAbility.can(testCase.action, subjectWithResource);
371
+ // Assert that both systems return the same result with detailed context
372
+ if (scopeResult !== roleResult) {
373
+ throw new Error(`Permission mismatch for ${role} role:\n` +
374
+ ` Action: ${testCase.action}\n` +
375
+ ` Subject: ${testCase.subject}\n` +
376
+ ` Resource: ${JSON.stringify(testCase.resource, null, 2)}\n` +
377
+ ` Role-based result: ${roleResult}\n` +
378
+ ` Scope-based result: ${scopeResult}\n` +
379
+ ` Expected: Both systems should return ${roleResult}`);
380
+ }
381
+ expect(scopeResult).toBe(roleResult);
382
+ });
383
+ });
384
+ });
385
+ });
386
+ describe('Combined Organization and Project Roles', () => {
387
+ const testCases = [
388
+ {
389
+ action: 'view',
390
+ subject: 'Dashboard',
391
+ resource: {
392
+ organizationUuid: 'org-uuid-test',
393
+ projectUuid: 'project-uuid-test',
394
+ isPrivate: false,
395
+ },
396
+ },
397
+ {
398
+ action: 'create',
399
+ subject: 'Space',
400
+ resource: {
401
+ organizationUuid: 'org-uuid-test',
402
+ projectUuid: 'project-uuid-test',
403
+ },
404
+ },
405
+ {
406
+ action: 'manage',
407
+ subject: 'Space',
408
+ resource: {
409
+ organizationUuid: 'org-uuid-test',
410
+ projectUuid: 'project-uuid-test',
411
+ isPrivate: false,
412
+ },
413
+ },
414
+ {
415
+ action: 'manage',
416
+ subject: 'Project',
417
+ resource: { projectUuid: 'project-uuid-test' },
418
+ },
419
+ {
420
+ action: 'manage',
421
+ subject: 'Validation',
422
+ resource: { projectUuid: 'project-uuid-test' },
423
+ },
424
+ {
425
+ action: 'view',
426
+ subject: 'Analytics',
427
+ resource: { projectUuid: 'project-uuid-test' },
428
+ },
429
+ ];
430
+ const roleCombinations = [
431
+ {
432
+ description: 'viewer org + viewer project',
433
+ orgRole: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
434
+ projectRole: projectMemberRole_1.ProjectMemberRole.VIEWER,
435
+ },
436
+ {
437
+ description: 'viewer org + developer project',
438
+ orgRole: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
439
+ projectRole: projectMemberRole_1.ProjectMemberRole.DEVELOPER,
440
+ },
441
+ {
442
+ description: 'editor org + developer project',
443
+ orgRole: organizationMemberProfile_1.OrganizationMemberRole.EDITOR,
444
+ projectRole: projectMemberRole_1.ProjectMemberRole.DEVELOPER,
445
+ },
446
+ {
447
+ description: 'developer org + admin project',
448
+ orgRole: organizationMemberProfile_1.OrganizationMemberRole.DEVELOPER,
449
+ projectRole: projectMemberRole_1.ProjectMemberRole.ADMIN,
450
+ },
451
+ {
452
+ description: 'viewer org + admin project',
453
+ orgRole: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
454
+ projectRole: projectMemberRole_1.ProjectMemberRole.ADMIN,
455
+ },
456
+ ];
457
+ roleCombinations.forEach(({ description, orgRole, projectRole }) => {
458
+ it(`should have equivalent abilities for ${description}`, () => {
459
+ const user = {
460
+ role: orgRole,
461
+ organizationUuid: 'org-uuid-test',
462
+ userUuid: 'user-uuid-test',
463
+ roleUuid: undefined,
464
+ };
465
+ const projectProfiles = [
466
+ {
467
+ projectUuid: 'project-uuid-test',
468
+ role: projectRole,
469
+ userUuid: 'user-uuid-test',
470
+ roleUuid: undefined,
471
+ },
472
+ ];
473
+ // Build ability using the combined role-based system
474
+ const roleBasedBuilder = (0, index_1.getUserAbilityBuilder)({
475
+ user,
476
+ projectProfiles,
477
+ permissionsConfig: {
478
+ pat: {
479
+ enabled: false,
480
+ allowedOrgRoles: [],
481
+ },
482
+ },
483
+ customRoleScopes: {},
484
+ customRolesEnabled: false,
485
+ isEnterprise: false,
486
+ });
487
+ const roleBasedAbility = roleBasedBuilder.build();
488
+ // Build equivalent scope-based ability
489
+ // Convert OrganizationMemberRole to ProjectMemberRole for scope mapping
490
+ // Note: This is a simplification - in reality, org roles may have different scope mappings
491
+ const orgRoleAsProjectRole = orgRole;
492
+ const orgScopes = (0, roleToScopeMapping_1.getNonEnterpriseScopesForRole)(orgRoleAsProjectRole);
493
+ const projectScopes = (0, roleToScopeMapping_1.getNonEnterpriseScopesForRole)(projectRole);
494
+ const allScopes = [
495
+ ...new Set([...orgScopes, ...projectScopes]),
496
+ ]; // Remove duplicates
497
+ const scopeBuilder = new ability_1.AbilityBuilder(ability_1.Ability);
498
+ (0, scopeAbilityBuilder_1.buildAbilityFromScopes)({
499
+ organizationUuid: 'org-uuid-test',
500
+ userUuid: 'user-uuid-test',
501
+ scopes: orgScopes,
502
+ isEnterprise: false,
503
+ organizationRole: orgRole,
504
+ permissionsConfig: {
505
+ pat: {
506
+ enabled: false,
507
+ allowedOrgRoles: [],
508
+ },
509
+ },
510
+ }, scopeBuilder);
511
+ (0, scopeAbilityBuilder_1.buildAbilityFromScopes)({
512
+ projectUuid: projectProfiles[0].projectUuid,
513
+ userUuid: 'user-uuid-test',
514
+ scopes: projectScopes,
515
+ isEnterprise: false,
516
+ organizationRole: orgRole,
517
+ permissionsConfig: {
518
+ pat: {
519
+ enabled: false,
520
+ allowedOrgRoles: [],
521
+ },
522
+ },
523
+ }, scopeBuilder);
524
+ const scopeBasedAbility = scopeBuilder.build();
525
+ // Test each permission combination
526
+ testCases.forEach((testCase) => {
527
+ const subjectWithResource = (0, ability_1.subject)(testCase.subject, testCase.resource);
528
+ const roleBasedResult = roleBasedAbility.can(testCase.action, subjectWithResource);
529
+ const scopeBasedResult = scopeBasedAbility.can(testCase.action, subjectWithResource);
530
+ // Provide detailed error information for mismatches
531
+ if (roleBasedResult !== scopeBasedResult) {
532
+ throw new Error(`Permission mismatch for ${description}:\n` +
533
+ ` Action: ${testCase.action}\n` +
534
+ ` Subject: ${testCase.subject}\n` +
535
+ ` Resource: ${JSON.stringify(testCase.resource, null, 2)}\n` +
536
+ ` Role-based result: ${roleBasedResult}\n` +
537
+ ` Scope-based result: ${scopeBasedResult}\n` +
538
+ ` Organization role: ${orgRole}\n` +
539
+ ` Project role: ${projectRole}\n` +
540
+ ` Combined scopes: ${allScopes.length} scopes\n` +
541
+ ` Expected: Both systems should return ${roleBasedResult}`);
542
+ }
543
+ expect(scopeBasedResult).toBe(roleBasedResult);
544
+ });
545
+ });
546
+ });
547
+ });
548
+ });
549
+ //# sourceMappingURL=roleToScopeMapping.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roleToScopeMapping.test.js","sourceRoot":"","sources":["../../../src/authorization/roleToScopeMapping.test.ts"],"names":[],"mappings":"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"}