@workos-inc/node 2.6.1 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/lib/audit-logs/audit-logs.d.ts +7 -0
  2. package/lib/audit-logs/audit-logs.js +26 -0
  3. package/lib/audit-logs/audit-logs.spec.d.ts +1 -0
  4. package/lib/audit-logs/audit-logs.spec.js +110 -0
  5. package/lib/audit-logs/interfaces/create-audit-log-event-options.interface.d.ts +26 -0
  6. package/lib/{mfa/interfaces/verify-factor-response.js → audit-logs/interfaces/create-audit-log-event-options.interface.js} +0 -0
  7. package/lib/audit-logs/interfaces/index.d.ts +1 -0
  8. package/lib/audit-logs/interfaces/index.js +2 -0
  9. package/lib/common/exceptions/bad-request.exception.d.ts +14 -0
  10. package/lib/common/exceptions/bad-request.exception.js +22 -0
  11. package/lib/common/exceptions/not-found.exception.d.ts +8 -2
  12. package/lib/common/exceptions/not-found.exception.js +5 -3
  13. package/lib/common/interfaces/pagination-options.interface.d.ts +1 -0
  14. package/lib/directory-sync/directory-sync.spec.js +3 -0
  15. package/lib/directory-sync/interfaces/group.interface.d.ts +3 -0
  16. package/lib/mfa/interfaces/challenge.interface.d.ts +1 -1
  17. package/lib/mfa/interfaces/verify-challenge-options.d.ts +4 -0
  18. package/lib/mfa/interfaces/verify-challenge-options.js +2 -0
  19. package/lib/mfa/interfaces/{verify-factor-response.d.ts → verify-challenge-response.d.ts} +0 -0
  20. package/lib/mfa/interfaces/verify-challenge-response.js +2 -0
  21. package/lib/mfa/interfaces/verify-factor-options.d.ts +3 -0
  22. package/lib/mfa/mfa.d.ts +6 -1
  23. package/lib/mfa/mfa.js +10 -4
  24. package/lib/mfa/mfa.spec.js +11 -20
  25. package/lib/sso/interfaces/connection-type.enum.d.ts +18 -0
  26. package/lib/sso/interfaces/connection-type.enum.js +18 -0
  27. package/lib/workos.d.ts +3 -0
  28. package/lib/workos.js +56 -125
  29. package/lib/workos.spec.js +34 -2
  30. package/package.json +8 -8
@@ -0,0 +1,7 @@
1
+ import { WorkOS } from '../workos';
2
+ import { CreateAuditLogEventOptions, CreateAuditLogEventRequestOptions } from './interfaces';
3
+ export declare class AuditLogs {
4
+ private readonly workos;
5
+ constructor(workos: WorkOS);
6
+ createEvent(organization: string, event: CreateAuditLogEventOptions, options?: CreateAuditLogEventRequestOptions): Promise<void>;
7
+ }
@@ -0,0 +1,26 @@
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
+ exports.AuditLogs = void 0;
13
+ class AuditLogs {
14
+ constructor(workos) {
15
+ this.workos = workos;
16
+ }
17
+ createEvent(organization, event, options = {}) {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ yield this.workos.post('/audit_logs/events', {
20
+ event,
21
+ organization_id: organization,
22
+ }, options);
23
+ });
24
+ }
25
+ }
26
+ exports.AuditLogs = AuditLogs;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,110 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const axios_1 = __importDefault(require("axios"));
16
+ const axios_mock_adapter_1 = __importDefault(require("axios-mock-adapter"));
17
+ const exceptions_1 = require("../common/exceptions");
18
+ const bad_request_exception_1 = require("../common/exceptions/bad-request.exception");
19
+ const workos_1 = require("../workos");
20
+ const mock = new axios_mock_adapter_1.default(axios_1.default);
21
+ const event = {
22
+ action: 'document.updated',
23
+ occurred_at: new Date(),
24
+ actor: {
25
+ id: 'user_1',
26
+ name: 'Jon Smith',
27
+ type: 'user',
28
+ },
29
+ targets: [
30
+ {
31
+ id: 'document_39127',
32
+ type: 'document',
33
+ },
34
+ ],
35
+ context: {
36
+ location: ' 192.0.0.8',
37
+ user_agent: 'Firefox',
38
+ },
39
+ metadata: {
40
+ successful: true,
41
+ },
42
+ };
43
+ const serializeEventOptions = (options) => (Object.assign(Object.assign({}, options), { occurred_at: options.occurred_at.toISOString() }));
44
+ describe('AuditLogs', () => {
45
+ describe('createEvent', () => {
46
+ describe('with an idempotency key', () => {
47
+ it('includes an idempotency key with request', () => __awaiter(void 0, void 0, void 0, function* () {
48
+ mock
49
+ .onPost('/audit_logs/events', {
50
+ event: serializeEventOptions(event),
51
+ organization_id: 'org_123',
52
+ })
53
+ .replyOnce(201, { success: true });
54
+ const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
55
+ yield expect(workos.auditLogs.createEvent('org_123', event, {
56
+ idempotencyKey: 'the-idempotency-key',
57
+ })).resolves.toBeUndefined();
58
+ expect(mock.history.post[0].headers['Idempotency-Key']).toEqual('the-idempotency-key');
59
+ }));
60
+ });
61
+ describe('when the api responds with a 200', () => {
62
+ it('returns void', () => __awaiter(void 0, void 0, void 0, function* () {
63
+ mock
64
+ .onPost('/audit_logs/events', {
65
+ organization_id: 'org_123',
66
+ event: serializeEventOptions(event),
67
+ })
68
+ .replyOnce(201, { success: true });
69
+ const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
70
+ yield expect(workos.auditLogs.createEvent('org_123', event)).resolves.toBeUndefined();
71
+ }));
72
+ });
73
+ describe('when the api responds with a 401', () => {
74
+ it('throws an UnauthorizedException', () => __awaiter(void 0, void 0, void 0, function* () {
75
+ mock
76
+ .onPost('/audit_logs/events', {
77
+ organization_id: 'org_123',
78
+ event: serializeEventOptions(event),
79
+ })
80
+ .replyOnce(401, {
81
+ message: 'Unauthorized',
82
+ }, { 'X-Request-ID': 'a-request-id' });
83
+ const workos = new workos_1.WorkOS('invalid apikey');
84
+ yield expect(workos.auditLogs.createEvent('org_123', event)).rejects.toStrictEqual(new exceptions_1.UnauthorizedException('a-request-id'));
85
+ }));
86
+ });
87
+ describe('when the api responds with a 400', () => {
88
+ it('throws an BadRequestException', () => __awaiter(void 0, void 0, void 0, function* () {
89
+ const errors = [
90
+ {
91
+ field: 'occurred_at',
92
+ code: 'occurred_at must be an ISO 8601 date string',
93
+ },
94
+ ];
95
+ mock
96
+ .onPost('/audit_logs/events', {
97
+ organization_id: 'org_123',
98
+ event: serializeEventOptions(event),
99
+ })
100
+ .replyOnce(400, {
101
+ message: 'Audit Log could not be processed due to missing or incorrect data.',
102
+ code: 'invalid_audit_log',
103
+ errors,
104
+ }, { 'X-Request-ID': 'a-request-id' });
105
+ const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
106
+ yield expect(workos.auditLogs.createEvent('org_123', event)).rejects.toThrow(bad_request_exception_1.BadRequestException);
107
+ }));
108
+ });
109
+ });
110
+ });
@@ -0,0 +1,26 @@
1
+ import { PostOptions } from '../../common/interfaces';
2
+ export interface AuditLogActor {
3
+ id: string;
4
+ name?: string;
5
+ type: string;
6
+ metadata?: Record<string, string | number | boolean>;
7
+ }
8
+ export interface AuditLogTarget {
9
+ id: string;
10
+ name?: string;
11
+ type: string;
12
+ metadata?: Record<string, string | number | boolean>;
13
+ }
14
+ export interface CreateAuditLogEventOptions {
15
+ action: string;
16
+ version?: number;
17
+ occurred_at: Date;
18
+ actor: AuditLogActor;
19
+ targets: AuditLogTarget[];
20
+ context: {
21
+ location: string;
22
+ user_agent?: string;
23
+ };
24
+ metadata?: Record<string, string | number | boolean>;
25
+ }
26
+ export declare type CreateAuditLogEventRequestOptions = Pick<PostOptions, 'idempotencyKey'>;
@@ -0,0 +1 @@
1
+ export { CreateAuditLogEventOptions, CreateAuditLogEventRequestOptions, } from './create-audit-log-event-options.interface';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,14 @@
1
+ export declare class BadRequestException extends Error {
2
+ readonly status: number;
3
+ readonly name: string;
4
+ readonly message: string;
5
+ readonly code?: string;
6
+ readonly errors?: unknown[];
7
+ readonly requestID: string;
8
+ constructor({ code, errors, message, requestID, }: {
9
+ code?: string;
10
+ errors?: unknown[];
11
+ message?: string;
12
+ requestID: string;
13
+ });
14
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BadRequestException = void 0;
4
+ class BadRequestException extends Error {
5
+ constructor({ code, errors, message, requestID, }) {
6
+ super();
7
+ this.status = 400;
8
+ this.name = 'BadRequestException';
9
+ this.message = 'Bad request';
10
+ this.requestID = requestID;
11
+ if (message) {
12
+ this.message = message;
13
+ }
14
+ if (code) {
15
+ this.code = code;
16
+ }
17
+ if (errors) {
18
+ this.errors = errors;
19
+ }
20
+ }
21
+ }
22
+ exports.BadRequestException = BadRequestException;
@@ -1,7 +1,13 @@
1
1
  export declare class NotFoundException extends Error {
2
- readonly requestID: string;
3
2
  readonly status: number;
4
3
  readonly name: string;
5
4
  readonly message: string;
6
- constructor(path: string, requestID: string);
5
+ readonly code?: string;
6
+ readonly requestID: string;
7
+ constructor({ code, message, path, requestID, }: {
8
+ code?: string;
9
+ message?: string;
10
+ path: string;
11
+ requestID: string;
12
+ });
7
13
  }
@@ -2,12 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NotFoundException = void 0;
4
4
  class NotFoundException extends Error {
5
- constructor(path, requestID) {
5
+ constructor({ code, message, path, requestID, }) {
6
6
  super();
7
- this.requestID = requestID;
8
7
  this.status = 404;
9
8
  this.name = 'NotFoundException';
10
- this.message = `The requested path '${path}' could not be found.`;
9
+ this.code = code;
10
+ this.message =
11
+ message !== null && message !== void 0 ? message : `The requested path '${path}' could not be found.`;
12
+ this.requestID = requestID;
11
13
  }
12
14
  }
13
15
  exports.NotFoundException = NotFoundException;
@@ -2,4 +2,5 @@ export interface PaginationOptions {
2
2
  limit?: number;
3
3
  before?: string;
4
4
  after?: string;
5
+ order?: 'asc' | 'desc';
5
6
  }
@@ -33,8 +33,11 @@ describe('DirectorySync', () => {
33
33
  };
34
34
  const groupResponse = {
35
35
  id: 'dir_grp_123',
36
+ idp_id: '123',
36
37
  directory_id: 'dir_123',
37
38
  name: 'Foo Group',
39
+ created_at: `2021-10-27 15:21:50.640958`,
40
+ updated_at: '2021-10-27 15:21:50.640959',
38
41
  raw_attributes: {
39
42
  foo: 'bar',
40
43
  },
@@ -1,6 +1,9 @@
1
1
  export interface Group {
2
2
  id: string;
3
+ idp_id: string;
3
4
  directory_id: string;
4
5
  name: string;
6
+ created_at: string;
7
+ updated_at: string;
5
8
  raw_attributes: any;
6
9
  }
@@ -3,7 +3,7 @@ export interface Challenge {
3
3
  id: string;
4
4
  created_at: string;
5
5
  updated_at: string;
6
- expires_at: string;
6
+ expires_at?: string;
7
7
  code: string;
8
8
  authentication_factor_id: string;
9
9
  }
@@ -0,0 +1,4 @@
1
+ export interface VerifyChallengeOptions {
2
+ authenticationChallengeId: string;
3
+ code: string;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @deprecated Please use `VerifyChallengeOptions` instead.
3
+ */
1
4
  export declare type VerifyFactorOptions = {
2
5
  authenticationChallengeId: string;
3
6
  code: string;
package/lib/mfa/mfa.d.ts CHANGED
@@ -4,7 +4,8 @@ import { Challenge } from './interfaces/challenge.interface';
4
4
  import { EnrollFactorOptions } from './interfaces/enroll-factor-options';
5
5
  import { Factor } from './interfaces/factor.interface';
6
6
  import { VerifyFactorOptions } from './interfaces/verify-factor-options';
7
- import { VerifyResponse } from './interfaces/verify-factor-response';
7
+ import { VerifyResponse } from './interfaces/verify-challenge-response';
8
+ import { VerifyChallengeOptions } from './interfaces/verify-challenge-options';
8
9
  export declare class Mfa {
9
10
  private readonly workos;
10
11
  constructor(workos: WorkOS);
@@ -12,5 +13,9 @@ export declare class Mfa {
12
13
  getFactor(id: string): Promise<any>;
13
14
  enrollFactor(options: EnrollFactorOptions): Promise<Factor>;
14
15
  challengeFactor(options: ChallengeFactorOptions): Promise<Challenge>;
16
+ /**
17
+ * @deprecated Please use `verifyChallenge` instead.
18
+ */
15
19
  verifyFactor(options: VerifyFactorOptions): Promise<VerifyResponse>;
20
+ verifyChallenge(options: VerifyChallengeOptions): Promise<VerifyResponse>;
16
21
  }
package/lib/mfa/mfa.js CHANGED
@@ -47,17 +47,23 @@ class Mfa {
47
47
  }
48
48
  challengeFactor(options) {
49
49
  return __awaiter(this, void 0, void 0, function* () {
50
- const { data } = yield this.workos.post('/auth/factors/challenge', {
51
- authentication_factor_id: options.authenticationFactorId,
50
+ const { data } = yield this.workos.post(`/auth/factors/${options.authenticationFactorId}/challenge`, {
52
51
  sms_template: 'smsTemplate' in options ? options.smsTemplate : undefined,
53
52
  });
54
53
  return data;
55
54
  });
56
55
  }
56
+ /**
57
+ * @deprecated Please use `verifyChallenge` instead.
58
+ */
57
59
  verifyFactor(options) {
58
60
  return __awaiter(this, void 0, void 0, function* () {
59
- const { data } = yield this.workos.post('/auth/factors/verify', {
60
- authentication_challenge_id: options.authenticationChallengeId,
61
+ return this.verifyChallenge(options);
62
+ });
63
+ }
64
+ verifyChallenge(options) {
65
+ return __awaiter(this, void 0, void 0, function* () {
66
+ const { data } = yield this.workos.post(`/auth/challenges/${options.authenticationChallengeId}/verify`, {
61
67
  code: options.code,
62
68
  });
63
69
  return data;
@@ -157,11 +157,7 @@ describe('MFA', () => {
157
157
  describe('with no sms template', () => {
158
158
  it('challenge a factor with no sms template', () => __awaiter(void 0, void 0, void 0, function* () {
159
159
  const mock = new axios_mock_adapter_1.default(axios_1.default);
160
- mock
161
- .onPost('/auth/factors/challenge', {
162
- authentication_factor_id: 'auth_factor_1234',
163
- })
164
- .reply(200, {
160
+ mock.onPost('/auth/factors/auth_factor_1234/challenge').reply(200, {
165
161
  object: 'authentication_challenge',
166
162
  id: 'auth_challenge_1234',
167
163
  created_at: '2022-03-15T20:39:19.892Z',
@@ -193,8 +189,7 @@ describe('MFA', () => {
193
189
  it('challenge a factor with sms template', () => __awaiter(void 0, void 0, void 0, function* () {
194
190
  const mock = new axios_mock_adapter_1.default(axios_1.default);
195
191
  mock
196
- .onPost('/auth/factors/challenge', {
197
- authentication_factor_id: 'auth_factor_1234',
192
+ .onPost('/auth/factors/auth_factor_1234/challenge', {
198
193
  sms_template: 'This is your code: 12345',
199
194
  })
200
195
  .reply(200, {
@@ -227,13 +222,12 @@ describe('MFA', () => {
227
222
  }));
228
223
  });
229
224
  });
230
- describe('verifyFactor', () => {
225
+ describe('verifyChallenge', () => {
231
226
  describe('verify with successful response', () => {
232
227
  it('verifies a successful factor', () => __awaiter(void 0, void 0, void 0, function* () {
233
228
  const mock = new axios_mock_adapter_1.default(axios_1.default);
234
229
  mock
235
- .onPost('/auth/factors/verify', {
236
- authentication_challenge_id: 'auth_challenge_1234',
230
+ .onPost('/auth/challenges/auth_challenge_1234/verify', {
237
231
  code: '12345',
238
232
  })
239
233
  .reply(200, {
@@ -251,7 +245,7 @@ describe('MFA', () => {
251
245
  const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
252
246
  apiHostname: 'api.workos.dev',
253
247
  });
254
- const verifyResponse = yield workos.mfa.verifyFactor({
248
+ const verifyResponse = yield workos.mfa.verifyChallenge({
255
249
  authenticationChallengeId: 'auth_challenge_1234',
256
250
  code: '12345',
257
251
  });
@@ -275,8 +269,7 @@ describe('MFA', () => {
275
269
  it('throws an exception', () => __awaiter(void 0, void 0, void 0, function* () {
276
270
  const mock = new axios_mock_adapter_1.default(axios_1.default);
277
271
  mock
278
- .onPost('/auth/factors/verify', {
279
- authentication_challenge_id: 'auth_challenge_1234',
272
+ .onPost('/auth/challenges/auth_challenge_1234/verify', {
280
273
  code: '12345',
281
274
  })
282
275
  .reply(422, {
@@ -288,7 +281,7 @@ describe('MFA', () => {
288
281
  const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
289
282
  apiHostname: 'api.workos.dev',
290
283
  });
291
- yield expect(workos.mfa.verifyFactor({
284
+ yield expect(workos.mfa.verifyChallenge({
292
285
  authenticationChallengeId: 'auth_challenge_1234',
293
286
  code: '12345',
294
287
  })).rejects.toThrow(exceptions_1.UnprocessableEntityException);
@@ -298,8 +291,7 @@ describe('MFA', () => {
298
291
  it('throws an exception', () => __awaiter(void 0, void 0, void 0, function* () {
299
292
  const mock = new axios_mock_adapter_1.default(axios_1.default);
300
293
  mock
301
- .onPost('/auth/factors/verify', {
302
- authentication_challenge_id: 'auth_challenge_1234',
294
+ .onPost('/auth/challenges/auth_challenge_1234/verify', {
303
295
  code: '12345',
304
296
  })
305
297
  .reply(422, {
@@ -311,7 +303,7 @@ describe('MFA', () => {
311
303
  const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
312
304
  apiHostname: 'api.workos.dev',
313
305
  });
314
- yield expect(workos.mfa.verifyFactor({
306
+ yield expect(workos.mfa.verifyChallenge({
315
307
  authenticationChallengeId: 'auth_challenge_1234',
316
308
  code: '12345',
317
309
  })).rejects.toThrow(exceptions_1.UnprocessableEntityException);
@@ -319,8 +311,7 @@ describe('MFA', () => {
319
311
  it('exception has code', () => __awaiter(void 0, void 0, void 0, function* () {
320
312
  const mock = new axios_mock_adapter_1.default(axios_1.default);
321
313
  mock
322
- .onPost('/auth/factors/verify', {
323
- authentication_challenge_id: 'auth_challenge_1234',
314
+ .onPost('/auth/challenges/auth_challenge_1234/verify', {
324
315
  code: '12345',
325
316
  })
326
317
  .reply(422, {
@@ -333,7 +324,7 @@ describe('MFA', () => {
333
324
  apiHostname: 'api.workos.dev',
334
325
  });
335
326
  try {
336
- yield workos.mfa.verifyFactor({
327
+ yield workos.mfa.verifyChallenge({
337
328
  authenticationChallengeId: 'auth_challenge_1234',
338
329
  code: '12345',
339
330
  });
@@ -1,15 +1,33 @@
1
1
  export declare enum ConnectionType {
2
2
  ADFSSAML = "ADFSSAML",
3
+ AdpOidc = "AdpOidc",
3
4
  Auth0SAML = "Auth0SAML",
4
5
  AzureSAML = "AzureSAML",
6
+ CasSAML = "CasSAML",
7
+ ClassLinkSAML = "ClassLinkSAML",
8
+ CloudflareSAML = "CloudflareSAML",
9
+ CyberArkSAML = "CyberArkSAML",
10
+ DuoSAML = "DuoSAML",
5
11
  GenericOIDC = "GenericOIDC",
6
12
  GenericSAML = "GenericSAML",
7
13
  GoogleOAuth = "GoogleOAuth",
8
14
  GoogleSAML = "GoogleSAML",
15
+ JumpCloudSAML = "JumpCloudSAML",
16
+ KeycloakSAML = "KeycloakSAML",
17
+ LastPassSAML = "LastPassSAML",
9
18
  MagicLink = "MagicLink",
19
+ MicrosoftOAuth = "MicrosoftOAuth",
20
+ MiniOrangeSAML = "MiniOrangeSAML",
21
+ NetIqSAML = "NetIqSAML",
10
22
  OktaSAML = "OktaSAML",
11
23
  OneLoginSAML = "OneLoginSAML",
24
+ OracleSAML = "OracleSAML",
12
25
  PingFederateSAML = "PingFederateSAML",
13
26
  PingOneSAML = "PingOneSAML",
27
+ RipplingSAML = "RipplingSAML",
28
+ SalesforceSAML = "SalesforceSAML",
29
+ ShibbolethGenericSAML = "ShibbolethGenericSAML",
30
+ ShibbolethSAML = "ShibbolethSAML",
31
+ SimpleSamlPhpSAML = "SimpleSamlPhpSAML",
14
32
  VMwareSAML = "VMwareSAML"
15
33
  }
@@ -4,16 +4,34 @@ exports.ConnectionType = void 0;
4
4
  var ConnectionType;
5
5
  (function (ConnectionType) {
6
6
  ConnectionType["ADFSSAML"] = "ADFSSAML";
7
+ ConnectionType["AdpOidc"] = "AdpOidc";
7
8
  ConnectionType["Auth0SAML"] = "Auth0SAML";
8
9
  ConnectionType["AzureSAML"] = "AzureSAML";
10
+ ConnectionType["CasSAML"] = "CasSAML";
11
+ ConnectionType["ClassLinkSAML"] = "ClassLinkSAML";
12
+ ConnectionType["CloudflareSAML"] = "CloudflareSAML";
13
+ ConnectionType["CyberArkSAML"] = "CyberArkSAML";
14
+ ConnectionType["DuoSAML"] = "DuoSAML";
9
15
  ConnectionType["GenericOIDC"] = "GenericOIDC";
10
16
  ConnectionType["GenericSAML"] = "GenericSAML";
11
17
  ConnectionType["GoogleOAuth"] = "GoogleOAuth";
12
18
  ConnectionType["GoogleSAML"] = "GoogleSAML";
19
+ ConnectionType["JumpCloudSAML"] = "JumpCloudSAML";
20
+ ConnectionType["KeycloakSAML"] = "KeycloakSAML";
21
+ ConnectionType["LastPassSAML"] = "LastPassSAML";
13
22
  ConnectionType["MagicLink"] = "MagicLink";
23
+ ConnectionType["MicrosoftOAuth"] = "MicrosoftOAuth";
24
+ ConnectionType["MiniOrangeSAML"] = "MiniOrangeSAML";
25
+ ConnectionType["NetIqSAML"] = "NetIqSAML";
14
26
  ConnectionType["OktaSAML"] = "OktaSAML";
15
27
  ConnectionType["OneLoginSAML"] = "OneLoginSAML";
28
+ ConnectionType["OracleSAML"] = "OracleSAML";
16
29
  ConnectionType["PingFederateSAML"] = "PingFederateSAML";
17
30
  ConnectionType["PingOneSAML"] = "PingOneSAML";
31
+ ConnectionType["RipplingSAML"] = "RipplingSAML";
32
+ ConnectionType["SalesforceSAML"] = "SalesforceSAML";
33
+ ConnectionType["ShibbolethGenericSAML"] = "ShibbolethGenericSAML";
34
+ ConnectionType["ShibbolethSAML"] = "ShibbolethSAML";
35
+ ConnectionType["SimpleSamlPhpSAML"] = "SimpleSamlPhpSAML";
18
36
  ConnectionType["VMwareSAML"] = "VMwareSAML";
19
37
  })(ConnectionType = exports.ConnectionType || (exports.ConnectionType = {}));
package/lib/workos.d.ts CHANGED
@@ -8,11 +8,13 @@ import { Portal } from './portal/portal';
8
8
  import { SSO } from './sso/sso';
9
9
  import { Webhooks } from './webhooks/webhooks';
10
10
  import { Mfa } from './mfa/mfa';
11
+ import { AuditLogs } from './audit-logs/audit-logs';
11
12
  export declare class WorkOS {
12
13
  readonly key?: string | undefined;
13
14
  readonly options: WorkOSOptions;
14
15
  readonly baseURL: string;
15
16
  private readonly client;
17
+ readonly auditLogs: AuditLogs;
16
18
  readonly auditTrail: AuditTrail;
17
19
  readonly directorySync: DirectorySync;
18
20
  readonly organizations: Organizations;
@@ -27,4 +29,5 @@ export declare class WorkOS {
27
29
  put(path: string, entity: any, options?: PutOptions): Promise<AxiosResponse>;
28
30
  delete(path: string, query?: any): Promise<AxiosResponse>;
29
31
  emitWarning(warning: string): void;
32
+ private handleAxiosError;
30
33
  }
package/lib/workos.js CHANGED
@@ -23,12 +23,15 @@ const portal_1 = require("./portal/portal");
23
23
  const sso_1 = require("./sso/sso");
24
24
  const webhooks_1 = require("./webhooks/webhooks");
25
25
  const mfa_1 = require("./mfa/mfa");
26
- const VERSION = '2.6.1';
26
+ const audit_logs_1 = require("./audit-logs/audit-logs");
27
+ const bad_request_exception_1 = require("./common/exceptions/bad-request.exception");
28
+ const VERSION = '2.8.1';
27
29
  const DEFAULT_HOSTNAME = 'api.workos.com';
28
30
  class WorkOS {
29
31
  constructor(key, options = {}) {
30
32
  this.key = key;
31
33
  this.options = options;
34
+ this.auditLogs = new audit_logs_1.AuditLogs(this);
32
35
  this.auditTrail = new audit_trail_1.AuditTrail(this);
33
36
  this.directorySync = new directory_sync_1.DirectorySync(this);
34
37
  this.organizations = new organizations_1.Organizations(this);
@@ -74,37 +77,7 @@ class WorkOS {
74
77
  });
75
78
  }
76
79
  catch (error) {
77
- const { response } = error;
78
- if (response) {
79
- const { status, data, headers } = response;
80
- const requestID = headers['X-Request-ID'];
81
- const { code, error_description: errorDescription, error, message, } = data;
82
- switch (status) {
83
- case 401: {
84
- throw new exceptions_1.UnauthorizedException(requestID);
85
- }
86
- case 422: {
87
- const { errors } = data;
88
- throw new exceptions_1.UnprocessableEntityException({
89
- code,
90
- errors,
91
- message,
92
- requestID,
93
- });
94
- }
95
- case 404: {
96
- throw new exceptions_1.NotFoundException(path, requestID);
97
- }
98
- default: {
99
- if (error || errorDescription) {
100
- throw new exceptions_1.OauthException(status, requestID, error, errorDescription);
101
- }
102
- else {
103
- throw new exceptions_1.GenericServerException(status, data.message, requestID);
104
- }
105
- }
106
- }
107
- }
80
+ this.handleAxiosError({ path, error });
108
81
  throw error;
109
82
  }
110
83
  });
@@ -123,37 +96,7 @@ class WorkOS {
123
96
  });
124
97
  }
125
98
  catch (error) {
126
- const { response } = error;
127
- if (response) {
128
- const { status, data, headers } = response;
129
- const requestID = headers['X-Request-ID'];
130
- const { code, error_description: errorDescription, error, message, } = data;
131
- switch (status) {
132
- case 401: {
133
- throw new exceptions_1.UnauthorizedException(requestID);
134
- }
135
- case 422: {
136
- const { errors } = data;
137
- throw new exceptions_1.UnprocessableEntityException({
138
- code,
139
- errors,
140
- message,
141
- requestID,
142
- });
143
- }
144
- case 404: {
145
- throw new exceptions_1.NotFoundException(path, requestID);
146
- }
147
- default: {
148
- if (error || errorDescription) {
149
- throw new exceptions_1.OauthException(status, requestID, error, errorDescription);
150
- }
151
- else {
152
- throw new exceptions_1.GenericServerException(status, data.message, requestID);
153
- }
154
- }
155
- }
156
- }
99
+ this.handleAxiosError({ path, error });
157
100
  throw error;
158
101
  }
159
102
  });
@@ -171,37 +114,7 @@ class WorkOS {
171
114
  });
172
115
  }
173
116
  catch (error) {
174
- const { response } = error;
175
- if (response) {
176
- const { status, data, headers } = response;
177
- const requestID = headers['X-Request-ID'];
178
- const { code, error_description: errorDescription, error, message, } = data;
179
- switch (status) {
180
- case 401: {
181
- throw new exceptions_1.UnauthorizedException(requestID);
182
- }
183
- case 422: {
184
- const { errors } = data;
185
- throw new exceptions_1.UnprocessableEntityException({
186
- code,
187
- errors,
188
- message,
189
- requestID,
190
- });
191
- }
192
- case 404: {
193
- throw new exceptions_1.NotFoundException(path, requestID);
194
- }
195
- default: {
196
- if (error || errorDescription) {
197
- throw new exceptions_1.OauthException(status, requestID, error, errorDescription);
198
- }
199
- else {
200
- throw new exceptions_1.GenericServerException(status, data.message, requestID);
201
- }
202
- }
203
- }
204
- }
117
+ this.handleAxiosError({ path, error });
205
118
  throw error;
206
119
  }
207
120
  });
@@ -214,37 +127,7 @@ class WorkOS {
214
127
  });
215
128
  }
216
129
  catch (error) {
217
- const { response } = error;
218
- if (response) {
219
- const { status, data, headers } = response;
220
- const requestID = headers['X-Request-ID'];
221
- const { code, error_description: errorDescription, error, message, } = data;
222
- switch (status) {
223
- case 401: {
224
- throw new exceptions_1.UnauthorizedException(requestID);
225
- }
226
- case 422: {
227
- const { errors } = data;
228
- throw new exceptions_1.UnprocessableEntityException({
229
- code,
230
- errors,
231
- message,
232
- requestID,
233
- });
234
- }
235
- case 404: {
236
- throw new exceptions_1.NotFoundException(path, requestID);
237
- }
238
- default: {
239
- if (error || errorDescription) {
240
- throw new exceptions_1.OauthException(status, requestID, error, errorDescription);
241
- }
242
- else {
243
- throw new exceptions_1.GenericServerException(status, data.message, requestID);
244
- }
245
- }
246
- }
247
- }
130
+ this.handleAxiosError({ path, error });
248
131
  throw error;
249
132
  }
250
133
  });
@@ -256,5 +139,53 @@ class WorkOS {
256
139
  }
257
140
  return process.emitWarning(warning, 'WorkOS');
258
141
  }
142
+ handleAxiosError({ path, error }) {
143
+ const { response } = error;
144
+ if (response) {
145
+ const { status, data, headers } = response;
146
+ const requestID = headers['X-Request-ID'];
147
+ const { code, error_description: errorDescription, error, errors, message, } = data;
148
+ switch (status) {
149
+ case 401: {
150
+ throw new exceptions_1.UnauthorizedException(requestID);
151
+ }
152
+ case 422: {
153
+ const { errors } = data;
154
+ throw new exceptions_1.UnprocessableEntityException({
155
+ code,
156
+ errors,
157
+ message,
158
+ requestID,
159
+ });
160
+ }
161
+ case 404: {
162
+ throw new exceptions_1.NotFoundException({
163
+ code,
164
+ message,
165
+ path,
166
+ requestID,
167
+ });
168
+ }
169
+ default: {
170
+ if (error || errorDescription) {
171
+ throw new exceptions_1.OauthException(status, requestID, error, errorDescription);
172
+ }
173
+ else if (code && errors) {
174
+ // Note: ideally this should be mapped directly with a `400` status code.
175
+ // However, this would break existing logic for the `OauthException` exception.
176
+ throw new bad_request_exception_1.BadRequestException({
177
+ code,
178
+ errors,
179
+ message,
180
+ requestID,
181
+ });
182
+ }
183
+ else {
184
+ throw new exceptions_1.GenericServerException(status, data.message, requestID);
185
+ }
186
+ }
187
+ }
188
+ }
189
+ }
259
190
  }
260
191
  exports.WorkOS = WorkOS;
@@ -69,11 +69,43 @@ describe('WorkOS', () => {
69
69
  describe('post', () => {
70
70
  describe('when the api responds with a 404', () => {
71
71
  it('throws a NotFoundException', () => __awaiter(void 0, void 0, void 0, function* () {
72
+ const message = 'Not Found';
72
73
  mock.onPost().reply(404, {
73
- message: 'Not Found',
74
+ message,
74
75
  }, { 'X-Request-ID': 'a-request-id' });
75
76
  const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
76
- yield expect(workos.post('/path', {})).rejects.toStrictEqual(new exceptions_1.NotFoundException('/path', 'a-request-id'));
77
+ yield expect(workos.post('/path', {})).rejects.toStrictEqual(new exceptions_1.NotFoundException({
78
+ message,
79
+ path: '/path',
80
+ requestID: 'a-request-id',
81
+ }));
82
+ }));
83
+ it('preserves the error code, status, and message from the underlying response', () => __awaiter(void 0, void 0, void 0, function* () {
84
+ const message = 'The thing you are looking for is not here.';
85
+ const code = 'thing-not-found';
86
+ mock.onPost().reply(404, {
87
+ code,
88
+ message,
89
+ }, { 'X-Request-ID': 'a-request-id' });
90
+ const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
91
+ yield expect(workos.post('/path', {})).rejects.toMatchObject({
92
+ code,
93
+ message,
94
+ status: 404,
95
+ });
96
+ }));
97
+ it('includes the path in the message if there is no message in the response', () => __awaiter(void 0, void 0, void 0, function* () {
98
+ const code = 'thing-not-found';
99
+ const path = '/path/to/thing/that-aint-there';
100
+ mock.onPost().reply(404, {
101
+ code,
102
+ }, { 'X-Request-ID': 'a-request-id' });
103
+ const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
104
+ yield expect(workos.post(path, {})).rejects.toMatchObject({
105
+ code,
106
+ message: `The requested path '${path}' could not be found.`,
107
+ status: 404,
108
+ });
77
109
  }));
78
110
  });
79
111
  describe('when the api responds with a 500 and no error/error_description', () => {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.6.1",
2
+ "version": "2.8.1",
3
3
  "name": "@workos-inc/node",
4
4
  "author": "WorkOS",
5
5
  "description": "A Node wrapper for the WorkOS API",
@@ -9,8 +9,8 @@
9
9
  "workos"
10
10
  ],
11
11
  "volta": {
12
- "node": "14.19.3",
13
- "yarn": "1.22.18"
12
+ "node": "14.20.0",
13
+ "yarn": "1.22.19"
14
14
  },
15
15
  "main": "lib/index.js",
16
16
  "typings": "lib/index.d.ts",
@@ -39,15 +39,15 @@
39
39
  "query-string": "7.1.1"
40
40
  },
41
41
  "devDependencies": {
42
- "@types/jest": "27.5.1",
43
- "@types/node": "14.18.18",
42
+ "@types/jest": "27.5.2",
43
+ "@types/node": "14.18.21",
44
44
  "@types/pluralize": "0.0.29",
45
- "axios-mock-adapter": "1.20.0",
45
+ "axios-mock-adapter": "1.21.1",
46
46
  "jest": "27.5.1",
47
- "prettier": "2.6.2",
47
+ "prettier": "2.7.1",
48
48
  "supertest": "6.2.3",
49
49
  "ts-jest": "27.1.5",
50
50
  "tslint": "6.1.3",
51
- "typescript": "4.6.4"
51
+ "typescript": "4.7.4"
52
52
  }
53
53
  }