@workos-inc/node 5.2.0 → 6.0.0-rc.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.
- package/lib/audit-logs/audit-logs.spec.js +18 -4
- package/lib/common/interfaces/workos-options.interface.d.ts +1 -2
- package/lib/common/utils/fetch-client.d.ts +29 -0
- package/lib/common/utils/fetch-client.js +97 -0
- package/lib/common/utils/fetch-error.d.ts +13 -0
- package/lib/common/utils/fetch-error.js +13 -0
- package/lib/common/utils/test-utils.d.ts +8 -0
- package/lib/common/utils/test-utils.js +45 -0
- package/lib/directory-sync/directory-sync.spec.js +34 -45
- package/lib/events/events.spec.js +5 -6
- package/lib/mfa/mfa.spec.js +39 -42
- package/lib/organization-domains/organization-domains.spec.js +12 -24
- package/lib/organizations/organizations.spec.js +49 -74
- package/lib/passwordless/passwordless.spec.js +9 -16
- package/lib/portal/portal.spec.js +41 -47
- package/lib/sso/sso.spec.js +56 -100
- package/lib/user-management/user-management.spec.js +90 -123
- package/lib/webhooks/webhooks.d.ts +5 -5
- package/lib/webhooks/webhooks.js +64 -42
- package/lib/webhooks/webhooks.spec.js +40 -30
- package/lib/workos.d.ts +11 -6
- package/lib/workos.js +12 -17
- package/lib/workos.spec.js +17 -22
- package/package.json +3 -2
package/lib/webhooks/webhooks.js
CHANGED
|
@@ -1,32 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
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
|
+
});
|
|
4
10
|
};
|
|
5
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
12
|
exports.Webhooks = void 0;
|
|
7
|
-
const crypto_1 = __importDefault(require("crypto"));
|
|
8
13
|
const exceptions_1 = require("../common/exceptions");
|
|
9
14
|
const serializers_1 = require("../common/serializers");
|
|
10
15
|
class Webhooks {
|
|
11
16
|
constructEvent({ payload, sigHeader, secret, tolerance = 180000, }) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18
|
+
const options = { payload, sigHeader, secret, tolerance };
|
|
19
|
+
yield this.verifyHeader(options);
|
|
20
|
+
const webhookPayload = payload;
|
|
21
|
+
return (0, serializers_1.deserializeEvent)(webhookPayload);
|
|
22
|
+
});
|
|
16
23
|
}
|
|
17
24
|
verifyHeader({ payload, sigHeader, secret, tolerance = 180000, }) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
const [timestamp, signatureHash] = this.getTimestampAndSignatureHash(sigHeader);
|
|
27
|
+
if (!signatureHash || Object.keys(signatureHash).length === 0) {
|
|
28
|
+
throw new exceptions_1.SignatureVerificationException('No signature hash found with expected scheme v1');
|
|
29
|
+
}
|
|
30
|
+
if (parseInt(timestamp, 10) < Date.now() - tolerance) {
|
|
31
|
+
throw new exceptions_1.SignatureVerificationException('Timestamp outside the tolerance zone');
|
|
32
|
+
}
|
|
33
|
+
const expectedSig = yield this.computeSignature(timestamp, payload, secret);
|
|
34
|
+
if ((yield this.secureCompare(expectedSig, signatureHash)) === false) {
|
|
35
|
+
throw new exceptions_1.SignatureVerificationException('Signature hash does not match the expected signature hash for payload');
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
});
|
|
30
39
|
}
|
|
31
40
|
getTimestampAndSignatureHash(sigHeader) {
|
|
32
41
|
const signature = sigHeader;
|
|
@@ -39,31 +48,44 @@ class Webhooks {
|
|
|
39
48
|
return [timestamp, signatureHash];
|
|
40
49
|
}
|
|
41
50
|
computeSignature(timestamp, payload, secret) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
.
|
|
46
|
-
.
|
|
47
|
-
.
|
|
48
|
-
.
|
|
49
|
-
|
|
51
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
payload = JSON.stringify(payload);
|
|
53
|
+
const signedPayload = `${timestamp}.${payload}`;
|
|
54
|
+
const key = yield crypto.subtle.importKey('raw', new TextEncoder().encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
55
|
+
const signatureBuffer = yield crypto.subtle.sign('HMAC', key, new TextEncoder().encode(signedPayload));
|
|
56
|
+
// crypto.subtle returns the signature in base64 format. This must be
|
|
57
|
+
// encoded in hex to match the CryptoProvider contract. We map each byte in
|
|
58
|
+
// the buffer to its corresponding hex octet and then combine into a string.
|
|
59
|
+
const signatureBytes = new Uint8Array(signatureBuffer);
|
|
60
|
+
const signatureHexCodes = new Array(signatureBytes.length);
|
|
61
|
+
for (let i = 0; i < signatureBytes.length; i++) {
|
|
62
|
+
signatureHexCodes[i] = byteHexMapping[signatureBytes[i]];
|
|
63
|
+
}
|
|
64
|
+
return signatureHexCodes.join('');
|
|
65
|
+
});
|
|
50
66
|
}
|
|
51
67
|
secureCompare(stringA, stringB) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
const bufferA = Buffer.from(stringA);
|
|
70
|
+
const bufferB = Buffer.from(stringB);
|
|
71
|
+
if (bufferA.length !== bufferB.length) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
const algorithm = { name: 'HMAC', hash: 'SHA-256' };
|
|
75
|
+
const key = (yield crypto.subtle.generateKey(algorithm, false, [
|
|
76
|
+
'sign',
|
|
77
|
+
'verify',
|
|
78
|
+
]));
|
|
79
|
+
const hmac = yield crypto.subtle.sign(algorithm, key, bufferA);
|
|
80
|
+
const equal = yield crypto.subtle.verify(algorithm, key, hmac, bufferB);
|
|
81
|
+
return equal;
|
|
82
|
+
});
|
|
67
83
|
}
|
|
68
84
|
}
|
|
69
85
|
exports.Webhooks = Webhooks;
|
|
86
|
+
// Cached mapping of byte to hex representation. We do this once to avoid re-
|
|
87
|
+
// computing every time we need to convert the result of a signature to hex.
|
|
88
|
+
const byteHexMapping = new Array(256);
|
|
89
|
+
for (let i = 0; i < byteHexMapping.length; i++) {
|
|
90
|
+
byteHexMapping[i] = i.toString(16).padStart(2, '0');
|
|
91
|
+
}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
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
|
+
};
|
|
2
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
13
|
};
|
|
@@ -90,76 +99,77 @@ describe('Webhooks', () => {
|
|
|
90
99
|
});
|
|
91
100
|
describe('constructEvent', () => {
|
|
92
101
|
describe('with the correct payload, sig_header, and secret', () => {
|
|
93
|
-
it('returns a webhook event', () => {
|
|
102
|
+
it('returns a webhook event', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
94
103
|
const sigHeader = `t=${timestamp}, v1=${signatureHash}`;
|
|
95
104
|
const options = { payload, sigHeader, secret };
|
|
96
|
-
const webhook = workos.webhooks.constructEvent(options);
|
|
105
|
+
const webhook = yield workos.webhooks.constructEvent(options);
|
|
97
106
|
expect(webhook.data).toEqual(expectation);
|
|
98
107
|
expect(webhook.event).toEqual('dsync.user.created');
|
|
99
108
|
expect(webhook.id).toEqual('wh_123');
|
|
100
|
-
});
|
|
109
|
+
}));
|
|
101
110
|
});
|
|
102
111
|
describe('with the correct payload, sig_header, secret, and tolerance', () => {
|
|
103
|
-
it('returns a webhook event', () => {
|
|
112
|
+
it('returns a webhook event', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
104
113
|
const sigHeader = `t=${timestamp}, v1=${signatureHash}`;
|
|
105
114
|
const options = { payload, sigHeader, secret, tolerance: 200 };
|
|
106
|
-
const webhook = workos.webhooks.constructEvent(options);
|
|
115
|
+
const webhook = yield workos.webhooks.constructEvent(options);
|
|
107
116
|
expect(webhook.data).toEqual(expectation);
|
|
108
117
|
expect(webhook.event).toEqual('dsync.user.created');
|
|
109
118
|
expect(webhook.id).toEqual('wh_123');
|
|
110
|
-
});
|
|
119
|
+
}));
|
|
111
120
|
});
|
|
112
121
|
describe('with an empty header', () => {
|
|
113
|
-
it('raises an error', () => {
|
|
122
|
+
it('raises an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
114
123
|
const sigHeader = '';
|
|
115
124
|
const options = { payload, sigHeader, secret };
|
|
116
|
-
expect(
|
|
117
|
-
});
|
|
125
|
+
yield expect(workos.webhooks.constructEvent(options)).rejects.toThrowError(exceptions_1.SignatureVerificationException);
|
|
126
|
+
}));
|
|
118
127
|
});
|
|
119
128
|
describe('with an empty signature hash', () => {
|
|
120
|
-
it('raises an error', () => {
|
|
129
|
+
it('raises an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
121
130
|
const sigHeader = `t=${timestamp}, v1=`;
|
|
122
131
|
const options = { payload, sigHeader, secret };
|
|
123
|
-
expect(
|
|
124
|
-
});
|
|
132
|
+
yield expect(workos.webhooks.constructEvent(options)).rejects.toThrowError(exceptions_1.SignatureVerificationException);
|
|
133
|
+
}));
|
|
125
134
|
});
|
|
126
135
|
describe('with an incorrect signature hash', () => {
|
|
127
|
-
it('raises an error', () => {
|
|
136
|
+
it('raises an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
128
137
|
const sigHeader = `t=${timestamp}, v1=99999`;
|
|
129
138
|
const options = { payload, sigHeader, secret };
|
|
130
|
-
expect(
|
|
131
|
-
});
|
|
139
|
+
yield expect(workos.webhooks.constructEvent(options)).rejects.toThrowError(exceptions_1.SignatureVerificationException);
|
|
140
|
+
}));
|
|
132
141
|
});
|
|
133
142
|
describe('with an incorrect payload', () => {
|
|
134
|
-
it('raises an error', () => {
|
|
143
|
+
it('raises an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
135
144
|
const sigHeader = `t=${timestamp}, v1=${signatureHash}`;
|
|
136
145
|
payload = 'invalid';
|
|
137
146
|
const options = { payload, sigHeader, secret };
|
|
138
|
-
expect(
|
|
139
|
-
});
|
|
147
|
+
yield expect(workos.webhooks.constructEvent(options)).rejects.toThrowError(exceptions_1.SignatureVerificationException);
|
|
148
|
+
}));
|
|
140
149
|
});
|
|
141
150
|
describe('with an incorrect webhook secret', () => {
|
|
142
|
-
it('raises an error', () => {
|
|
151
|
+
it('raises an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
143
152
|
const sigHeader = `t=${timestamp}, v1=${signatureHash}`;
|
|
144
153
|
secret = 'invalid';
|
|
145
154
|
const options = { payload, sigHeader, secret };
|
|
146
|
-
expect(
|
|
147
|
-
});
|
|
155
|
+
yield expect(workos.webhooks.constructEvent(options)).rejects.toThrowError(exceptions_1.SignatureVerificationException);
|
|
156
|
+
}));
|
|
148
157
|
});
|
|
149
158
|
describe('with a timestamp outside tolerance', () => {
|
|
150
|
-
it('raises an error', () => {
|
|
159
|
+
it('raises an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
151
160
|
const sigHeader = `t=9999, v1=${signatureHash}`;
|
|
152
161
|
const options = { payload, sigHeader, secret };
|
|
153
|
-
expect(
|
|
154
|
-
});
|
|
162
|
+
yield expect(workos.webhooks.constructEvent(options)).rejects.toThrowError(exceptions_1.SignatureVerificationException);
|
|
163
|
+
}));
|
|
155
164
|
});
|
|
156
165
|
});
|
|
157
166
|
describe('verifyHeader', () => {
|
|
158
|
-
it('returns true when the signature is valid', () => {
|
|
167
|
+
it('returns true when the signature is valid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
159
168
|
const sigHeader = `t=${timestamp}, v1=${signatureHash}`;
|
|
160
169
|
const options = { payload, sigHeader, secret };
|
|
161
|
-
|
|
162
|
-
|
|
170
|
+
const result = yield workos.webhooks.verifyHeader(options);
|
|
171
|
+
expect(result).toBeTruthy();
|
|
172
|
+
}));
|
|
163
173
|
});
|
|
164
174
|
describe('getTimestampAndSignatureHash', () => {
|
|
165
175
|
it('returns the timestamp and signature when the signature is valid', () => {
|
|
@@ -172,9 +182,9 @@ describe('Webhooks', () => {
|
|
|
172
182
|
});
|
|
173
183
|
});
|
|
174
184
|
describe('computeSignature', () => {
|
|
175
|
-
it('returns the computed signature', () => {
|
|
176
|
-
const signature = workos.webhooks.computeSignature(timestamp, payload, secret);
|
|
185
|
+
it('returns the computed signature', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
186
|
+
const signature = yield workos.webhooks.computeSignature(timestamp, payload, secret);
|
|
177
187
|
expect(signature).toEqual(signatureHash);
|
|
178
|
-
});
|
|
188
|
+
}));
|
|
179
189
|
});
|
|
180
190
|
});
|
package/lib/workos.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AxiosResponse } from 'axios';
|
|
2
1
|
import { GetOptions, PostOptions, PutOptions, WorkOSOptions } from './common/interfaces';
|
|
3
2
|
import { DirectorySync } from './directory-sync/directory-sync';
|
|
4
3
|
import { Events } from './events/events';
|
|
@@ -29,10 +28,16 @@ export declare class WorkOS {
|
|
|
29
28
|
readonly userManagement: UserManagement;
|
|
30
29
|
constructor(key?: string | undefined, options?: WorkOSOptions);
|
|
31
30
|
get version(): string;
|
|
32
|
-
post<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
post<Result = any, Entity = any>(path: string, entity: Entity, options?: PostOptions): Promise<{
|
|
32
|
+
data: Result;
|
|
33
|
+
}>;
|
|
34
|
+
get<Result = any>(path: string, options?: GetOptions): Promise<{
|
|
35
|
+
data: Result;
|
|
36
|
+
}>;
|
|
37
|
+
put<Result = any, Entity = any>(path: string, entity: Entity, options?: PutOptions): Promise<{
|
|
38
|
+
data: Result;
|
|
39
|
+
}>;
|
|
40
|
+
delete(path: string, query?: any): Promise<void>;
|
|
36
41
|
emitWarning(warning: string): void;
|
|
37
|
-
private
|
|
42
|
+
private handleFetchError;
|
|
38
43
|
}
|
package/lib/workos.js
CHANGED
|
@@ -8,12 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
12
|
exports.WorkOS = void 0;
|
|
16
|
-
const axios_1 = __importDefault(require("axios"));
|
|
17
13
|
const exceptions_1 = require("./common/exceptions");
|
|
18
14
|
const directory_sync_1 = require("./directory-sync/directory-sync");
|
|
19
15
|
const events_1 = require("./events/events");
|
|
@@ -27,7 +23,8 @@ const mfa_1 = require("./mfa/mfa");
|
|
|
27
23
|
const audit_logs_1 = require("./audit-logs/audit-logs");
|
|
28
24
|
const user_management_1 = require("./user-management/user-management");
|
|
29
25
|
const bad_request_exception_1 = require("./common/exceptions/bad-request.exception");
|
|
30
|
-
const
|
|
26
|
+
const fetch_client_1 = require("./common/utils/fetch-client");
|
|
27
|
+
const VERSION = '6.0.0-rc.1';
|
|
31
28
|
const DEFAULT_HOSTNAME = 'api.workos.com';
|
|
32
29
|
class WorkOS {
|
|
33
30
|
constructor(key, options = {}) {
|
|
@@ -61,7 +58,7 @@ class WorkOS {
|
|
|
61
58
|
if (port) {
|
|
62
59
|
this.baseURL = this.baseURL + `:${port}`;
|
|
63
60
|
}
|
|
64
|
-
this.client =
|
|
61
|
+
this.client = new fetch_client_1.FetchClient(this.baseURL, Object.assign(Object.assign({}, options.config), { headers: Object.assign(Object.assign({}, (_a = options.config) === null || _a === void 0 ? void 0 : _a.headers), { Authorization: `Bearer ${this.key}`, 'User-Agent': `workos-node/${VERSION}` }) }));
|
|
65
62
|
}
|
|
66
63
|
get version() {
|
|
67
64
|
return VERSION;
|
|
@@ -79,7 +76,7 @@ class WorkOS {
|
|
|
79
76
|
});
|
|
80
77
|
}
|
|
81
78
|
catch (error) {
|
|
82
|
-
this.
|
|
79
|
+
this.handleFetchError({ path, error });
|
|
83
80
|
throw error;
|
|
84
81
|
}
|
|
85
82
|
});
|
|
@@ -91,14 +88,12 @@ class WorkOS {
|
|
|
91
88
|
return yield this.client.get(path, {
|
|
92
89
|
params: options.query,
|
|
93
90
|
headers: accessToken
|
|
94
|
-
? {
|
|
95
|
-
Authorization: `Bearer ${accessToken}`,
|
|
96
|
-
}
|
|
91
|
+
? { Authorization: `Bearer ${accessToken}` }
|
|
97
92
|
: undefined,
|
|
98
93
|
});
|
|
99
94
|
}
|
|
100
95
|
catch (error) {
|
|
101
|
-
this.
|
|
96
|
+
this.handleFetchError({ path, error });
|
|
102
97
|
throw error;
|
|
103
98
|
}
|
|
104
99
|
});
|
|
@@ -116,7 +111,7 @@ class WorkOS {
|
|
|
116
111
|
});
|
|
117
112
|
}
|
|
118
113
|
catch (error) {
|
|
119
|
-
this.
|
|
114
|
+
this.handleFetchError({ path, error });
|
|
120
115
|
throw error;
|
|
121
116
|
}
|
|
122
117
|
});
|
|
@@ -124,12 +119,12 @@ class WorkOS {
|
|
|
124
119
|
delete(path, query) {
|
|
125
120
|
return __awaiter(this, void 0, void 0, function* () {
|
|
126
121
|
try {
|
|
127
|
-
|
|
122
|
+
yield this.client.delete(path, {
|
|
128
123
|
params: query,
|
|
129
124
|
});
|
|
130
125
|
}
|
|
131
126
|
catch (error) {
|
|
132
|
-
this.
|
|
127
|
+
this.handleFetchError({ path, error });
|
|
133
128
|
throw error;
|
|
134
129
|
}
|
|
135
130
|
});
|
|
@@ -141,18 +136,18 @@ class WorkOS {
|
|
|
141
136
|
}
|
|
142
137
|
return process.emitWarning(warning, 'WorkOS');
|
|
143
138
|
}
|
|
144
|
-
|
|
139
|
+
handleFetchError({ path, error }) {
|
|
140
|
+
var _a;
|
|
145
141
|
const { response } = error;
|
|
146
142
|
if (response) {
|
|
147
143
|
const { status, data, headers } = response;
|
|
148
|
-
const requestID = headers
|
|
144
|
+
const requestID = (_a = headers.get('X-Request-ID')) !== null && _a !== void 0 ? _a : '';
|
|
149
145
|
const { code, error_description: errorDescription, error, errors, message, } = data;
|
|
150
146
|
switch (status) {
|
|
151
147
|
case 401: {
|
|
152
148
|
throw new exceptions_1.UnauthorizedException(requestID);
|
|
153
149
|
}
|
|
154
150
|
case 422: {
|
|
155
|
-
const { errors } = data;
|
|
156
151
|
throw new exceptions_1.UnprocessableEntityException({
|
|
157
152
|
code,
|
|
158
153
|
errors,
|
package/lib/workos.spec.js
CHANGED
|
@@ -12,13 +12,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const
|
|
16
|
-
const
|
|
15
|
+
const jest_fetch_mock_1 = __importDefault(require("jest-fetch-mock"));
|
|
16
|
+
const test_utils_1 = require("./common/utils/test-utils");
|
|
17
17
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
18
18
|
const exceptions_1 = require("./common/exceptions");
|
|
19
19
|
const workos_1 = require("./workos");
|
|
20
|
-
const mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
21
20
|
describe('WorkOS', () => {
|
|
21
|
+
beforeEach(() => jest_fetch_mock_1.default.resetMocks());
|
|
22
22
|
describe('constructor', () => {
|
|
23
23
|
const OLD_ENV = process.env;
|
|
24
24
|
beforeEach(() => {
|
|
@@ -66,18 +66,18 @@ describe('WorkOS', () => {
|
|
|
66
66
|
expect(workos.baseURL).toEqual('https://localhost:4000');
|
|
67
67
|
});
|
|
68
68
|
});
|
|
69
|
-
describe('when the `
|
|
70
|
-
it('applies the configuration to the
|
|
71
|
-
|
|
69
|
+
describe('when the `config` option is provided', () => {
|
|
70
|
+
it('applies the configuration to the fetch client', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
|
+
(0, test_utils_1.fetchOnce)('{}', { headers: { 'X-Request-ID': 'a-request-id' } });
|
|
72
72
|
const workos = new workos_1.WorkOS('sk_test', {
|
|
73
|
-
|
|
73
|
+
config: {
|
|
74
74
|
headers: {
|
|
75
75
|
'X-My-Custom-Header': 'Hey there!',
|
|
76
76
|
},
|
|
77
77
|
},
|
|
78
78
|
});
|
|
79
79
|
yield workos.post('/somewhere', {});
|
|
80
|
-
expect(
|
|
80
|
+
expect((0, test_utils_1.fetchHeaders)()).toMatchObject({
|
|
81
81
|
'X-My-Custom-Header': 'Hey there!',
|
|
82
82
|
});
|
|
83
83
|
}));
|
|
@@ -96,9 +96,7 @@ describe('WorkOS', () => {
|
|
|
96
96
|
describe('when the api responds with a 404', () => {
|
|
97
97
|
it('throws a NotFoundException', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
98
98
|
const message = 'Not Found';
|
|
99
|
-
|
|
100
|
-
message,
|
|
101
|
-
}, { 'X-Request-ID': 'a-request-id' });
|
|
99
|
+
(0, test_utils_1.fetchOnce)({ message }, { status: 404, headers: { 'X-Request-ID': 'a-request-id' } });
|
|
102
100
|
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
103
101
|
yield expect(workos.post('/path', {})).rejects.toStrictEqual(new exceptions_1.NotFoundException({
|
|
104
102
|
message,
|
|
@@ -109,10 +107,7 @@ describe('WorkOS', () => {
|
|
|
109
107
|
it('preserves the error code, status, and message from the underlying response', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
110
108
|
const message = 'The thing you are looking for is not here.';
|
|
111
109
|
const code = 'thing-not-found';
|
|
112
|
-
|
|
113
|
-
code,
|
|
114
|
-
message,
|
|
115
|
-
}, { 'X-Request-ID': 'a-request-id' });
|
|
110
|
+
(0, test_utils_1.fetchOnce)({ code, message }, { status: 404, headers: { 'X-Request-ID': 'a-request-id' } });
|
|
116
111
|
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
117
112
|
yield expect(workos.post('/path', {})).rejects.toMatchObject({
|
|
118
113
|
code,
|
|
@@ -123,9 +118,7 @@ describe('WorkOS', () => {
|
|
|
123
118
|
it('includes the path in the message if there is no message in the response', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
124
119
|
const code = 'thing-not-found';
|
|
125
120
|
const path = '/path/to/thing/that-aint-there';
|
|
126
|
-
|
|
127
|
-
code,
|
|
128
|
-
}, { 'X-Request-ID': 'a-request-id' });
|
|
121
|
+
(0, test_utils_1.fetchOnce)({ code }, { status: 404, headers: { 'X-Request-ID': 'a-request-id' } });
|
|
129
122
|
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
130
123
|
yield expect(workos.post(path, {})).rejects.toMatchObject({
|
|
131
124
|
code,
|
|
@@ -136,8 +129,9 @@ describe('WorkOS', () => {
|
|
|
136
129
|
});
|
|
137
130
|
describe('when the api responds with a 500 and no error/error_description', () => {
|
|
138
131
|
it('throws an GenericServerException', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
139
|
-
|
|
140
|
-
|
|
132
|
+
(0, test_utils_1.fetchOnce)({}, {
|
|
133
|
+
status: 500,
|
|
134
|
+
headers: { 'X-Request-ID': 'a-request-id' },
|
|
141
135
|
});
|
|
142
136
|
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
143
137
|
yield expect(workos.post('/path', {})).rejects.toStrictEqual(new exceptions_1.GenericServerException(500, undefined, {}, 'a-request-id'));
|
|
@@ -145,8 +139,9 @@ describe('WorkOS', () => {
|
|
|
145
139
|
});
|
|
146
140
|
describe('when the api responds with a 400 and an error/error_description', () => {
|
|
147
141
|
it('throws an OauthException', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
148
|
-
|
|
149
|
-
|
|
142
|
+
(0, test_utils_1.fetchOnce)({ error: 'error', error_description: 'error description' }, {
|
|
143
|
+
status: 400,
|
|
144
|
+
headers: { 'X-Request-ID': 'a-request-id' },
|
|
150
145
|
});
|
|
151
146
|
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
152
147
|
yield expect(workos.post('/path', {})).rejects.toStrictEqual(new exceptions_1.OauthException(400, 'a-request-id', 'error', 'error description', { error: 'error', error_description: 'error description' }));
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "6.0.0-rc.1",
|
|
3
3
|
"name": "@workos-inc/node",
|
|
4
4
|
"author": "WorkOS",
|
|
5
5
|
"description": "A Node wrapper for the WorkOS API",
|
|
@@ -34,15 +34,16 @@
|
|
|
34
34
|
"prepublishOnly": "yarn run build"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"axios": "~1.6.5",
|
|
38
37
|
"pluralize": "8.0.0"
|
|
39
38
|
},
|
|
40
39
|
"devDependencies": {
|
|
40
|
+
"@peculiar/webcrypto": "^1.4.5",
|
|
41
41
|
"@types/jest": "29.5.3",
|
|
42
42
|
"@types/node": "14.18.54",
|
|
43
43
|
"@types/pluralize": "0.0.30",
|
|
44
44
|
"axios-mock-adapter": "1.21.5",
|
|
45
45
|
"jest": "29.6.2",
|
|
46
|
+
"jest-fetch-mock": "^3.0.3",
|
|
46
47
|
"prettier": "2.8.8",
|
|
47
48
|
"supertest": "6.3.3",
|
|
48
49
|
"ts-jest": "29.1.1",
|