@workos-inc/node 7.16.0 → 7.17.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 (55) hide show
  1. package/lib/common/interfaces/get-options.interface.d.ts +1 -0
  2. package/lib/common/interfaces/post-options.interface.d.ts +1 -0
  3. package/lib/common/utils/fetch-and-deserialize.d.ts +2 -2
  4. package/lib/common/utils/fetch-and-deserialize.js +2 -4
  5. package/lib/fga/fga-live-test.spec.d.ts +1 -0
  6. package/lib/fga/fga-live-test.spec.js +872 -0
  7. package/lib/fga/fga.d.ts +18 -0
  8. package/lib/fga/fga.js +105 -0
  9. package/lib/fga/fga.spec.d.ts +1 -0
  10. package/lib/fga/fga.spec.js +518 -0
  11. package/lib/fga/interfaces/check-op.enum.d.ts +5 -0
  12. package/lib/fga/interfaces/check-op.enum.js +9 -0
  13. package/lib/fga/interfaces/check.interface.d.ts +71 -0
  14. package/lib/fga/interfaces/check.interface.js +21 -0
  15. package/lib/fga/interfaces/index.d.ts +7 -0
  16. package/lib/fga/interfaces/index.js +23 -0
  17. package/lib/fga/interfaces/query.interface.d.ts +30 -0
  18. package/lib/fga/interfaces/query.interface.js +2 -0
  19. package/lib/fga/interfaces/resource.interface.d.ts +60 -0
  20. package/lib/fga/interfaces/resource.interface.js +2 -0
  21. package/lib/fga/interfaces/warrant-op.enum.d.ts +4 -0
  22. package/lib/fga/interfaces/warrant-op.enum.js +8 -0
  23. package/lib/fga/interfaces/warrant-token.interface.d.ts +6 -0
  24. package/lib/fga/interfaces/warrant-token.interface.js +2 -0
  25. package/lib/fga/interfaces/warrant.interface.d.ts +65 -0
  26. package/lib/fga/interfaces/warrant.interface.js +2 -0
  27. package/lib/fga/serializers/check-options.serializer.d.ts +4 -0
  28. package/lib/fga/serializers/check-options.serializer.js +62 -0
  29. package/lib/fga/serializers/create-resource-options.serializer.d.ts +2 -0
  30. package/lib/fga/serializers/create-resource-options.serializer.js +16 -0
  31. package/lib/fga/serializers/delete-resource-options.serializer.d.ts +2 -0
  32. package/lib/fga/serializers/delete-resource-options.serializer.js +15 -0
  33. package/lib/fga/serializers/index.d.ts +11 -0
  34. package/lib/fga/serializers/index.js +27 -0
  35. package/lib/fga/serializers/list-resources-options.serializer.d.ts +2 -0
  36. package/lib/fga/serializers/list-resources-options.serializer.js +12 -0
  37. package/lib/fga/serializers/list-warrants-options.serializer.d.ts +2 -0
  38. package/lib/fga/serializers/list-warrants-options.serializer.js +14 -0
  39. package/lib/fga/serializers/query-options.serializer.d.ts +2 -0
  40. package/lib/fga/serializers/query-options.serializer.js +12 -0
  41. package/lib/fga/serializers/query-result.serializer.d.ts +2 -0
  42. package/lib/fga/serializers/query-result.serializer.js +21 -0
  43. package/lib/fga/serializers/resource.serializer.d.ts +2 -0
  44. package/lib/fga/serializers/resource.serializer.js +9 -0
  45. package/lib/fga/serializers/warrant-token.serializer.d.ts +2 -0
  46. package/lib/fga/serializers/warrant-token.serializer.js +7 -0
  47. package/lib/fga/serializers/warrant.serializer.d.ts +2 -0
  48. package/lib/fga/serializers/warrant.serializer.js +14 -0
  49. package/lib/fga/serializers/write-warrant-options.serializer.d.ts +2 -0
  50. package/lib/fga/serializers/write-warrant-options.serializer.js +27 -0
  51. package/lib/fga/utils/interface-check.d.ts +3 -0
  52. package/lib/fga/utils/interface-check.js +15 -0
  53. package/lib/workos.d.ts +2 -0
  54. package/lib/workos.js +19 -7
  55. package/package.json +1 -1
@@ -0,0 +1,872 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const jest_fetch_mock_1 = require("jest-fetch-mock");
13
+ const workos_1 = require("../workos");
14
+ const interfaces_1 = require("./interfaces");
15
+ describe.skip('FGA Live Test', () => {
16
+ let workos;
17
+ beforeAll(() => {
18
+ (0, jest_fetch_mock_1.disableFetchMocks)();
19
+ workos = new workos_1.WorkOS('API_KEY');
20
+ });
21
+ afterAll(() => {
22
+ (0, jest_fetch_mock_1.enableFetchMocks)();
23
+ });
24
+ it('CRUD resources', () => __awaiter(void 0, void 0, void 0, function* () {
25
+ const resource1 = yield workos.fga.createResource({
26
+ resource: { resourceType: 'document' },
27
+ });
28
+ expect(resource1.resourceType).toEqual('document');
29
+ expect(resource1.resourceId).toBeDefined();
30
+ expect(resource1.meta).toBeUndefined();
31
+ let resource2 = yield workos.fga.createResource({
32
+ resource: { resourceType: 'folder', resourceId: 'planning' },
33
+ });
34
+ let refetchedResource = yield workos.fga.getResource(resource2);
35
+ expect(refetchedResource.resourceType).toEqual(resource2.resourceType);
36
+ expect(refetchedResource.resourceId).toEqual(resource2.resourceId);
37
+ expect(refetchedResource.meta).toEqual(resource2.meta);
38
+ resource2 = yield workos.fga.updateResource({
39
+ resource: { resourceType: 'folder', resourceId: 'planning' },
40
+ meta: { description: 'Second document' },
41
+ });
42
+ refetchedResource = yield workos.fga.getResource(resource2);
43
+ expect(refetchedResource.resourceType).toEqual(resource2.resourceType);
44
+ expect(refetchedResource.resourceId).toEqual(resource2.resourceId);
45
+ expect(refetchedResource.meta).toEqual(resource2.meta);
46
+ let resourcesList = yield workos.fga.listResources({ limit: 10 });
47
+ expect(resourcesList.data.length).toEqual(2);
48
+ expect(resourcesList.data[0].resourceType).toEqual(resource2.resourceType);
49
+ expect(resourcesList.data[0].resourceId).toEqual(resource2.resourceId);
50
+ expect(resourcesList.data[1].resourceType).toEqual(resource1.resourceType);
51
+ expect(resourcesList.data[1].resourceId).toEqual(resource1.resourceId);
52
+ resourcesList = yield workos.fga.listResources({
53
+ limit: 10,
54
+ search: 'planning',
55
+ });
56
+ expect(resourcesList.data.length).toEqual(1);
57
+ expect(resourcesList.data[0].resourceType).toEqual(resource2.resourceType);
58
+ expect(resourcesList.data[0].resourceId).toEqual(resource2.resourceId);
59
+ yield workos.fga.deleteResource(resource1);
60
+ yield workos.fga.deleteResource(resource2);
61
+ resourcesList = yield workos.fga.listResources({ limit: 10 });
62
+ expect(resourcesList.data.length).toEqual(0);
63
+ }));
64
+ it('multi-tenancy example', () => __awaiter(void 0, void 0, void 0, function* () {
65
+ // Create users
66
+ const user1 = yield workos.fga.createResource({
67
+ resource: { resourceType: 'user' },
68
+ });
69
+ const user2 = yield workos.fga.createResource({
70
+ resource: { resourceType: 'user' },
71
+ });
72
+ // Create tenants
73
+ const tenant1 = yield workos.fga.createResource({
74
+ resource: { resourceType: 'tenant', resourceId: 'tenant-1' },
75
+ meta: { name: 'Tenant 1' },
76
+ });
77
+ const tenant2 = yield workos.fga.createResource({
78
+ resource: { resourceType: 'tenant', resourceId: 'tenant-2' },
79
+ meta: { name: 'Tenant 2' },
80
+ });
81
+ let user1TenantsList = yield workos.fga.query({
82
+ q: `select tenant where user:${user1.resourceId} is member`,
83
+ limit: 10,
84
+ }, { warrantToken: 'latest' });
85
+ expect(user1TenantsList.data.length).toEqual(0);
86
+ let tenant1UsersList = yield workos.fga.query({
87
+ q: `select member of type user for tenant:${tenant1.resourceId}`,
88
+ limit: 10,
89
+ }, { warrantToken: 'latest' });
90
+ expect(tenant1UsersList.data.length).toEqual(0);
91
+ // Assign user1 -> tenant1
92
+ yield workos.fga.writeWarrant({
93
+ resource: tenant1,
94
+ relation: 'member',
95
+ subject: user1,
96
+ });
97
+ user1TenantsList = yield workos.fga.query({
98
+ q: `select tenant where user:${user1.resourceId} is member`,
99
+ limit: 10,
100
+ }, { warrantToken: 'latest' });
101
+ expect(user1TenantsList.data.length).toEqual(1);
102
+ expect(user1TenantsList.data[0].resourceType).toEqual('tenant');
103
+ expect(user1TenantsList.data[0].resourceId).toEqual('tenant-1');
104
+ expect(user1TenantsList.data[0].meta).toEqual({ name: 'Tenant 1' });
105
+ tenant1UsersList = yield workos.fga.query({
106
+ q: `select member of type user for tenant:${tenant1.resourceId}`,
107
+ limit: 10,
108
+ }, { warrantToken: 'latest' });
109
+ expect(tenant1UsersList.data.length).toEqual(1);
110
+ expect(tenant1UsersList.data[0].resourceType).toEqual('user');
111
+ expect(tenant1UsersList.data[0].resourceId).toEqual(user1.resourceId);
112
+ expect(tenant1UsersList.data[0].meta).toBeUndefined();
113
+ // Remove user1 -> tenant1
114
+ yield workos.fga.writeWarrant({
115
+ op: interfaces_1.WarrantOp.Delete,
116
+ resource: tenant1,
117
+ relation: 'member',
118
+ subject: user1,
119
+ });
120
+ user1TenantsList = yield workos.fga.query({
121
+ q: `select tenant where user:${user1.resourceId} is member`,
122
+ limit: 10,
123
+ }, { warrantToken: 'latest' });
124
+ expect(user1TenantsList.data.length).toEqual(0);
125
+ tenant1UsersList = yield workos.fga.query({
126
+ q: `select member of type user for tenant:${tenant1.resourceId}`,
127
+ limit: 10,
128
+ }, { warrantToken: 'latest' });
129
+ expect(tenant1UsersList.data.length).toEqual(0);
130
+ // Clean up
131
+ yield workos.fga.deleteResource(user1);
132
+ yield workos.fga.deleteResource(user2);
133
+ yield workos.fga.deleteResource(tenant1);
134
+ yield workos.fga.deleteResource(tenant2);
135
+ }));
136
+ it('RBAC example', () => __awaiter(void 0, void 0, void 0, function* () {
137
+ // Create users
138
+ const adminUser = yield workos.fga.createResource({
139
+ resource: { resourceType: 'user' },
140
+ });
141
+ const viewerUser = yield workos.fga.createResource({
142
+ resource: { resourceType: 'user' },
143
+ });
144
+ // Create roles
145
+ const adminRole = yield workos.fga.createResource({
146
+ resource: { resourceType: 'role', resourceId: 'admin' },
147
+ meta: { name: 'Admin', description: 'The admin role' },
148
+ });
149
+ const viewerRole = yield workos.fga.createResource({
150
+ resource: { resourceType: 'role', resourceId: 'viewer' },
151
+ meta: { name: 'Viewer', description: 'The viewer role' },
152
+ });
153
+ // Create permissions
154
+ const createPermission = yield workos.fga.createResource({
155
+ resource: { resourceType: 'permission', resourceId: 'create-report' },
156
+ meta: {
157
+ name: 'Create Report',
158
+ description: 'Permission to create reports',
159
+ },
160
+ });
161
+ const viewPermission = yield workos.fga.createResource({
162
+ resource: { resourceType: 'permission', resourceId: 'view-report' },
163
+ meta: { name: 'View Report', description: 'Permission to view reports' },
164
+ });
165
+ let adminUserRolesList = yield workos.fga.query({
166
+ q: `select role where user:${adminUser.resourceId} is member`,
167
+ limit: 10,
168
+ }, { warrantToken: 'latest' });
169
+ let adminRolePermissionsList = yield workos.fga.query({
170
+ q: `select permission where role:${adminRole.resourceId} is member`,
171
+ limit: 10,
172
+ }, { warrantToken: 'latest' });
173
+ expect(adminUserRolesList.data.length).toEqual(0);
174
+ expect(adminRolePermissionsList.data.length).toEqual(0);
175
+ let adminUserHasPermission = yield workos.fga.check({
176
+ checks: [
177
+ {
178
+ resource: createPermission,
179
+ relation: 'member',
180
+ subject: adminUser,
181
+ },
182
+ ],
183
+ }, { warrantToken: 'latest' });
184
+ expect(adminUserHasPermission.isAuthorized()).toEqual(false);
185
+ // Assign 'create-report' -> admin role -> admin user
186
+ yield workos.fga.writeWarrant({
187
+ resource: createPermission,
188
+ relation: 'member',
189
+ subject: adminRole,
190
+ });
191
+ yield workos.fga.writeWarrant({
192
+ resource: adminRole,
193
+ relation: 'member',
194
+ subject: adminUser,
195
+ });
196
+ adminUserHasPermission = yield workos.fga.check({
197
+ checks: [
198
+ {
199
+ resource: createPermission,
200
+ relation: 'member',
201
+ subject: adminUser,
202
+ },
203
+ ],
204
+ }, { warrantToken: 'latest' });
205
+ expect(adminUserHasPermission.isAuthorized()).toEqual(true);
206
+ adminUserRolesList = yield workos.fga.query({
207
+ q: `select role where user:${adminUser.resourceId} is member`,
208
+ limit: 10,
209
+ }, { warrantToken: 'latest' });
210
+ expect(adminUserRolesList.data.length).toEqual(1);
211
+ expect(adminUserRolesList.data[0].resourceType).toEqual('role');
212
+ expect(adminUserRolesList.data[0].resourceId).toEqual('admin');
213
+ expect(adminUserRolesList.data[0].meta).toEqual({
214
+ name: 'Admin',
215
+ description: 'The admin role',
216
+ });
217
+ adminRolePermissionsList = yield workos.fga.query({
218
+ q: `select permission where role:${adminRole.resourceId} is member`,
219
+ limit: 10,
220
+ }, { warrantToken: 'latest' });
221
+ expect(adminRolePermissionsList.data.length).toEqual(1);
222
+ expect(adminRolePermissionsList.data[0].resourceType).toEqual('permission');
223
+ expect(adminRolePermissionsList.data[0].resourceId).toEqual('create-report');
224
+ expect(adminRolePermissionsList.data[0].meta).toEqual({
225
+ name: 'Create Report',
226
+ description: 'Permission to create reports',
227
+ });
228
+ yield workos.fga.writeWarrant({
229
+ op: interfaces_1.WarrantOp.Delete,
230
+ resource: createPermission,
231
+ relation: 'member',
232
+ subject: adminRole,
233
+ });
234
+ yield workos.fga.writeWarrant({
235
+ op: interfaces_1.WarrantOp.Delete,
236
+ resource: adminRole,
237
+ relation: 'member',
238
+ subject: adminUser,
239
+ });
240
+ adminUserHasPermission = yield workos.fga.check({
241
+ checks: [
242
+ {
243
+ resource: createPermission,
244
+ relation: 'member',
245
+ subject: adminUser,
246
+ },
247
+ ],
248
+ }, { warrantToken: 'latest' });
249
+ expect(adminUserHasPermission.isAuthorized()).toEqual(false);
250
+ adminUserRolesList = yield workos.fga.query({
251
+ q: `select role where user:${adminUser.resourceId} is member`,
252
+ limit: 10,
253
+ }, { warrantToken: 'latest' });
254
+ expect(adminUserRolesList.data.length).toEqual(0);
255
+ adminRolePermissionsList = yield workos.fga.query({
256
+ q: `select permission where role:${adminRole.resourceId} is member`,
257
+ limit: 10,
258
+ }, { warrantToken: 'latest' });
259
+ expect(adminRolePermissionsList.data.length).toEqual(0);
260
+ // Assign 'view-report' -> viewer user
261
+ let viewerUserHasPermission = yield workos.fga.check({
262
+ checks: [
263
+ { resource: viewPermission, relation: 'member', subject: viewerUser },
264
+ ],
265
+ }, { warrantToken: 'latest' });
266
+ expect(viewerUserHasPermission.isAuthorized()).toEqual(false);
267
+ let viewerUserPermissionsList = yield workos.fga.query({
268
+ q: `select permission where user:${viewerUser.resourceId} is member`,
269
+ limit: 10,
270
+ }, { warrantToken: 'latest' });
271
+ expect(viewerUserPermissionsList.data.length).toEqual(0);
272
+ yield workos.fga.writeWarrant({
273
+ resource: viewPermission,
274
+ relation: 'member',
275
+ subject: viewerUser,
276
+ });
277
+ viewerUserHasPermission = yield workos.fga.check({
278
+ checks: [
279
+ { resource: viewPermission, relation: 'member', subject: viewerUser },
280
+ ],
281
+ }, { warrantToken: 'latest' });
282
+ expect(viewerUserHasPermission.isAuthorized()).toEqual(true);
283
+ viewerUserPermissionsList = yield workos.fga.query({
284
+ q: `select permission where user:${viewerUser.resourceId} is member`,
285
+ limit: 10,
286
+ }, { warrantToken: 'latest' });
287
+ expect(viewerUserPermissionsList.data.length).toEqual(1);
288
+ expect(viewerUserPermissionsList.data[0].resourceType).toEqual('permission');
289
+ expect(viewerUserPermissionsList.data[0].resourceId).toEqual('view-report');
290
+ expect(viewerUserPermissionsList.data[0].meta).toEqual({
291
+ name: 'View Report',
292
+ description: 'Permission to view reports',
293
+ });
294
+ yield workos.fga.writeWarrant({
295
+ op: interfaces_1.WarrantOp.Delete,
296
+ resource: viewPermission,
297
+ relation: 'member',
298
+ subject: viewerUser,
299
+ });
300
+ viewerUserHasPermission = yield workos.fga.check({
301
+ checks: [
302
+ { resource: viewPermission, relation: 'member', subject: viewerUser },
303
+ ],
304
+ }, { warrantToken: 'latest' });
305
+ expect(viewerUserHasPermission.isAuthorized()).toEqual(false);
306
+ viewerUserPermissionsList = yield workos.fga.query({
307
+ q: `select permission where user:${viewerUser.resourceId} is member`,
308
+ limit: 10,
309
+ }, { warrantToken: 'latest' });
310
+ expect(viewerUserPermissionsList.data.length).toEqual(0);
311
+ // Clean up
312
+ yield workos.fga.deleteResource(adminUser);
313
+ yield workos.fga.deleteResource(viewerUser);
314
+ yield workos.fga.deleteResource(adminRole);
315
+ yield workos.fga.deleteResource(viewerRole);
316
+ yield workos.fga.deleteResource(createPermission);
317
+ yield workos.fga.deleteResource(viewPermission);
318
+ }), 10000);
319
+ it('pricing tiers, features, and users example', () => __awaiter(void 0, void 0, void 0, function* () {
320
+ // Create users
321
+ const freeUser = yield workos.fga.createResource({
322
+ resource: { resourceType: 'user' },
323
+ });
324
+ const paidUser = yield workos.fga.createResource({
325
+ resource: { resourceType: 'user' },
326
+ });
327
+ // Create pricing tiers
328
+ const freeTier = yield workos.fga.createResource({
329
+ resource: { resourceType: 'pricing-tier', resourceId: 'free' },
330
+ meta: { name: 'Free Tier' },
331
+ });
332
+ const paidTier = yield workos.fga.createResource({
333
+ resource: { resourceType: 'pricing-tier', resourceId: 'paid' },
334
+ });
335
+ // Create features
336
+ const customFeature = yield workos.fga.createResource({
337
+ resource: { resourceType: 'feature', resourceId: 'custom-feature' },
338
+ meta: { name: 'Custom Feature' },
339
+ });
340
+ const feature1 = yield workos.fga.createResource({
341
+ resource: { resourceType: 'feature', resourceId: 'feature-1' },
342
+ });
343
+ const feature2 = yield workos.fga.createResource({
344
+ resource: { resourceType: 'feature', resourceId: 'feature-2' },
345
+ });
346
+ // Assign 'custom-feature' -> paid user
347
+ let paidUserHasFeature = yield workos.fga.check({
348
+ checks: [
349
+ { resource: customFeature, relation: 'member', subject: paidUser },
350
+ ],
351
+ }, { warrantToken: 'latest' });
352
+ expect(paidUserHasFeature.isAuthorized()).toEqual(false);
353
+ let paidUserFeaturesList = yield workos.fga.query({
354
+ q: `select feature where user:${paidUser.resourceId} is member`,
355
+ limit: 10,
356
+ }, { warrantToken: 'latest' });
357
+ expect(paidUserFeaturesList.data.length).toEqual(0);
358
+ yield workos.fga.writeWarrant({
359
+ resource: customFeature,
360
+ relation: 'member',
361
+ subject: paidUser,
362
+ });
363
+ paidUserHasFeature = yield workos.fga.check({
364
+ checks: [
365
+ { resource: customFeature, relation: 'member', subject: paidUser },
366
+ ],
367
+ }, { warrantToken: 'latest' });
368
+ expect(paidUserHasFeature.isAuthorized()).toEqual(true);
369
+ paidUserFeaturesList = yield workos.fga.query({
370
+ q: `select feature where user:${paidUser.resourceId} is member`,
371
+ limit: 10,
372
+ }, { warrantToken: 'latest' });
373
+ expect(paidUserFeaturesList.data.length).toEqual(1);
374
+ expect(paidUserFeaturesList.data[0].resourceType).toEqual('feature');
375
+ expect(paidUserFeaturesList.data[0].resourceId).toEqual('custom-feature');
376
+ expect(paidUserFeaturesList.data[0].meta).toEqual({
377
+ name: 'Custom Feature',
378
+ });
379
+ yield workos.fga.writeWarrant({
380
+ op: interfaces_1.WarrantOp.Delete,
381
+ resource: customFeature,
382
+ relation: 'member',
383
+ subject: paidUser,
384
+ });
385
+ paidUserHasFeature = yield workos.fga.check({
386
+ checks: [
387
+ { resource: customFeature, relation: 'member', subject: paidUser },
388
+ ],
389
+ }, { warrantToken: 'latest' });
390
+ expect(paidUserHasFeature.isAuthorized()).toEqual(false);
391
+ paidUserFeaturesList = yield workos.fga.query({
392
+ q: `select feature where user:${paidUser.resourceId} is member`,
393
+ limit: 10,
394
+ }, { warrantToken: 'latest' });
395
+ expect(paidUserFeaturesList.data.length).toEqual(0);
396
+ // Assign 'feature-1' -> 'free' tier -> free user
397
+ let freeUserHasFeature = yield workos.fga.check({
398
+ checks: [{ resource: feature1, relation: 'member', subject: freeUser }],
399
+ }, { warrantToken: 'latest' });
400
+ expect(freeUserHasFeature.isAuthorized()).toEqual(false);
401
+ let freeUserFeaturesList = yield workos.fga.query({
402
+ q: `select feature where user:${freeUser.resourceId} is member`,
403
+ limit: 10,
404
+ }, { warrantToken: 'latest' });
405
+ expect(freeUserFeaturesList.data.length).toEqual(0);
406
+ let freeUserTiersList = yield workos.fga.query({
407
+ q: `select pricing-tier where user:${freeUser.resourceId} is member`,
408
+ limit: 10,
409
+ }, { warrantToken: 'latest' });
410
+ expect(freeUserTiersList.data.length).toEqual(0);
411
+ yield workos.fga.writeWarrant({
412
+ resource: feature1,
413
+ relation: 'member',
414
+ subject: freeTier,
415
+ });
416
+ yield workos.fga.writeWarrant({
417
+ resource: freeTier,
418
+ relation: 'member',
419
+ subject: freeUser,
420
+ });
421
+ freeUserHasFeature = yield workos.fga.check({
422
+ checks: [{ resource: feature1, relation: 'member', subject: freeUser }],
423
+ }, { warrantToken: 'latest' });
424
+ expect(freeUserHasFeature.isAuthorized()).toEqual(true);
425
+ freeUserFeaturesList = yield workos.fga.query({
426
+ q: `select feature where user:${freeUser.resourceId} is member`,
427
+ limit: 10,
428
+ }, { warrantToken: 'latest' });
429
+ expect(freeUserFeaturesList.data.length).toEqual(1);
430
+ expect(freeUserFeaturesList.data[0].resourceType).toEqual('feature');
431
+ expect(freeUserFeaturesList.data[0].resourceId).toEqual('feature-1');
432
+ expect(freeUserFeaturesList.data[0].meta).toBeUndefined();
433
+ freeUserTiersList = yield workos.fga.query({
434
+ q: `select pricing-tier where user:${freeUser.resourceId} is member`,
435
+ limit: 10,
436
+ }, { warrantToken: 'latest' });
437
+ expect(freeUserTiersList.data.length).toEqual(1);
438
+ expect(freeUserTiersList.data[0].resourceType).toEqual('pricing-tier');
439
+ expect(freeUserTiersList.data[0].resourceId).toEqual('free');
440
+ expect(freeUserTiersList.data[0].meta).toEqual({ name: 'Free Tier' });
441
+ yield workos.fga.writeWarrant({
442
+ op: interfaces_1.WarrantOp.Delete,
443
+ resource: feature1,
444
+ relation: 'member',
445
+ subject: freeTier,
446
+ });
447
+ yield workos.fga.writeWarrant({
448
+ op: interfaces_1.WarrantOp.Delete,
449
+ resource: freeTier,
450
+ relation: 'member',
451
+ subject: freeUser,
452
+ });
453
+ freeUserHasFeature = yield workos.fga.check({
454
+ checks: [{ resource: feature1, relation: 'member', subject: freeUser }],
455
+ }, { warrantToken: 'latest' });
456
+ expect(freeUserHasFeature.isAuthorized()).toEqual(false);
457
+ freeUserFeaturesList = yield workos.fga.query({
458
+ q: `select feature where user:${freeUser.resourceId} is member`,
459
+ limit: 10,
460
+ }, { warrantToken: 'latest' });
461
+ expect(freeUserFeaturesList.data.length).toEqual(0);
462
+ freeUserTiersList = yield workos.fga.query({
463
+ q: `select pricing-tier where user:${freeUser.resourceId} is member`,
464
+ limit: 10,
465
+ }, { warrantToken: 'latest' });
466
+ expect(freeUserTiersList.data.length).toEqual(0);
467
+ // Clean up
468
+ yield workos.fga.deleteResource(freeUser);
469
+ yield workos.fga.deleteResource(paidUser);
470
+ yield workos.fga.deleteResource(freeTier);
471
+ yield workos.fga.deleteResource(paidTier);
472
+ yield workos.fga.deleteResource(customFeature);
473
+ yield workos.fga.deleteResource(feature1);
474
+ yield workos.fga.deleteResource(feature2);
475
+ }), 10000);
476
+ it('warrants', () => __awaiter(void 0, void 0, void 0, function* () {
477
+ const user1 = yield workos.fga.createResource({
478
+ resource: { resourceType: 'user', resourceId: 'userA' },
479
+ });
480
+ const user2 = yield workos.fga.createResource({
481
+ resource: { resourceType: 'user', resourceId: 'userB' },
482
+ });
483
+ const newPermission = yield workos.fga.createResource({
484
+ resource: { resourceType: 'permission', resourceId: 'perm1' },
485
+ meta: { name: 'Permission 1', description: 'Permission 1' },
486
+ });
487
+ let userHasPermission = yield workos.fga.check({
488
+ checks: [
489
+ { resource: newPermission, relation: 'member', subject: user1 },
490
+ ],
491
+ }, { warrantToken: 'latest' });
492
+ expect(userHasPermission.isAuthorized()).toEqual(false);
493
+ const warrant1 = yield workos.fga.writeWarrant({
494
+ resource: newPermission,
495
+ relation: 'member',
496
+ subject: user1,
497
+ });
498
+ expect(warrant1.warrantToken).toBeDefined();
499
+ const warrant2 = yield workos.fga.writeWarrant({
500
+ resource: newPermission,
501
+ relation: 'member',
502
+ subject: user2,
503
+ });
504
+ expect(warrant2.warrantToken).toBeDefined();
505
+ const warrants1 = yield workos.fga.listWarrants({ limit: 1 }, { warrantToken: 'latest' });
506
+ expect(warrants1.data.length).toEqual(1);
507
+ expect(warrants1.data[0].resourceType).toEqual('permission');
508
+ expect(warrants1.data[0].resourceId).toEqual('perm1');
509
+ expect(warrants1.data[0].relation).toEqual('member');
510
+ expect(warrants1.data[0].subject.resourceType).toEqual('user');
511
+ expect(warrants1.data[0].subject.resourceId).toEqual(user2.resourceId);
512
+ const warrants2 = yield workos.fga.listWarrants({ limit: 1, after: warrants1.listMetadata.after }, { warrantToken: 'latest' });
513
+ expect(warrants2.data.length).toEqual(1);
514
+ expect(warrants2.data[0].resourceType).toEqual('permission');
515
+ expect(warrants2.data[0].resourceId).toEqual('perm1');
516
+ expect(warrants2.data[0].relation).toEqual('member');
517
+ expect(warrants2.data[0].subject.resourceType).toEqual('user');
518
+ expect(warrants2.data[0].subject.resourceId).toEqual(user1.resourceId);
519
+ const warrants3 = yield workos.fga.listWarrants({ subjectType: 'user', subjectId: user1.resourceId }, { warrantToken: 'latest' });
520
+ expect(warrants3.data.length).toEqual(1);
521
+ expect(warrants3.data[0].resourceType).toEqual('permission');
522
+ expect(warrants3.data[0].resourceId).toEqual('perm1');
523
+ expect(warrants3.data[0].relation).toEqual('member');
524
+ expect(warrants3.data[0].subject.resourceType).toEqual('user');
525
+ expect(warrants3.data[0].subject.resourceId).toEqual(user1.resourceId);
526
+ userHasPermission = yield workos.fga.check({
527
+ checks: [
528
+ { resource: newPermission, relation: 'member', subject: user1 },
529
+ ],
530
+ }, { warrantToken: 'latest' });
531
+ expect(userHasPermission.isAuthorized()).toEqual(true);
532
+ const query = `select permission where user:${user1.resourceId} is member`;
533
+ const response = yield workos.fga.query({ q: query }, { warrantToken: 'latest' });
534
+ expect(response.data.length).toEqual(1);
535
+ expect(response.data[0].resourceType).toEqual('permission');
536
+ expect(response.data[0].resourceId).toEqual('perm1');
537
+ expect(response.data[0].relation).toEqual('member');
538
+ yield workos.fga.writeWarrant({
539
+ op: interfaces_1.WarrantOp.Delete,
540
+ resource: newPermission,
541
+ relation: 'member',
542
+ subject: user1,
543
+ });
544
+ userHasPermission = yield workos.fga.check({
545
+ checks: [
546
+ { resource: newPermission, relation: 'member', subject: user1 },
547
+ ],
548
+ }, { warrantToken: 'latest' });
549
+ expect(userHasPermission.isAuthorized()).toEqual(false);
550
+ // Clean up
551
+ yield workos.fga.deleteResource(user1);
552
+ yield workos.fga.deleteResource(user2);
553
+ yield workos.fga.deleteResource(newPermission);
554
+ }));
555
+ it('check many warrants', () => __awaiter(void 0, void 0, void 0, function* () {
556
+ const newUser = yield workos.fga.createResource({
557
+ resource: { resourceType: 'user' },
558
+ });
559
+ const permission1 = yield workos.fga.createResource({
560
+ resource: { resourceType: 'permission', resourceId: 'perm1' },
561
+ meta: { name: 'Permission 1', description: 'Permission 1' },
562
+ });
563
+ const permission2 = yield workos.fga.createResource({
564
+ resource: { resourceType: 'permission', resourceId: 'perm2' },
565
+ meta: { name: 'Permission 2', description: 'Permission 2' },
566
+ });
567
+ const userHasPermissions = yield workos.fga.check({
568
+ op: interfaces_1.CheckOp.AnyOf,
569
+ checks: [
570
+ { resource: permission1, relation: 'member', subject: newUser },
571
+ { resource: permission2, relation: 'member', subject: newUser },
572
+ ],
573
+ }, { warrantToken: 'latest' });
574
+ expect(userHasPermissions.isAuthorized()).toEqual(false);
575
+ let warrantResponse = yield workos.fga.writeWarrant({
576
+ resource: permission1,
577
+ relation: 'member',
578
+ subject: newUser,
579
+ });
580
+ expect(warrantResponse.warrantToken).toBeDefined();
581
+ let userHasAtLeastOnePermission = yield workos.fga.check({
582
+ op: interfaces_1.CheckOp.AnyOf,
583
+ checks: [
584
+ { resource: permission1, relation: 'member', subject: newUser },
585
+ { resource: permission2, relation: 'member', subject: newUser },
586
+ ],
587
+ }, { warrantToken: 'latest' });
588
+ expect(userHasAtLeastOnePermission.isAuthorized()).toEqual(true);
589
+ let userHasAllPermissions = yield workos.fga.check({
590
+ op: interfaces_1.CheckOp.AllOf,
591
+ checks: [
592
+ { resource: permission1, relation: 'member', subject: newUser },
593
+ { resource: permission2, relation: 'member', subject: newUser },
594
+ ],
595
+ }, { warrantToken: 'latest' });
596
+ expect(userHasAllPermissions.isAuthorized()).toEqual(false);
597
+ warrantResponse = yield workos.fga.writeWarrant({
598
+ resource: permission2,
599
+ relation: 'member',
600
+ subject: newUser,
601
+ });
602
+ expect(warrantResponse.warrantToken).toBeDefined();
603
+ userHasAtLeastOnePermission = yield workos.fga.check({
604
+ op: interfaces_1.CheckOp.AnyOf,
605
+ checks: [
606
+ { resource: permission1, relation: 'member', subject: newUser },
607
+ { resource: permission2, relation: 'member', subject: newUser },
608
+ ],
609
+ }, { warrantToken: 'latest' });
610
+ expect(userHasAtLeastOnePermission.isAuthorized()).toEqual(true);
611
+ userHasAllPermissions = yield workos.fga.check({
612
+ op: interfaces_1.CheckOp.AllOf,
613
+ checks: [
614
+ { resource: permission1, relation: 'member', subject: newUser },
615
+ { resource: permission2, relation: 'member', subject: newUser },
616
+ ],
617
+ }, { warrantToken: 'latest' });
618
+ expect(userHasAllPermissions.isAuthorized()).toEqual(true);
619
+ warrantResponse = yield workos.fga.batchWriteWarrants([
620
+ {
621
+ op: interfaces_1.WarrantOp.Delete,
622
+ resource: permission1,
623
+ relation: 'member',
624
+ subject: newUser,
625
+ },
626
+ {
627
+ op: interfaces_1.WarrantOp.Delete,
628
+ resource: permission2,
629
+ relation: 'member',
630
+ subject: newUser,
631
+ },
632
+ ]);
633
+ expect(warrantResponse.warrantToken).toBeDefined();
634
+ // Clean up
635
+ yield workos.fga.deleteResource(newUser);
636
+ yield workos.fga.deleteResource(permission1);
637
+ yield workos.fga.deleteResource(permission2);
638
+ }));
639
+ it('batch create/delete/check warrants', () => __awaiter(void 0, void 0, void 0, function* () {
640
+ const newUser = yield workos.fga.createResource({
641
+ resource: { resourceType: 'user' },
642
+ });
643
+ const permission1 = yield workos.fga.createResource({
644
+ resource: { resourceType: 'permission', resourceId: 'perm1' },
645
+ meta: { name: 'Permission 1', description: 'Permission 1' },
646
+ });
647
+ const permission2 = yield workos.fga.createResource({
648
+ resource: { resourceType: 'permission', resourceId: 'perm2' },
649
+ meta: { name: 'Permission 2', description: 'Permission 2' },
650
+ });
651
+ let userHasPermissions = yield workos.fga.checkBatch({
652
+ checks: [
653
+ { resource: permission1, relation: 'member', subject: newUser },
654
+ { resource: permission2, relation: 'member', subject: newUser },
655
+ ],
656
+ }, { warrantToken: 'latest' });
657
+ expect(userHasPermissions[0].isAuthorized()).toEqual(false);
658
+ expect(userHasPermissions[1].isAuthorized()).toEqual(false);
659
+ const warrants = yield workos.fga.batchWriteWarrants([
660
+ { resource: permission1, relation: 'member', subject: newUser },
661
+ { resource: permission2, relation: 'member', subject: newUser },
662
+ ]);
663
+ expect(warrants.warrantToken).toBeDefined();
664
+ userHasPermissions = yield workos.fga.checkBatch({
665
+ checks: [
666
+ { resource: permission1, relation: 'member', subject: newUser },
667
+ { resource: permission2, relation: 'member', subject: newUser },
668
+ ],
669
+ }, { warrantToken: 'latest' });
670
+ expect(userHasPermissions[0].isAuthorized()).toEqual(true);
671
+ expect(userHasPermissions[1].isAuthorized()).toEqual(true);
672
+ const warrantToken = yield workos.fga.batchWriteWarrants([
673
+ {
674
+ op: interfaces_1.WarrantOp.Delete,
675
+ resource: permission1,
676
+ relation: 'member',
677
+ subject: newUser,
678
+ },
679
+ {
680
+ op: interfaces_1.WarrantOp.Delete,
681
+ resource: permission2,
682
+ relation: 'member',
683
+ subject: newUser,
684
+ },
685
+ ]);
686
+ expect(warrantToken).toBeDefined();
687
+ userHasPermissions = yield workos.fga.checkBatch({
688
+ checks: [
689
+ { resource: permission1, relation: 'member', subject: newUser },
690
+ { resource: permission2, relation: 'member', subject: newUser },
691
+ ],
692
+ }, { warrantToken: 'latest' });
693
+ expect(userHasPermissions[0].isAuthorized()).toEqual(false);
694
+ expect(userHasPermissions[1].isAuthorized()).toEqual(false);
695
+ yield workos.fga.deleteResource(newUser);
696
+ yield workos.fga.deleteResource(permission1);
697
+ yield workos.fga.deleteResource(permission2);
698
+ }));
699
+ it('warrant with policy', () => __awaiter(void 0, void 0, void 0, function* () {
700
+ let writeResult = yield workos.fga.writeWarrant({
701
+ resource: { resourceType: 'permission', resourceId: 'test-permission' },
702
+ relation: 'member',
703
+ subject: { resourceType: 'user', resourceId: 'user-1' },
704
+ policy: `geo == "us"`,
705
+ });
706
+ expect(writeResult.warrantToken).toBeDefined();
707
+ let checkResult = yield workos.fga.check({
708
+ checks: [
709
+ {
710
+ resource: {
711
+ resourceType: 'permission',
712
+ resourceId: 'test-permission',
713
+ },
714
+ relation: 'member',
715
+ subject: { resourceType: 'user', resourceId: 'user-1' },
716
+ context: { geo: 'us' },
717
+ },
718
+ ],
719
+ }, {
720
+ warrantToken: 'latest',
721
+ });
722
+ expect(checkResult.isAuthorized()).toEqual(true);
723
+ checkResult = yield workos.fga.check({
724
+ checks: [
725
+ {
726
+ resource: {
727
+ resourceType: 'permission',
728
+ resourceId: 'test-permission',
729
+ },
730
+ relation: 'member',
731
+ subject: { resourceType: 'user', resourceId: 'user-1' },
732
+ context: { geo: 'eu' },
733
+ },
734
+ ],
735
+ }, {
736
+ warrantToken: 'latest',
737
+ });
738
+ expect(checkResult.isAuthorized()).toEqual(false);
739
+ writeResult = yield workos.fga.writeWarrant({
740
+ op: interfaces_1.WarrantOp.Delete,
741
+ resource: { resourceType: 'permission', resourceId: 'test-permission' },
742
+ relation: 'member',
743
+ subject: { resourceType: 'user', resourceId: 'user-1' },
744
+ policy: `geo == "us"`,
745
+ });
746
+ expect(writeResult.warrantToken).toBeDefined();
747
+ // Clean up
748
+ yield workos.fga.deleteResource({
749
+ resourceType: 'permission',
750
+ resourceId: 'test-permission',
751
+ });
752
+ yield workos.fga.deleteResource({
753
+ resourceType: 'user',
754
+ resourceId: 'user-1',
755
+ });
756
+ }));
757
+ it('query', () => __awaiter(void 0, void 0, void 0, function* () {
758
+ const userA = yield workos.fga.createResource({
759
+ resource: { resourceType: 'user', resourceId: 'userA' },
760
+ });
761
+ const userB = yield workos.fga.createResource({
762
+ resource: { resourceType: 'user', resourceId: 'userB' },
763
+ });
764
+ const permission1 = yield workos.fga.createResource({
765
+ resource: { resourceType: 'permission', resourceId: 'perm1' },
766
+ meta: { name: 'Permission 1', description: 'This is permission 1.' },
767
+ });
768
+ const permission2 = yield workos.fga.createResource({
769
+ resource: { resourceType: 'permission', resourceId: 'perm2' },
770
+ });
771
+ const permission3 = yield workos.fga.createResource({
772
+ resource: { resourceType: 'permission', resourceId: 'perm3' },
773
+ meta: { name: 'Permission 3', description: 'This is permission 3.' },
774
+ });
775
+ const role1 = yield workos.fga.createResource({
776
+ resource: { resourceType: 'role', resourceId: 'role1' },
777
+ meta: { name: 'Role 1', description: 'This is role 1.' },
778
+ });
779
+ const role2 = yield workos.fga.createResource({
780
+ resource: { resourceType: 'role', resourceId: 'role2' },
781
+ meta: { name: 'Role 2' },
782
+ });
783
+ yield workos.fga.writeWarrant({
784
+ resource: permission1,
785
+ relation: 'member',
786
+ subject: role1,
787
+ });
788
+ yield workos.fga.writeWarrant({
789
+ resource: permission2,
790
+ relation: 'member',
791
+ subject: role2,
792
+ });
793
+ yield workos.fga.writeWarrant({
794
+ resource: permission3,
795
+ relation: 'member',
796
+ subject: role2,
797
+ });
798
+ yield workos.fga.writeWarrant({
799
+ resource: role2,
800
+ relation: 'member',
801
+ subject: role1,
802
+ });
803
+ yield workos.fga.writeWarrant({
804
+ resource: permission1,
805
+ relation: 'member',
806
+ subject: role2,
807
+ policy: 'tenantId == 123',
808
+ });
809
+ yield workos.fga.writeWarrant({
810
+ resource: role1,
811
+ relation: 'member',
812
+ subject: userA,
813
+ });
814
+ yield workos.fga.writeWarrant({
815
+ resource: role2,
816
+ relation: 'member',
817
+ subject: userB,
818
+ });
819
+ let resultSet = yield workos.fga.query({ q: 'select role where user:userA is member', limit: 1, order: 'asc' }, { warrantToken: 'latest' });
820
+ expect(resultSet.data.length).toEqual(1);
821
+ expect(resultSet.data[0].resourceType).toEqual('role');
822
+ expect(resultSet.data[0].resourceId).toEqual('role1');
823
+ expect(resultSet.data[0].relation).toEqual('member');
824
+ expect(resultSet.data[0].warrant.resourceType).toEqual('role');
825
+ expect(resultSet.data[0].warrant.resourceId).toEqual('role1');
826
+ expect(resultSet.data[0].warrant.relation).toEqual('member');
827
+ expect(resultSet.data[0].warrant.subject.resourceType).toEqual('user');
828
+ expect(resultSet.data[0].warrant.subject.resourceId).toEqual('userA');
829
+ expect(resultSet.data[0].warrant.policy).toBeUndefined();
830
+ expect(resultSet.data[0].isImplicit).toEqual(false);
831
+ resultSet = yield workos.fga.query({
832
+ q: 'select role where user:userA is member',
833
+ limit: 1,
834
+ order: 'asc',
835
+ after: resultSet.listMetadata.after,
836
+ }, { warrantToken: 'latest' });
837
+ expect(resultSet.data.length).toEqual(1);
838
+ expect(resultSet.data[0].resourceType).toEqual('role');
839
+ expect(resultSet.data[0].resourceId).toEqual('role2');
840
+ expect(resultSet.data[0].relation).toEqual('member');
841
+ expect(resultSet.data[0].warrant.resourceType).toEqual('role');
842
+ expect(resultSet.data[0].warrant.resourceId).toEqual('role2');
843
+ expect(resultSet.data[0].warrant.relation).toEqual('member');
844
+ expect(resultSet.data[0].warrant.subject.resourceType).toEqual('role');
845
+ expect(resultSet.data[0].warrant.subject.resourceId).toEqual('role1');
846
+ expect(resultSet.data[0].warrant.policy).toBeUndefined();
847
+ expect(resultSet.data[0].isImplicit).toEqual(true);
848
+ resultSet = yield workos.fga.query({
849
+ q: 'select permission where user:userB is member',
850
+ context: { tenantId: 123 },
851
+ order: 'asc',
852
+ }, { warrantToken: 'latest' });
853
+ expect(resultSet.data.length).toEqual(3);
854
+ expect(resultSet.data[0].resourceType).toEqual('permission');
855
+ expect(resultSet.data[0].resourceId).toEqual('perm1');
856
+ expect(resultSet.data[0].relation).toEqual('member');
857
+ expect(resultSet.data[1].resourceType).toEqual('permission');
858
+ expect(resultSet.data[1].resourceId).toEqual('perm2');
859
+ expect(resultSet.data[1].relation).toEqual('member');
860
+ expect(resultSet.data[2].resourceType).toEqual('permission');
861
+ expect(resultSet.data[2].resourceId).toEqual('perm3');
862
+ expect(resultSet.data[2].relation).toEqual('member');
863
+ // Clean up
864
+ yield workos.fga.deleteResource(role1);
865
+ yield workos.fga.deleteResource(role2);
866
+ yield workos.fga.deleteResource(permission1);
867
+ yield workos.fga.deleteResource(permission2);
868
+ yield workos.fga.deleteResource(permission3);
869
+ yield workos.fga.deleteResource(userA);
870
+ yield workos.fga.deleteResource(userB);
871
+ }));
872
+ });