@workos-inc/node 2.2.0 → 2.5.0-alpha.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/common/exceptions/index.js +5 -1
- package/lib/common/interfaces/index.js +5 -1
- package/lib/directory-sync/interfaces/list-directories-options.interface.d.ts +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +6 -1
- package/lib/mfa/interfaces/challenge-factor-options.d.ts +6 -0
- package/lib/mfa/interfaces/challenge-factor-options.js +2 -0
- package/lib/mfa/interfaces/challenge.interface.d.ts +9 -0
- package/lib/mfa/interfaces/challenge.interface.js +2 -0
- package/lib/mfa/interfaces/enroll-factor-options.d.ts +10 -0
- package/lib/mfa/interfaces/enroll-factor-options.js +2 -0
- package/lib/mfa/interfaces/factor.interface.d.ts +12 -0
- package/lib/mfa/interfaces/factor.interface.js +2 -0
- package/lib/mfa/interfaces/sms.interface.d.ts +3 -0
- package/lib/mfa/interfaces/sms.interface.js +2 -0
- package/lib/mfa/interfaces/totp.interface.d.ts +4 -0
- package/lib/mfa/interfaces/totp.interface.js +2 -0
- package/lib/mfa/interfaces/verify-factor-options.d.ts +4 -0
- package/lib/mfa/interfaces/verify-factor-options.js +2 -0
- package/lib/mfa/interfaces/verify-factor-response.d.ts +10 -0
- package/lib/mfa/interfaces/verify-factor-response.js +2 -0
- package/lib/mfa/mfa.d.ts +16 -0
- package/lib/mfa/mfa.js +47 -0
- package/lib/mfa/mfa.spec.d.ts +1 -0
- package/lib/mfa/mfa.spec.js +248 -0
- package/lib/organizations/interfaces/index.js +5 -1
- package/lib/sso/interfaces/authorization-url-options.interface.d.ts +6 -0
- package/lib/sso/interfaces/index.js +5 -1
- package/lib/sso/sso.d.ts +1 -1
- package/lib/sso/sso.js +9 -3
- package/lib/sso/sso.spec.js +39 -0
- package/lib/webhooks/interfaces/index.js +5 -1
- package/lib/webhooks/webhooks.js +2 -2
- package/lib/workos.d.ts +2 -0
- package/lib/workos.js +3 -1
- package/package.json +10 -10
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
package/lib/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './audit-trail/interfaces';
|
|
|
3
3
|
export * from './common/exceptions';
|
|
4
4
|
export * from './common/interfaces';
|
|
5
5
|
export * from './directory-sync/interfaces';
|
|
6
|
+
export * from './organizations/interfaces';
|
|
6
7
|
export * from './passwordless/interfaces';
|
|
7
8
|
export * from './portal/interfaces';
|
|
8
9
|
export * from './sso/interfaces';
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -17,6 +21,7 @@ __exportStar(require("./audit-trail/interfaces"), exports);
|
|
|
17
21
|
__exportStar(require("./common/exceptions"), exports);
|
|
18
22
|
__exportStar(require("./common/interfaces"), exports);
|
|
19
23
|
__exportStar(require("./directory-sync/interfaces"), exports);
|
|
24
|
+
__exportStar(require("./organizations/interfaces"), exports);
|
|
20
25
|
__exportStar(require("./passwordless/interfaces"), exports);
|
|
21
26
|
__exportStar(require("./portal/interfaces"), exports);
|
|
22
27
|
__exportStar(require("./sso/interfaces"), exports);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Sms } from './sms.interface';
|
|
2
|
+
import { Totp } from './totp.interface';
|
|
3
|
+
export interface Factor {
|
|
4
|
+
object: 'authentication_factor';
|
|
5
|
+
id: string;
|
|
6
|
+
created_at: string;
|
|
7
|
+
updated_at: string;
|
|
8
|
+
type: string;
|
|
9
|
+
environment_id: string;
|
|
10
|
+
sms: Sms;
|
|
11
|
+
totp: Totp;
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Challenge } from './challenge.interface';
|
|
2
|
+
export interface VerifyResponseSuccess {
|
|
3
|
+
challenge: Challenge;
|
|
4
|
+
valid: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface VerifyResponseError {
|
|
7
|
+
code: string;
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
export declare type VerifyResponse = VerifyResponseSuccess | VerifyResponseError;
|
package/lib/mfa/mfa.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { WorkOS } from '../workos';
|
|
2
|
+
import { ChallengeFactorOptions } from './interfaces/challenge-factor-options';
|
|
3
|
+
import { Challenge } from './interfaces/challenge.interface';
|
|
4
|
+
import { EnrollFactorOptions } from './interfaces/enroll-factor-options';
|
|
5
|
+
import { Factor } from './interfaces/factor.interface';
|
|
6
|
+
import { VerifyFactorOptions } from './interfaces/verify-factor-options';
|
|
7
|
+
import { VerifyResponse } from './interfaces/verify-factor-response';
|
|
8
|
+
export declare class Mfa {
|
|
9
|
+
private readonly workos;
|
|
10
|
+
constructor(workos: WorkOS);
|
|
11
|
+
deleteFactor(id: string): Promise<void>;
|
|
12
|
+
getFactor(id: string): Promise<any>;
|
|
13
|
+
enrollFactor(options: EnrollFactorOptions): Promise<Factor>;
|
|
14
|
+
challengeFactor(options: ChallengeFactorOptions): Promise<Challenge>;
|
|
15
|
+
verifyFactor(options: VerifyFactorOptions): Promise<VerifyResponse>;
|
|
16
|
+
}
|
package/lib/mfa/mfa.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
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.Mfa = void 0;
|
|
13
|
+
class Mfa {
|
|
14
|
+
constructor(workos) {
|
|
15
|
+
this.workos = workos;
|
|
16
|
+
}
|
|
17
|
+
deleteFactor(id) {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
yield this.workos.delete(`/auth/factors/${id}`);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
getFactor(id) {
|
|
23
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
const { data } = yield this.workos.get(`/auth/factors/${id}`);
|
|
25
|
+
return data;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
enrollFactor(options) {
|
|
29
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
const { data } = yield this.workos.post('/auth/factors/enroll', options);
|
|
31
|
+
return data;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
challengeFactor(options) {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
const { data } = yield this.workos.post('/auth/factors/challenge', options);
|
|
37
|
+
return data;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
verifyFactor(options) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
const { data } = yield this.workos.post('/auth/factors/verify', options);
|
|
43
|
+
return data;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.Mfa = Mfa;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,248 @@
|
|
|
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 workos_1 = require("../workos");
|
|
18
|
+
describe('MFA', () => {
|
|
19
|
+
describe('getFactor', () => {
|
|
20
|
+
it('throws an error for incomplete arguments', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
+
const mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
22
|
+
mock.onGet().reply(200, {});
|
|
23
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
24
|
+
const factor = yield workos.mfa.getFactor('test_123');
|
|
25
|
+
expect(factor).toMatchInlineSnapshot(`Object {}`);
|
|
26
|
+
}));
|
|
27
|
+
});
|
|
28
|
+
describe('deleteFactor', () => {
|
|
29
|
+
it('sends request to delete a Factor', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
|
+
const mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
31
|
+
mock.onDelete().reply(200, {});
|
|
32
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
33
|
+
yield workos.mfa.deleteFactor('conn_123');
|
|
34
|
+
expect(mock.history.delete[0].url).toEqual('/auth/factors/conn_123');
|
|
35
|
+
}));
|
|
36
|
+
});
|
|
37
|
+
describe('enrollFactor', () => {
|
|
38
|
+
describe('with generic', () => {
|
|
39
|
+
it('enrolls a factor with generic type', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
|
+
const mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
41
|
+
mock.onPost('/auth/factors/enroll').reply(200, {
|
|
42
|
+
object: 'authentication_factor',
|
|
43
|
+
id: 'auth_factor_1234',
|
|
44
|
+
created_at: '2022-03-15T20:39:19.892Z',
|
|
45
|
+
updated_at: '2022-03-15T20:39:19.892Z',
|
|
46
|
+
type: 'generic_otp',
|
|
47
|
+
environment_id: 'environment_1234',
|
|
48
|
+
});
|
|
49
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
|
|
50
|
+
apiHostname: 'api.workos.dev',
|
|
51
|
+
});
|
|
52
|
+
const enrollResponse = yield workos.mfa.enrollFactor({
|
|
53
|
+
type: 'generic_otp',
|
|
54
|
+
});
|
|
55
|
+
expect(enrollResponse).toMatchInlineSnapshot(`
|
|
56
|
+
Object {
|
|
57
|
+
"created_at": "2022-03-15T20:39:19.892Z",
|
|
58
|
+
"environment_id": "environment_1234",
|
|
59
|
+
"id": "auth_factor_1234",
|
|
60
|
+
"object": "authentication_factor",
|
|
61
|
+
"type": "generic_otp",
|
|
62
|
+
"updated_at": "2022-03-15T20:39:19.892Z",
|
|
63
|
+
}
|
|
64
|
+
`);
|
|
65
|
+
}));
|
|
66
|
+
});
|
|
67
|
+
describe('with totp', () => {
|
|
68
|
+
it('enrolls a factor with totp type', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
+
const mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
70
|
+
mock.onPost('/auth/factors/enroll').reply(200, {
|
|
71
|
+
object: 'authentication_factor',
|
|
72
|
+
id: 'auth_factor_1234',
|
|
73
|
+
created_at: '2022-03-15T20:39:19.892Z',
|
|
74
|
+
updated_at: '2022-03-15T20:39:19.892Z',
|
|
75
|
+
type: 'totp',
|
|
76
|
+
environment_id: 'environment_1234',
|
|
77
|
+
totp: {
|
|
78
|
+
qr_code: 'qr-code-test',
|
|
79
|
+
secret: 'secret-test',
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
|
|
83
|
+
apiHostname: 'api.workos.dev',
|
|
84
|
+
});
|
|
85
|
+
const enrollResponse = yield workos.mfa.enrollFactor({
|
|
86
|
+
type: 'totp',
|
|
87
|
+
issuer: 'WorkOS',
|
|
88
|
+
user: 'some_user',
|
|
89
|
+
});
|
|
90
|
+
expect(enrollResponse).toMatchInlineSnapshot(`
|
|
91
|
+
Object {
|
|
92
|
+
"created_at": "2022-03-15T20:39:19.892Z",
|
|
93
|
+
"environment_id": "environment_1234",
|
|
94
|
+
"id": "auth_factor_1234",
|
|
95
|
+
"object": "authentication_factor",
|
|
96
|
+
"totp": Object {
|
|
97
|
+
"qr_code": "qr-code-test",
|
|
98
|
+
"secret": "secret-test",
|
|
99
|
+
},
|
|
100
|
+
"type": "totp",
|
|
101
|
+
"updated_at": "2022-03-15T20:39:19.892Z",
|
|
102
|
+
}
|
|
103
|
+
`);
|
|
104
|
+
}));
|
|
105
|
+
});
|
|
106
|
+
describe('with sms', () => {
|
|
107
|
+
it('enrolls a factor with sms type', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
108
|
+
const mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
109
|
+
mock.onPost('/auth/factors/enroll').reply(200, {
|
|
110
|
+
object: 'authentication_factor',
|
|
111
|
+
id: 'auth_factor_1234',
|
|
112
|
+
created_at: '2022-03-15T20:39:19.892Z',
|
|
113
|
+
updated_at: '2022-03-15T20:39:19.892Z',
|
|
114
|
+
type: 'sms',
|
|
115
|
+
environment_id: 'environment_1234',
|
|
116
|
+
sms: {
|
|
117
|
+
phone_number: '+15555555555',
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
|
|
121
|
+
apiHostname: 'api.workos.dev',
|
|
122
|
+
});
|
|
123
|
+
const enrollResponse = yield workos.mfa.enrollFactor({
|
|
124
|
+
type: 'sms',
|
|
125
|
+
phoneNumber: '+1555555555',
|
|
126
|
+
});
|
|
127
|
+
expect(enrollResponse).toMatchInlineSnapshot(`
|
|
128
|
+
Object {
|
|
129
|
+
"created_at": "2022-03-15T20:39:19.892Z",
|
|
130
|
+
"environment_id": "environment_1234",
|
|
131
|
+
"id": "auth_factor_1234",
|
|
132
|
+
"object": "authentication_factor",
|
|
133
|
+
"sms": Object {
|
|
134
|
+
"phone_number": "+15555555555",
|
|
135
|
+
},
|
|
136
|
+
"type": "sms",
|
|
137
|
+
"updated_at": "2022-03-15T20:39:19.892Z",
|
|
138
|
+
}
|
|
139
|
+
`);
|
|
140
|
+
}));
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
describe('challengeFactor', () => {
|
|
144
|
+
describe('with no sms template', () => {
|
|
145
|
+
it('challenge a factor with no sms template', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
146
|
+
const mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
147
|
+
mock.onPost('/auth/factors/challenge').reply(200, {
|
|
148
|
+
object: 'authentication_challenge',
|
|
149
|
+
id: 'auth_challenge_1234',
|
|
150
|
+
created_at: '2022-03-15T20:39:19.892Z',
|
|
151
|
+
updated_at: '2022-03-15T20:39:19.892Z',
|
|
152
|
+
expires_at: '2022-03-15T21:39:19.892Z',
|
|
153
|
+
code: '12345',
|
|
154
|
+
authentication_factor_id: 'auth_factor_1234',
|
|
155
|
+
});
|
|
156
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
|
|
157
|
+
apiHostname: 'api.workos.dev',
|
|
158
|
+
});
|
|
159
|
+
const challengeResponse = yield workos.mfa.challengeFactor({
|
|
160
|
+
authentication_factor_id: 'auth_factor_1234',
|
|
161
|
+
});
|
|
162
|
+
expect(challengeResponse).toMatchInlineSnapshot(`
|
|
163
|
+
Object {
|
|
164
|
+
"authentication_factor_id": "auth_factor_1234",
|
|
165
|
+
"code": "12345",
|
|
166
|
+
"created_at": "2022-03-15T20:39:19.892Z",
|
|
167
|
+
"expires_at": "2022-03-15T21:39:19.892Z",
|
|
168
|
+
"id": "auth_challenge_1234",
|
|
169
|
+
"object": "authentication_challenge",
|
|
170
|
+
"updated_at": "2022-03-15T20:39:19.892Z",
|
|
171
|
+
}
|
|
172
|
+
`);
|
|
173
|
+
}));
|
|
174
|
+
});
|
|
175
|
+
describe('with totp', () => {
|
|
176
|
+
it('challenge a factor with sms template', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
177
|
+
const mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
178
|
+
mock.onPost('/auth/factors/challenge').reply(200, {
|
|
179
|
+
object: 'authentication_challenge',
|
|
180
|
+
id: 'auth_challenge_1234',
|
|
181
|
+
created_at: '2022-03-15T20:39:19.892Z',
|
|
182
|
+
updated_at: '2022-03-15T20:39:19.892Z',
|
|
183
|
+
expires_at: '2022-03-15T21:39:19.892Z',
|
|
184
|
+
code: '12345',
|
|
185
|
+
authentication_factor_id: 'auth_factor_1234',
|
|
186
|
+
});
|
|
187
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
|
|
188
|
+
apiHostname: 'api.workos.dev',
|
|
189
|
+
});
|
|
190
|
+
const challengeResponse = yield workos.mfa.challengeFactor({
|
|
191
|
+
authentication_factor_id: 'auth_factor_1234',
|
|
192
|
+
sms_template: 'This is your code: 12345',
|
|
193
|
+
});
|
|
194
|
+
expect(challengeResponse).toMatchInlineSnapshot(`
|
|
195
|
+
Object {
|
|
196
|
+
"authentication_factor_id": "auth_factor_1234",
|
|
197
|
+
"code": "12345",
|
|
198
|
+
"created_at": "2022-03-15T20:39:19.892Z",
|
|
199
|
+
"expires_at": "2022-03-15T21:39:19.892Z",
|
|
200
|
+
"id": "auth_challenge_1234",
|
|
201
|
+
"object": "authentication_challenge",
|
|
202
|
+
"updated_at": "2022-03-15T20:39:19.892Z",
|
|
203
|
+
}
|
|
204
|
+
`);
|
|
205
|
+
}));
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
describe('verifyFactor', () => {
|
|
209
|
+
describe('verify with successful response', () => {
|
|
210
|
+
it('verifies a successful factor', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
211
|
+
const mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
212
|
+
mock.onPost('/auth/factors/verify').reply(200, {
|
|
213
|
+
challenge: {
|
|
214
|
+
object: 'authentication_challenge',
|
|
215
|
+
id: 'auth_challenge_1234',
|
|
216
|
+
created_at: '2022-03-15T20:39:19.892Z',
|
|
217
|
+
updated_at: '2022-03-15T20:39:19.892Z',
|
|
218
|
+
expires_at: '2022-03-15T21:39:19.892Z',
|
|
219
|
+
code: '12345',
|
|
220
|
+
authentication_factor_id: 'auth_factor_1234',
|
|
221
|
+
},
|
|
222
|
+
valid: true,
|
|
223
|
+
});
|
|
224
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
|
|
225
|
+
apiHostname: 'api.workos.dev',
|
|
226
|
+
});
|
|
227
|
+
const verifyResponse = yield workos.mfa.verifyFactor({
|
|
228
|
+
authentication_challenge_id: 'auth_challenge_1234',
|
|
229
|
+
code: '12345',
|
|
230
|
+
});
|
|
231
|
+
expect(verifyResponse).toMatchInlineSnapshot(`
|
|
232
|
+
Object {
|
|
233
|
+
"challenge": Object {
|
|
234
|
+
"authentication_factor_id": "auth_factor_1234",
|
|
235
|
+
"code": "12345",
|
|
236
|
+
"created_at": "2022-03-15T20:39:19.892Z",
|
|
237
|
+
"expires_at": "2022-03-15T21:39:19.892Z",
|
|
238
|
+
"id": "auth_challenge_1234",
|
|
239
|
+
"object": "authentication_challenge",
|
|
240
|
+
"updated_at": "2022-03-15T20:39:19.892Z",
|
|
241
|
+
},
|
|
242
|
+
"valid": true,
|
|
243
|
+
}
|
|
244
|
+
`);
|
|
245
|
+
}));
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
});
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
export interface AuthorizationURLOptions {
|
|
2
2
|
clientID: string;
|
|
3
3
|
connection?: string;
|
|
4
|
+
organization?: string;
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated Please use `organization` instead.
|
|
7
|
+
*/
|
|
4
8
|
domain?: string;
|
|
9
|
+
domainHint?: string;
|
|
10
|
+
loginHint?: string;
|
|
5
11
|
provider?: string;
|
|
6
12
|
redirectURI: string;
|
|
7
13
|
state?: string;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
package/lib/sso/sso.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare class SSO {
|
|
|
11
11
|
private readonly workos;
|
|
12
12
|
constructor(workos: WorkOS);
|
|
13
13
|
deleteConnection(id: string): Promise<void>;
|
|
14
|
-
getAuthorizationURL({ connection, clientID, domain, provider, redirectURI, state, }: AuthorizationURLOptions): string;
|
|
14
|
+
getAuthorizationURL({ connection, clientID, domain, domainHint, loginHint, organization, provider, redirectURI, state, }: AuthorizationURLOptions): string;
|
|
15
15
|
getConnection(id: string): Promise<Connection>;
|
|
16
16
|
getProfileAndToken({ code, clientID, }: GetProfileAndTokenOptions): Promise<ProfileAndToken>;
|
|
17
17
|
getProfile({ accessToken }: GetProfileOptions): Promise<Profile>;
|
package/lib/sso/sso.js
CHANGED
|
@@ -23,13 +23,19 @@ class SSO {
|
|
|
23
23
|
yield this.workos.delete(`/connections/${id}`);
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
-
getAuthorizationURL({ connection, clientID, domain, provider, redirectURI, state, }) {
|
|
27
|
-
if (!domain && !provider && !connection) {
|
|
28
|
-
throw new Error(`Incomplete arguments. Need to specify either a 'connection', 'domain', or 'provider'.`);
|
|
26
|
+
getAuthorizationURL({ connection, clientID, domain, domainHint, loginHint, organization, provider, redirectURI, state, }) {
|
|
27
|
+
if (!domain && !provider && !connection && !organization) {
|
|
28
|
+
throw new Error(`Incomplete arguments. Need to specify either a 'connection', 'organization', 'domain', or 'provider'.`);
|
|
29
|
+
}
|
|
30
|
+
if (domain) {
|
|
31
|
+
this.workos.emitWarning('The `domain` parameter for `getAuthorizationURL` is deprecated. Please use `organization` instead.');
|
|
29
32
|
}
|
|
30
33
|
const query = query_string_1.default.stringify({
|
|
31
34
|
connection,
|
|
35
|
+
organization,
|
|
32
36
|
domain,
|
|
37
|
+
domain_hint: domainHint,
|
|
38
|
+
login_hint: loginHint,
|
|
33
39
|
provider,
|
|
34
40
|
client_id: clientID,
|
|
35
41
|
redirect_uri: redirectURI,
|
package/lib/sso/sso.spec.js
CHANGED
|
@@ -65,6 +65,19 @@ describe('SSO', () => {
|
|
|
65
65
|
expect(url).toMatchSnapshot();
|
|
66
66
|
});
|
|
67
67
|
});
|
|
68
|
+
describe('with an `organization`', () => {
|
|
69
|
+
it('generates an authorization URL with the organization', () => {
|
|
70
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
|
|
71
|
+
apiHostname: 'api.workos.dev',
|
|
72
|
+
});
|
|
73
|
+
const url = workos.sso.getAuthorizationURL({
|
|
74
|
+
organization: 'organization_123',
|
|
75
|
+
clientID: 'proj_123',
|
|
76
|
+
redirectURI: 'example.com/sso/workos/callback',
|
|
77
|
+
});
|
|
78
|
+
expect(url).toMatchSnapshot();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
68
81
|
describe('with a custom api hostname', () => {
|
|
69
82
|
it('generates an authorize url with the custom api hostname', () => {
|
|
70
83
|
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
|
|
@@ -90,6 +103,32 @@ describe('SSO', () => {
|
|
|
90
103
|
expect(url).toMatchSnapshot();
|
|
91
104
|
});
|
|
92
105
|
});
|
|
106
|
+
describe('with domainHint', () => {
|
|
107
|
+
it('generates an authorize url with the provided domain hint', () => {
|
|
108
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
109
|
+
const url = workos.sso.getAuthorizationURL({
|
|
110
|
+
domainHint: 'lyft.com',
|
|
111
|
+
connection: 'connection_123',
|
|
112
|
+
clientID: 'proj_123',
|
|
113
|
+
redirectURI: 'example.com/sso/workos/callback',
|
|
114
|
+
state: 'custom state',
|
|
115
|
+
});
|
|
116
|
+
expect(url).toMatchInlineSnapshot(`"https://api.workos.com/sso/authorize?client_id=proj_123&connection=connection_123&domain_hint=lyft.com&redirect_uri=example.com%2Fsso%2Fworkos%2Fcallback&response_type=code&state=custom%20state"`);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe('with loginHint', () => {
|
|
120
|
+
it('generates an authorize url with the provided login hint', () => {
|
|
121
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
122
|
+
const url = workos.sso.getAuthorizationURL({
|
|
123
|
+
loginHint: 'foo@workos.com',
|
|
124
|
+
connection: 'connection_123',
|
|
125
|
+
clientID: 'proj_123',
|
|
126
|
+
redirectURI: 'example.com/sso/workos/callback',
|
|
127
|
+
state: 'custom state',
|
|
128
|
+
});
|
|
129
|
+
expect(url).toMatchInlineSnapshot(`"https://api.workos.com/sso/authorize?client_id=proj_123&connection=connection_123&login_hint=foo%40workos.com&redirect_uri=example.com%2Fsso%2Fworkos%2Fcallback&response_type=code&state=custom%20state"`);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
93
132
|
});
|
|
94
133
|
describe('getProfileAndToken', () => {
|
|
95
134
|
describe('with all information provided', () => {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
package/lib/webhooks/webhooks.js
CHANGED
|
@@ -7,13 +7,13 @@ exports.Webhooks = void 0;
|
|
|
7
7
|
const crypto_1 = __importDefault(require("crypto"));
|
|
8
8
|
const exceptions_1 = require("../common/exceptions");
|
|
9
9
|
class Webhooks {
|
|
10
|
-
constructEvent({ payload, sigHeader, secret, tolerance =
|
|
10
|
+
constructEvent({ payload, sigHeader, secret, tolerance = 180000, }) {
|
|
11
11
|
const options = { payload, sigHeader, secret, tolerance };
|
|
12
12
|
this.verifyHeader(options);
|
|
13
13
|
const webhookPayload = payload;
|
|
14
14
|
return webhookPayload;
|
|
15
15
|
}
|
|
16
|
-
verifyHeader({ payload, sigHeader, secret, tolerance =
|
|
16
|
+
verifyHeader({ payload, sigHeader, secret, tolerance = 180000, }) {
|
|
17
17
|
const [timestamp, signatureHash] = this.getTimestampAndSignatureHash(sigHeader);
|
|
18
18
|
if (!signatureHash || Object.keys(signatureHash).length === 0) {
|
|
19
19
|
throw new exceptions_1.SignatureVerificationException('No signature hash found with expected scheme v1');
|
package/lib/workos.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { Passwordless } from './passwordless/passwordless';
|
|
|
7
7
|
import { Portal } from './portal/portal';
|
|
8
8
|
import { SSO } from './sso/sso';
|
|
9
9
|
import { Webhooks } from './webhooks/webhooks';
|
|
10
|
+
import { Mfa } from './mfa/mfa';
|
|
10
11
|
export declare class WorkOS {
|
|
11
12
|
readonly key?: string | undefined;
|
|
12
13
|
readonly options: WorkOSOptions;
|
|
@@ -19,6 +20,7 @@ export declare class WorkOS {
|
|
|
19
20
|
readonly portal: Portal;
|
|
20
21
|
readonly sso: SSO;
|
|
21
22
|
readonly webhooks: Webhooks;
|
|
23
|
+
readonly mfa: Mfa;
|
|
22
24
|
constructor(key?: string | undefined, options?: WorkOSOptions);
|
|
23
25
|
post(path: string, entity: any, options?: PostOptions): Promise<AxiosResponse>;
|
|
24
26
|
get(path: string, options?: GetOptions): Promise<AxiosResponse>;
|
package/lib/workos.js
CHANGED
|
@@ -22,7 +22,8 @@ const passwordless_1 = require("./passwordless/passwordless");
|
|
|
22
22
|
const portal_1 = require("./portal/portal");
|
|
23
23
|
const sso_1 = require("./sso/sso");
|
|
24
24
|
const webhooks_1 = require("./webhooks/webhooks");
|
|
25
|
-
const
|
|
25
|
+
const mfa_1 = require("./mfa/mfa");
|
|
26
|
+
const VERSION = '2.5.0-alpha.1';
|
|
26
27
|
const DEFAULT_HOSTNAME = 'api.workos.com';
|
|
27
28
|
class WorkOS {
|
|
28
29
|
constructor(key, options = {}) {
|
|
@@ -35,6 +36,7 @@ class WorkOS {
|
|
|
35
36
|
this.portal = new portal_1.Portal(this);
|
|
36
37
|
this.sso = new sso_1.SSO(this);
|
|
37
38
|
this.webhooks = new webhooks_1.Webhooks();
|
|
39
|
+
this.mfa = new mfa_1.Mfa(this);
|
|
38
40
|
if (!key) {
|
|
39
41
|
this.key = process.env.WORKOS_API_KEY;
|
|
40
42
|
if (!this.key) {
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.5.0-alpha.1",
|
|
3
3
|
"name": "@workos-inc/node",
|
|
4
4
|
"author": "WorkOS",
|
|
5
5
|
"description": "A Node wrapper for the WorkOS API",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"workos"
|
|
10
10
|
],
|
|
11
11
|
"volta": {
|
|
12
|
-
"node": "14.
|
|
12
|
+
"node": "14.19.0",
|
|
13
13
|
"yarn": "1.22.17"
|
|
14
14
|
},
|
|
15
15
|
"main": "lib/index.js",
|
|
@@ -36,18 +36,18 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"axios": "0.21.4",
|
|
38
38
|
"pluralize": "8.0.0",
|
|
39
|
-
"query-string": "7.
|
|
39
|
+
"query-string": "7.1.1"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@types/jest": "27.
|
|
43
|
-
"@types/node": "14.
|
|
42
|
+
"@types/jest": "27.4.1",
|
|
43
|
+
"@types/node": "14.18.12",
|
|
44
44
|
"@types/pluralize": "0.0.29",
|
|
45
45
|
"axios-mock-adapter": "1.20.0",
|
|
46
|
-
"jest": "27.
|
|
47
|
-
"prettier": "2.
|
|
48
|
-
"supertest": "6.
|
|
49
|
-
"ts-jest": "27.
|
|
46
|
+
"jest": "27.5.1",
|
|
47
|
+
"prettier": "2.6.0",
|
|
48
|
+
"supertest": "6.2.2",
|
|
49
|
+
"ts-jest": "27.1.3",
|
|
50
50
|
"tslint": "6.1.3",
|
|
51
|
-
"typescript": "4.
|
|
51
|
+
"typescript": "4.6.2"
|
|
52
52
|
}
|
|
53
53
|
}
|