@workos-inc/node 7.36.1 → 7.37.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.
- package/lib/actions/actions.spec.js +2 -0
- package/lib/actions/fixtures/authentication-action-context.json +1 -0
- package/lib/actions/fixtures/user-registration-action-context.json +1 -0
- package/lib/actions/interfaces/action.interface.d.ts +4 -0
- package/lib/actions/serializers/action.serializer.js +2 -0
- package/lib/user-management/session.d.ts +3 -1
- package/lib/user-management/session.js +2 -1
- package/lib/user-management/session.spec.js +25 -0
- package/lib/user-management/user-management.d.ts +2 -1
- package/lib/user-management/user-management.js +7 -2
- package/lib/user-management/user-management.spec.js +10 -0
- package/lib/workos.js +1 -1
- package/package.json +1 -2
|
@@ -106,6 +106,7 @@ describe('Actions', () => {
|
|
|
106
106
|
},
|
|
107
107
|
ipAddress: '50.141.123.10',
|
|
108
108
|
userAgent: 'Mozilla/5.0',
|
|
109
|
+
deviceFingerprint: 'notafingerprint',
|
|
109
110
|
issuer: 'test',
|
|
110
111
|
object: 'authentication_action_context',
|
|
111
112
|
organization: {
|
|
@@ -150,6 +151,7 @@ describe('Actions', () => {
|
|
|
150
151
|
},
|
|
151
152
|
ipAddress: '50.141.123.10',
|
|
152
153
|
userAgent: 'Mozilla/5.0',
|
|
154
|
+
deviceFingerprint: 'notafingerprint',
|
|
153
155
|
invitation: expect.objectContaining({
|
|
154
156
|
object: 'invitation',
|
|
155
157
|
id: '01JBVZWH8HJ855YZ5BWHG1WNZN',
|
|
@@ -8,6 +8,7 @@ interface AuthenticationActionContext {
|
|
|
8
8
|
organizationMembership?: OrganizationMembership;
|
|
9
9
|
ipAddress?: string;
|
|
10
10
|
userAgent?: string;
|
|
11
|
+
deviceFingerprint?: string;
|
|
11
12
|
issuer?: string;
|
|
12
13
|
}
|
|
13
14
|
export interface UserData {
|
|
@@ -23,6 +24,7 @@ interface UserRegistrationActionContext {
|
|
|
23
24
|
invitation?: Invitation;
|
|
24
25
|
ipAddress?: string;
|
|
25
26
|
userAgent?: string;
|
|
27
|
+
deviceFingerprint?: string;
|
|
26
28
|
}
|
|
27
29
|
export type ActionContext = AuthenticationActionContext | UserRegistrationActionContext;
|
|
28
30
|
interface AuthenticationActionPayload {
|
|
@@ -33,6 +35,7 @@ interface AuthenticationActionPayload {
|
|
|
33
35
|
organization_membership?: OrganizationMembershipResponse;
|
|
34
36
|
ip_address?: string;
|
|
35
37
|
user_agent?: string;
|
|
38
|
+
device_fingerprint?: string;
|
|
36
39
|
issuer?: string;
|
|
37
40
|
}
|
|
38
41
|
export interface UserDataPayload {
|
|
@@ -48,6 +51,7 @@ export interface UserRegistrationActionPayload {
|
|
|
48
51
|
invitation?: InvitationResponse;
|
|
49
52
|
ip_address?: string;
|
|
50
53
|
user_agent?: string;
|
|
54
|
+
device_fingerprint?: string;
|
|
51
55
|
}
|
|
52
56
|
export type ActionPayload = AuthenticationActionPayload | UserRegistrationActionPayload;
|
|
53
57
|
export {};
|
|
@@ -24,6 +24,7 @@ const deserializeAction = (actionPayload) => {
|
|
|
24
24
|
: undefined,
|
|
25
25
|
ipAddress: actionPayload.ip_address,
|
|
26
26
|
userAgent: actionPayload.user_agent,
|
|
27
|
+
deviceFingerprint: actionPayload.device_fingerprint,
|
|
27
28
|
};
|
|
28
29
|
case 'authentication_action_context':
|
|
29
30
|
return {
|
|
@@ -38,6 +39,7 @@ const deserializeAction = (actionPayload) => {
|
|
|
38
39
|
: undefined,
|
|
39
40
|
ipAddress: actionPayload.ip_address,
|
|
40
41
|
userAgent: actionPayload.user_agent,
|
|
42
|
+
deviceFingerprint: actionPayload.device_fingerprint,
|
|
41
43
|
issuer: actionPayload.issuer,
|
|
42
44
|
};
|
|
43
45
|
}
|
|
@@ -31,7 +31,9 @@ export declare class Session {
|
|
|
31
31
|
*
|
|
32
32
|
* @returns The URL to redirect the user to for logging out.
|
|
33
33
|
*/
|
|
34
|
-
getLogoutUrl(
|
|
34
|
+
getLogoutUrl({ returnTo, }?: {
|
|
35
|
+
returnTo?: string;
|
|
36
|
+
}): Promise<string>;
|
|
35
37
|
private isValidJwt;
|
|
36
38
|
}
|
|
37
39
|
export {};
|
|
@@ -143,7 +143,7 @@ class Session {
|
|
|
143
143
|
*
|
|
144
144
|
* @returns The URL to redirect the user to for logging out.
|
|
145
145
|
*/
|
|
146
|
-
getLogoutUrl() {
|
|
146
|
+
getLogoutUrl({ returnTo, } = {}) {
|
|
147
147
|
return __awaiter(this, void 0, void 0, function* () {
|
|
148
148
|
const authenticationResponse = yield this.authenticate();
|
|
149
149
|
if (!authenticationResponse.authenticated) {
|
|
@@ -152,6 +152,7 @@ class Session {
|
|
|
152
152
|
}
|
|
153
153
|
return this.userManagement.getLogoutUrl({
|
|
154
154
|
sessionId: authenticationResponse.sessionId,
|
|
155
|
+
returnTo,
|
|
155
156
|
});
|
|
156
157
|
});
|
|
157
158
|
}
|
|
@@ -278,5 +278,30 @@ describe('Session', () => {
|
|
|
278
278
|
});
|
|
279
279
|
yield expect(session.getLogoutUrl()).rejects.toThrow('Failed to extract session ID for logout URL: no_session_cookie_provided');
|
|
280
280
|
}));
|
|
281
|
+
describe('when a returnTo URL is provided', () => {
|
|
282
|
+
it('returns a logout URL for the user', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
283
|
+
jest
|
|
284
|
+
.spyOn(jose, 'jwtVerify')
|
|
285
|
+
.mockResolvedValue({});
|
|
286
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
287
|
+
const sessionData = yield (0, iron_session_1.sealData)({
|
|
288
|
+
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJzdWIiOiAiMTIzNDU2Nzg5MCIsCiAgIm5hbWUiOiAiSm9obiBEb2UiLAogICJpYXQiOiAxNTE2MjM5MDIyLAogICJzaWQiOiAic2Vzc2lvbl8xMjMiLAogICJvcmdfaWQiOiAib3JnXzEyMyIsCiAgInJvbGUiOiAibWVtYmVyIiwKICAicGVybWlzc2lvbnMiOiBbInBvc3RzOmNyZWF0ZSIsICJwb3N0czpkZWxldGUiXQp9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
|
|
289
|
+
refreshToken: 'def456',
|
|
290
|
+
user: {
|
|
291
|
+
object: 'user',
|
|
292
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
293
|
+
email: 'test01@example.com',
|
|
294
|
+
},
|
|
295
|
+
}, { password: cookiePassword });
|
|
296
|
+
const session = workos.userManagement.loadSealedSession({
|
|
297
|
+
sessionData,
|
|
298
|
+
cookiePassword,
|
|
299
|
+
});
|
|
300
|
+
const url = yield session.getLogoutUrl({
|
|
301
|
+
returnTo: 'https://example.com/signed-out',
|
|
302
|
+
});
|
|
303
|
+
expect(url).toBe('https://api.workos.com/user_management/sessions/logout?session_id=session_123&return_to=https%3A%2F%2Fexample.com%2Fsigned-out');
|
|
304
|
+
}));
|
|
305
|
+
});
|
|
281
306
|
});
|
|
282
307
|
});
|
|
@@ -104,8 +104,9 @@ export declare class UserManagement {
|
|
|
104
104
|
revokeInvitation(invitationId: string): Promise<Invitation>;
|
|
105
105
|
revokeSession(payload: RevokeSessionOptions): Promise<void>;
|
|
106
106
|
getAuthorizationUrl({ connectionId, codeChallenge, codeChallengeMethod, context, clientId, domainHint, loginHint, organizationId, provider, redirectUri, state, screenHint, }: AuthorizationURLOptions): string;
|
|
107
|
-
getLogoutUrl({ sessionId }: {
|
|
107
|
+
getLogoutUrl({ sessionId, returnTo, }: {
|
|
108
108
|
sessionId: string;
|
|
109
|
+
returnTo?: string;
|
|
109
110
|
}): string;
|
|
110
111
|
/**
|
|
111
112
|
* @deprecated This method is deprecated and will be removed in a future major version.
|
|
@@ -532,11 +532,16 @@ class UserManagement {
|
|
|
532
532
|
});
|
|
533
533
|
return `${this.workos.baseURL}/user_management/authorize?${query}`;
|
|
534
534
|
}
|
|
535
|
-
getLogoutUrl({ sessionId }) {
|
|
535
|
+
getLogoutUrl({ sessionId, returnTo, }) {
|
|
536
536
|
if (!sessionId) {
|
|
537
537
|
throw new TypeError(`Incomplete arguments. Need to specify 'sessionId'.`);
|
|
538
538
|
}
|
|
539
|
-
|
|
539
|
+
const url = new URL('/user_management/sessions/logout', this.workos.baseURL);
|
|
540
|
+
url.searchParams.set('session_id', sessionId);
|
|
541
|
+
if (returnTo) {
|
|
542
|
+
url.searchParams.set('return_to', returnTo);
|
|
543
|
+
}
|
|
544
|
+
return url.toString();
|
|
540
545
|
}
|
|
541
546
|
/**
|
|
542
547
|
* @deprecated This method is deprecated and will be removed in a future major version.
|
|
@@ -1604,6 +1604,16 @@ describe('UserManagement', () => {
|
|
|
1604
1604
|
});
|
|
1605
1605
|
expect(url).toBe('https://api.workos.com/user_management/sessions/logout?session_id=123456');
|
|
1606
1606
|
});
|
|
1607
|
+
describe('when a `returnTo` is given', () => {
|
|
1608
|
+
it('includes a `return_to` in the URL', () => {
|
|
1609
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
1610
|
+
const url = workos.userManagement.getLogoutUrl({
|
|
1611
|
+
sessionId: '123456',
|
|
1612
|
+
returnTo: 'https://your-app.com/signed-out',
|
|
1613
|
+
});
|
|
1614
|
+
expect(url).toBe('https://api.workos.com/user_management/sessions/logout?session_id=123456&return_to=https%3A%2F%2Fyour-app.com%2Fsigned-out');
|
|
1615
|
+
});
|
|
1616
|
+
});
|
|
1607
1617
|
});
|
|
1608
1618
|
describe('getLogoutUrlFromSessionCookie', () => {
|
|
1609
1619
|
beforeEach(() => {
|
package/lib/workos.js
CHANGED
|
@@ -29,7 +29,7 @@ const subtle_crypto_provider_1 = require("./common/crypto/subtle-crypto-provider
|
|
|
29
29
|
const fetch_client_1 = require("./common/net/fetch-client");
|
|
30
30
|
const widgets_1 = require("./widgets/widgets");
|
|
31
31
|
const actions_1 = require("./actions/actions");
|
|
32
|
-
const VERSION = '7.
|
|
32
|
+
const VERSION = '7.37.0';
|
|
33
33
|
const DEFAULT_HOSTNAME = 'api.workos.com';
|
|
34
34
|
const HEADER_AUTHORIZATION = 'Authorization';
|
|
35
35
|
const HEADER_IDEMPOTENCY_KEY = 'Idempotency-Key';
|