@workos-inc/node 7.50.0 → 7.51.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 (58) hide show
  1. package/lib/actions/actions.js +2 -2
  2. package/lib/actions/actions.spec.js +3 -3
  3. package/lib/common/crypto/crypto-provider.d.ts +33 -0
  4. package/lib/common/crypto/{CryptoProvider.spec.js → crypto-provider.spec.js} +8 -8
  5. package/lib/common/crypto/node-crypto-provider.d.ts +7 -0
  6. package/lib/common/crypto/node-crypto-provider.js +38 -2
  7. package/lib/common/crypto/{SignatureProvider.d.ts → signature-provider.d.ts} +1 -1
  8. package/lib/common/crypto/{SignatureProvider.spec.js → signature-provider.spec.js} +4 -4
  9. package/lib/common/crypto/subtle-crypto-provider.d.ts +7 -0
  10. package/lib/common/crypto/subtle-crypto-provider.js +48 -0
  11. package/lib/common/utils/base64.d.ts +12 -0
  12. package/lib/common/utils/base64.js +52 -0
  13. package/lib/common/utils/pagination.d.ts +1 -1
  14. package/lib/fga/fga.d.ts +2 -1
  15. package/lib/fga/fga.js +3 -1
  16. package/lib/fga/fga.spec.js +144 -0
  17. package/lib/fga/interfaces/check.interface.d.ts +4 -0
  18. package/lib/fga/interfaces/check.interface.js +1 -0
  19. package/lib/fga/interfaces/list.interface.d.ts +8 -0
  20. package/lib/fga/interfaces/list.interface.js +2 -0
  21. package/lib/fga/interfaces/warning.interface.d.ts +9 -0
  22. package/lib/fga/interfaces/warning.interface.js +2 -0
  23. package/lib/fga/serializers/index.d.ts +1 -0
  24. package/lib/fga/serializers/index.js +1 -0
  25. package/lib/fga/serializers/list.serializer.d.ts +5 -0
  26. package/lib/fga/serializers/list.serializer.js +10 -0
  27. package/lib/fga/serializers/query-result.serializer.d.ts +5 -0
  28. package/lib/fga/utils/fetch-and-deserialize-list.d.ts +5 -0
  29. package/lib/fga/utils/fetch-and-deserialize-list.js +18 -0
  30. package/lib/fga/utils/fga-paginatable.d.ts +9 -0
  31. package/lib/fga/utils/fga-paginatable.js +13 -0
  32. package/lib/index.d.ts +2 -0
  33. package/lib/index.js +5 -9
  34. package/lib/index.worker.d.ts +2 -0
  35. package/lib/index.worker.js +3 -0
  36. package/lib/user-management/interfaces/update-user-options.interface.d.ts +4 -2
  37. package/lib/user-management/serializers/update-user-options.serializer.js +2 -1
  38. package/lib/user-management/user-management.spec.js +10 -0
  39. package/lib/vault/vault.d.ts +5 -3
  40. package/lib/vault/vault.js +60 -6
  41. package/lib/vault/vault.spec.js +39 -0
  42. package/lib/webhooks/webhooks.js +2 -2
  43. package/lib/workos.d.ts +2 -0
  44. package/lib/workos.js +6 -3
  45. package/package.json +1 -1
  46. package/lib/common/crypto/CryptoProvider.d.ts +0 -32
  47. package/lib/common/crypto/CryptoProvider.js +0 -13
  48. package/lib/common/crypto/NodeCryptoProvider.d.ts +0 -12
  49. package/lib/common/crypto/NodeCryptoProvider.js +0 -73
  50. package/lib/common/crypto/SubtleCryptoProvider.d.ts +0 -15
  51. package/lib/common/crypto/SubtleCryptoProvider.js +0 -75
  52. package/lib/vault/cryptography/decrypt.d.ts +0 -9
  53. package/lib/vault/cryptography/decrypt.js +0 -39
  54. package/lib/vault/cryptography/encrypt.d.ts +0 -1
  55. package/lib/vault/cryptography/encrypt.js +0 -33
  56. /package/lib/common/crypto/{CryptoProvider.spec.d.ts → crypto-provider.spec.d.ts} +0 -0
  57. /package/lib/common/crypto/{SignatureProvider.js → signature-provider.js} +0 -0
  58. /package/lib/common/crypto/{SignatureProvider.spec.d.ts → signature-provider.spec.d.ts} +0 -0
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deserializeFGAList = void 0;
4
+ const deserializeFGAList = (response, deserializeFn) => ({
5
+ object: 'list',
6
+ data: response.data.map(deserializeFn),
7
+ listMetadata: response.list_metadata,
8
+ warnings: response.warnings,
9
+ });
10
+ exports.deserializeFGAList = deserializeFGAList;
@@ -1,2 +1,7 @@
1
1
  import { QueryResult, QueryResultResponse } from '../interfaces';
2
+ import { Warning } from '../interfaces/warning.interface';
3
+ import { ListResponse } from '../../common/interfaces';
4
+ export interface QueryResultListResponse extends ListResponse<QueryResultResponse> {
5
+ warnings?: Warning[];
6
+ }
2
7
  export declare const deserializeQueryResult: (queryResult: QueryResultResponse) => QueryResult;
@@ -0,0 +1,5 @@
1
+ import { WorkOS } from '../../workos';
2
+ import { FGAList } from '../interfaces/list.interface';
3
+ import { QueryRequestOptions } from '../interfaces';
4
+ import { PaginationOptions } from '../../common/interfaces';
5
+ export declare const fetchAndDeserializeFGAList: <T, U>(workos: WorkOS, endpoint: string, deserializeFn: (data: T) => U, options?: PaginationOptions, requestOptions?: QueryRequestOptions) => Promise<FGAList<U>>;
@@ -0,0 +1,18 @@
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.fetchAndDeserializeFGAList = void 0;
13
+ const list_serializer_1 = require("../serializers/list.serializer");
14
+ const fetchAndDeserializeFGAList = (workos, endpoint, deserializeFn, options, requestOptions) => __awaiter(void 0, void 0, void 0, function* () {
15
+ const { data: response } = yield workos.get(endpoint, Object.assign({ query: options }, requestOptions));
16
+ return (0, list_serializer_1.deserializeFGAList)(response, deserializeFn);
17
+ });
18
+ exports.fetchAndDeserializeFGAList = fetchAndDeserializeFGAList;
@@ -0,0 +1,9 @@
1
+ import { AutoPaginatable } from '../../common/utils/pagination';
2
+ import { FGAList } from '../interfaces/list.interface';
3
+ import { Warning } from '../interfaces/warning.interface';
4
+ import { PaginationOptions } from '../../common/interfaces';
5
+ export declare class FgaPaginatable<T> extends AutoPaginatable<T> {
6
+ protected list: FGAList<T>;
7
+ constructor(list: FGAList<T>, apiCall: (params: PaginationOptions) => Promise<FGAList<T>>, options?: PaginationOptions);
8
+ get warnings(): Warning[] | undefined;
9
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FgaPaginatable = void 0;
4
+ const pagination_1 = require("../../common/utils/pagination");
5
+ class FgaPaginatable extends pagination_1.AutoPaginatable {
6
+ constructor(list, apiCall, options) {
7
+ super(list, apiCall, options);
8
+ }
9
+ get warnings() {
10
+ return this.list.warnings;
11
+ }
12
+ }
13
+ exports.FgaPaginatable = FgaPaginatable;
package/lib/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { CryptoProvider } from './common/crypto/crypto-provider';
1
2
  import { HttpClient } from './common/net/http-client';
2
3
  import { Actions } from './actions/actions';
3
4
  import { Webhooks } from './webhooks/webhooks';
@@ -25,6 +26,7 @@ declare class WorkOSNode extends WorkOS {
25
26
  createHttpClient(options: WorkOSOptions, userAgent: string): HttpClient;
26
27
  /** @override */
27
28
  createWebhookClient(): Webhooks;
29
+ getCryptoProvider(): CryptoProvider;
28
30
  /** @override */
29
31
  createActionsClient(): Actions;
30
32
  /** @override */
package/lib/index.js CHANGED
@@ -54,6 +54,9 @@ class WorkOSNode extends workos_1.WorkOS {
54
54
  }
55
55
  /** @override */
56
56
  createWebhookClient() {
57
+ return new webhooks_1.Webhooks(this.getCryptoProvider());
58
+ }
59
+ getCryptoProvider() {
57
60
  let cryptoProvider;
58
61
  if (typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined') {
59
62
  cryptoProvider = new subtle_crypto_provider_1.SubtleCryptoProvider();
@@ -61,18 +64,11 @@ class WorkOSNode extends workos_1.WorkOS {
61
64
  else {
62
65
  cryptoProvider = new node_crypto_provider_1.NodeCryptoProvider();
63
66
  }
64
- return new webhooks_1.Webhooks(cryptoProvider);
67
+ return cryptoProvider;
65
68
  }
66
69
  /** @override */
67
70
  createActionsClient() {
68
- let cryptoProvider;
69
- if (typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined') {
70
- cryptoProvider = new subtle_crypto_provider_1.SubtleCryptoProvider();
71
- }
72
- else {
73
- cryptoProvider = new node_crypto_provider_1.NodeCryptoProvider();
74
- }
75
- return new actions_1.Actions(cryptoProvider);
71
+ return new actions_1.Actions(this.getCryptoProvider());
76
72
  }
77
73
  /** @override */
78
74
  createIronSessionProvider() {
@@ -1,4 +1,5 @@
1
1
  import { Actions } from './actions/actions';
2
+ import { CryptoProvider } from './common/crypto/crypto-provider';
2
3
  import { IronSessionProvider } from './common/iron-session/iron-session-provider';
3
4
  import { HttpClient } from './common/net/http-client';
4
5
  import { WorkOSOptions } from './index.worker';
@@ -25,6 +26,7 @@ declare class WorkOSWorker extends WorkOS {
25
26
  createHttpClient(options: WorkOSOptions, userAgent: string): HttpClient;
26
27
  /** @override */
27
28
  createWebhookClient(): Webhooks;
29
+ getCryptoProvider(): CryptoProvider;
28
30
  /** @override */
29
31
  createActionsClient(): Actions;
30
32
  /** @override */
@@ -48,6 +48,9 @@ class WorkOSWorker extends workos_1.WorkOS {
48
48
  const cryptoProvider = new subtle_crypto_provider_1.SubtleCryptoProvider();
49
49
  return new webhooks_1.Webhooks(cryptoProvider);
50
50
  }
51
+ getCryptoProvider() {
52
+ return new subtle_crypto_provider_1.SubtleCryptoProvider();
53
+ }
51
54
  /** @override */
52
55
  createActionsClient() {
53
56
  const cryptoProvider = new subtle_crypto_provider_1.SubtleCryptoProvider();
@@ -1,6 +1,7 @@
1
1
  import { PasswordHashType } from './password-hash-type.interface';
2
2
  export interface UpdateUserOptions {
3
3
  userId: string;
4
+ email?: string;
4
5
  firstName?: string;
5
6
  lastName?: string;
6
7
  emailVerified?: boolean;
@@ -8,9 +9,10 @@ export interface UpdateUserOptions {
8
9
  passwordHash?: string;
9
10
  passwordHashType?: PasswordHashType;
10
11
  externalId?: string;
11
- metadata?: Record<string, string>;
12
+ metadata?: Record<string, string | null>;
12
13
  }
13
14
  export interface SerializedUpdateUserOptions {
15
+ email?: string;
14
16
  first_name?: string;
15
17
  last_name?: string;
16
18
  email_verified?: boolean;
@@ -18,5 +20,5 @@ export interface SerializedUpdateUserOptions {
18
20
  password_hash?: string;
19
21
  password_hash_type?: PasswordHashType;
20
22
  external_id?: string;
21
- metadata?: Record<string, string>;
23
+ metadata?: Record<string, string | null>;
22
24
  }
@@ -2,9 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.serializeUpdateUserOptions = void 0;
4
4
  const serializeUpdateUserOptions = (options) => ({
5
+ email: options.email,
6
+ email_verified: options.emailVerified,
5
7
  first_name: options.firstName,
6
8
  last_name: options.lastName,
7
- email_verified: options.emailVerified,
8
9
  password: options.password,
9
10
  password_hash: options.passwordHash,
10
11
  password_hash_type: options.passwordHashType,
@@ -1112,6 +1112,16 @@ describe('UserManagement', () => {
1112
1112
  metadata: { key: 'value' },
1113
1113
  });
1114
1114
  }));
1115
+ it('removes metadata from the request', () => __awaiter(void 0, void 0, void 0, function* () {
1116
+ (0, test_utils_1.fetchOnce)(user_json_1.default);
1117
+ yield workos.userManagement.updateUser({
1118
+ userId,
1119
+ metadata: { key: null },
1120
+ });
1121
+ expect((0, test_utils_1.fetchBody)()).toMatchObject({
1122
+ metadata: {},
1123
+ });
1124
+ }));
1115
1125
  });
1116
1126
  describe('enrollAuthFactor', () => {
1117
1127
  it('sends an enrollAuthFactor request', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -1,10 +1,12 @@
1
- import { PaginationOptions } from '../index.worker';
2
- import { WorkOS } from '../workos';
3
- import { CreateDataKeyOptions, CreateObjectOptions, DataKey, DataKeyPair, DecryptDataKeyOptions, DeleteObjectOptions, ReadObjectOptions, KeyContext, ObjectDigest, ObjectMetadata, ObjectVersion, UpdateObjectOptions, VaultObject } from './interfaces';
4
1
  import { List } from '../common/interfaces';
2
+ import { PaginationOptions } from '../index.worker';
3
+ import type { WorkOS } from '../workos';
4
+ import { CreateDataKeyOptions, CreateObjectOptions, DataKey, DataKeyPair, DecryptDataKeyOptions, DeleteObjectOptions, KeyContext, ObjectDigest, ObjectMetadata, ObjectVersion, ReadObjectOptions, UpdateObjectOptions, VaultObject } from './interfaces';
5
5
  export declare class Vault {
6
6
  private readonly workos;
7
+ private cryptoProvider;
7
8
  constructor(workos: WorkOS);
9
+ private decode;
8
10
  createObject(options: CreateObjectOptions): Promise<ObjectMetadata>;
9
11
  listObjects(options?: PaginationOptions | undefined): Promise<List<ObjectDigest>>;
10
12
  listObjectVersions(options: ReadObjectOptions): Promise<ObjectVersion[]>;
@@ -10,8 +10,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.Vault = void 0;
13
- const decrypt_1 = require("./cryptography/decrypt");
14
- const encrypt_1 = require("./cryptography/encrypt");
13
+ const leb_1 = require("leb");
14
+ const base64_1 = require("../common/utils/base64");
15
15
  const vault_key_serializer_1 = require("./serializers/vault-key.serializer");
16
16
  const vault_object_serializer_1 = require("./serializers/vault-object.serializer");
17
17
  class Vault {
@@ -45,6 +45,24 @@ class Vault {
45
45
  * @deprecated Use `deleteObject` instead.
46
46
  */
47
47
  this.deleteSecret = this.deleteObject;
48
+ this.cryptoProvider = workos.getCryptoProvider();
49
+ }
50
+ decode(payload) {
51
+ const inputData = (0, base64_1.base64ToUint8Array)(payload);
52
+ // Use 12 bytes for IV (standard for AES-GCM)
53
+ const iv = new Uint8Array(inputData.subarray(0, 12));
54
+ const tag = new Uint8Array(inputData.subarray(12, 28));
55
+ const { value: keyLen, nextIndex } = (0, leb_1.decodeUInt32)(inputData, 28);
56
+ // Use subarray instead of slice and convert directly to base64
57
+ const keysBuffer = inputData.subarray(nextIndex, nextIndex + keyLen);
58
+ const keys = (0, base64_1.uint8ArrayToBase64)(keysBuffer);
59
+ const ciphertext = new Uint8Array(inputData.subarray(nextIndex + keyLen));
60
+ return {
61
+ iv,
62
+ tag,
63
+ keys,
64
+ ciphertext,
65
+ };
48
66
  }
49
67
  createObject(options) {
50
68
  return __awaiter(this, void 0, void 0, function* () {
@@ -108,17 +126,53 @@ class Vault {
108
126
  }
109
127
  encrypt(data, context, associatedData) {
110
128
  return __awaiter(this, void 0, void 0, function* () {
111
- const { dataKey, encryptedKeys } = yield this.createDataKey({
129
+ const keyPair = yield this.createDataKey({
112
130
  context,
113
131
  });
114
- return (0, encrypt_1.encrypt)(data, dataKey.key, encryptedKeys, associatedData || '');
132
+ // Convert base64 key to Uint8Array
133
+ const encoder = new TextEncoder();
134
+ // Use our cross-runtime base64 utility
135
+ const key = (0, base64_1.base64ToUint8Array)(keyPair.dataKey.key);
136
+ const keyBlob = (0, base64_1.base64ToUint8Array)(keyPair.encryptedKeys);
137
+ const prefixLenBuffer = (0, leb_1.encodeUInt32)(keyBlob.length);
138
+ const aadBuffer = associatedData
139
+ ? encoder.encode(associatedData)
140
+ : undefined;
141
+ // Use a 12-byte IV for AES-GCM (industry standard)
142
+ const iv = this.cryptoProvider.randomBytes(12);
143
+ const { ciphertext, iv: resultIv, tag, } = yield this.cryptoProvider.encrypt(encoder.encode(data), key, iv, aadBuffer);
144
+ // Concatenate all parts into a single array
145
+ const resultArray = new Uint8Array(resultIv.length +
146
+ tag.length +
147
+ prefixLenBuffer.length +
148
+ keyBlob.length +
149
+ ciphertext.length);
150
+ let offset = 0;
151
+ resultArray.set(resultIv, offset);
152
+ offset += resultIv.length;
153
+ resultArray.set(tag, offset);
154
+ offset += tag.length;
155
+ resultArray.set(new Uint8Array(prefixLenBuffer), offset);
156
+ offset += prefixLenBuffer.length;
157
+ resultArray.set(keyBlob, offset);
158
+ offset += keyBlob.length;
159
+ resultArray.set(ciphertext, offset);
160
+ // Convert to base64 using our cross-runtime utility
161
+ return (0, base64_1.uint8ArrayToBase64)(resultArray);
115
162
  });
116
163
  }
117
164
  decrypt(encryptedData, associatedData) {
118
165
  return __awaiter(this, void 0, void 0, function* () {
119
- const decoded = (0, decrypt_1.decode)(encryptedData);
166
+ const decoded = this.decode(encryptedData);
120
167
  const dataKey = yield this.decryptDataKey({ keys: decoded.keys });
121
- return (0, decrypt_1.decrypt)(decoded, dataKey.key, associatedData || '');
168
+ // Convert base64 key to Uint8Array using our cross-runtime utility
169
+ const key = (0, base64_1.base64ToUint8Array)(dataKey.key);
170
+ const encoder = new TextEncoder();
171
+ const aadBuffer = associatedData
172
+ ? encoder.encode(associatedData)
173
+ : undefined;
174
+ const decrypted = yield this.cryptoProvider.decrypt(decoded.ciphertext, key, decoded.iv, decoded.tag, aadBuffer);
175
+ return new TextDecoder().decode(decrypted);
122
176
  });
123
177
  }
124
178
  }
@@ -244,4 +244,43 @@ describe('Vault', () => {
244
244
  expect((0, test_utils_1.fetchMethod)()).toBe('PUT');
245
245
  }));
246
246
  });
247
+ describe('encrypt and decrypt', () => {
248
+ it('correctly encrypts and decrypts data', () => __awaiter(void 0, void 0, void 0, function* () {
249
+ // Generate a valid 32-byte (256-bit) key for AES-256-GCM
250
+ const validKey = Buffer.alloc(32).fill('A').toString('base64');
251
+ // Mock createDataKey to return a valid key for testing
252
+ (0, test_utils_1.fetchOnce)({
253
+ data_key: validKey,
254
+ encrypted_keys: 'ZW5jcnlwdGVkX2tleXM=',
255
+ id: 'key123',
256
+ context: { type: 'test' },
257
+ });
258
+ // Mock decryptDataKey to return same key
259
+ (0, test_utils_1.fetchOnce)({
260
+ data_key: validKey,
261
+ id: 'key123',
262
+ });
263
+ const originalText = 'This is a secret message';
264
+ const context = { type: 'test' };
265
+ const associatedData = 'additional-auth-data';
266
+ // Encrypt the data
267
+ const encrypted = yield workos.vault.encrypt(originalText, context, associatedData);
268
+ // Verify encrypt API call
269
+ expect((0, test_utils_1.fetchURL)()).toContain('/vault/v1/keys/data-key');
270
+ expect((0, test_utils_1.fetchMethod)()).toBe('POST');
271
+ // Reset fetch for the decrypt call
272
+ jest_fetch_mock_1.default.resetMocks();
273
+ (0, test_utils_1.fetchOnce)({
274
+ data_key: validKey,
275
+ id: 'key123',
276
+ });
277
+ // Decrypt the data
278
+ const decrypted = yield workos.vault.decrypt(encrypted, associatedData);
279
+ // Verify decrypt API call
280
+ expect((0, test_utils_1.fetchURL)()).toContain('/vault/v1/keys/decrypt');
281
+ expect((0, test_utils_1.fetchMethod)()).toBe('POST');
282
+ // Verify the decrypted text matches the original
283
+ expect(decrypted).toBe(originalText);
284
+ }));
285
+ });
247
286
  });
@@ -11,10 +11,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.Webhooks = void 0;
13
13
  const serializers_1 = require("../common/serializers");
14
- const SignatureProvider_1 = require("../common/crypto/SignatureProvider");
14
+ const signature_provider_1 = require("../common/crypto/signature-provider");
15
15
  class Webhooks {
16
16
  constructor(cryptoProvider) {
17
- this.signatureProvider = new SignatureProvider_1.SignatureProvider(cryptoProvider);
17
+ this.signatureProvider = new signature_provider_1.SignatureProvider(cryptoProvider);
18
18
  }
19
19
  get verifyHeader() {
20
20
  return this.signatureProvider.verifyHeader.bind(this.signatureProvider);
package/lib/workos.d.ts CHANGED
@@ -16,6 +16,7 @@ import { IronSessionProvider } from './common/iron-session/iron-session-provider
16
16
  import { Widgets } from './widgets/widgets';
17
17
  import { Actions } from './actions/actions';
18
18
  import { Vault } from './vault/vault';
19
+ import { CryptoProvider } from './common/crypto/crypto-provider';
19
20
  export declare class WorkOS {
20
21
  readonly key?: string | undefined;
21
22
  readonly options: WorkOSOptions;
@@ -40,6 +41,7 @@ export declare class WorkOS {
40
41
  constructor(key?: string | undefined, options?: WorkOSOptions);
41
42
  createWebhookClient(): Webhooks;
42
43
  createActionsClient(): Actions;
44
+ getCryptoProvider(): CryptoProvider;
43
45
  createHttpClient(options: WorkOSOptions, userAgent: string): HttpClient;
44
46
  createIronSessionProvider(): IronSessionProvider;
45
47
  get version(): string;
package/lib/workos.js CHANGED
@@ -31,7 +31,7 @@ const widgets_1 = require("./widgets/widgets");
31
31
  const actions_1 = require("./actions/actions");
32
32
  const vault_1 = require("./vault/vault");
33
33
  const conflict_exception_1 = require("./common/exceptions/conflict.exception");
34
- const VERSION = '7.50.0';
34
+ const VERSION = '7.51.0';
35
35
  const DEFAULT_HOSTNAME = 'api.workos.com';
36
36
  const HEADER_AUTHORIZATION = 'Authorization';
37
37
  const HEADER_IDEMPOTENCY_KEY = 'Idempotency-Key';
@@ -88,10 +88,13 @@ class WorkOS {
88
88
  this.client = this.createHttpClient(options, userAgent);
89
89
  }
90
90
  createWebhookClient() {
91
- return new webhooks_1.Webhooks(new subtle_crypto_provider_1.SubtleCryptoProvider());
91
+ return new webhooks_1.Webhooks(this.getCryptoProvider());
92
92
  }
93
93
  createActionsClient() {
94
- return new actions_1.Actions(new subtle_crypto_provider_1.SubtleCryptoProvider());
94
+ return new actions_1.Actions(this.getCryptoProvider());
95
+ }
96
+ getCryptoProvider() {
97
+ return new subtle_crypto_provider_1.SubtleCryptoProvider();
95
98
  }
96
99
  createHttpClient(options, userAgent) {
97
100
  var _a;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "7.50.0",
2
+ "version": "7.51.0",
3
3
  "name": "@workos-inc/node",
4
4
  "author": "WorkOS",
5
5
  "description": "A Node wrapper for the WorkOS API",
@@ -1,32 +0,0 @@
1
- /**
2
- * Interface encapsulating the various crypto computations used by the library,
3
- * allowing pluggable underlying crypto implementations.
4
- */
5
- export declare abstract class CryptoProvider {
6
- encoder: TextEncoder;
7
- /**
8
- * Computes a SHA-256 HMAC given a secret and a payload (encoded in UTF-8).
9
- * The output HMAC should be encoded in hexadecimal.
10
- *
11
- * Sample values for implementations:
12
- * - computeHMACSignature('', 'test_secret') => 'f7f9bd47fb987337b5796fdc1fdb9ba221d0d5396814bfcaf9521f43fd8927fd'
13
- * - computeHMACSignature('\ud83d\ude00', 'test_secret') => '837da296d05c4fe31f61d5d7ead035099d9585a5bcde87de952012a78f0b0c43
14
- */
15
- abstract computeHMACSignature(payload: string, secret: string): string;
16
- /**
17
- * Asynchronous version of `computeHMACSignature`. Some implementations may
18
- * only allow support async signature computation.
19
- *
20
- * Computes a SHA-256 HMAC given a secret and a payload (encoded in UTF-8).
21
- * The output HMAC should be encoded in hexadecimal.
22
- *
23
- * Sample values for implementations:
24
- * - computeHMACSignature('', 'test_secret') => 'f7f9bd47fb987337b5796fdc1fdb9ba221d0d5396814bfcaf9521f43fd8927fd'
25
- * - computeHMACSignature('\ud83d\ude00', 'test_secret') => '837da296d05c4fe31f61d5d7ead035099d9585a5bcde87de952012a78f0b0c43
26
- */
27
- abstract computeHMACSignatureAsync(payload: string, secret: string): Promise<string>;
28
- /**
29
- * Cryptographically determine whether two signatures are equal
30
- */
31
- abstract secureCompare(stringA: string, stringB: string): Promise<boolean>;
32
- }
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CryptoProvider = void 0;
4
- /**
5
- * Interface encapsulating the various crypto computations used by the library,
6
- * allowing pluggable underlying crypto implementations.
7
- */
8
- class CryptoProvider {
9
- constructor() {
10
- this.encoder = new TextEncoder();
11
- }
12
- }
13
- exports.CryptoProvider = CryptoProvider;
@@ -1,12 +0,0 @@
1
- import { CryptoProvider } from './CryptoProvider';
2
- /**
3
- * `CryptoProvider which uses the Node `crypto` package for its computations.
4
- */
5
- export declare class NodeCryptoProvider extends CryptoProvider {
6
- /** @override */
7
- computeHMACSignature(payload: string, secret: string): string;
8
- /** @override */
9
- computeHMACSignatureAsync(payload: string, secret: string): Promise<string>;
10
- /** @override */
11
- secureCompare(stringA: string, stringB: string): Promise<boolean>;
12
- }
@@ -1,73 +0,0 @@
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
- };
25
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
- return new (P || (P = Promise))(function (resolve, reject) {
28
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
- step((generator = generator.apply(thisArg, _arguments || [])).next());
32
- });
33
- };
34
- Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.NodeCryptoProvider = void 0;
36
- const crypto = __importStar(require("crypto"));
37
- const CryptoProvider_1 = require("./CryptoProvider");
38
- /**
39
- * `CryptoProvider which uses the Node `crypto` package for its computations.
40
- */
41
- class NodeCryptoProvider extends CryptoProvider_1.CryptoProvider {
42
- /** @override */
43
- computeHMACSignature(payload, secret) {
44
- return crypto
45
- .createHmac('sha256', secret)
46
- .update(payload, 'utf8')
47
- .digest('hex');
48
- }
49
- /** @override */
50
- computeHMACSignatureAsync(payload, secret) {
51
- return __awaiter(this, void 0, void 0, function* () {
52
- const signature = yield this.computeHMACSignature(payload, secret);
53
- return signature;
54
- });
55
- }
56
- /** @override */
57
- secureCompare(stringA, stringB) {
58
- return __awaiter(this, void 0, void 0, function* () {
59
- const bufferA = this.encoder.encode(stringA);
60
- const bufferB = this.encoder.encode(stringB);
61
- if (bufferA.length !== bufferB.length) {
62
- return false;
63
- }
64
- // Generate a random key for HMAC
65
- const key = crypto.randomBytes(32); // Generates a 256-bit key
66
- const hmacA = crypto.createHmac('sha256', key).update(bufferA).digest();
67
- const hmacB = crypto.createHmac('sha256', key).update(bufferB).digest();
68
- // Perform a constant time comparison
69
- return crypto.timingSafeEqual(hmacA, hmacB);
70
- });
71
- }
72
- }
73
- exports.NodeCryptoProvider = NodeCryptoProvider;
@@ -1,15 +0,0 @@
1
- import { CryptoProvider } from './CryptoProvider';
2
- /**
3
- * `CryptoProvider which uses the SubtleCrypto interface of the Web Crypto API.
4
- *
5
- * This only supports asynchronous operations.
6
- */
7
- export declare class SubtleCryptoProvider extends CryptoProvider {
8
- subtleCrypto: SubtleCrypto;
9
- constructor(subtleCrypto?: SubtleCrypto);
10
- computeHMACSignature(_payload: string, _secret: string): string;
11
- /** @override */
12
- computeHMACSignatureAsync(payload: string, secret: string): Promise<string>;
13
- /** @override */
14
- secureCompare(stringA: string, stringB: string): Promise<boolean>;
15
- }
@@ -1,75 +0,0 @@
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.SubtleCryptoProvider = void 0;
13
- const CryptoProvider_1 = require("./CryptoProvider");
14
- /**
15
- * `CryptoProvider which uses the SubtleCrypto interface of the Web Crypto API.
16
- *
17
- * This only supports asynchronous operations.
18
- */
19
- class SubtleCryptoProvider extends CryptoProvider_1.CryptoProvider {
20
- constructor(subtleCrypto) {
21
- super();
22
- // If no subtle crypto is interface, default to the global namespace. This
23
- // is to allow custom interfaces (eg. using the Node webcrypto interface in
24
- // tests).
25
- this.subtleCrypto = subtleCrypto || crypto.subtle;
26
- }
27
- computeHMACSignature(_payload, _secret) {
28
- throw new Error('SubleCryptoProvider cannot be used in a synchronous context.');
29
- }
30
- /** @override */
31
- computeHMACSignatureAsync(payload, secret) {
32
- return __awaiter(this, void 0, void 0, function* () {
33
- const encoder = new TextEncoder();
34
- const key = yield this.subtleCrypto.importKey('raw', encoder.encode(secret), {
35
- name: 'HMAC',
36
- hash: { name: 'SHA-256' },
37
- }, false, ['sign']);
38
- const signatureBuffer = yield this.subtleCrypto.sign('hmac', key, encoder.encode(payload));
39
- // crypto.subtle returns the signature in base64 format. This must be
40
- // encoded in hex to match the CryptoProvider contract. We map each byte in
41
- // the buffer to its corresponding hex octet and then combine into a string.
42
- const signatureBytes = new Uint8Array(signatureBuffer);
43
- const signatureHexCodes = new Array(signatureBytes.length);
44
- for (let i = 0; i < signatureBytes.length; i++) {
45
- signatureHexCodes[i] = byteHexMapping[signatureBytes[i]];
46
- }
47
- return signatureHexCodes.join('');
48
- });
49
- }
50
- /** @override */
51
- secureCompare(stringA, stringB) {
52
- return __awaiter(this, void 0, void 0, function* () {
53
- const bufferA = this.encoder.encode(stringA);
54
- const bufferB = this.encoder.encode(stringB);
55
- if (bufferA.length !== bufferB.length) {
56
- return false;
57
- }
58
- const algorithm = { name: 'HMAC', hash: 'SHA-256' };
59
- const key = (yield crypto.subtle.generateKey(algorithm, false, [
60
- 'sign',
61
- 'verify',
62
- ]));
63
- const hmac = yield crypto.subtle.sign(algorithm, key, bufferA);
64
- const equal = yield crypto.subtle.verify(algorithm, key, hmac, bufferB);
65
- return equal;
66
- });
67
- }
68
- }
69
- exports.SubtleCryptoProvider = SubtleCryptoProvider;
70
- // Cached mapping of byte to hex representation. We do this once to avoid re-
71
- // computing every time we need to convert the result of a signature to hex.
72
- const byteHexMapping = new Array(256);
73
- for (let i = 0; i < byteHexMapping.length; i++) {
74
- byteHexMapping[i] = i.toString(16).padStart(2, '0');
75
- }