guardrail-core 1.0.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.
Files changed (189) hide show
  1. package/dist/__tests__/autopilot.test.d.ts +7 -0
  2. package/dist/__tests__/autopilot.test.d.ts.map +1 -0
  3. package/dist/__tests__/autopilot.test.js +156 -0
  4. package/dist/__tests__/tier-config.test.d.ts +9 -0
  5. package/dist/__tests__/tier-config.test.d.ts.map +1 -0
  6. package/dist/__tests__/tier-config.test.js +230 -0
  7. package/dist/__tests__/utils/hash-inline.test.d.ts +2 -0
  8. package/dist/__tests__/utils/hash-inline.test.d.ts.map +1 -0
  9. package/dist/__tests__/utils/hash-inline.test.js +62 -0
  10. package/dist/__tests__/utils/hash.test.d.ts +3 -0
  11. package/dist/__tests__/utils/hash.test.d.ts.map +1 -0
  12. package/dist/__tests__/utils/hash.test.js +95 -0
  13. package/dist/__tests__/utils/simple.test.d.ts +1 -0
  14. package/dist/__tests__/utils/simple.test.d.ts.map +1 -0
  15. package/dist/__tests__/utils/simple.test.js +10 -0
  16. package/dist/__tests__/utils/utils-simple.test.d.ts +1 -0
  17. package/dist/__tests__/utils/utils-simple.test.d.ts.map +1 -0
  18. package/dist/__tests__/utils/utils-simple.test.js +6 -0
  19. package/dist/__tests__/utils/utils.test.d.ts +15 -0
  20. package/dist/__tests__/utils/utils.test.d.ts.map +1 -0
  21. package/dist/__tests__/utils/utils.test.js +172 -0
  22. package/dist/autopilot/autopilot-runner.d.ts +33 -0
  23. package/dist/autopilot/autopilot-runner.d.ts.map +1 -0
  24. package/dist/autopilot/autopilot-runner.js +479 -0
  25. package/dist/autopilot/index.d.ts +6 -0
  26. package/dist/autopilot/index.d.ts.map +1 -0
  27. package/dist/autopilot/index.js +25 -0
  28. package/dist/autopilot/types.d.ts +102 -0
  29. package/dist/autopilot/types.d.ts.map +1 -0
  30. package/dist/autopilot/types.js +18 -0
  31. package/dist/cache/index.d.ts +7 -0
  32. package/dist/cache/index.d.ts.map +1 -0
  33. package/dist/cache/index.js +22 -0
  34. package/dist/cache/redis-cache.d.ts +145 -0
  35. package/dist/cache/redis-cache.d.ts.map +1 -0
  36. package/dist/cache/redis-cache.js +459 -0
  37. package/dist/ci/github-actions.d.ts +77 -0
  38. package/dist/ci/github-actions.d.ts.map +1 -0
  39. package/dist/ci/github-actions.js +277 -0
  40. package/dist/ci/index.d.ts +12 -0
  41. package/dist/ci/index.d.ts.map +1 -0
  42. package/dist/ci/index.js +27 -0
  43. package/dist/ci/pre-commit.d.ts +65 -0
  44. package/dist/ci/pre-commit.d.ts.map +1 -0
  45. package/dist/ci/pre-commit.js +286 -0
  46. package/dist/entitlements.d.ts +149 -0
  47. package/dist/entitlements.d.ts.map +1 -0
  48. package/dist/entitlements.js +464 -0
  49. package/dist/env.d.ts +113 -0
  50. package/dist/env.d.ts.map +1 -0
  51. package/dist/env.js +204 -0
  52. package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts +7 -0
  53. package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts.map +1 -0
  54. package/dist/fix-packs/__tests__/generate-fix-packs.test.js +250 -0
  55. package/dist/fix-packs/generate-fix-packs.d.ts +15 -0
  56. package/dist/fix-packs/generate-fix-packs.d.ts.map +1 -0
  57. package/dist/fix-packs/generate-fix-packs.js +505 -0
  58. package/dist/fix-packs/index.d.ts +8 -0
  59. package/dist/fix-packs/index.d.ts.map +1 -0
  60. package/dist/fix-packs/index.js +23 -0
  61. package/dist/fix-packs/types.d.ts +113 -0
  62. package/dist/fix-packs/types.d.ts.map +1 -0
  63. package/dist/fix-packs/types.js +71 -0
  64. package/dist/index.d.ts +13 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +28 -0
  67. package/dist/metrics/prometheus.d.ts +99 -0
  68. package/dist/metrics/prometheus.d.ts.map +1 -0
  69. package/dist/metrics/prometheus.js +306 -0
  70. package/dist/quota-ledger.d.ts +119 -0
  71. package/dist/quota-ledger.d.ts.map +1 -0
  72. package/dist/quota-ledger.js +462 -0
  73. package/dist/rbac/__tests__/permissions.test.d.ts +8 -0
  74. package/dist/rbac/__tests__/permissions.test.d.ts.map +1 -0
  75. package/dist/rbac/__tests__/permissions.test.js +350 -0
  76. package/dist/rbac/index.d.ts +9 -0
  77. package/dist/rbac/index.d.ts.map +1 -0
  78. package/dist/rbac/index.js +32 -0
  79. package/dist/rbac/permissions.d.ts +71 -0
  80. package/dist/rbac/permissions.d.ts.map +1 -0
  81. package/dist/rbac/permissions.js +247 -0
  82. package/dist/rbac/types.d.ts +69 -0
  83. package/dist/rbac/types.d.ts.map +1 -0
  84. package/dist/rbac/types.js +213 -0
  85. package/dist/tier-config.d.ts +203 -0
  86. package/dist/tier-config.d.ts.map +1 -0
  87. package/dist/tier-config.js +675 -0
  88. package/dist/types.d.ts +365 -0
  89. package/dist/types.d.ts.map +1 -0
  90. package/dist/types.js +5 -0
  91. package/dist/utils.d.ts +36 -0
  92. package/dist/utils.d.ts.map +1 -0
  93. package/dist/utils.js +127 -0
  94. package/dist/verified-autofix/__tests__/format-validator.test.d.ts +11 -0
  95. package/dist/verified-autofix/__tests__/format-validator.test.d.ts.map +1 -0
  96. package/dist/verified-autofix/__tests__/format-validator.test.js +285 -0
  97. package/dist/verified-autofix/__tests__/pipeline.test.d.ts +11 -0
  98. package/dist/verified-autofix/__tests__/pipeline.test.d.ts.map +1 -0
  99. package/dist/verified-autofix/__tests__/pipeline.test.js +389 -0
  100. package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts +11 -0
  101. package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts.map +1 -0
  102. package/dist/verified-autofix/__tests__/repo-fingerprint.test.js +236 -0
  103. package/dist/verified-autofix/__tests__/workspace.test.d.ts +11 -0
  104. package/dist/verified-autofix/__tests__/workspace.test.d.ts.map +1 -0
  105. package/dist/verified-autofix/__tests__/workspace.test.js +314 -0
  106. package/dist/verified-autofix/format-validator.d.ts +101 -0
  107. package/dist/verified-autofix/format-validator.d.ts.map +1 -0
  108. package/dist/verified-autofix/format-validator.js +446 -0
  109. package/dist/verified-autofix/index.d.ts +14 -0
  110. package/dist/verified-autofix/index.d.ts.map +1 -0
  111. package/dist/verified-autofix/index.js +39 -0
  112. package/dist/verified-autofix/pipeline.d.ts +68 -0
  113. package/dist/verified-autofix/pipeline.d.ts.map +1 -0
  114. package/dist/verified-autofix/pipeline.js +330 -0
  115. package/dist/verified-autofix/repo-fingerprint.d.ts +56 -0
  116. package/dist/verified-autofix/repo-fingerprint.d.ts.map +1 -0
  117. package/dist/verified-autofix/repo-fingerprint.js +396 -0
  118. package/dist/verified-autofix/workspace.d.ts +83 -0
  119. package/dist/verified-autofix/workspace.d.ts.map +1 -0
  120. package/dist/verified-autofix/workspace.js +454 -0
  121. package/dist/verified-autofix.d.ts +182 -0
  122. package/dist/verified-autofix.d.ts.map +1 -0
  123. package/dist/verified-autofix.js +1021 -0
  124. package/dist/visualization/dependency-graph.d.ts +79 -0
  125. package/dist/visualization/dependency-graph.d.ts.map +1 -0
  126. package/dist/visualization/dependency-graph.js +399 -0
  127. package/dist/visualization/index.d.ts +5 -0
  128. package/dist/visualization/index.d.ts.map +1 -0
  129. package/dist/visualization/index.js +20 -0
  130. package/package.json +29 -0
  131. package/src/__tests__/autopilot.test.ts +196 -0
  132. package/src/__tests__/tier-config.test.ts +289 -0
  133. package/src/__tests__/utils/hash-inline.test.ts +76 -0
  134. package/src/__tests__/utils/hash.test.ts +119 -0
  135. package/src/__tests__/utils/simple.test.ts +10 -0
  136. package/src/__tests__/utils/utils-simple.test.ts +5 -0
  137. package/src/__tests__/utils/utils.test.ts +203 -0
  138. package/src/autopilot/autopilot-runner.ts +503 -0
  139. package/src/autopilot/index.ts +6 -0
  140. package/src/autopilot/types.ts +119 -0
  141. package/src/cache/index.ts +7 -0
  142. package/src/cache/redis-cache.d.ts +155 -0
  143. package/src/cache/redis-cache.d.ts.map +1 -0
  144. package/src/cache/redis-cache.ts +517 -0
  145. package/src/ci/github-actions.ts +335 -0
  146. package/src/ci/index.ts +12 -0
  147. package/src/ci/pre-commit.ts +338 -0
  148. package/src/db/usage-schema.prisma +114 -0
  149. package/src/entitlements.ts +570 -0
  150. package/src/env.d.ts +68 -0
  151. package/src/env.d.ts.map +1 -0
  152. package/src/env.ts +247 -0
  153. package/src/fix-packs/__tests__/generate-fix-packs.test.ts +317 -0
  154. package/src/fix-packs/generate-fix-packs.ts +577 -0
  155. package/src/fix-packs/index.ts +8 -0
  156. package/src/fix-packs/types.ts +206 -0
  157. package/src/index.d.ts +7 -0
  158. package/src/index.d.ts.map +1 -0
  159. package/src/index.ts +12 -0
  160. package/src/metrics/prometheus.d.ts +104 -0
  161. package/src/metrics/prometheus.d.ts.map +1 -0
  162. package/src/metrics/prometheus.ts +446 -0
  163. package/src/quota-ledger.ts +548 -0
  164. package/src/rbac/__tests__/permissions.test.ts +446 -0
  165. package/src/rbac/index.ts +46 -0
  166. package/src/rbac/permissions.ts +301 -0
  167. package/src/rbac/types.ts +298 -0
  168. package/src/tier-config.json +157 -0
  169. package/src/tier-config.ts +815 -0
  170. package/src/types.d.ts +365 -0
  171. package/src/types.d.ts.map +1 -0
  172. package/src/types.ts +441 -0
  173. package/src/utils.d.ts +36 -0
  174. package/src/utils.d.ts.map +1 -0
  175. package/src/utils.ts +140 -0
  176. package/src/verified-autofix/__tests__/format-validator.test.ts +335 -0
  177. package/src/verified-autofix/__tests__/pipeline.test.ts +419 -0
  178. package/src/verified-autofix/__tests__/repo-fingerprint.test.ts +241 -0
  179. package/src/verified-autofix/__tests__/workspace.test.ts +373 -0
  180. package/src/verified-autofix/format-validator.ts +517 -0
  181. package/src/verified-autofix/index.ts +63 -0
  182. package/src/verified-autofix/pipeline.ts +403 -0
  183. package/src/verified-autofix/repo-fingerprint.ts +459 -0
  184. package/src/verified-autofix/workspace.ts +531 -0
  185. package/src/verified-autofix.ts +1187 -0
  186. package/src/visualization/dependency-graph.d.ts +85 -0
  187. package/src/visualization/dependency-graph.d.ts.map +1 -0
  188. package/src/visualization/dependency-graph.ts +495 -0
  189. package/src/visualization/index.ts +5 -0
@@ -0,0 +1,350 @@
1
+ "use strict";
2
+ /**
3
+ * RBAC Permission Tests
4
+ *
5
+ * Tests for role-based access control permission checking logic.
6
+ * Validates acceptance criteria for different roles.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const permissions_1 = require("../permissions");
10
+ const types_1 = require("../types");
11
+ // =============================================================================
12
+ // TEST HELPERS
13
+ // =============================================================================
14
+ function createContext(role, tier) {
15
+ return {
16
+ userId: 'user_123',
17
+ teamId: 'team_456',
18
+ role,
19
+ permissions: (0, permissions_1.getEffectivePermissions)(role),
20
+ tier,
21
+ };
22
+ }
23
+ // =============================================================================
24
+ // ROLE VALIDATION TESTS
25
+ // =============================================================================
26
+ describe('Role Validation', () => {
27
+ test('isValidRole returns true for valid roles', () => {
28
+ expect((0, permissions_1.isValidRole)('owner')).toBe(true);
29
+ expect((0, permissions_1.isValidRole)('admin')).toBe(true);
30
+ expect((0, permissions_1.isValidRole)('dev')).toBe(true);
31
+ expect((0, permissions_1.isValidRole)('viewer')).toBe(true);
32
+ expect((0, permissions_1.isValidRole)('compliance-auditor')).toBe(true);
33
+ });
34
+ test('isValidRole returns false for invalid roles', () => {
35
+ expect((0, permissions_1.isValidRole)('superadmin')).toBe(false);
36
+ expect((0, permissions_1.isValidRole)('')).toBe(false);
37
+ expect((0, permissions_1.isValidRole)('ADMIN')).toBe(false);
38
+ });
39
+ test('parseRole returns role for valid input', () => {
40
+ expect((0, permissions_1.parseRole)('owner')).toBe('owner');
41
+ expect((0, permissions_1.parseRole)('admin')).toBe('admin');
42
+ });
43
+ test('parseRole returns null for invalid input', () => {
44
+ expect((0, permissions_1.parseRole)('invalid')).toBeNull();
45
+ expect((0, permissions_1.parseRole)('')).toBeNull();
46
+ });
47
+ });
48
+ // =============================================================================
49
+ // PERMISSION VALIDATION TESTS
50
+ // =============================================================================
51
+ describe('Permission Validation', () => {
52
+ test('isValidPermission returns true for valid permissions', () => {
53
+ expect((0, permissions_1.isValidPermission)('manage_team')).toBe(true);
54
+ expect((0, permissions_1.isValidPermission)('view_audit')).toBe(true);
55
+ expect((0, permissions_1.isValidPermission)('run_autopilot')).toBe(true);
56
+ });
57
+ test('isValidPermission returns false for invalid permissions', () => {
58
+ expect((0, permissions_1.isValidPermission)('invalid_permission')).toBe(false);
59
+ expect((0, permissions_1.isValidPermission)('')).toBe(false);
60
+ });
61
+ });
62
+ // =============================================================================
63
+ // ROLE HIERARCHY TESTS
64
+ // =============================================================================
65
+ describe('Role Hierarchy', () => {
66
+ test('compareRoles returns correct hierarchy order', () => {
67
+ expect((0, permissions_1.compareRoles)('owner', 'admin')).toBeGreaterThan(0);
68
+ expect((0, permissions_1.compareRoles)('admin', 'dev')).toBeGreaterThan(0);
69
+ expect((0, permissions_1.compareRoles)('dev', 'viewer')).toBeGreaterThan(0);
70
+ expect((0, permissions_1.compareRoles)('viewer', 'owner')).toBeLessThan(0);
71
+ expect((0, permissions_1.compareRoles)('admin', 'admin')).toBe(0);
72
+ });
73
+ test('isRoleAtLeast correctly compares roles', () => {
74
+ expect((0, permissions_1.isRoleAtLeast)('owner', 'admin')).toBe(true);
75
+ expect((0, permissions_1.isRoleAtLeast)('owner', 'owner')).toBe(true);
76
+ expect((0, permissions_1.isRoleAtLeast)('admin', 'owner')).toBe(false);
77
+ expect((0, permissions_1.isRoleAtLeast)('dev', 'viewer')).toBe(true);
78
+ expect((0, permissions_1.isRoleAtLeast)('viewer', 'dev')).toBe(false);
79
+ });
80
+ });
81
+ // =============================================================================
82
+ // PERMISSION CHECKING TESTS
83
+ // =============================================================================
84
+ describe('Permission Checking', () => {
85
+ test('roleHasPermission returns correct values', () => {
86
+ expect((0, permissions_1.roleHasPermission)('owner', 'manage_billing')).toBe(true);
87
+ expect((0, permissions_1.roleHasPermission)('admin', 'manage_billing')).toBe(false);
88
+ expect((0, permissions_1.roleHasPermission)('viewer', 'view_dashboard')).toBe(true);
89
+ expect((0, permissions_1.roleHasPermission)('viewer', 'run_autopilot')).toBe(false);
90
+ });
91
+ test('hasPermission returns allowed for valid permissions', () => {
92
+ const ownerContext = createContext('owner');
93
+ const result = (0, permissions_1.hasPermission)(ownerContext, 'manage_billing');
94
+ expect(result.allowed).toBe(true);
95
+ });
96
+ test('hasPermission returns denied with reason for missing permissions', () => {
97
+ const viewerContext = createContext('viewer');
98
+ const result = (0, permissions_1.hasPermission)(viewerContext, 'manage_team');
99
+ expect(result.allowed).toBe(false);
100
+ expect(result.reason).toContain('manage_team');
101
+ expect(result.requiredPermissions).toContain('manage_team');
102
+ });
103
+ test('hasAllPermissions requires all permissions', () => {
104
+ const adminContext = createContext('admin');
105
+ const allPresent = (0, permissions_1.hasAllPermissions)(adminContext, ['manage_team', 'run_autopilot']);
106
+ expect(allPresent.allowed).toBe(true);
107
+ const someMissing = (0, permissions_1.hasAllPermissions)(adminContext, ['manage_team', 'manage_billing']);
108
+ expect(someMissing.allowed).toBe(false);
109
+ });
110
+ test('hasAnyPermission allows with any matching permission', () => {
111
+ const devContext = createContext('dev');
112
+ const onePresent = (0, permissions_1.hasAnyPermission)(devContext, ['run_scan', 'manage_billing']);
113
+ expect(onePresent.allowed).toBe(true);
114
+ const nonePresent = (0, permissions_1.hasAnyPermission)(devContext, ['manage_billing', 'admin_settings']);
115
+ expect(nonePresent.allowed).toBe(false);
116
+ });
117
+ });
118
+ // =============================================================================
119
+ // ACCEPTANCE CRITERIA TESTS
120
+ // =============================================================================
121
+ describe('Acceptance Criteria: Compliance Auditor', () => {
122
+ const auditorContext = createContext('compliance-auditor');
123
+ test('can view audit logs', () => {
124
+ const result = (0, permissions_1.hasPermission)(auditorContext, 'view_audit');
125
+ expect(result.allowed).toBe(true);
126
+ });
127
+ test('can export audit logs', () => {
128
+ const result = (0, permissions_1.hasPermission)(auditorContext, 'export_audit');
129
+ expect(result.allowed).toBe(true);
130
+ });
131
+ test('cannot edit policies', () => {
132
+ const result = (0, permissions_1.hasPermission)(auditorContext, 'manage_policies');
133
+ expect(result.allowed).toBe(false);
134
+ });
135
+ test('cannot manage team', () => {
136
+ const result = (0, permissions_1.hasPermission)(auditorContext, 'manage_team');
137
+ expect(result.allowed).toBe(false);
138
+ });
139
+ test('cannot run autopilot', () => {
140
+ const result = (0, permissions_1.hasPermission)(auditorContext, 'run_autopilot');
141
+ expect(result.allowed).toBe(false);
142
+ });
143
+ });
144
+ describe('Acceptance Criteria: Viewer', () => {
145
+ const viewerContext = createContext('viewer');
146
+ test('can see dashboard', () => {
147
+ const result = (0, permissions_1.hasPermission)(viewerContext, 'view_dashboard');
148
+ expect(result.allowed).toBe(true);
149
+ });
150
+ test('can view reports', () => {
151
+ const result = (0, permissions_1.hasPermission)(viewerContext, 'view_reports');
152
+ expect(result.allowed).toBe(true);
153
+ });
154
+ test('cannot run Reality Mode', () => {
155
+ const result = (0, permissions_1.hasPermission)(viewerContext, 'run_reality');
156
+ expect(result.allowed).toBe(false);
157
+ });
158
+ test('cannot run Autopilot', () => {
159
+ const result = (0, permissions_1.hasPermission)(viewerContext, 'run_autopilot');
160
+ expect(result.allowed).toBe(false);
161
+ });
162
+ test('cannot run scans', () => {
163
+ const result = (0, permissions_1.hasPermission)(viewerContext, 'run_scan');
164
+ expect(result.allowed).toBe(false);
165
+ });
166
+ test('cannot manage policies', () => {
167
+ const result = (0, permissions_1.hasPermission)(viewerContext, 'manage_policies');
168
+ expect(result.allowed).toBe(false);
169
+ });
170
+ });
171
+ describe('Acceptance Criteria: Developer', () => {
172
+ const devContext = createContext('dev');
173
+ test('can run scans', () => {
174
+ const result = (0, permissions_1.hasPermission)(devContext, 'run_scan');
175
+ expect(result.allowed).toBe(true);
176
+ });
177
+ test('can run Reality Mode', () => {
178
+ const result = (0, permissions_1.hasPermission)(devContext, 'run_reality');
179
+ expect(result.allowed).toBe(true);
180
+ });
181
+ test('can run fixes', () => {
182
+ const result = (0, permissions_1.hasPermission)(devContext, 'run_fix');
183
+ expect(result.allowed).toBe(true);
184
+ });
185
+ test('cannot run Autopilot', () => {
186
+ const result = (0, permissions_1.hasPermission)(devContext, 'run_autopilot');
187
+ expect(result.allowed).toBe(false);
188
+ });
189
+ test('cannot manage team', () => {
190
+ const result = (0, permissions_1.hasPermission)(devContext, 'manage_team');
191
+ expect(result.allowed).toBe(false);
192
+ });
193
+ });
194
+ describe('Acceptance Criteria: Admin', () => {
195
+ const adminContext = createContext('admin');
196
+ test('can manage team', () => {
197
+ const result = (0, permissions_1.hasPermission)(adminContext, 'manage_team');
198
+ expect(result.allowed).toBe(true);
199
+ });
200
+ test('can run Autopilot', () => {
201
+ const result = (0, permissions_1.hasPermission)(adminContext, 'run_autopilot');
202
+ expect(result.allowed).toBe(true);
203
+ });
204
+ test('can manage policies', () => {
205
+ const result = (0, permissions_1.hasPermission)(adminContext, 'manage_policies');
206
+ expect(result.allowed).toBe(true);
207
+ });
208
+ test('cannot manage billing', () => {
209
+ const result = (0, permissions_1.hasPermission)(adminContext, 'manage_billing');
210
+ expect(result.allowed).toBe(false);
211
+ });
212
+ });
213
+ describe('Acceptance Criteria: Owner', () => {
214
+ const ownerContext = createContext('owner');
215
+ test('has all permissions', () => {
216
+ const permissions = [
217
+ 'manage_team',
218
+ 'manage_billing',
219
+ 'run_autopilot',
220
+ 'manage_policies',
221
+ 'admin_settings',
222
+ ];
223
+ for (const permission of permissions) {
224
+ const result = (0, permissions_1.hasPermission)(ownerContext, permission);
225
+ expect(result.allowed).toBe(true);
226
+ }
227
+ });
228
+ });
229
+ // =============================================================================
230
+ // ROLE ASSIGNMENT TESTS
231
+ // =============================================================================
232
+ describe('Role Assignment', () => {
233
+ test('owner can assign any role', () => {
234
+ expect((0, permissions_1.canAssignRole)('owner', 'admin').allowed).toBe(true);
235
+ expect((0, permissions_1.canAssignRole)('owner', 'dev').allowed).toBe(true);
236
+ expect((0, permissions_1.canAssignRole)('owner', 'viewer').allowed).toBe(true);
237
+ expect((0, permissions_1.canAssignRole)('owner', 'compliance-auditor').allowed).toBe(true);
238
+ });
239
+ test('admin can assign lower roles', () => {
240
+ expect((0, permissions_1.canAssignRole)('admin', 'dev').allowed).toBe(true);
241
+ expect((0, permissions_1.canAssignRole)('admin', 'viewer').allowed).toBe(true);
242
+ });
243
+ test('admin cannot assign admin or owner', () => {
244
+ expect((0, permissions_1.canAssignRole)('admin', 'admin').allowed).toBe(false);
245
+ expect((0, permissions_1.canAssignRole)('admin', 'owner').allowed).toBe(false);
246
+ });
247
+ test('dev cannot assign roles', () => {
248
+ expect((0, permissions_1.canAssignRole)('dev', 'viewer').allowed).toBe(false);
249
+ });
250
+ test('viewer cannot assign roles', () => {
251
+ expect((0, permissions_1.canAssignRole)('viewer', 'viewer').allowed).toBe(false);
252
+ });
253
+ });
254
+ // =============================================================================
255
+ // MEMBER REMOVAL TESTS
256
+ // =============================================================================
257
+ describe('Member Removal', () => {
258
+ test('owner can remove any non-owner member', () => {
259
+ expect((0, permissions_1.canRemoveMember)('owner', 'admin').allowed).toBe(true);
260
+ expect((0, permissions_1.canRemoveMember)('owner', 'dev').allowed).toBe(true);
261
+ expect((0, permissions_1.canRemoveMember)('owner', 'viewer').allowed).toBe(true);
262
+ });
263
+ test('nobody can remove owner', () => {
264
+ expect((0, permissions_1.canRemoveMember)('owner', 'owner').allowed).toBe(false);
265
+ expect((0, permissions_1.canRemoveMember)('admin', 'owner').allowed).toBe(false);
266
+ });
267
+ test('admin can remove lower roles', () => {
268
+ expect((0, permissions_1.canRemoveMember)('admin', 'dev').allowed).toBe(true);
269
+ expect((0, permissions_1.canRemoveMember)('admin', 'viewer').allowed).toBe(true);
270
+ });
271
+ test('admin cannot remove admin', () => {
272
+ expect((0, permissions_1.canRemoveMember)('admin', 'admin').allowed).toBe(false);
273
+ });
274
+ test('dev cannot remove members', () => {
275
+ expect((0, permissions_1.canRemoveMember)('dev', 'viewer').allowed).toBe(false);
276
+ });
277
+ });
278
+ // =============================================================================
279
+ // PERMISSION MATRIX TESTS
280
+ // =============================================================================
281
+ describe('Permission Matrix', () => {
282
+ test('generatePermissionMatrix returns valid structure', () => {
283
+ const matrix = (0, permissions_1.generatePermissionMatrix)();
284
+ expect(matrix.roles).toEqual(types_1.ROLES);
285
+ expect(matrix.permissions.length).toBeGreaterThan(0);
286
+ expect(typeof matrix.matrix).toBe('object');
287
+ });
288
+ test('matrix contains all role-permission combinations', () => {
289
+ const matrix = (0, permissions_1.generatePermissionMatrix)();
290
+ for (const role of types_1.ROLES) {
291
+ expect(matrix.matrix[role]).toBeDefined();
292
+ for (const permission of matrix.permissions) {
293
+ expect(typeof matrix.matrix[role][permission]).toBe('boolean');
294
+ }
295
+ }
296
+ });
297
+ test('matrix values match roleHasPermission', () => {
298
+ const matrix = (0, permissions_1.generatePermissionMatrix)();
299
+ for (const role of types_1.ROLES) {
300
+ for (const permission of matrix.permissions) {
301
+ const matrixValue = matrix.matrix[role][permission];
302
+ const functionValue = (0, permissions_1.roleHasPermission)(role, permission);
303
+ expect(matrixValue).toBe(functionValue);
304
+ }
305
+ }
306
+ });
307
+ });
308
+ // =============================================================================
309
+ // MINIMUM ROLE TESTS
310
+ // =============================================================================
311
+ describe('Minimum Role for Permission', () => {
312
+ test('getMinimumRoleForPermission returns correct minimum role', () => {
313
+ expect((0, permissions_1.getMinimumRoleForPermission)('view_dashboard')).toBe('viewer');
314
+ expect((0, permissions_1.getMinimumRoleForPermission)('view_audit')).toBe('compliance-auditor');
315
+ expect((0, permissions_1.getMinimumRoleForPermission)('run_scan')).toBe('dev');
316
+ expect((0, permissions_1.getMinimumRoleForPermission)('manage_team')).toBe('admin');
317
+ expect((0, permissions_1.getMinimumRoleForPermission)('manage_billing')).toBe('owner');
318
+ });
319
+ });
320
+ // =============================================================================
321
+ // EFFECTIVE PERMISSIONS TESTS
322
+ // =============================================================================
323
+ describe('Effective Permissions', () => {
324
+ test('getEffectivePermissions returns array for each role', () => {
325
+ for (const role of types_1.ROLES) {
326
+ const permissions = (0, permissions_1.getEffectivePermissions)(role);
327
+ expect(Array.isArray(permissions)).toBe(true);
328
+ expect(permissions.length).toBeGreaterThan(0);
329
+ }
330
+ });
331
+ test('owner has more permissions than admin', () => {
332
+ const ownerPerms = (0, permissions_1.getEffectivePermissions)('owner');
333
+ const adminPerms = (0, permissions_1.getEffectivePermissions)('admin');
334
+ expect(ownerPerms.length).toBeGreaterThan(adminPerms.length);
335
+ });
336
+ test('admin has more permissions than dev', () => {
337
+ const adminPerms = (0, permissions_1.getEffectivePermissions)('admin');
338
+ const devPerms = (0, permissions_1.getEffectivePermissions)('dev');
339
+ expect(adminPerms.length).toBeGreaterThan(devPerms.length);
340
+ });
341
+ test('viewer has fewest permissions', () => {
342
+ const viewerPerms = (0, permissions_1.getEffectivePermissions)('viewer');
343
+ for (const role of types_1.ROLES) {
344
+ if (role !== 'viewer') {
345
+ const otherPerms = (0, permissions_1.getEffectivePermissions)(role);
346
+ expect(viewerPerms.length).toBeLessThanOrEqual(otherPerms.length);
347
+ }
348
+ }
349
+ });
350
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * RBAC Module - Role-Based Access Control
3
+ *
4
+ * Exports all RBAC types, permissions, and utilities.
5
+ */
6
+ export type { Permission, PermissionCheck, PermissionMatrix, RBACContext, Role, RoleAssignment, RoleMetadata, TeamInvitation, TeamMemberWithRole, } from './types';
7
+ export { PERMISSIONS, ROLE_HIERARCHY, ROLE_METADATA, ROLE_PERMISSIONS, ROLES, } from './types';
8
+ export { canAssignRole, canRemoveMember, checkTierAndPermission, compareRoles, generatePermissionMatrix, getEffectivePermissions, getMinimumRoleForPermission, hasAllPermissions, hasAnyPermission, hasPermission, isRoleAtLeast, isValidPermission, isValidRole, parseRole, roleHasPermission, } from './permissions';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rbac/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,IAAI,EACJ,cAAc,EACd,YAAY,EACZ,cAAc,EACd,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,WAAW,EACX,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,KAAK,GACN,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,YAAY,EACZ,wBAAwB,EACxB,uBAAuB,EACvB,2BAA2B,EAC3B,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,iBAAiB,GAClB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * RBAC Module - Role-Based Access Control
4
+ *
5
+ * Exports all RBAC types, permissions, and utilities.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.roleHasPermission = exports.parseRole = exports.isValidRole = exports.isValidPermission = exports.isRoleAtLeast = exports.hasPermission = exports.hasAnyPermission = exports.hasAllPermissions = exports.getMinimumRoleForPermission = exports.getEffectivePermissions = exports.generatePermissionMatrix = exports.compareRoles = exports.checkTierAndPermission = exports.canRemoveMember = exports.canAssignRole = exports.ROLES = exports.ROLE_PERMISSIONS = exports.ROLE_METADATA = exports.ROLE_HIERARCHY = exports.PERMISSIONS = void 0;
9
+ // Values
10
+ var types_1 = require("./types");
11
+ Object.defineProperty(exports, "PERMISSIONS", { enumerable: true, get: function () { return types_1.PERMISSIONS; } });
12
+ Object.defineProperty(exports, "ROLE_HIERARCHY", { enumerable: true, get: function () { return types_1.ROLE_HIERARCHY; } });
13
+ Object.defineProperty(exports, "ROLE_METADATA", { enumerable: true, get: function () { return types_1.ROLE_METADATA; } });
14
+ Object.defineProperty(exports, "ROLE_PERMISSIONS", { enumerable: true, get: function () { return types_1.ROLE_PERMISSIONS; } });
15
+ Object.defineProperty(exports, "ROLES", { enumerable: true, get: function () { return types_1.ROLES; } });
16
+ // Permission checking
17
+ var permissions_1 = require("./permissions");
18
+ Object.defineProperty(exports, "canAssignRole", { enumerable: true, get: function () { return permissions_1.canAssignRole; } });
19
+ Object.defineProperty(exports, "canRemoveMember", { enumerable: true, get: function () { return permissions_1.canRemoveMember; } });
20
+ Object.defineProperty(exports, "checkTierAndPermission", { enumerable: true, get: function () { return permissions_1.checkTierAndPermission; } });
21
+ Object.defineProperty(exports, "compareRoles", { enumerable: true, get: function () { return permissions_1.compareRoles; } });
22
+ Object.defineProperty(exports, "generatePermissionMatrix", { enumerable: true, get: function () { return permissions_1.generatePermissionMatrix; } });
23
+ Object.defineProperty(exports, "getEffectivePermissions", { enumerable: true, get: function () { return permissions_1.getEffectivePermissions; } });
24
+ Object.defineProperty(exports, "getMinimumRoleForPermission", { enumerable: true, get: function () { return permissions_1.getMinimumRoleForPermission; } });
25
+ Object.defineProperty(exports, "hasAllPermissions", { enumerable: true, get: function () { return permissions_1.hasAllPermissions; } });
26
+ Object.defineProperty(exports, "hasAnyPermission", { enumerable: true, get: function () { return permissions_1.hasAnyPermission; } });
27
+ Object.defineProperty(exports, "hasPermission", { enumerable: true, get: function () { return permissions_1.hasPermission; } });
28
+ Object.defineProperty(exports, "isRoleAtLeast", { enumerable: true, get: function () { return permissions_1.isRoleAtLeast; } });
29
+ Object.defineProperty(exports, "isValidPermission", { enumerable: true, get: function () { return permissions_1.isValidPermission; } });
30
+ Object.defineProperty(exports, "isValidRole", { enumerable: true, get: function () { return permissions_1.isValidRole; } });
31
+ Object.defineProperty(exports, "parseRole", { enumerable: true, get: function () { return permissions_1.parseRole; } });
32
+ Object.defineProperty(exports, "roleHasPermission", { enumerable: true, get: function () { return permissions_1.roleHasPermission; } });
@@ -0,0 +1,71 @@
1
+ /**
2
+ * RBAC Permission Checker
3
+ *
4
+ * Core permission checking logic for role-based access control.
5
+ * Provides functions to verify user permissions against required permissions.
6
+ */
7
+ import { Tier } from '../tier-config';
8
+ import { Permission, PermissionCheck, PermissionMatrix, RBACContext, Role } from './types';
9
+ /**
10
+ * Check if a role has a specific permission
11
+ */
12
+ export declare function roleHasPermission(role: Role, permission: Permission): boolean;
13
+ /**
14
+ * Check if a user has a specific permission based on their role
15
+ */
16
+ export declare function hasPermission(context: RBACContext, permission: Permission): PermissionCheck;
17
+ /**
18
+ * Check if a user has ALL of the specified permissions
19
+ */
20
+ export declare function hasAllPermissions(context: RBACContext, permissions: Permission[]): PermissionCheck;
21
+ /**
22
+ * Check if a user has ANY of the specified permissions
23
+ */
24
+ export declare function hasAnyPermission(context: RBACContext, permissions: Permission[]): PermissionCheck;
25
+ /**
26
+ * Compare two roles and return their relative hierarchy
27
+ * Returns positive if role1 > role2, negative if role1 < role2, 0 if equal
28
+ */
29
+ export declare function compareRoles(role1: Role, role2: Role): number;
30
+ /**
31
+ * Check if role1 is higher than or equal to role2 in the hierarchy
32
+ */
33
+ export declare function isRoleAtLeast(role: Role, minimumRole: Role): boolean;
34
+ /**
35
+ * Get the minimum role required for a specific permission
36
+ */
37
+ export declare function getMinimumRoleForPermission(permission: Permission): Role;
38
+ /**
39
+ * Get all permissions for a role (including inherited)
40
+ */
41
+ export declare function getEffectivePermissions(role: Role): Permission[];
42
+ /**
43
+ * Check if a tier allows a specific operation with RBAC
44
+ */
45
+ export declare function checkTierAndPermission(context: RBACContext, permission: Permission, requiredTier: Tier): PermissionCheck;
46
+ /**
47
+ * Generate a permission matrix for UI display
48
+ */
49
+ export declare function generatePermissionMatrix(): PermissionMatrix;
50
+ /**
51
+ * Check if a user can assign a specific role to another user
52
+ * Users can only assign roles lower than their own
53
+ */
54
+ export declare function canAssignRole(assignerRole: Role, targetRole: Role): PermissionCheck;
55
+ /**
56
+ * Check if a user can remove another user from the team
57
+ */
58
+ export declare function canRemoveMember(removerRole: Role, targetRole: Role): PermissionCheck;
59
+ /**
60
+ * Validate if a string is a valid role
61
+ */
62
+ export declare function isValidRole(role: string): role is Role;
63
+ /**
64
+ * Validate if a string is a valid permission
65
+ */
66
+ export declare function isValidPermission(permission: string): permission is Permission;
67
+ /**
68
+ * Get role from string with validation
69
+ */
70
+ export declare function parseRole(role: string): Role | null;
71
+ //# sourceMappingURL=permissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/rbac/permissions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAc,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,UAAU,EAEV,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,IAAI,EAIL,MAAM,SAAS,CAAC;AAMjB;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAG7E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,UAAU,GACrB,eAAe,CAqBjB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,WAAW,EACpB,WAAW,EAAE,UAAU,EAAE,GACxB,eAAe,CAkBjB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,WAAW,EACpB,WAAW,EAAE,UAAU,EAAE,GACxB,eAAe,CAYjB;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,GAAG,OAAO,CAEpE;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAYxE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,EAAE,CAEhE;AAMD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,IAAI,GACjB,eAAe,CAqBjB;AAMD;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,gBAAgB,CAe3D;AAMD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,IAAI,EAClB,UAAU,EAAE,IAAI,GACf,eAAe,CAsBjB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,IAAI,EACjB,UAAU,EAAE,IAAI,GACf,eAAe,CA0BjB;AAMD;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,IAAI,CAEtD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,IAAI,UAAU,CAE9E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEnD"}