@workos-inc/node 7.14.0 → 7.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common/interfaces/event.interface.d.ts +67 -3
- package/lib/common/interfaces/workos-options.interface.d.ts +1 -0
- package/lib/common/net/node-client.d.ts +0 -1
- package/lib/common/serializers/event.serializer.js +9 -0
- package/lib/user-management/interfaces/authenticate-with-options-base.interface.d.ts +5 -0
- package/lib/user-management/interfaces/authenticate-with-session-cookie.interface.d.ts +24 -0
- package/lib/user-management/interfaces/authenticate-with-session-cookie.interface.js +9 -0
- package/lib/user-management/interfaces/authentication-event.interface.d.ts +25 -0
- package/lib/user-management/interfaces/authentication-event.interface.js +2 -0
- package/lib/user-management/interfaces/authentication-response.interface.d.ts +1 -0
- package/lib/user-management/interfaces/index.d.ts +3 -0
- package/lib/user-management/interfaces/index.js +3 -0
- package/lib/user-management/interfaces/refresh-and-seal-session-data.interface.d.ts +16 -0
- package/lib/user-management/interfaces/refresh-and-seal-session-data.interface.js +11 -0
- package/lib/user-management/interfaces/session-handler-options.interface.d.ts +4 -0
- package/lib/user-management/interfaces/session-handler-options.interface.js +2 -0
- package/lib/user-management/serializers/authentication-event.serializer.d.ts +2 -0
- package/lib/user-management/serializers/authentication-event.serializer.js +13 -0
- package/lib/user-management/serializers/index.d.ts +1 -0
- package/lib/user-management/serializers/index.js +1 -0
- package/lib/user-management/user-management.d.ts +20 -10
- package/lib/user-management/user-management.js +225 -47
- package/lib/user-management/user-management.spec.js +503 -5
- package/lib/workos.d.ts +1 -0
- package/lib/workos.js +5 -2
- package/package.json +4 -2
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
26
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
27
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -27,7 +50,8 @@ const organization_membership_json_1 = __importDefault(require("./fixtures/organ
|
|
|
27
50
|
const password_reset_json_1 = __importDefault(require("./fixtures/password_reset.json"));
|
|
28
51
|
const user_json_1 = __importDefault(require("./fixtures/user.json"));
|
|
29
52
|
const identity_json_1 = __importDefault(require("./fixtures/identity.json"));
|
|
30
|
-
const
|
|
53
|
+
const jose = __importStar(require("jose"));
|
|
54
|
+
const iron_session_1 = require("iron-session");
|
|
31
55
|
const userId = 'user_01H5JQDV7R7ATEYZDEG0W5PRYS';
|
|
32
56
|
const organizationMembershipId = 'om_01H5JQDV7R7ATEYZDEG0W5PRYS';
|
|
33
57
|
const emailVerificationId = 'email_verification_01H5JQDV7R7ATEYZDEG0W5PRYS';
|
|
@@ -36,6 +60,13 @@ const invitationToken = 'Z1uX3RbwcIl5fIGJJJCXXisdI';
|
|
|
36
60
|
const magicAuthId = 'magic_auth_01H5JQDV7R7ATEYZDEG0W5PRYS';
|
|
37
61
|
const passwordResetId = 'password_reset_01H5JQDV7R7ATEYZDEG0W5PRYS';
|
|
38
62
|
describe('UserManagement', () => {
|
|
63
|
+
let workos;
|
|
64
|
+
beforeAll(() => {
|
|
65
|
+
workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
|
|
66
|
+
apiHostname: 'api.workos.test',
|
|
67
|
+
clientId: 'proj_123',
|
|
68
|
+
});
|
|
69
|
+
});
|
|
39
70
|
beforeEach(() => jest_fetch_mock_1.default.resetMocks());
|
|
40
71
|
describe('getUser', () => {
|
|
41
72
|
it('sends a Get User request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -127,8 +158,45 @@ describe('UserManagement', () => {
|
|
|
127
158
|
},
|
|
128
159
|
});
|
|
129
160
|
}));
|
|
161
|
+
describe('when sealSession = true', () => {
|
|
162
|
+
beforeEach(() => {
|
|
163
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
164
|
+
});
|
|
165
|
+
describe('when the cookie password is undefined', () => {
|
|
166
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
167
|
+
yield expect(workos.userManagement.authenticateWithMagicAuth({
|
|
168
|
+
clientId: 'proj_whatever',
|
|
169
|
+
code: '123456',
|
|
170
|
+
email: user_json_1.default.email,
|
|
171
|
+
session: { sealSession: true },
|
|
172
|
+
})).rejects.toThrow('Cookie password is required');
|
|
173
|
+
}));
|
|
174
|
+
});
|
|
175
|
+
describe('when successfully authenticated', () => {
|
|
176
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
177
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
178
|
+
const response = yield workos.userManagement.authenticateWithMagicAuth({
|
|
179
|
+
clientId: 'proj_whatever',
|
|
180
|
+
code: '123456',
|
|
181
|
+
email: user_json_1.default.email,
|
|
182
|
+
session: { sealSession: true, cookiePassword },
|
|
183
|
+
});
|
|
184
|
+
expect(response).toEqual({
|
|
185
|
+
sealedSession: expect.any(String),
|
|
186
|
+
accessToken: undefined,
|
|
187
|
+
authenticationMethod: undefined,
|
|
188
|
+
impersonator: undefined,
|
|
189
|
+
organizationId: undefined,
|
|
190
|
+
refreshToken: undefined,
|
|
191
|
+
user: expect.objectContaining({
|
|
192
|
+
email: 'test01@example.com',
|
|
193
|
+
}),
|
|
194
|
+
});
|
|
195
|
+
}));
|
|
196
|
+
});
|
|
197
|
+
});
|
|
130
198
|
});
|
|
131
|
-
describe('
|
|
199
|
+
describe('authenticateWithPassword', () => {
|
|
132
200
|
it('sends an password authentication request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
133
201
|
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
134
202
|
const resp = yield workos.userManagement.authenticateWithPassword({
|
|
@@ -143,8 +211,45 @@ describe('UserManagement', () => {
|
|
|
143
211
|
},
|
|
144
212
|
});
|
|
145
213
|
}));
|
|
214
|
+
describe('when sealSession = true', () => {
|
|
215
|
+
beforeEach(() => {
|
|
216
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
217
|
+
});
|
|
218
|
+
describe('when the cookie password is undefined', () => {
|
|
219
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
220
|
+
yield expect(workos.userManagement.authenticateWithPassword({
|
|
221
|
+
clientId: 'proj_whatever',
|
|
222
|
+
email: 'test01@example.com',
|
|
223
|
+
password: 'extra-secure',
|
|
224
|
+
session: { sealSession: true },
|
|
225
|
+
})).rejects.toThrow('Cookie password is required');
|
|
226
|
+
}));
|
|
227
|
+
});
|
|
228
|
+
describe('when successfully authenticated', () => {
|
|
229
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
230
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
231
|
+
const response = yield workos.userManagement.authenticateWithPassword({
|
|
232
|
+
clientId: 'proj_whatever',
|
|
233
|
+
email: 'test01@example.com',
|
|
234
|
+
password: 'extra-secure',
|
|
235
|
+
session: { sealSession: true, cookiePassword },
|
|
236
|
+
});
|
|
237
|
+
expect(response).toEqual({
|
|
238
|
+
sealedSession: expect.any(String),
|
|
239
|
+
accessToken: undefined,
|
|
240
|
+
authenticationMethod: undefined,
|
|
241
|
+
impersonator: undefined,
|
|
242
|
+
organizationId: undefined,
|
|
243
|
+
refreshToken: undefined,
|
|
244
|
+
user: expect.objectContaining({
|
|
245
|
+
email: 'test01@example.com',
|
|
246
|
+
}),
|
|
247
|
+
});
|
|
248
|
+
}));
|
|
249
|
+
});
|
|
250
|
+
});
|
|
146
251
|
});
|
|
147
|
-
describe('
|
|
252
|
+
describe('authenticateWithCode', () => {
|
|
148
253
|
it('sends a token authentication request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
149
254
|
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
150
255
|
const resp = yield workos.userManagement.authenticateWithCode({
|
|
@@ -225,6 +330,41 @@ describe('UserManagement', () => {
|
|
|
225
330
|
});
|
|
226
331
|
}));
|
|
227
332
|
});
|
|
333
|
+
describe('when sealSession = true', () => {
|
|
334
|
+
beforeEach(() => {
|
|
335
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
336
|
+
});
|
|
337
|
+
describe('when the cookie password is undefined', () => {
|
|
338
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
339
|
+
yield expect(workos.userManagement.authenticateWithCode({
|
|
340
|
+
clientId: 'proj_whatever',
|
|
341
|
+
code: 'or this',
|
|
342
|
+
session: { sealSession: true },
|
|
343
|
+
})).rejects.toThrow('Cookie password is required');
|
|
344
|
+
}));
|
|
345
|
+
});
|
|
346
|
+
describe('when successfully authenticated', () => {
|
|
347
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
348
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
349
|
+
const response = yield workos.userManagement.authenticateWithCode({
|
|
350
|
+
clientId: 'proj_whatever',
|
|
351
|
+
code: 'or this',
|
|
352
|
+
session: { sealSession: true, cookiePassword },
|
|
353
|
+
});
|
|
354
|
+
expect(response).toEqual({
|
|
355
|
+
sealedSession: expect.any(String),
|
|
356
|
+
accessToken: undefined,
|
|
357
|
+
authenticationMethod: undefined,
|
|
358
|
+
impersonator: undefined,
|
|
359
|
+
organizationId: undefined,
|
|
360
|
+
refreshToken: undefined,
|
|
361
|
+
user: expect.objectContaining({
|
|
362
|
+
email: 'test01@example.com',
|
|
363
|
+
}),
|
|
364
|
+
});
|
|
365
|
+
}));
|
|
366
|
+
});
|
|
367
|
+
});
|
|
228
368
|
});
|
|
229
369
|
describe('authenticateWithRefreshToken', () => {
|
|
230
370
|
it('sends a refresh_token authentication request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -249,8 +389,43 @@ describe('UserManagement', () => {
|
|
|
249
389
|
refreshToken: 'refreshToken2',
|
|
250
390
|
});
|
|
251
391
|
}));
|
|
392
|
+
describe('when sealSession = true', () => {
|
|
393
|
+
beforeEach(() => {
|
|
394
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
395
|
+
});
|
|
396
|
+
describe('when the cookie password is undefined', () => {
|
|
397
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
398
|
+
yield expect(workos.userManagement.authenticateWithRefreshToken({
|
|
399
|
+
clientId: 'proj_whatever',
|
|
400
|
+
refreshToken: 'refresh_token1',
|
|
401
|
+
session: { sealSession: true },
|
|
402
|
+
})).rejects.toThrow('Cookie password is required');
|
|
403
|
+
}));
|
|
404
|
+
});
|
|
405
|
+
describe('when successfully authenticated', () => {
|
|
406
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
407
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
408
|
+
const response = yield workos.userManagement.authenticateWithRefreshToken({
|
|
409
|
+
clientId: 'proj_whatever',
|
|
410
|
+
refreshToken: 'refresh_token1',
|
|
411
|
+
session: { sealSession: true, cookiePassword },
|
|
412
|
+
});
|
|
413
|
+
expect(response).toEqual({
|
|
414
|
+
sealedSession: expect.any(String),
|
|
415
|
+
accessToken: undefined,
|
|
416
|
+
authenticationMethod: undefined,
|
|
417
|
+
impersonator: undefined,
|
|
418
|
+
organizationId: undefined,
|
|
419
|
+
refreshToken: undefined,
|
|
420
|
+
user: expect.objectContaining({
|
|
421
|
+
email: 'test01@example.com',
|
|
422
|
+
}),
|
|
423
|
+
});
|
|
424
|
+
}));
|
|
425
|
+
});
|
|
426
|
+
});
|
|
252
427
|
});
|
|
253
|
-
describe('
|
|
428
|
+
describe('authenticateWithTotp', () => {
|
|
254
429
|
it('sends a token authentication request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
255
430
|
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
256
431
|
const resp = yield workos.userManagement.authenticateWithTotp({
|
|
@@ -274,8 +449,47 @@ describe('UserManagement', () => {
|
|
|
274
449
|
},
|
|
275
450
|
});
|
|
276
451
|
}));
|
|
452
|
+
describe('when sealSession = true', () => {
|
|
453
|
+
beforeEach(() => {
|
|
454
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
455
|
+
});
|
|
456
|
+
describe('when the cookie password is undefined', () => {
|
|
457
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
458
|
+
yield expect(workos.userManagement.authenticateWithTotp({
|
|
459
|
+
clientId: 'proj_whatever',
|
|
460
|
+
code: 'or this',
|
|
461
|
+
authenticationChallengeId: 'auth_challenge_01H96FETXGTW1QMBSBT2T36PW0',
|
|
462
|
+
pendingAuthenticationToken: 'cTDQJTTkTkkVYxQUlKBIxEsFs',
|
|
463
|
+
session: { sealSession: true },
|
|
464
|
+
})).rejects.toThrow('Cookie password is required');
|
|
465
|
+
}));
|
|
466
|
+
});
|
|
467
|
+
describe('when successfully authenticated', () => {
|
|
468
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
469
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
470
|
+
const response = yield workos.userManagement.authenticateWithTotp({
|
|
471
|
+
clientId: 'proj_whatever',
|
|
472
|
+
code: 'or this',
|
|
473
|
+
authenticationChallengeId: 'auth_challenge_01H96FETXGTW1QMBSBT2T36PW0',
|
|
474
|
+
pendingAuthenticationToken: 'cTDQJTTkTkkVYxQUlKBIxEsFs',
|
|
475
|
+
session: { sealSession: true, cookiePassword },
|
|
476
|
+
});
|
|
477
|
+
expect(response).toEqual({
|
|
478
|
+
sealedSession: expect.any(String),
|
|
479
|
+
accessToken: undefined,
|
|
480
|
+
authenticationMethod: undefined,
|
|
481
|
+
impersonator: undefined,
|
|
482
|
+
organizationId: undefined,
|
|
483
|
+
refreshToken: undefined,
|
|
484
|
+
user: expect.objectContaining({
|
|
485
|
+
email: 'test01@example.com',
|
|
486
|
+
}),
|
|
487
|
+
});
|
|
488
|
+
}));
|
|
489
|
+
});
|
|
490
|
+
});
|
|
277
491
|
});
|
|
278
|
-
describe('
|
|
492
|
+
describe('authenticateWithEmailVerification', () => {
|
|
279
493
|
it('sends an email verification authentication request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
280
494
|
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
281
495
|
const resp = yield workos.userManagement.authenticateWithEmailVerification({
|
|
@@ -297,6 +511,43 @@ describe('UserManagement', () => {
|
|
|
297
511
|
},
|
|
298
512
|
});
|
|
299
513
|
}));
|
|
514
|
+
describe('when sealSession = true', () => {
|
|
515
|
+
beforeEach(() => {
|
|
516
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
517
|
+
});
|
|
518
|
+
describe('when the cookie password is undefined', () => {
|
|
519
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
520
|
+
yield expect(workos.userManagement.authenticateWithEmailVerification({
|
|
521
|
+
clientId: 'proj_whatever',
|
|
522
|
+
code: 'or this',
|
|
523
|
+
pendingAuthenticationToken: 'cTDQJTTkTkkVYxQUlKBIxEsFs',
|
|
524
|
+
session: { sealSession: true },
|
|
525
|
+
})).rejects.toThrow('Cookie password is required');
|
|
526
|
+
}));
|
|
527
|
+
});
|
|
528
|
+
describe('when successfully authenticated', () => {
|
|
529
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
530
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
531
|
+
const response = yield workos.userManagement.authenticateWithEmailVerification({
|
|
532
|
+
clientId: 'proj_whatever',
|
|
533
|
+
code: 'or this',
|
|
534
|
+
pendingAuthenticationToken: 'cTDQJTTkTkkVYxQUlKBIxEsFs',
|
|
535
|
+
session: { sealSession: true, cookiePassword },
|
|
536
|
+
});
|
|
537
|
+
expect(response).toEqual({
|
|
538
|
+
sealedSession: expect.any(String),
|
|
539
|
+
accessToken: undefined,
|
|
540
|
+
authenticationMethod: undefined,
|
|
541
|
+
impersonator: undefined,
|
|
542
|
+
organizationId: undefined,
|
|
543
|
+
refreshToken: undefined,
|
|
544
|
+
user: expect.objectContaining({
|
|
545
|
+
email: 'test01@example.com',
|
|
546
|
+
}),
|
|
547
|
+
});
|
|
548
|
+
}));
|
|
549
|
+
});
|
|
550
|
+
});
|
|
300
551
|
});
|
|
301
552
|
describe('authenticateWithOrganizationSelection', () => {
|
|
302
553
|
it('sends an Organization Selection Authentication request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -320,6 +571,253 @@ describe('UserManagement', () => {
|
|
|
320
571
|
},
|
|
321
572
|
});
|
|
322
573
|
}));
|
|
574
|
+
describe('when sealSession = true', () => {
|
|
575
|
+
beforeEach(() => {
|
|
576
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
577
|
+
});
|
|
578
|
+
describe('when the cookie password is undefined', () => {
|
|
579
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
580
|
+
yield expect(workos.userManagement.authenticateWithOrganizationSelection({
|
|
581
|
+
clientId: 'proj_whatever',
|
|
582
|
+
pendingAuthenticationToken: 'cTDQJTTkTkkVYxQUlKBIxEsFs',
|
|
583
|
+
organizationId: 'org_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
584
|
+
session: { sealSession: true },
|
|
585
|
+
})).rejects.toThrow('Cookie password is required');
|
|
586
|
+
}));
|
|
587
|
+
});
|
|
588
|
+
describe('when successfully authenticated', () => {
|
|
589
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
590
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
591
|
+
const response = yield workos.userManagement.authenticateWithOrganizationSelection({
|
|
592
|
+
clientId: 'proj_whatever',
|
|
593
|
+
pendingAuthenticationToken: 'cTDQJTTkTkkVYxQUlKBIxEsFs',
|
|
594
|
+
organizationId: 'org_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
595
|
+
session: { sealSession: true, cookiePassword },
|
|
596
|
+
});
|
|
597
|
+
expect(response).toEqual({
|
|
598
|
+
sealedSession: expect.any(String),
|
|
599
|
+
accessToken: undefined,
|
|
600
|
+
authenticationMethod: undefined,
|
|
601
|
+
impersonator: undefined,
|
|
602
|
+
organizationId: undefined,
|
|
603
|
+
refreshToken: undefined,
|
|
604
|
+
user: expect.objectContaining({
|
|
605
|
+
email: 'test01@example.com',
|
|
606
|
+
}),
|
|
607
|
+
});
|
|
608
|
+
}));
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
});
|
|
612
|
+
describe('authenticateWithSessionCookie', () => {
|
|
613
|
+
beforeEach(() => {
|
|
614
|
+
// Mock createRemoteJWKSet
|
|
615
|
+
jest
|
|
616
|
+
.spyOn(jose, 'createRemoteJWKSet')
|
|
617
|
+
.mockImplementation((_url, _options) => {
|
|
618
|
+
// This function simulates the token verification process
|
|
619
|
+
const verifyFunction = (_protectedHeader, _token) => {
|
|
620
|
+
return Promise.resolve({
|
|
621
|
+
type: 'public',
|
|
622
|
+
});
|
|
623
|
+
};
|
|
624
|
+
// Return an object that includes the verify function and the additional expected properties
|
|
625
|
+
return {
|
|
626
|
+
__call__: verifyFunction,
|
|
627
|
+
coolingDown: false,
|
|
628
|
+
fresh: false,
|
|
629
|
+
reloading: false,
|
|
630
|
+
reload: jest.fn().mockResolvedValue(undefined),
|
|
631
|
+
jwks: () => undefined,
|
|
632
|
+
};
|
|
633
|
+
});
|
|
634
|
+
});
|
|
635
|
+
it('throws an error when the cookie password is undefined', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
636
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
637
|
+
sessionData: 'session_cookie',
|
|
638
|
+
})).rejects.toThrow('Cookie password is required');
|
|
639
|
+
}));
|
|
640
|
+
it('returns authenticated = false when the session cookie is empty', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
641
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
642
|
+
sessionData: '',
|
|
643
|
+
cookiePassword: 'secret',
|
|
644
|
+
})).resolves.toEqual({
|
|
645
|
+
authenticated: false,
|
|
646
|
+
reason: 'no_session_cookie_provided',
|
|
647
|
+
});
|
|
648
|
+
}));
|
|
649
|
+
it('returns authenticated = false when session cookie is invalid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
650
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
651
|
+
sessionData: 'thisisacookie',
|
|
652
|
+
cookiePassword: 'secret',
|
|
653
|
+
})).resolves.toEqual({
|
|
654
|
+
authenticated: false,
|
|
655
|
+
reason: 'invalid_session_cookie',
|
|
656
|
+
});
|
|
657
|
+
}));
|
|
658
|
+
it('returns authenticated = false when session cookie cannot be unsealed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
659
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
660
|
+
const sessionData = yield (0, iron_session_1.sealData)({
|
|
661
|
+
accessToken: 'abc123',
|
|
662
|
+
refreshToken: 'def456',
|
|
663
|
+
user: {
|
|
664
|
+
object: 'user',
|
|
665
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
666
|
+
email: 'test@example.com',
|
|
667
|
+
},
|
|
668
|
+
}, { password: cookiePassword });
|
|
669
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
670
|
+
sessionData,
|
|
671
|
+
cookiePassword: 'secretpasswordwhichisalsolongbutnottherightone',
|
|
672
|
+
})).resolves.toEqual({
|
|
673
|
+
authenticated: false,
|
|
674
|
+
reason: 'invalid_session_cookie',
|
|
675
|
+
});
|
|
676
|
+
}));
|
|
677
|
+
it('returns authenticated = false when the JWT is invalid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
678
|
+
jest.spyOn(jose, 'jwtVerify').mockImplementationOnce(() => {
|
|
679
|
+
throw new Error('Invalid JWT');
|
|
680
|
+
});
|
|
681
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
682
|
+
const sessionData = yield (0, iron_session_1.sealData)({
|
|
683
|
+
accessToken: 'abc123',
|
|
684
|
+
refreshToken: 'def456',
|
|
685
|
+
user: {
|
|
686
|
+
object: 'user',
|
|
687
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
688
|
+
email: 'test@example.com',
|
|
689
|
+
},
|
|
690
|
+
}, { password: cookiePassword });
|
|
691
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
692
|
+
sessionData,
|
|
693
|
+
cookiePassword,
|
|
694
|
+
})).resolves.toEqual({ authenticated: false, reason: 'invalid_jwt' });
|
|
695
|
+
}));
|
|
696
|
+
it('returns the JWT claims when provided a valid JWT', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
697
|
+
jest
|
|
698
|
+
.spyOn(jose, 'jwtVerify')
|
|
699
|
+
.mockResolvedValue({});
|
|
700
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
701
|
+
const sessionData = yield (0, iron_session_1.sealData)({
|
|
702
|
+
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJzdWIiOiAiMTIzNDU2Nzg5MCIsCiAgIm5hbWUiOiAiSm9obiBEb2UiLAogICJpYXQiOiAxNTE2MjM5MDIyLAogICJzaWQiOiAic2Vzc2lvbl8xMjMiLAogICJvcmdfaWQiOiAib3JnXzEyMyIsCiAgInJvbGUiOiAibWVtYmVyIiwKICAicGVybWlzc2lvbnMiOiBbInBvc3RzOmNyZWF0ZSIsICJwb3N0czpkZWxldGUiXQp9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
|
|
703
|
+
refreshToken: 'def456',
|
|
704
|
+
user: {
|
|
705
|
+
object: 'user',
|
|
706
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
707
|
+
email: 'test@example.com',
|
|
708
|
+
},
|
|
709
|
+
}, { password: cookiePassword });
|
|
710
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
711
|
+
sessionData,
|
|
712
|
+
cookiePassword,
|
|
713
|
+
})).resolves.toEqual({
|
|
714
|
+
authenticated: true,
|
|
715
|
+
sessionId: 'session_123',
|
|
716
|
+
organizationId: 'org_123',
|
|
717
|
+
role: 'member',
|
|
718
|
+
permissions: ['posts:create', 'posts:delete'],
|
|
719
|
+
});
|
|
720
|
+
}));
|
|
721
|
+
});
|
|
722
|
+
describe('refreshAndSealSessionData', () => {
|
|
723
|
+
it('throws an error when the cookie password is undefined', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
724
|
+
yield expect(workos.userManagement.refreshAndSealSessionData({
|
|
725
|
+
sessionData: 'session_cookie',
|
|
726
|
+
})).rejects.toThrow('Cookie password is required');
|
|
727
|
+
}));
|
|
728
|
+
it('returns authenticated = false when the session cookie is empty', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
729
|
+
yield expect(workos.userManagement.refreshAndSealSessionData({
|
|
730
|
+
sessionData: '',
|
|
731
|
+
cookiePassword: 'secret',
|
|
732
|
+
})).resolves.toEqual({
|
|
733
|
+
authenticated: false,
|
|
734
|
+
reason: 'no_session_cookie_provided',
|
|
735
|
+
});
|
|
736
|
+
}));
|
|
737
|
+
it('returns authenticated = false when session cookie is invalid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
738
|
+
yield expect(workos.userManagement.refreshAndSealSessionData({
|
|
739
|
+
sessionData: 'thisisacookie',
|
|
740
|
+
cookiePassword: 'secret',
|
|
741
|
+
})).resolves.toEqual({
|
|
742
|
+
authenticated: false,
|
|
743
|
+
reason: 'invalid_session_cookie',
|
|
744
|
+
});
|
|
745
|
+
}));
|
|
746
|
+
it('returns authenticated = false when session cookie cannot be unsealed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
747
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
748
|
+
const sessionData = yield (0, iron_session_1.sealData)({
|
|
749
|
+
accessToken: 'abc123',
|
|
750
|
+
refreshToken: 'def456',
|
|
751
|
+
user: {
|
|
752
|
+
object: 'user',
|
|
753
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
754
|
+
email: 'test@example.com',
|
|
755
|
+
},
|
|
756
|
+
}, { password: cookiePassword });
|
|
757
|
+
yield expect(workos.userManagement.refreshAndSealSessionData({
|
|
758
|
+
sessionData,
|
|
759
|
+
cookiePassword: 'secretpasswordwhichisalsolongbutnottherightone',
|
|
760
|
+
})).resolves.toEqual({
|
|
761
|
+
authenticated: false,
|
|
762
|
+
reason: 'invalid_session_cookie',
|
|
763
|
+
});
|
|
764
|
+
}));
|
|
765
|
+
it('returns the sealed refreshed session cookie when provided a valid existing session cookie', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
766
|
+
(0, test_utils_1.fetchOnce)({
|
|
767
|
+
user: user_json_1.default,
|
|
768
|
+
access_token: 'access_token',
|
|
769
|
+
refresh_token: 'refresh_token',
|
|
770
|
+
});
|
|
771
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
772
|
+
const sessionData = yield (0, iron_session_1.sealData)({
|
|
773
|
+
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJzdWIiOiAiMTIzNDU2Nzg5MCIsCiAgIm5hbWUiOiAiSm9obiBEb2UiLAogICJpYXQiOiAxNTE2MjM5MDIyLAogICJzaWQiOiAic2Vzc2lvbl8xMjMiLAogICJvcmdfaWQiOiAib3JnXzEyMyIsCiAgInJvbGUiOiAibWVtYmVyIiwKICAicGVybWlzc2lvbnMiOiBbInBvc3RzOmNyZWF0ZSIsICJwb3N0czpkZWxldGUiXQp9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
|
|
774
|
+
refreshToken: 'def456',
|
|
775
|
+
user: {
|
|
776
|
+
object: 'user',
|
|
777
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
778
|
+
email: 'test@example.com',
|
|
779
|
+
},
|
|
780
|
+
}, { password: cookiePassword });
|
|
781
|
+
yield expect(workos.userManagement.refreshAndSealSessionData({
|
|
782
|
+
sessionData,
|
|
783
|
+
cookiePassword,
|
|
784
|
+
})).resolves.toEqual({
|
|
785
|
+
sealedSession: expect.any(String),
|
|
786
|
+
authenticated: true,
|
|
787
|
+
});
|
|
788
|
+
}));
|
|
789
|
+
});
|
|
790
|
+
describe('getSessionFromCookie', () => {
|
|
791
|
+
it('throws an error when the cookie password is undefined', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
792
|
+
yield expect(workos.userManagement.getSessionFromCookie({
|
|
793
|
+
sessionData: 'session_cookie',
|
|
794
|
+
})).rejects.toThrow('Cookie password is required');
|
|
795
|
+
}));
|
|
796
|
+
it('returns undefined when the session cookie cannot be unsealed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
797
|
+
yield expect(workos.userManagement.getSessionFromCookie({
|
|
798
|
+
sessionData: '',
|
|
799
|
+
cookiePassword: 'secret',
|
|
800
|
+
})).resolves.toBeUndefined();
|
|
801
|
+
}));
|
|
802
|
+
it('returns the unsealed session cookie data when provided a valid session cookie', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
803
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
804
|
+
const sessionCookieData = {
|
|
805
|
+
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJzdWIiOiAiMTIzNDU2Nzg5MCIsCiAgIm5hbWUiOiAiSm9obiBEb2UiLAogICJpYXQiOiAxNTE2MjM5MDIyLAogICJzaWQiOiAic2Vzc2lvbl8xMjMiLAogICJvcmdfaWQiOiAib3JnXzEyMyIsCiAgInJvbGUiOiAibWVtYmVyIiwKICAicGVybWlzc2lvbnMiOiBbInBvc3RzOmNyZWF0ZSIsICJwb3N0czpkZWxldGUiXQp9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
|
|
806
|
+
refreshToken: 'def456',
|
|
807
|
+
user: {
|
|
808
|
+
object: 'user',
|
|
809
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
810
|
+
email: 'test@example.com',
|
|
811
|
+
},
|
|
812
|
+
};
|
|
813
|
+
const sessionData = yield (0, iron_session_1.sealData)(sessionCookieData, {
|
|
814
|
+
password: cookiePassword,
|
|
815
|
+
});
|
|
816
|
+
yield expect(workos.userManagement.getSessionFromCookie({
|
|
817
|
+
sessionData,
|
|
818
|
+
cookiePassword,
|
|
819
|
+
})).resolves.toEqual(sessionCookieData);
|
|
820
|
+
}));
|
|
323
821
|
});
|
|
324
822
|
describe('getEmailVerification', () => {
|
|
325
823
|
it('sends a Get EmailVerification request', () => __awaiter(void 0, void 0, void 0, function* () {
|
package/lib/workos.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export declare class WorkOS {
|
|
|
16
16
|
readonly options: WorkOSOptions;
|
|
17
17
|
readonly baseURL: string;
|
|
18
18
|
readonly client: HttpClient;
|
|
19
|
+
readonly clientId?: string;
|
|
19
20
|
readonly auditLogs: AuditLogs;
|
|
20
21
|
readonly directorySync: DirectorySync;
|
|
21
22
|
readonly organizations: Organizations;
|
package/lib/workos.js
CHANGED
|
@@ -26,10 +26,11 @@ const bad_request_exception_1 = require("./common/exceptions/bad-request.excepti
|
|
|
26
26
|
const http_client_1 = require("./common/net/http-client");
|
|
27
27
|
const subtle_crypto_provider_1 = require("./common/crypto/subtle-crypto-provider");
|
|
28
28
|
const fetch_client_1 = require("./common/net/fetch-client");
|
|
29
|
-
const VERSION = '7.
|
|
29
|
+
const VERSION = '7.16.0';
|
|
30
30
|
const DEFAULT_HOSTNAME = 'api.workos.com';
|
|
31
31
|
class WorkOS {
|
|
32
32
|
constructor(key, options = {}) {
|
|
33
|
+
var _a;
|
|
33
34
|
this.key = key;
|
|
34
35
|
this.options = options;
|
|
35
36
|
this.auditLogs = new audit_logs_1.AuditLogs(this);
|
|
@@ -41,7 +42,6 @@ class WorkOS {
|
|
|
41
42
|
this.sso = new sso_1.SSO(this);
|
|
42
43
|
this.mfa = new mfa_1.Mfa(this);
|
|
43
44
|
this.events = new events_1.Events(this);
|
|
44
|
-
this.userManagement = new user_management_1.UserManagement(this);
|
|
45
45
|
if (!key) {
|
|
46
46
|
// process might be undefined in some environments
|
|
47
47
|
this.key = process === null || process === void 0 ? void 0 : process.env.WORKOS_API_KEY;
|
|
@@ -52,6 +52,7 @@ class WorkOS {
|
|
|
52
52
|
if (this.options.https === undefined) {
|
|
53
53
|
this.options.https = true;
|
|
54
54
|
}
|
|
55
|
+
this.clientId = (_a = this.options.clientId) !== null && _a !== void 0 ? _a : process === null || process === void 0 ? void 0 : process.env.WORKOS_CLIENT_ID;
|
|
55
56
|
const protocol = this.options.https ? 'https' : 'http';
|
|
56
57
|
const apiHostname = this.options.apiHostname || DEFAULT_HOSTNAME;
|
|
57
58
|
const port = this.options.port;
|
|
@@ -65,6 +66,8 @@ class WorkOS {
|
|
|
65
66
|
userAgent += ` ${name}: ${version}`;
|
|
66
67
|
}
|
|
67
68
|
this.webhooks = this.createWebhookClient();
|
|
69
|
+
// Must initialize UserManagement after baseURL is configured
|
|
70
|
+
this.userManagement = new user_management_1.UserManagement(this);
|
|
68
71
|
this.client = this.createHttpClient(options, userAgent);
|
|
69
72
|
}
|
|
70
73
|
createWebhookClient() {
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "7.
|
|
2
|
+
"version": "7.16.0",
|
|
3
3
|
"name": "@workos-inc/node",
|
|
4
4
|
"author": "WorkOS",
|
|
5
5
|
"description": "A Node wrapper for the WorkOS API",
|
|
@@ -37,6 +37,8 @@
|
|
|
37
37
|
"prepublishOnly": "yarn run build"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
+
"iron-session": "~6.3.1",
|
|
41
|
+
"jose": "~5.6.3",
|
|
40
42
|
"pluralize": "8.0.0"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
@@ -63,4 +65,4 @@
|
|
|
63
65
|
"default": "./lib/index.js"
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
|
-
}
|
|
68
|
+
}
|