@workos-inc/node 7.68.0 → 7.69.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/sso/interfaces/authorization-url-options.interface.d.ts +2 -0
- package/lib/sso/interfaces/profile-and-token.interface.d.ts +3 -0
- package/lib/sso/serializers/profile-and-token.serializer.js +2 -0
- package/lib/sso/sso.d.ts +1 -1
- package/lib/sso/sso.js +14 -10
- package/lib/sso/sso.spec.js +131 -0
- package/lib/workos.js +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { UnknownRecord } from '../../common/interfaces/unknown-record.interface';
|
|
2
|
+
import { OauthTokens, OauthTokensResponse } from '../../user-management/interfaces/oauth-tokens.interface';
|
|
2
3
|
import { Profile, ProfileResponse } from './profile.interface';
|
|
3
4
|
export interface ProfileAndToken<CustomAttributesType extends UnknownRecord> {
|
|
4
5
|
accessToken: string;
|
|
5
6
|
profile: Profile<CustomAttributesType>;
|
|
7
|
+
oauthTokens?: OauthTokens;
|
|
6
8
|
}
|
|
7
9
|
export interface ProfileAndTokenResponse<CustomAttributesType extends UnknownRecord> {
|
|
8
10
|
access_token: string;
|
|
9
11
|
profile: ProfileResponse<CustomAttributesType>;
|
|
12
|
+
oauth_tokens?: OauthTokensResponse;
|
|
10
13
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.deserializeProfileAndToken = void 0;
|
|
4
|
+
const oauth_tokens_serializer_1 = require("../../user-management/serializers/oauth-tokens.serializer");
|
|
4
5
|
const profile_serializer_1 = require("./profile.serializer");
|
|
5
6
|
const deserializeProfileAndToken = (profileAndToken) => ({
|
|
6
7
|
accessToken: profileAndToken.access_token,
|
|
7
8
|
profile: (0, profile_serializer_1.deserializeProfile)(profileAndToken.profile),
|
|
9
|
+
oauthTokens: (0, oauth_tokens_serializer_1.deserializeOauthTokens)(profileAndToken.oauth_tokens),
|
|
8
10
|
});
|
|
9
11
|
exports.deserializeProfileAndToken = deserializeProfileAndToken;
|
package/lib/sso/sso.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare class SSO {
|
|
|
7
7
|
constructor(workos: WorkOS);
|
|
8
8
|
listConnections(options?: ListConnectionsOptions): Promise<AutoPaginatable<Connection>>;
|
|
9
9
|
deleteConnection(id: string): Promise<void>;
|
|
10
|
-
getAuthorizationUrl({ connection, clientId, domain, domainHint, loginHint, organization, provider, redirectUri, state, }: SSOAuthorizationURLOptions): string;
|
|
10
|
+
getAuthorizationUrl({ connection, clientId, domain, domainHint, loginHint, organization, provider, providerQueryParams, providerScopes, redirectUri, state, }: SSOAuthorizationURLOptions): string;
|
|
11
11
|
getConnection(id: string): Promise<Connection>;
|
|
12
12
|
getProfileAndToken<CustomAttributesType extends UnknownRecord = UnknownRecord>({ code, clientId, }: GetProfileAndTokenOptions): Promise<ProfileAndToken<CustomAttributesType>>;
|
|
13
13
|
getProfile<CustomAttributesType extends UnknownRecord = UnknownRecord>({ accessToken, }: GetProfileOptions): Promise<Profile<CustomAttributesType>>;
|
package/lib/sso/sso.js
CHANGED
|
@@ -8,21 +8,23 @@ 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
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
15
|
exports.SSO = void 0;
|
|
16
|
+
const qs_1 = __importDefault(require("qs"));
|
|
13
17
|
const fetch_and_deserialize_1 = require("../common/utils/fetch-and-deserialize");
|
|
14
18
|
const pagination_1 = require("../common/utils/pagination");
|
|
15
19
|
const serializers_1 = require("./serializers");
|
|
16
20
|
const toQueryString = (options) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
return searchParams.toString();
|
|
21
|
+
return qs_1.default.stringify(options, {
|
|
22
|
+
arrayFormat: 'repeat',
|
|
23
|
+
// sorts the keys alphabetically to maintain backwards compatibility
|
|
24
|
+
sort: (a, b) => a.localeCompare(b),
|
|
25
|
+
// encodes space as + instead of %20 to maintain backwards compatibility
|
|
26
|
+
format: 'RFC1738',
|
|
27
|
+
});
|
|
26
28
|
};
|
|
27
29
|
class SSO {
|
|
28
30
|
constructor(workos) {
|
|
@@ -38,7 +40,7 @@ class SSO {
|
|
|
38
40
|
yield this.workos.delete(`/connections/${id}`);
|
|
39
41
|
});
|
|
40
42
|
}
|
|
41
|
-
getAuthorizationUrl({ connection, clientId, domain, domainHint, loginHint, organization, provider, redirectUri, state, }) {
|
|
43
|
+
getAuthorizationUrl({ connection, clientId, domain, domainHint, loginHint, organization, provider, providerQueryParams, providerScopes, redirectUri, state, }) {
|
|
42
44
|
if (!domain && !provider && !connection && !organization) {
|
|
43
45
|
throw new Error(`Incomplete arguments. Need to specify either a 'connection', 'organization', 'domain', or 'provider'.`);
|
|
44
46
|
}
|
|
@@ -52,6 +54,8 @@ class SSO {
|
|
|
52
54
|
domain_hint: domainHint,
|
|
53
55
|
login_hint: loginHint,
|
|
54
56
|
provider,
|
|
57
|
+
provider_query_params: providerQueryParams,
|
|
58
|
+
provider_scopes: providerScopes,
|
|
55
59
|
client_id: clientId,
|
|
56
60
|
redirect_uri: redirectUri,
|
|
57
61
|
response_type: 'code',
|
package/lib/sso/sso.spec.js
CHANGED
|
@@ -161,6 +161,54 @@ describe('SSO', () => {
|
|
|
161
161
|
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+state"`);
|
|
162
162
|
});
|
|
163
163
|
});
|
|
164
|
+
describe('with providerScopes', () => {
|
|
165
|
+
it('generates an authorize url with the provided provider scopes', () => {
|
|
166
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
167
|
+
const url = workos.sso.getAuthorizationUrl({
|
|
168
|
+
provider: 'Google',
|
|
169
|
+
providerScopes: ['profile', 'email', 'calendar'],
|
|
170
|
+
clientId: 'proj_123',
|
|
171
|
+
redirectUri: 'example.com/sso/workos/callback',
|
|
172
|
+
});
|
|
173
|
+
expect(url).toMatchSnapshot();
|
|
174
|
+
});
|
|
175
|
+
it('handles empty provider scopes array', () => {
|
|
176
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
177
|
+
const url = workos.sso.getAuthorizationUrl({
|
|
178
|
+
provider: 'Google',
|
|
179
|
+
providerScopes: [],
|
|
180
|
+
clientId: 'proj_123',
|
|
181
|
+
redirectUri: 'example.com/sso/workos/callback',
|
|
182
|
+
});
|
|
183
|
+
expect(url).toMatchInlineSnapshot(`"https://api.workos.com/sso/authorize?client_id=proj_123&provider=Google&redirect_uri=example.com%2Fsso%2Fworkos%2Fcallback&response_type=code"`);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
describe('with providerQueryParams', () => {
|
|
187
|
+
it('generates an authorize url with the provided provider query params', () => {
|
|
188
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
189
|
+
const url = workos.sso.getAuthorizationUrl({
|
|
190
|
+
provider: 'Google',
|
|
191
|
+
providerQueryParams: {
|
|
192
|
+
custom_param: 'custom_value',
|
|
193
|
+
another_param: 123,
|
|
194
|
+
bool_param: true,
|
|
195
|
+
},
|
|
196
|
+
clientId: 'proj_123',
|
|
197
|
+
redirectUri: 'example.com/sso/workos/callback',
|
|
198
|
+
});
|
|
199
|
+
expect(url).toMatchInlineSnapshot(`"https://api.workos.com/sso/authorize?client_id=proj_123&provider=Google&provider_query_params%5Banother_param%5D=123&provider_query_params%5Bbool_param%5D=true&provider_query_params%5Bcustom_param%5D=custom_value&redirect_uri=example.com%2Fsso%2Fworkos%2Fcallback&response_type=code"`);
|
|
200
|
+
});
|
|
201
|
+
it('handles empty provider query params', () => {
|
|
202
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
203
|
+
const url = workos.sso.getAuthorizationUrl({
|
|
204
|
+
provider: 'Google',
|
|
205
|
+
providerQueryParams: {},
|
|
206
|
+
clientId: 'proj_123',
|
|
207
|
+
redirectUri: 'example.com/sso/workos/callback',
|
|
208
|
+
});
|
|
209
|
+
expect(url).toMatchInlineSnapshot(`"https://api.workos.com/sso/authorize?client_id=proj_123&provider=Google&redirect_uri=example.com%2Fsso%2Fworkos%2Fcallback&response_type=code"`);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
164
212
|
});
|
|
165
213
|
describe('getProfileAndToken', () => {
|
|
166
214
|
describe('with all information provided', () => {
|
|
@@ -240,6 +288,89 @@ describe('SSO', () => {
|
|
|
240
288
|
expect(profile).toMatchSnapshot();
|
|
241
289
|
}));
|
|
242
290
|
});
|
|
291
|
+
describe('with oauth tokens in the response', () => {
|
|
292
|
+
it('returns the oauth tokens from the profile and token response', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
293
|
+
(0, test_utils_1.fetchOnce)({
|
|
294
|
+
access_token: '01DMEK0J53CVMC32CK5SE0KZ8Q',
|
|
295
|
+
profile: {
|
|
296
|
+
id: 'prof_123',
|
|
297
|
+
idp_id: '123',
|
|
298
|
+
organization_id: 'org_123',
|
|
299
|
+
connection_id: 'conn_123',
|
|
300
|
+
connection_type: 'OktaSAML',
|
|
301
|
+
email: 'foo@test.com',
|
|
302
|
+
first_name: 'foo',
|
|
303
|
+
last_name: 'bar',
|
|
304
|
+
role: {
|
|
305
|
+
slug: 'admin',
|
|
306
|
+
},
|
|
307
|
+
groups: ['Admins', 'Developers'],
|
|
308
|
+
raw_attributes: {
|
|
309
|
+
email: 'foo@test.com',
|
|
310
|
+
first_name: 'foo',
|
|
311
|
+
last_name: 'bar',
|
|
312
|
+
groups: ['Admins', 'Developers'],
|
|
313
|
+
},
|
|
314
|
+
custom_attributes: {},
|
|
315
|
+
},
|
|
316
|
+
oauth_tokens: {
|
|
317
|
+
access_token: 'oauth_access_token',
|
|
318
|
+
refresh_token: 'oauth_refresh_token',
|
|
319
|
+
expires_at: 1640995200,
|
|
320
|
+
scopes: ['profile', 'email'],
|
|
321
|
+
},
|
|
322
|
+
});
|
|
323
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
324
|
+
const { accessToken, profile, oauthTokens } = yield workos.sso.getProfileAndToken({
|
|
325
|
+
code: 'authorization_code',
|
|
326
|
+
clientId: 'proj_123',
|
|
327
|
+
});
|
|
328
|
+
expect(jest_fetch_mock_1.default.mock.calls.length).toEqual(1);
|
|
329
|
+
expect(accessToken).toBe('01DMEK0J53CVMC32CK5SE0KZ8Q');
|
|
330
|
+
expect(profile).toBeDefined();
|
|
331
|
+
expect(oauthTokens).toEqual({
|
|
332
|
+
accessToken: 'oauth_access_token',
|
|
333
|
+
refreshToken: 'oauth_refresh_token',
|
|
334
|
+
expiresAt: 1640995200,
|
|
335
|
+
scopes: ['profile', 'email'],
|
|
336
|
+
});
|
|
337
|
+
}));
|
|
338
|
+
});
|
|
339
|
+
describe('without oauth tokens in the response', () => {
|
|
340
|
+
it('returns undefined for oauth tokens when not present in response', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
341
|
+
(0, test_utils_1.fetchOnce)({
|
|
342
|
+
access_token: '01DMEK0J53CVMC32CK5SE0KZ8Q',
|
|
343
|
+
profile: {
|
|
344
|
+
id: 'prof_123',
|
|
345
|
+
idp_id: '123',
|
|
346
|
+
organization_id: 'org_123',
|
|
347
|
+
connection_id: 'conn_123',
|
|
348
|
+
connection_type: 'OktaSAML',
|
|
349
|
+
email: 'foo@test.com',
|
|
350
|
+
first_name: 'foo',
|
|
351
|
+
last_name: 'bar',
|
|
352
|
+
role: {
|
|
353
|
+
slug: 'admin',
|
|
354
|
+
},
|
|
355
|
+
raw_attributes: {
|
|
356
|
+
email: 'foo@test.com',
|
|
357
|
+
first_name: 'foo',
|
|
358
|
+
last_name: 'bar',
|
|
359
|
+
},
|
|
360
|
+
custom_attributes: {},
|
|
361
|
+
},
|
|
362
|
+
});
|
|
363
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
364
|
+
const { accessToken, profile, oauthTokens } = yield workos.sso.getProfileAndToken({
|
|
365
|
+
code: 'authorization_code',
|
|
366
|
+
clientId: 'proj_123',
|
|
367
|
+
});
|
|
368
|
+
expect(jest_fetch_mock_1.default.mock.calls.length).toEqual(1);
|
|
369
|
+
expect(accessToken).toBe('01DMEK0J53CVMC32CK5SE0KZ8Q');
|
|
370
|
+
expect(profile).toBeDefined();
|
|
371
|
+
expect(oauthTokens).toBeUndefined();
|
|
372
|
+
}));
|
|
373
|
+
});
|
|
243
374
|
});
|
|
244
375
|
describe('getProfile', () => {
|
|
245
376
|
it('calls the `/sso/profile` endpoint with the provided access token', () => __awaiter(void 0, void 0, void 0, function* () {
|
package/lib/workos.js
CHANGED
|
@@ -32,7 +32,7 @@ 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
34
|
const parse_error_1 = require("./common/exceptions/parse-error");
|
|
35
|
-
const VERSION = '7.
|
|
35
|
+
const VERSION = '7.69.1';
|
|
36
36
|
const DEFAULT_HOSTNAME = 'api.workos.com';
|
|
37
37
|
const HEADER_AUTHORIZATION = 'Authorization';
|
|
38
38
|
const HEADER_IDEMPOTENCY_KEY = 'Idempotency-Key';
|
package/package.json
CHANGED