@workos-inc/node 7.14.0 → 7.15.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/common/interfaces/workos-options.interface.d.ts +1 -0
- package/lib/common/net/node-client.d.ts +0 -1
- package/lib/user-management/interfaces/authenticate-with-options-base.interface.d.ts +5 -0
- package/lib/user-management/interfaces/authenticate-with-session-cookie.interface.d.ts +24 -0
- package/lib/user-management/interfaces/authenticate-with-session-cookie.interface.js +9 -0
- package/lib/user-management/interfaces/authentication-response.interface.d.ts +1 -0
- package/lib/user-management/interfaces/index.d.ts +2 -0
- package/lib/user-management/interfaces/index.js +2 -0
- package/lib/user-management/interfaces/refresh-and-seal-session-data.interface.d.ts +16 -0
- package/lib/user-management/interfaces/refresh-and-seal-session-data.interface.js +11 -0
- package/lib/user-management/interfaces/session-handler-options.interface.d.ts +4 -0
- package/lib/user-management/interfaces/session-handler-options.interface.js +2 -0
- package/lib/user-management/user-management.d.ts +20 -10
- package/lib/user-management/user-management.js +225 -47
- package/lib/user-management/user-management.spec.js +503 -5
- package/lib/workos.d.ts +1 -0
- package/lib/workos.js +5 -2
- package/package.json +4 -2
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
export interface AuthenticateWithSessionOptions {
|
|
2
|
+
cookiePassword?: string;
|
|
3
|
+
sealSession: boolean;
|
|
4
|
+
}
|
|
1
5
|
export interface AuthenticateWithOptionsBase {
|
|
2
6
|
clientId: string;
|
|
3
7
|
ipAddress?: string;
|
|
4
8
|
userAgent?: string;
|
|
9
|
+
session?: AuthenticateWithSessionOptions;
|
|
5
10
|
}
|
|
6
11
|
export interface SerializedAuthenticateWithOptionsBase {
|
|
7
12
|
client_id: string;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { AuthenticationResponse } from './authentication-response.interface';
|
|
2
|
+
export interface AccessToken {
|
|
3
|
+
sid: string;
|
|
4
|
+
org_id?: string;
|
|
5
|
+
role?: string;
|
|
6
|
+
permissions?: string[];
|
|
7
|
+
}
|
|
8
|
+
export type SessionCookieData = Pick<AuthenticationResponse, 'accessToken' | 'impersonator' | 'organizationId' | 'refreshToken' | 'user'>;
|
|
9
|
+
export declare enum AuthenticateWithSessionCookieFailureReason {
|
|
10
|
+
INVALID_JWT = "invalid_jwt",
|
|
11
|
+
INVALID_SESSION_COOKIE = "invalid_session_cookie",
|
|
12
|
+
NO_SESSION_COOKIE_PROVIDED = "no_session_cookie_provided"
|
|
13
|
+
}
|
|
14
|
+
export type AuthenticateWithSessionCookieFailedResponse = {
|
|
15
|
+
authenticated: false;
|
|
16
|
+
reason: AuthenticateWithSessionCookieFailureReason;
|
|
17
|
+
};
|
|
18
|
+
export type AuthenticateWithSessionCookieSuccessResponse = {
|
|
19
|
+
authenticated: true;
|
|
20
|
+
sessionId: string;
|
|
21
|
+
organizationId?: string;
|
|
22
|
+
role?: string;
|
|
23
|
+
permissions?: string[];
|
|
24
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthenticateWithSessionCookieFailureReason = void 0;
|
|
4
|
+
var AuthenticateWithSessionCookieFailureReason;
|
|
5
|
+
(function (AuthenticateWithSessionCookieFailureReason) {
|
|
6
|
+
AuthenticateWithSessionCookieFailureReason["INVALID_JWT"] = "invalid_jwt";
|
|
7
|
+
AuthenticateWithSessionCookieFailureReason["INVALID_SESSION_COOKIE"] = "invalid_session_cookie";
|
|
8
|
+
AuthenticateWithSessionCookieFailureReason["NO_SESSION_COOKIE_PROVIDED"] = "no_session_cookie_provided";
|
|
9
|
+
})(AuthenticateWithSessionCookieFailureReason || (exports.AuthenticateWithSessionCookieFailureReason = AuthenticateWithSessionCookieFailureReason = {}));
|
|
@@ -7,6 +7,7 @@ export * from './authenticate-with-options-base.interface';
|
|
|
7
7
|
export * from './authenticate-with-organization-selection.interface';
|
|
8
8
|
export * from './authenticate-with-password-options.interface';
|
|
9
9
|
export * from './authenticate-with-refresh-token-options.interface';
|
|
10
|
+
export * from './authenticate-with-session-cookie.interface';
|
|
10
11
|
export * from './authenticate-with-totp-options.interface';
|
|
11
12
|
export * from './authentication-response.interface';
|
|
12
13
|
export * from './create-magic-auth-options.interface';
|
|
@@ -25,6 +26,7 @@ export * from './list-users-options.interface';
|
|
|
25
26
|
export * from './magic-auth.interface';
|
|
26
27
|
export * from './organization-membership.interface';
|
|
27
28
|
export * from './password-reset.interface';
|
|
29
|
+
export * from './refresh-and-seal-session-data.interface';
|
|
28
30
|
export * from './reset-password-options.interface';
|
|
29
31
|
export * from './revoke-session-options.interface';
|
|
30
32
|
export * from './send-invitation-options.interface';
|
|
@@ -23,6 +23,7 @@ __exportStar(require("./authenticate-with-options-base.interface"), exports);
|
|
|
23
23
|
__exportStar(require("./authenticate-with-organization-selection.interface"), exports);
|
|
24
24
|
__exportStar(require("./authenticate-with-password-options.interface"), exports);
|
|
25
25
|
__exportStar(require("./authenticate-with-refresh-token-options.interface"), exports);
|
|
26
|
+
__exportStar(require("./authenticate-with-session-cookie.interface"), exports);
|
|
26
27
|
__exportStar(require("./authenticate-with-totp-options.interface"), exports);
|
|
27
28
|
__exportStar(require("./authentication-response.interface"), exports);
|
|
28
29
|
__exportStar(require("./create-magic-auth-options.interface"), exports);
|
|
@@ -41,6 +42,7 @@ __exportStar(require("./list-users-options.interface"), exports);
|
|
|
41
42
|
__exportStar(require("./magic-auth.interface"), exports);
|
|
42
43
|
__exportStar(require("./organization-membership.interface"), exports);
|
|
43
44
|
__exportStar(require("./password-reset.interface"), exports);
|
|
45
|
+
__exportStar(require("./refresh-and-seal-session-data.interface"), exports);
|
|
44
46
|
__exportStar(require("./reset-password-options.interface"), exports);
|
|
45
47
|
__exportStar(require("./revoke-session-options.interface"), exports);
|
|
46
48
|
__exportStar(require("./send-invitation-options.interface"), exports);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare enum RefreshAndSealSessionDataFailureReason {
|
|
2
|
+
INVALID_SESSION_COOKE = "invalid_session_cookie",
|
|
3
|
+
NO_SESSION_COOKIE_PROVIDED = "no_session_cookie_provided",
|
|
4
|
+
INVALID_GRANT = "invalid_grant",
|
|
5
|
+
ORGANIZATION_NOT_AUTHORIZED = "organization_not_authorized"
|
|
6
|
+
}
|
|
7
|
+
type RefreshAndSealSessionDataFailedResponse = {
|
|
8
|
+
authenticated: false;
|
|
9
|
+
reason: RefreshAndSealSessionDataFailureReason;
|
|
10
|
+
};
|
|
11
|
+
type RefreshAndSealSessionDataSuccessResponse = {
|
|
12
|
+
authenticated: true;
|
|
13
|
+
sealedSession: string;
|
|
14
|
+
};
|
|
15
|
+
export type RefreshAndSealSessionDataResponse = RefreshAndSealSessionDataFailedResponse | RefreshAndSealSessionDataSuccessResponse;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RefreshAndSealSessionDataFailureReason = void 0;
|
|
4
|
+
var RefreshAndSealSessionDataFailureReason;
|
|
5
|
+
(function (RefreshAndSealSessionDataFailureReason) {
|
|
6
|
+
RefreshAndSealSessionDataFailureReason["INVALID_SESSION_COOKE"] = "invalid_session_cookie";
|
|
7
|
+
RefreshAndSealSessionDataFailureReason["NO_SESSION_COOKIE_PROVIDED"] = "no_session_cookie_provided";
|
|
8
|
+
// API OauthErrors for refresh tokens
|
|
9
|
+
RefreshAndSealSessionDataFailureReason["INVALID_GRANT"] = "invalid_grant";
|
|
10
|
+
RefreshAndSealSessionDataFailureReason["ORGANIZATION_NOT_AUTHORIZED"] = "organization_not_authorized";
|
|
11
|
+
})(RefreshAndSealSessionDataFailureReason || (exports.RefreshAndSealSessionDataFailureReason = RefreshAndSealSessionDataFailureReason = {}));
|
|
@@ -1,22 +1,26 @@
|
|
|
1
|
-
import { WorkOS } from '../workos';
|
|
2
1
|
import { AutoPaginatable } from '../common/utils/pagination';
|
|
3
|
-
import { AuthenticateWithCodeOptions, AuthenticateWithMagicAuthOptions, AuthenticateWithPasswordOptions, AuthenticateWithTotpOptions, AuthenticationResponse, ResetPasswordOptions, SendPasswordResetEmailOptions, CreateUserOptions, EnrollAuthFactorOptions, ListAuthFactorsOptions, ListUsersOptions, SendMagicAuthCodeOptions, SendVerificationEmailOptions, UpdateUserOptions, User, VerifyEmailOptions, AuthenticateWithRefreshTokenOptions, MagicAuth, CreateMagicAuthOptions, EmailVerification, PasswordReset, CreatePasswordResetOptions } from './interfaces';
|
|
4
2
|
import { Challenge } from '../mfa/interfaces';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { CreateOrganizationMembershipOptions } from './interfaces/create-organization-membership-options.interface';
|
|
8
|
-
import { Invitation } from './interfaces/invitation.interface';
|
|
9
|
-
import { ListInvitationsOptions } from './interfaces/list-invitations-options.interface';
|
|
10
|
-
import { SendInvitationOptions } from './interfaces/send-invitation-options.interface';
|
|
11
|
-
import { AuthorizationURLOptions } from './interfaces/authorization-url-options.interface';
|
|
3
|
+
import { WorkOS } from '../workos';
|
|
4
|
+
import { AuthenticateWithCodeOptions, AuthenticateWithMagicAuthOptions, AuthenticateWithPasswordOptions, AuthenticateWithRefreshTokenOptions, AuthenticateWithTotpOptions, AuthenticationResponse, CreateMagicAuthOptions, CreatePasswordResetOptions, CreateUserOptions, EmailVerification, EnrollAuthFactorOptions, ListAuthFactorsOptions, ListUsersOptions, MagicAuth, PasswordReset, ResetPasswordOptions, SendMagicAuthCodeOptions, SendPasswordResetEmailOptions, SendVerificationEmailOptions, UpdateUserOptions, User, VerifyEmailOptions } from './interfaces';
|
|
12
5
|
import { AuthenticateWithEmailVerificationOptions } from './interfaces/authenticate-with-email-verification-options.interface';
|
|
13
6
|
import { AuthenticateWithOrganizationSelectionOptions } from './interfaces/authenticate-with-organization-selection.interface';
|
|
7
|
+
import { AuthenticateWithSessionCookieFailedResponse, AuthenticateWithSessionCookieSuccessResponse, SessionCookieData } from './interfaces/authenticate-with-session-cookie.interface';
|
|
8
|
+
import { AuthorizationURLOptions } from './interfaces/authorization-url-options.interface';
|
|
9
|
+
import { CreateOrganizationMembershipOptions } from './interfaces/create-organization-membership-options.interface';
|
|
14
10
|
import { Factor, FactorWithSecrets } from './interfaces/factor.interface';
|
|
11
|
+
import { Identity } from './interfaces/identity.interface';
|
|
12
|
+
import { Invitation } from './interfaces/invitation.interface';
|
|
13
|
+
import { ListInvitationsOptions } from './interfaces/list-invitations-options.interface';
|
|
14
|
+
import { ListOrganizationMembershipsOptions } from './interfaces/list-organization-memberships-options.interface';
|
|
15
|
+
import { OrganizationMembership } from './interfaces/organization-membership.interface';
|
|
16
|
+
import { RefreshAndSealSessionDataResponse } from './interfaces/refresh-and-seal-session-data.interface';
|
|
15
17
|
import { RevokeSessionOptions } from './interfaces/revoke-session-options.interface';
|
|
18
|
+
import { SendInvitationOptions } from './interfaces/send-invitation-options.interface';
|
|
19
|
+
import { SessionHandlerOptions } from './interfaces/session-handler-options.interface';
|
|
16
20
|
import { UpdateOrganizationMembershipOptions } from './interfaces/update-organization-membership-options.interface';
|
|
17
|
-
import { Identity } from './interfaces/identity.interface';
|
|
18
21
|
export declare class UserManagement {
|
|
19
22
|
private readonly workos;
|
|
23
|
+
private jwks;
|
|
20
24
|
constructor(workos: WorkOS);
|
|
21
25
|
getUser(userId: string): Promise<User>;
|
|
22
26
|
listUsers(options?: ListUsersOptions): Promise<AutoPaginatable<User>>;
|
|
@@ -28,6 +32,12 @@ export declare class UserManagement {
|
|
|
28
32
|
authenticateWithTotp(payload: AuthenticateWithTotpOptions): Promise<AuthenticationResponse>;
|
|
29
33
|
authenticateWithEmailVerification(payload: AuthenticateWithEmailVerificationOptions): Promise<AuthenticationResponse>;
|
|
30
34
|
authenticateWithOrganizationSelection(payload: AuthenticateWithOrganizationSelectionOptions): Promise<AuthenticationResponse>;
|
|
35
|
+
authenticateWithSessionCookie({ sessionData, cookiePassword, }: SessionHandlerOptions): Promise<AuthenticateWithSessionCookieSuccessResponse | AuthenticateWithSessionCookieFailedResponse>;
|
|
36
|
+
private isValidJwt;
|
|
37
|
+
refreshAndSealSessionData({ sessionData, cookiePassword, }: SessionHandlerOptions): Promise<RefreshAndSealSessionDataResponse>;
|
|
38
|
+
private prepareAuthenticationResponse;
|
|
39
|
+
private sealSessionDataFromAuthenticationResponse;
|
|
40
|
+
getSessionFromCookie({ sessionData, cookiePassword, }: SessionHandlerOptions): Promise<SessionCookieData | undefined>;
|
|
31
41
|
getEmailVerification(emailVerificationId: string): Promise<EmailVerification>;
|
|
32
42
|
sendVerificationEmail({ userId, }: SendVerificationEmailOptions): Promise<{
|
|
33
43
|
user: User;
|
|
@@ -21,23 +21,28 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
21
21
|
};
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
23
|
exports.UserManagement = void 0;
|
|
24
|
-
const
|
|
25
|
-
const
|
|
24
|
+
const iron_session_1 = require("iron-session");
|
|
25
|
+
const jose_1 = require("jose");
|
|
26
|
+
const oauth_exception_1 = require("../common/exceptions/oauth.exception");
|
|
26
27
|
const fetch_and_deserialize_1 = require("../common/utils/fetch-and-deserialize");
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
28
|
+
const pagination_1 = require("../common/utils/pagination");
|
|
29
|
+
const serializers_1 = require("../mfa/serializers");
|
|
30
|
+
const authenticate_with_session_cookie_interface_1 = require("./interfaces/authenticate-with-session-cookie.interface");
|
|
31
|
+
const refresh_and_seal_session_data_interface_1 = require("./interfaces/refresh-and-seal-session-data.interface");
|
|
32
|
+
const revoke_session_options_interface_1 = require("./interfaces/revoke-session-options.interface");
|
|
33
|
+
const serializers_2 = require("./serializers");
|
|
34
|
+
const authenticate_with_email_verification_serializer_1 = require("./serializers/authenticate-with-email-verification.serializer");
|
|
35
|
+
const authenticate_with_organization_selection_options_serializer_1 = require("./serializers/authenticate-with-organization-selection-options.serializer");
|
|
30
36
|
const create_organization_membership_options_serializer_1 = require("./serializers/create-organization-membership-options.serializer");
|
|
37
|
+
const factor_serializer_1 = require("./serializers/factor.serializer");
|
|
38
|
+
const identity_serializer_1 = require("./serializers/identity.serializer");
|
|
31
39
|
const invitation_serializer_1 = require("./serializers/invitation.serializer");
|
|
32
40
|
const list_invitations_options_serializer_1 = require("./serializers/list-invitations-options.serializer");
|
|
33
|
-
const
|
|
41
|
+
const list_organization_memberships_options_serializer_1 = require("./serializers/list-organization-memberships-options.serializer");
|
|
34
42
|
const list_users_options_serializer_1 = require("./serializers/list-users-options.serializer");
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const factor_serializer_1 = require("./serializers/factor.serializer");
|
|
38
|
-
const revoke_session_options_interface_1 = require("./interfaces/revoke-session-options.interface");
|
|
43
|
+
const organization_membership_serializer_1 = require("./serializers/organization-membership.serializer");
|
|
44
|
+
const send_invitation_options_serializer_1 = require("./serializers/send-invitation-options.serializer");
|
|
39
45
|
const update_organization_membership_options_serializer_1 = require("./serializers/update-organization-membership-options.serializer");
|
|
40
|
-
const identity_serializer_1 = require("./serializers/identity.serializer");
|
|
41
46
|
const toQueryString = (options) => {
|
|
42
47
|
const searchParams = new URLSearchParams();
|
|
43
48
|
const keys = Object.keys(options).sort();
|
|
@@ -52,88 +57,261 @@ const toQueryString = (options) => {
|
|
|
52
57
|
class UserManagement {
|
|
53
58
|
constructor(workos) {
|
|
54
59
|
this.workos = workos;
|
|
60
|
+
const { clientId } = workos.options;
|
|
61
|
+
// Set the JWKS URL. This is used to verify if the JWT is still valid
|
|
62
|
+
this.jwks = clientId
|
|
63
|
+
? (0, jose_1.createRemoteJWKSet)(new URL(this.getJwksUrl(clientId)))
|
|
64
|
+
: undefined;
|
|
55
65
|
}
|
|
56
66
|
getUser(userId) {
|
|
57
67
|
return __awaiter(this, void 0, void 0, function* () {
|
|
58
68
|
const { data } = yield this.workos.get(`/user_management/users/${userId}`);
|
|
59
|
-
return (0,
|
|
69
|
+
return (0, serializers_2.deserializeUser)(data);
|
|
60
70
|
});
|
|
61
71
|
}
|
|
62
72
|
listUsers(options) {
|
|
63
73
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
-
return new pagination_1.AutoPaginatable(yield (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, '/user_management/users',
|
|
74
|
+
return new pagination_1.AutoPaginatable(yield (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, '/user_management/users', serializers_2.deserializeUser, options ? (0, list_users_options_serializer_1.serializeListUsersOptions)(options) : undefined), (params) => (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, '/user_management/users', serializers_2.deserializeUser, params), options ? (0, list_users_options_serializer_1.serializeListUsersOptions)(options) : undefined);
|
|
65
75
|
});
|
|
66
76
|
}
|
|
67
77
|
createUser(payload) {
|
|
68
78
|
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
-
const { data } = yield this.workos.post('/user_management/users', (0,
|
|
70
|
-
return (0,
|
|
79
|
+
const { data } = yield this.workos.post('/user_management/users', (0, serializers_2.serializeCreateUserOptions)(payload));
|
|
80
|
+
return (0, serializers_2.deserializeUser)(data);
|
|
71
81
|
});
|
|
72
82
|
}
|
|
73
83
|
authenticateWithMagicAuth(payload) {
|
|
74
84
|
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
-
const {
|
|
76
|
-
|
|
85
|
+
const { session } = payload, remainingPayload = __rest(payload, ["session"]);
|
|
86
|
+
const { data } = yield this.workos.post('/user_management/authenticate', (0, serializers_2.serializeAuthenticateWithMagicAuthOptions)(Object.assign(Object.assign({}, remainingPayload), { clientSecret: this.workos.key })));
|
|
87
|
+
return this.prepareAuthenticationResponse({
|
|
88
|
+
authenticationResponse: (0, serializers_2.deserializeAuthenticationResponse)(data),
|
|
89
|
+
session,
|
|
90
|
+
});
|
|
77
91
|
});
|
|
78
92
|
}
|
|
79
93
|
authenticateWithPassword(payload) {
|
|
80
94
|
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
-
const {
|
|
82
|
-
|
|
95
|
+
const { session } = payload, remainingPayload = __rest(payload, ["session"]);
|
|
96
|
+
const { data } = yield this.workos.post('/user_management/authenticate', (0, serializers_2.serializeAuthenticateWithPasswordOptions)(Object.assign(Object.assign({}, remainingPayload), { clientSecret: this.workos.key })));
|
|
97
|
+
return this.prepareAuthenticationResponse({
|
|
98
|
+
authenticationResponse: (0, serializers_2.deserializeAuthenticationResponse)(data),
|
|
99
|
+
session,
|
|
100
|
+
});
|
|
83
101
|
});
|
|
84
102
|
}
|
|
85
103
|
authenticateWithCode(payload) {
|
|
86
104
|
return __awaiter(this, void 0, void 0, function* () {
|
|
87
|
-
const {
|
|
88
|
-
|
|
105
|
+
const { session } = payload, remainingPayload = __rest(payload, ["session"]);
|
|
106
|
+
const { data } = yield this.workos.post('/user_management/authenticate', (0, serializers_2.serializeAuthenticateWithCodeOptions)(Object.assign(Object.assign({}, remainingPayload), { clientSecret: this.workos.key })));
|
|
107
|
+
return this.prepareAuthenticationResponse({
|
|
108
|
+
authenticationResponse: (0, serializers_2.deserializeAuthenticationResponse)(data),
|
|
109
|
+
session,
|
|
110
|
+
});
|
|
89
111
|
});
|
|
90
112
|
}
|
|
91
113
|
authenticateWithRefreshToken(payload) {
|
|
92
114
|
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
-
const {
|
|
94
|
-
|
|
115
|
+
const { session } = payload, remainingPayload = __rest(payload, ["session"]);
|
|
116
|
+
const { data } = yield this.workos.post('/user_management/authenticate', (0, serializers_2.serializeAuthenticateWithRefreshTokenOptions)(Object.assign(Object.assign({}, remainingPayload), { clientSecret: this.workos.key })));
|
|
117
|
+
return this.prepareAuthenticationResponse({
|
|
118
|
+
authenticationResponse: (0, serializers_2.deserializeAuthenticationResponse)(data),
|
|
119
|
+
session,
|
|
120
|
+
});
|
|
95
121
|
});
|
|
96
122
|
}
|
|
97
123
|
authenticateWithTotp(payload) {
|
|
98
124
|
return __awaiter(this, void 0, void 0, function* () {
|
|
99
|
-
const {
|
|
100
|
-
|
|
125
|
+
const { session } = payload, remainingPayload = __rest(payload, ["session"]);
|
|
126
|
+
const { data } = yield this.workos.post('/user_management/authenticate', (0, serializers_2.serializeAuthenticateWithTotpOptions)(Object.assign(Object.assign({}, remainingPayload), { clientSecret: this.workos.key })));
|
|
127
|
+
return this.prepareAuthenticationResponse({
|
|
128
|
+
authenticationResponse: (0, serializers_2.deserializeAuthenticationResponse)(data),
|
|
129
|
+
session,
|
|
130
|
+
});
|
|
101
131
|
});
|
|
102
132
|
}
|
|
103
133
|
authenticateWithEmailVerification(payload) {
|
|
104
134
|
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
-
const {
|
|
106
|
-
|
|
135
|
+
const { session } = payload, remainingPayload = __rest(payload, ["session"]);
|
|
136
|
+
const { data } = yield this.workos.post('/user_management/authenticate', (0, authenticate_with_email_verification_serializer_1.serializeAuthenticateWithEmailVerificationOptions)(Object.assign(Object.assign({}, remainingPayload), { clientSecret: this.workos.key })));
|
|
137
|
+
return this.prepareAuthenticationResponse({
|
|
138
|
+
authenticationResponse: (0, serializers_2.deserializeAuthenticationResponse)(data),
|
|
139
|
+
session,
|
|
140
|
+
});
|
|
107
141
|
});
|
|
108
142
|
}
|
|
109
143
|
authenticateWithOrganizationSelection(payload) {
|
|
110
144
|
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
-
const {
|
|
112
|
-
|
|
145
|
+
const { session } = payload, remainingPayload = __rest(payload, ["session"]);
|
|
146
|
+
const { data } = yield this.workos.post('/user_management/authenticate', (0, authenticate_with_organization_selection_options_serializer_1.serializeAuthenticateWithOrganizationSelectionOptions)(Object.assign(Object.assign({}, remainingPayload), { clientSecret: this.workos.key })));
|
|
147
|
+
return this.prepareAuthenticationResponse({
|
|
148
|
+
authenticationResponse: (0, serializers_2.deserializeAuthenticationResponse)(data),
|
|
149
|
+
session,
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
authenticateWithSessionCookie({ sessionData, cookiePassword = process.env.WORKOS_COOKIE_PASSWORD, }) {
|
|
154
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
155
|
+
if (!cookiePassword) {
|
|
156
|
+
throw new Error('Cookie password is required');
|
|
157
|
+
}
|
|
158
|
+
if (!this.jwks) {
|
|
159
|
+
throw new Error('Must provide clientId to initialize JWKS');
|
|
160
|
+
}
|
|
161
|
+
if (!sessionData) {
|
|
162
|
+
return {
|
|
163
|
+
authenticated: false,
|
|
164
|
+
reason: authenticate_with_session_cookie_interface_1.AuthenticateWithSessionCookieFailureReason.NO_SESSION_COOKIE_PROVIDED,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const session = yield (0, iron_session_1.unsealData)(sessionData, {
|
|
168
|
+
password: cookiePassword,
|
|
169
|
+
});
|
|
170
|
+
if (!session.accessToken) {
|
|
171
|
+
return {
|
|
172
|
+
authenticated: false,
|
|
173
|
+
reason: authenticate_with_session_cookie_interface_1.AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
if (!(yield this.isValidJwt(session.accessToken))) {
|
|
177
|
+
return {
|
|
178
|
+
authenticated: false,
|
|
179
|
+
reason: authenticate_with_session_cookie_interface_1.AuthenticateWithSessionCookieFailureReason.INVALID_JWT,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
const { sid: sessionId, org_id: organizationId, role, permissions, } = (0, jose_1.decodeJwt)(session.accessToken);
|
|
183
|
+
return {
|
|
184
|
+
authenticated: true,
|
|
185
|
+
sessionId,
|
|
186
|
+
organizationId,
|
|
187
|
+
role,
|
|
188
|
+
permissions,
|
|
189
|
+
};
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
isValidJwt(accessToken) {
|
|
193
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
194
|
+
if (!this.jwks) {
|
|
195
|
+
throw new Error('Must provide clientId to initialize JWKS');
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
yield (0, jose_1.jwtVerify)(accessToken, this.jwks);
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
catch (e) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
refreshAndSealSessionData({ sessionData, cookiePassword = process.env.WORKOS_COOKIE_PASSWORD, }) {
|
|
207
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
208
|
+
if (!cookiePassword) {
|
|
209
|
+
throw new Error('Cookie password is required');
|
|
210
|
+
}
|
|
211
|
+
if (!sessionData) {
|
|
212
|
+
return {
|
|
213
|
+
authenticated: false,
|
|
214
|
+
reason: refresh_and_seal_session_data_interface_1.RefreshAndSealSessionDataFailureReason.NO_SESSION_COOKIE_PROVIDED,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
const session = yield (0, iron_session_1.unsealData)(sessionData, {
|
|
218
|
+
password: cookiePassword,
|
|
219
|
+
});
|
|
220
|
+
if (!session.refreshToken || !session.user) {
|
|
221
|
+
return {
|
|
222
|
+
authenticated: false,
|
|
223
|
+
reason: refresh_and_seal_session_data_interface_1.RefreshAndSealSessionDataFailureReason.INVALID_SESSION_COOKE,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
const { sealedSession } = yield this.authenticateWithRefreshToken({
|
|
228
|
+
clientId: this.workos.clientId,
|
|
229
|
+
refreshToken: session.refreshToken,
|
|
230
|
+
session: { sealSession: true, cookiePassword },
|
|
231
|
+
});
|
|
232
|
+
if (!sealedSession) {
|
|
233
|
+
return {
|
|
234
|
+
authenticated: false,
|
|
235
|
+
reason: refresh_and_seal_session_data_interface_1.RefreshAndSealSessionDataFailureReason.INVALID_SESSION_COOKE,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
return { authenticated: true, sealedSession };
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
if (error instanceof oauth_exception_1.OauthException &&
|
|
242
|
+
// TODO: Add additional known errors and remove re-throw
|
|
243
|
+
(error.error === refresh_and_seal_session_data_interface_1.RefreshAndSealSessionDataFailureReason.INVALID_GRANT ||
|
|
244
|
+
error.error ===
|
|
245
|
+
refresh_and_seal_session_data_interface_1.RefreshAndSealSessionDataFailureReason.ORGANIZATION_NOT_AUTHORIZED)) {
|
|
246
|
+
return {
|
|
247
|
+
authenticated: false,
|
|
248
|
+
reason: error.error,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
throw error;
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
prepareAuthenticationResponse({ authenticationResponse, session, }) {
|
|
256
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
257
|
+
if (session) {
|
|
258
|
+
return Object.assign(Object.assign({}, authenticationResponse), { sealedSession: yield this.sealSessionDataFromAuthenticationResponse({
|
|
259
|
+
authenticationResponse,
|
|
260
|
+
cookiePassword: session.cookiePassword,
|
|
261
|
+
}) });
|
|
262
|
+
}
|
|
263
|
+
return authenticationResponse;
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
sealSessionDataFromAuthenticationResponse({ authenticationResponse, cookiePassword, }) {
|
|
267
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
268
|
+
if (!cookiePassword) {
|
|
269
|
+
throw new Error('Cookie password is required');
|
|
270
|
+
}
|
|
271
|
+
const sessionData = {
|
|
272
|
+
user: authenticationResponse.user,
|
|
273
|
+
accessToken: authenticationResponse.accessToken,
|
|
274
|
+
refreshToken: authenticationResponse.refreshToken,
|
|
275
|
+
impersonator: authenticationResponse.impersonator,
|
|
276
|
+
};
|
|
277
|
+
return (0, iron_session_1.sealData)(sessionData, { password: cookiePassword });
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
getSessionFromCookie({ sessionData, cookiePassword = process.env.WORKOS_COOKIE_PASSWORD, }) {
|
|
281
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
282
|
+
if (!cookiePassword) {
|
|
283
|
+
throw new Error('Cookie password is required');
|
|
284
|
+
}
|
|
285
|
+
if (sessionData) {
|
|
286
|
+
return (0, iron_session_1.unsealData)(sessionData, {
|
|
287
|
+
password: cookiePassword,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
return undefined;
|
|
113
291
|
});
|
|
114
292
|
}
|
|
115
293
|
getEmailVerification(emailVerificationId) {
|
|
116
294
|
return __awaiter(this, void 0, void 0, function* () {
|
|
117
295
|
const { data } = yield this.workos.get(`/user_management/email_verification/${emailVerificationId}`);
|
|
118
|
-
return (0,
|
|
296
|
+
return (0, serializers_2.deserializeEmailVerification)(data);
|
|
119
297
|
});
|
|
120
298
|
}
|
|
121
299
|
sendVerificationEmail({ userId, }) {
|
|
122
300
|
return __awaiter(this, void 0, void 0, function* () {
|
|
123
301
|
const { data } = yield this.workos.post(`/user_management/users/${userId}/email_verification/send`, {});
|
|
124
|
-
return { user: (0,
|
|
302
|
+
return { user: (0, serializers_2.deserializeUser)(data.user) };
|
|
125
303
|
});
|
|
126
304
|
}
|
|
127
305
|
getMagicAuth(magicAuthId) {
|
|
128
306
|
return __awaiter(this, void 0, void 0, function* () {
|
|
129
307
|
const { data } = yield this.workos.get(`/user_management/magic_auth/${magicAuthId}`);
|
|
130
|
-
return (0,
|
|
308
|
+
return (0, serializers_2.deserializeMagicAuth)(data);
|
|
131
309
|
});
|
|
132
310
|
}
|
|
133
311
|
createMagicAuth(options) {
|
|
134
312
|
return __awaiter(this, void 0, void 0, function* () {
|
|
135
|
-
const { data } = yield this.workos.post('/user_management/magic_auth', (0,
|
|
136
|
-
return (0,
|
|
313
|
+
const { data } = yield this.workos.post('/user_management/magic_auth', (0, serializers_2.serializeCreateMagicAuthOptions)(Object.assign({}, options)));
|
|
314
|
+
return (0, serializers_2.deserializeMagicAuth)(data);
|
|
137
315
|
});
|
|
138
316
|
}
|
|
139
317
|
/**
|
|
@@ -141,7 +319,7 @@ class UserManagement {
|
|
|
141
319
|
*/
|
|
142
320
|
sendMagicAuthCode(options) {
|
|
143
321
|
return __awaiter(this, void 0, void 0, function* () {
|
|
144
|
-
yield this.workos.post('/user_management/magic_auth/send', (0,
|
|
322
|
+
yield this.workos.post('/user_management/magic_auth/send', (0, serializers_2.serializeSendMagicAuthCodeOptions)(options));
|
|
145
323
|
});
|
|
146
324
|
}
|
|
147
325
|
verifyEmail({ code, userId, }) {
|
|
@@ -149,19 +327,19 @@ class UserManagement {
|
|
|
149
327
|
const { data } = yield this.workos.post(`/user_management/users/${userId}/email_verification/confirm`, {
|
|
150
328
|
code,
|
|
151
329
|
});
|
|
152
|
-
return { user: (0,
|
|
330
|
+
return { user: (0, serializers_2.deserializeUser)(data.user) };
|
|
153
331
|
});
|
|
154
332
|
}
|
|
155
333
|
getPasswordReset(passwordResetId) {
|
|
156
334
|
return __awaiter(this, void 0, void 0, function* () {
|
|
157
335
|
const { data } = yield this.workos.get(`/user_management/password_reset/${passwordResetId}`);
|
|
158
|
-
return (0,
|
|
336
|
+
return (0, serializers_2.deserializePasswordReset)(data);
|
|
159
337
|
});
|
|
160
338
|
}
|
|
161
339
|
createPasswordReset(options) {
|
|
162
340
|
return __awaiter(this, void 0, void 0, function* () {
|
|
163
|
-
const { data } = yield this.workos.post('/user_management/password_reset', (0,
|
|
164
|
-
return (0,
|
|
341
|
+
const { data } = yield this.workos.post('/user_management/password_reset', (0, serializers_2.serializeCreatePasswordResetOptions)(Object.assign({}, options)));
|
|
342
|
+
return (0, serializers_2.deserializePasswordReset)(data);
|
|
165
343
|
});
|
|
166
344
|
}
|
|
167
345
|
/**
|
|
@@ -169,27 +347,27 @@ class UserManagement {
|
|
|
169
347
|
*/
|
|
170
348
|
sendPasswordResetEmail(payload) {
|
|
171
349
|
return __awaiter(this, void 0, void 0, function* () {
|
|
172
|
-
yield this.workos.post('/user_management/password_reset/send', (0,
|
|
350
|
+
yield this.workos.post('/user_management/password_reset/send', (0, serializers_2.serializeSendPasswordResetEmailOptions)(payload));
|
|
173
351
|
});
|
|
174
352
|
}
|
|
175
353
|
resetPassword(payload) {
|
|
176
354
|
return __awaiter(this, void 0, void 0, function* () {
|
|
177
|
-
const { data } = yield this.workos.post('/user_management/password_reset/confirm', (0,
|
|
178
|
-
return { user: (0,
|
|
355
|
+
const { data } = yield this.workos.post('/user_management/password_reset/confirm', (0, serializers_2.serializeResetPasswordOptions)(payload));
|
|
356
|
+
return { user: (0, serializers_2.deserializeUser)(data.user) };
|
|
179
357
|
});
|
|
180
358
|
}
|
|
181
359
|
updateUser(payload) {
|
|
182
360
|
return __awaiter(this, void 0, void 0, function* () {
|
|
183
|
-
const { data } = yield this.workos.put(`/user_management/users/${payload.userId}`, (0,
|
|
184
|
-
return (0,
|
|
361
|
+
const { data } = yield this.workos.put(`/user_management/users/${payload.userId}`, (0, serializers_2.serializeUpdateUserOptions)(payload));
|
|
362
|
+
return (0, serializers_2.deserializeUser)(data);
|
|
185
363
|
});
|
|
186
364
|
}
|
|
187
365
|
enrollAuthFactor(payload) {
|
|
188
366
|
return __awaiter(this, void 0, void 0, function* () {
|
|
189
|
-
const { data } = yield this.workos.post(`/user_management/users/${payload.userId}/auth_factors`, (0,
|
|
367
|
+
const { data } = yield this.workos.post(`/user_management/users/${payload.userId}/auth_factors`, (0, serializers_2.serializeEnrollAuthFactorOptions)(payload));
|
|
190
368
|
return {
|
|
191
|
-
authenticationFactor: (0,
|
|
192
|
-
authenticationChallenge: (0,
|
|
369
|
+
authenticationFactor: (0, serializers_2.deserializeFactorWithSecrets)(data.authentication_factor),
|
|
370
|
+
authenticationChallenge: (0, serializers_1.deserializeChallenge)(data.authentication_challenge),
|
|
193
371
|
};
|
|
194
372
|
});
|
|
195
373
|
}
|
|
@@ -1,4 +1,27 @@
|
|
|
1
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
|
+
};
|
|
2
25
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
26
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
27
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -27,7 +50,8 @@ const organization_membership_json_1 = __importDefault(require("./fixtures/organ
|
|
|
27
50
|
const password_reset_json_1 = __importDefault(require("./fixtures/password_reset.json"));
|
|
28
51
|
const user_json_1 = __importDefault(require("./fixtures/user.json"));
|
|
29
52
|
const identity_json_1 = __importDefault(require("./fixtures/identity.json"));
|
|
30
|
-
const
|
|
53
|
+
const jose = __importStar(require("jose"));
|
|
54
|
+
const iron_session_1 = require("iron-session");
|
|
31
55
|
const userId = 'user_01H5JQDV7R7ATEYZDEG0W5PRYS';
|
|
32
56
|
const organizationMembershipId = 'om_01H5JQDV7R7ATEYZDEG0W5PRYS';
|
|
33
57
|
const emailVerificationId = 'email_verification_01H5JQDV7R7ATEYZDEG0W5PRYS';
|
|
@@ -36,6 +60,13 @@ const invitationToken = 'Z1uX3RbwcIl5fIGJJJCXXisdI';
|
|
|
36
60
|
const magicAuthId = 'magic_auth_01H5JQDV7R7ATEYZDEG0W5PRYS';
|
|
37
61
|
const passwordResetId = 'password_reset_01H5JQDV7R7ATEYZDEG0W5PRYS';
|
|
38
62
|
describe('UserManagement', () => {
|
|
63
|
+
let workos;
|
|
64
|
+
beforeAll(() => {
|
|
65
|
+
workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU', {
|
|
66
|
+
apiHostname: 'api.workos.test',
|
|
67
|
+
clientId: 'proj_123',
|
|
68
|
+
});
|
|
69
|
+
});
|
|
39
70
|
beforeEach(() => jest_fetch_mock_1.default.resetMocks());
|
|
40
71
|
describe('getUser', () => {
|
|
41
72
|
it('sends a Get User request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -127,8 +158,45 @@ describe('UserManagement', () => {
|
|
|
127
158
|
},
|
|
128
159
|
});
|
|
129
160
|
}));
|
|
161
|
+
describe('when sealSession = true', () => {
|
|
162
|
+
beforeEach(() => {
|
|
163
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
164
|
+
});
|
|
165
|
+
describe('when the cookie password is undefined', () => {
|
|
166
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
167
|
+
yield expect(workos.userManagement.authenticateWithMagicAuth({
|
|
168
|
+
clientId: 'proj_whatever',
|
|
169
|
+
code: '123456',
|
|
170
|
+
email: user_json_1.default.email,
|
|
171
|
+
session: { sealSession: true },
|
|
172
|
+
})).rejects.toThrow('Cookie password is required');
|
|
173
|
+
}));
|
|
174
|
+
});
|
|
175
|
+
describe('when successfully authenticated', () => {
|
|
176
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
177
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
178
|
+
const response = yield workos.userManagement.authenticateWithMagicAuth({
|
|
179
|
+
clientId: 'proj_whatever',
|
|
180
|
+
code: '123456',
|
|
181
|
+
email: user_json_1.default.email,
|
|
182
|
+
session: { sealSession: true, cookiePassword },
|
|
183
|
+
});
|
|
184
|
+
expect(response).toEqual({
|
|
185
|
+
sealedSession: expect.any(String),
|
|
186
|
+
accessToken: undefined,
|
|
187
|
+
authenticationMethod: undefined,
|
|
188
|
+
impersonator: undefined,
|
|
189
|
+
organizationId: undefined,
|
|
190
|
+
refreshToken: undefined,
|
|
191
|
+
user: expect.objectContaining({
|
|
192
|
+
email: 'test01@example.com',
|
|
193
|
+
}),
|
|
194
|
+
});
|
|
195
|
+
}));
|
|
196
|
+
});
|
|
197
|
+
});
|
|
130
198
|
});
|
|
131
|
-
describe('
|
|
199
|
+
describe('authenticateWithPassword', () => {
|
|
132
200
|
it('sends an password authentication request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
133
201
|
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
134
202
|
const resp = yield workos.userManagement.authenticateWithPassword({
|
|
@@ -143,8 +211,45 @@ describe('UserManagement', () => {
|
|
|
143
211
|
},
|
|
144
212
|
});
|
|
145
213
|
}));
|
|
214
|
+
describe('when sealSession = true', () => {
|
|
215
|
+
beforeEach(() => {
|
|
216
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
217
|
+
});
|
|
218
|
+
describe('when the cookie password is undefined', () => {
|
|
219
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
220
|
+
yield expect(workos.userManagement.authenticateWithPassword({
|
|
221
|
+
clientId: 'proj_whatever',
|
|
222
|
+
email: 'test01@example.com',
|
|
223
|
+
password: 'extra-secure',
|
|
224
|
+
session: { sealSession: true },
|
|
225
|
+
})).rejects.toThrow('Cookie password is required');
|
|
226
|
+
}));
|
|
227
|
+
});
|
|
228
|
+
describe('when successfully authenticated', () => {
|
|
229
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
230
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
231
|
+
const response = yield workos.userManagement.authenticateWithPassword({
|
|
232
|
+
clientId: 'proj_whatever',
|
|
233
|
+
email: 'test01@example.com',
|
|
234
|
+
password: 'extra-secure',
|
|
235
|
+
session: { sealSession: true, cookiePassword },
|
|
236
|
+
});
|
|
237
|
+
expect(response).toEqual({
|
|
238
|
+
sealedSession: expect.any(String),
|
|
239
|
+
accessToken: undefined,
|
|
240
|
+
authenticationMethod: undefined,
|
|
241
|
+
impersonator: undefined,
|
|
242
|
+
organizationId: undefined,
|
|
243
|
+
refreshToken: undefined,
|
|
244
|
+
user: expect.objectContaining({
|
|
245
|
+
email: 'test01@example.com',
|
|
246
|
+
}),
|
|
247
|
+
});
|
|
248
|
+
}));
|
|
249
|
+
});
|
|
250
|
+
});
|
|
146
251
|
});
|
|
147
|
-
describe('
|
|
252
|
+
describe('authenticateWithCode', () => {
|
|
148
253
|
it('sends a token authentication request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
149
254
|
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
150
255
|
const resp = yield workos.userManagement.authenticateWithCode({
|
|
@@ -225,6 +330,41 @@ describe('UserManagement', () => {
|
|
|
225
330
|
});
|
|
226
331
|
}));
|
|
227
332
|
});
|
|
333
|
+
describe('when sealSession = true', () => {
|
|
334
|
+
beforeEach(() => {
|
|
335
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
336
|
+
});
|
|
337
|
+
describe('when the cookie password is undefined', () => {
|
|
338
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
339
|
+
yield expect(workos.userManagement.authenticateWithCode({
|
|
340
|
+
clientId: 'proj_whatever',
|
|
341
|
+
code: 'or this',
|
|
342
|
+
session: { sealSession: true },
|
|
343
|
+
})).rejects.toThrow('Cookie password is required');
|
|
344
|
+
}));
|
|
345
|
+
});
|
|
346
|
+
describe('when successfully authenticated', () => {
|
|
347
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
348
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
349
|
+
const response = yield workos.userManagement.authenticateWithCode({
|
|
350
|
+
clientId: 'proj_whatever',
|
|
351
|
+
code: 'or this',
|
|
352
|
+
session: { sealSession: true, cookiePassword },
|
|
353
|
+
});
|
|
354
|
+
expect(response).toEqual({
|
|
355
|
+
sealedSession: expect.any(String),
|
|
356
|
+
accessToken: undefined,
|
|
357
|
+
authenticationMethod: undefined,
|
|
358
|
+
impersonator: undefined,
|
|
359
|
+
organizationId: undefined,
|
|
360
|
+
refreshToken: undefined,
|
|
361
|
+
user: expect.objectContaining({
|
|
362
|
+
email: 'test01@example.com',
|
|
363
|
+
}),
|
|
364
|
+
});
|
|
365
|
+
}));
|
|
366
|
+
});
|
|
367
|
+
});
|
|
228
368
|
});
|
|
229
369
|
describe('authenticateWithRefreshToken', () => {
|
|
230
370
|
it('sends a refresh_token authentication request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -249,8 +389,43 @@ describe('UserManagement', () => {
|
|
|
249
389
|
refreshToken: 'refreshToken2',
|
|
250
390
|
});
|
|
251
391
|
}));
|
|
392
|
+
describe('when sealSession = true', () => {
|
|
393
|
+
beforeEach(() => {
|
|
394
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
395
|
+
});
|
|
396
|
+
describe('when the cookie password is undefined', () => {
|
|
397
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
398
|
+
yield expect(workos.userManagement.authenticateWithRefreshToken({
|
|
399
|
+
clientId: 'proj_whatever',
|
|
400
|
+
refreshToken: 'refresh_token1',
|
|
401
|
+
session: { sealSession: true },
|
|
402
|
+
})).rejects.toThrow('Cookie password is required');
|
|
403
|
+
}));
|
|
404
|
+
});
|
|
405
|
+
describe('when successfully authenticated', () => {
|
|
406
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
407
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
408
|
+
const response = yield workos.userManagement.authenticateWithRefreshToken({
|
|
409
|
+
clientId: 'proj_whatever',
|
|
410
|
+
refreshToken: 'refresh_token1',
|
|
411
|
+
session: { sealSession: true, cookiePassword },
|
|
412
|
+
});
|
|
413
|
+
expect(response).toEqual({
|
|
414
|
+
sealedSession: expect.any(String),
|
|
415
|
+
accessToken: undefined,
|
|
416
|
+
authenticationMethod: undefined,
|
|
417
|
+
impersonator: undefined,
|
|
418
|
+
organizationId: undefined,
|
|
419
|
+
refreshToken: undefined,
|
|
420
|
+
user: expect.objectContaining({
|
|
421
|
+
email: 'test01@example.com',
|
|
422
|
+
}),
|
|
423
|
+
});
|
|
424
|
+
}));
|
|
425
|
+
});
|
|
426
|
+
});
|
|
252
427
|
});
|
|
253
|
-
describe('
|
|
428
|
+
describe('authenticateWithTotp', () => {
|
|
254
429
|
it('sends a token authentication request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
255
430
|
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
256
431
|
const resp = yield workos.userManagement.authenticateWithTotp({
|
|
@@ -274,8 +449,47 @@ describe('UserManagement', () => {
|
|
|
274
449
|
},
|
|
275
450
|
});
|
|
276
451
|
}));
|
|
452
|
+
describe('when sealSession = true', () => {
|
|
453
|
+
beforeEach(() => {
|
|
454
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
455
|
+
});
|
|
456
|
+
describe('when the cookie password is undefined', () => {
|
|
457
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
458
|
+
yield expect(workos.userManagement.authenticateWithTotp({
|
|
459
|
+
clientId: 'proj_whatever',
|
|
460
|
+
code: 'or this',
|
|
461
|
+
authenticationChallengeId: 'auth_challenge_01H96FETXGTW1QMBSBT2T36PW0',
|
|
462
|
+
pendingAuthenticationToken: 'cTDQJTTkTkkVYxQUlKBIxEsFs',
|
|
463
|
+
session: { sealSession: true },
|
|
464
|
+
})).rejects.toThrow('Cookie password is required');
|
|
465
|
+
}));
|
|
466
|
+
});
|
|
467
|
+
describe('when successfully authenticated', () => {
|
|
468
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
469
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
470
|
+
const response = yield workos.userManagement.authenticateWithTotp({
|
|
471
|
+
clientId: 'proj_whatever',
|
|
472
|
+
code: 'or this',
|
|
473
|
+
authenticationChallengeId: 'auth_challenge_01H96FETXGTW1QMBSBT2T36PW0',
|
|
474
|
+
pendingAuthenticationToken: 'cTDQJTTkTkkVYxQUlKBIxEsFs',
|
|
475
|
+
session: { sealSession: true, cookiePassword },
|
|
476
|
+
});
|
|
477
|
+
expect(response).toEqual({
|
|
478
|
+
sealedSession: expect.any(String),
|
|
479
|
+
accessToken: undefined,
|
|
480
|
+
authenticationMethod: undefined,
|
|
481
|
+
impersonator: undefined,
|
|
482
|
+
organizationId: undefined,
|
|
483
|
+
refreshToken: undefined,
|
|
484
|
+
user: expect.objectContaining({
|
|
485
|
+
email: 'test01@example.com',
|
|
486
|
+
}),
|
|
487
|
+
});
|
|
488
|
+
}));
|
|
489
|
+
});
|
|
490
|
+
});
|
|
277
491
|
});
|
|
278
|
-
describe('
|
|
492
|
+
describe('authenticateWithEmailVerification', () => {
|
|
279
493
|
it('sends an email verification authentication request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
280
494
|
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
281
495
|
const resp = yield workos.userManagement.authenticateWithEmailVerification({
|
|
@@ -297,6 +511,43 @@ describe('UserManagement', () => {
|
|
|
297
511
|
},
|
|
298
512
|
});
|
|
299
513
|
}));
|
|
514
|
+
describe('when sealSession = true', () => {
|
|
515
|
+
beforeEach(() => {
|
|
516
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
517
|
+
});
|
|
518
|
+
describe('when the cookie password is undefined', () => {
|
|
519
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
520
|
+
yield expect(workos.userManagement.authenticateWithEmailVerification({
|
|
521
|
+
clientId: 'proj_whatever',
|
|
522
|
+
code: 'or this',
|
|
523
|
+
pendingAuthenticationToken: 'cTDQJTTkTkkVYxQUlKBIxEsFs',
|
|
524
|
+
session: { sealSession: true },
|
|
525
|
+
})).rejects.toThrow('Cookie password is required');
|
|
526
|
+
}));
|
|
527
|
+
});
|
|
528
|
+
describe('when successfully authenticated', () => {
|
|
529
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
530
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
531
|
+
const response = yield workos.userManagement.authenticateWithEmailVerification({
|
|
532
|
+
clientId: 'proj_whatever',
|
|
533
|
+
code: 'or this',
|
|
534
|
+
pendingAuthenticationToken: 'cTDQJTTkTkkVYxQUlKBIxEsFs',
|
|
535
|
+
session: { sealSession: true, cookiePassword },
|
|
536
|
+
});
|
|
537
|
+
expect(response).toEqual({
|
|
538
|
+
sealedSession: expect.any(String),
|
|
539
|
+
accessToken: undefined,
|
|
540
|
+
authenticationMethod: undefined,
|
|
541
|
+
impersonator: undefined,
|
|
542
|
+
organizationId: undefined,
|
|
543
|
+
refreshToken: undefined,
|
|
544
|
+
user: expect.objectContaining({
|
|
545
|
+
email: 'test01@example.com',
|
|
546
|
+
}),
|
|
547
|
+
});
|
|
548
|
+
}));
|
|
549
|
+
});
|
|
550
|
+
});
|
|
300
551
|
});
|
|
301
552
|
describe('authenticateWithOrganizationSelection', () => {
|
|
302
553
|
it('sends an Organization Selection Authentication request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -320,6 +571,253 @@ describe('UserManagement', () => {
|
|
|
320
571
|
},
|
|
321
572
|
});
|
|
322
573
|
}));
|
|
574
|
+
describe('when sealSession = true', () => {
|
|
575
|
+
beforeEach(() => {
|
|
576
|
+
(0, test_utils_1.fetchOnce)({ user: user_json_1.default });
|
|
577
|
+
});
|
|
578
|
+
describe('when the cookie password is undefined', () => {
|
|
579
|
+
it('throws an error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
580
|
+
yield expect(workos.userManagement.authenticateWithOrganizationSelection({
|
|
581
|
+
clientId: 'proj_whatever',
|
|
582
|
+
pendingAuthenticationToken: 'cTDQJTTkTkkVYxQUlKBIxEsFs',
|
|
583
|
+
organizationId: 'org_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
584
|
+
session: { sealSession: true },
|
|
585
|
+
})).rejects.toThrow('Cookie password is required');
|
|
586
|
+
}));
|
|
587
|
+
});
|
|
588
|
+
describe('when successfully authenticated', () => {
|
|
589
|
+
it('returns the sealed session data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
590
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
591
|
+
const response = yield workos.userManagement.authenticateWithOrganizationSelection({
|
|
592
|
+
clientId: 'proj_whatever',
|
|
593
|
+
pendingAuthenticationToken: 'cTDQJTTkTkkVYxQUlKBIxEsFs',
|
|
594
|
+
organizationId: 'org_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
595
|
+
session: { sealSession: true, cookiePassword },
|
|
596
|
+
});
|
|
597
|
+
expect(response).toEqual({
|
|
598
|
+
sealedSession: expect.any(String),
|
|
599
|
+
accessToken: undefined,
|
|
600
|
+
authenticationMethod: undefined,
|
|
601
|
+
impersonator: undefined,
|
|
602
|
+
organizationId: undefined,
|
|
603
|
+
refreshToken: undefined,
|
|
604
|
+
user: expect.objectContaining({
|
|
605
|
+
email: 'test01@example.com',
|
|
606
|
+
}),
|
|
607
|
+
});
|
|
608
|
+
}));
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
});
|
|
612
|
+
describe('authenticateWithSessionCookie', () => {
|
|
613
|
+
beforeEach(() => {
|
|
614
|
+
// Mock createRemoteJWKSet
|
|
615
|
+
jest
|
|
616
|
+
.spyOn(jose, 'createRemoteJWKSet')
|
|
617
|
+
.mockImplementation((_url, _options) => {
|
|
618
|
+
// This function simulates the token verification process
|
|
619
|
+
const verifyFunction = (_protectedHeader, _token) => {
|
|
620
|
+
return Promise.resolve({
|
|
621
|
+
type: 'public',
|
|
622
|
+
});
|
|
623
|
+
};
|
|
624
|
+
// Return an object that includes the verify function and the additional expected properties
|
|
625
|
+
return {
|
|
626
|
+
__call__: verifyFunction,
|
|
627
|
+
coolingDown: false,
|
|
628
|
+
fresh: false,
|
|
629
|
+
reloading: false,
|
|
630
|
+
reload: jest.fn().mockResolvedValue(undefined),
|
|
631
|
+
jwks: () => undefined,
|
|
632
|
+
};
|
|
633
|
+
});
|
|
634
|
+
});
|
|
635
|
+
it('throws an error when the cookie password is undefined', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
636
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
637
|
+
sessionData: 'session_cookie',
|
|
638
|
+
})).rejects.toThrow('Cookie password is required');
|
|
639
|
+
}));
|
|
640
|
+
it('returns authenticated = false when the session cookie is empty', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
641
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
642
|
+
sessionData: '',
|
|
643
|
+
cookiePassword: 'secret',
|
|
644
|
+
})).resolves.toEqual({
|
|
645
|
+
authenticated: false,
|
|
646
|
+
reason: 'no_session_cookie_provided',
|
|
647
|
+
});
|
|
648
|
+
}));
|
|
649
|
+
it('returns authenticated = false when session cookie is invalid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
650
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
651
|
+
sessionData: 'thisisacookie',
|
|
652
|
+
cookiePassword: 'secret',
|
|
653
|
+
})).resolves.toEqual({
|
|
654
|
+
authenticated: false,
|
|
655
|
+
reason: 'invalid_session_cookie',
|
|
656
|
+
});
|
|
657
|
+
}));
|
|
658
|
+
it('returns authenticated = false when session cookie cannot be unsealed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
659
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
660
|
+
const sessionData = yield (0, iron_session_1.sealData)({
|
|
661
|
+
accessToken: 'abc123',
|
|
662
|
+
refreshToken: 'def456',
|
|
663
|
+
user: {
|
|
664
|
+
object: 'user',
|
|
665
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
666
|
+
email: 'test@example.com',
|
|
667
|
+
},
|
|
668
|
+
}, { password: cookiePassword });
|
|
669
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
670
|
+
sessionData,
|
|
671
|
+
cookiePassword: 'secretpasswordwhichisalsolongbutnottherightone',
|
|
672
|
+
})).resolves.toEqual({
|
|
673
|
+
authenticated: false,
|
|
674
|
+
reason: 'invalid_session_cookie',
|
|
675
|
+
});
|
|
676
|
+
}));
|
|
677
|
+
it('returns authenticated = false when the JWT is invalid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
678
|
+
jest.spyOn(jose, 'jwtVerify').mockImplementationOnce(() => {
|
|
679
|
+
throw new Error('Invalid JWT');
|
|
680
|
+
});
|
|
681
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
682
|
+
const sessionData = yield (0, iron_session_1.sealData)({
|
|
683
|
+
accessToken: 'abc123',
|
|
684
|
+
refreshToken: 'def456',
|
|
685
|
+
user: {
|
|
686
|
+
object: 'user',
|
|
687
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
688
|
+
email: 'test@example.com',
|
|
689
|
+
},
|
|
690
|
+
}, { password: cookiePassword });
|
|
691
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
692
|
+
sessionData,
|
|
693
|
+
cookiePassword,
|
|
694
|
+
})).resolves.toEqual({ authenticated: false, reason: 'invalid_jwt' });
|
|
695
|
+
}));
|
|
696
|
+
it('returns the JWT claims when provided a valid JWT', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
697
|
+
jest
|
|
698
|
+
.spyOn(jose, 'jwtVerify')
|
|
699
|
+
.mockResolvedValue({});
|
|
700
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
701
|
+
const sessionData = yield (0, iron_session_1.sealData)({
|
|
702
|
+
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJzdWIiOiAiMTIzNDU2Nzg5MCIsCiAgIm5hbWUiOiAiSm9obiBEb2UiLAogICJpYXQiOiAxNTE2MjM5MDIyLAogICJzaWQiOiAic2Vzc2lvbl8xMjMiLAogICJvcmdfaWQiOiAib3JnXzEyMyIsCiAgInJvbGUiOiAibWVtYmVyIiwKICAicGVybWlzc2lvbnMiOiBbInBvc3RzOmNyZWF0ZSIsICJwb3N0czpkZWxldGUiXQp9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
|
|
703
|
+
refreshToken: 'def456',
|
|
704
|
+
user: {
|
|
705
|
+
object: 'user',
|
|
706
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
707
|
+
email: 'test@example.com',
|
|
708
|
+
},
|
|
709
|
+
}, { password: cookiePassword });
|
|
710
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
711
|
+
sessionData,
|
|
712
|
+
cookiePassword,
|
|
713
|
+
})).resolves.toEqual({
|
|
714
|
+
authenticated: true,
|
|
715
|
+
sessionId: 'session_123',
|
|
716
|
+
organizationId: 'org_123',
|
|
717
|
+
role: 'member',
|
|
718
|
+
permissions: ['posts:create', 'posts:delete'],
|
|
719
|
+
});
|
|
720
|
+
}));
|
|
721
|
+
});
|
|
722
|
+
describe('refreshAndSealSessionData', () => {
|
|
723
|
+
it('throws an error when the cookie password is undefined', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
724
|
+
yield expect(workos.userManagement.refreshAndSealSessionData({
|
|
725
|
+
sessionData: 'session_cookie',
|
|
726
|
+
})).rejects.toThrow('Cookie password is required');
|
|
727
|
+
}));
|
|
728
|
+
it('returns authenticated = false when the session cookie is empty', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
729
|
+
yield expect(workos.userManagement.refreshAndSealSessionData({
|
|
730
|
+
sessionData: '',
|
|
731
|
+
cookiePassword: 'secret',
|
|
732
|
+
})).resolves.toEqual({
|
|
733
|
+
authenticated: false,
|
|
734
|
+
reason: 'no_session_cookie_provided',
|
|
735
|
+
});
|
|
736
|
+
}));
|
|
737
|
+
it('returns authenticated = false when session cookie is invalid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
738
|
+
yield expect(workos.userManagement.refreshAndSealSessionData({
|
|
739
|
+
sessionData: 'thisisacookie',
|
|
740
|
+
cookiePassword: 'secret',
|
|
741
|
+
})).resolves.toEqual({
|
|
742
|
+
authenticated: false,
|
|
743
|
+
reason: 'invalid_session_cookie',
|
|
744
|
+
});
|
|
745
|
+
}));
|
|
746
|
+
it('returns authenticated = false when session cookie cannot be unsealed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
747
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
748
|
+
const sessionData = yield (0, iron_session_1.sealData)({
|
|
749
|
+
accessToken: 'abc123',
|
|
750
|
+
refreshToken: 'def456',
|
|
751
|
+
user: {
|
|
752
|
+
object: 'user',
|
|
753
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
754
|
+
email: 'test@example.com',
|
|
755
|
+
},
|
|
756
|
+
}, { password: cookiePassword });
|
|
757
|
+
yield expect(workos.userManagement.refreshAndSealSessionData({
|
|
758
|
+
sessionData,
|
|
759
|
+
cookiePassword: 'secretpasswordwhichisalsolongbutnottherightone',
|
|
760
|
+
})).resolves.toEqual({
|
|
761
|
+
authenticated: false,
|
|
762
|
+
reason: 'invalid_session_cookie',
|
|
763
|
+
});
|
|
764
|
+
}));
|
|
765
|
+
it('returns the sealed refreshed session cookie when provided a valid existing session cookie', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
766
|
+
(0, test_utils_1.fetchOnce)({
|
|
767
|
+
user: user_json_1.default,
|
|
768
|
+
access_token: 'access_token',
|
|
769
|
+
refresh_token: 'refresh_token',
|
|
770
|
+
});
|
|
771
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
772
|
+
const sessionData = yield (0, iron_session_1.sealData)({
|
|
773
|
+
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJzdWIiOiAiMTIzNDU2Nzg5MCIsCiAgIm5hbWUiOiAiSm9obiBEb2UiLAogICJpYXQiOiAxNTE2MjM5MDIyLAogICJzaWQiOiAic2Vzc2lvbl8xMjMiLAogICJvcmdfaWQiOiAib3JnXzEyMyIsCiAgInJvbGUiOiAibWVtYmVyIiwKICAicGVybWlzc2lvbnMiOiBbInBvc3RzOmNyZWF0ZSIsICJwb3N0czpkZWxldGUiXQp9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
|
|
774
|
+
refreshToken: 'def456',
|
|
775
|
+
user: {
|
|
776
|
+
object: 'user',
|
|
777
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
778
|
+
email: 'test@example.com',
|
|
779
|
+
},
|
|
780
|
+
}, { password: cookiePassword });
|
|
781
|
+
yield expect(workos.userManagement.refreshAndSealSessionData({
|
|
782
|
+
sessionData,
|
|
783
|
+
cookiePassword,
|
|
784
|
+
})).resolves.toEqual({
|
|
785
|
+
sealedSession: expect.any(String),
|
|
786
|
+
authenticated: true,
|
|
787
|
+
});
|
|
788
|
+
}));
|
|
789
|
+
});
|
|
790
|
+
describe('getSessionFromCookie', () => {
|
|
791
|
+
it('throws an error when the cookie password is undefined', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
792
|
+
yield expect(workos.userManagement.getSessionFromCookie({
|
|
793
|
+
sessionData: 'session_cookie',
|
|
794
|
+
})).rejects.toThrow('Cookie password is required');
|
|
795
|
+
}));
|
|
796
|
+
it('returns undefined when the session cookie cannot be unsealed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
797
|
+
yield expect(workos.userManagement.getSessionFromCookie({
|
|
798
|
+
sessionData: '',
|
|
799
|
+
cookiePassword: 'secret',
|
|
800
|
+
})).resolves.toBeUndefined();
|
|
801
|
+
}));
|
|
802
|
+
it('returns the unsealed session cookie data when provided a valid session cookie', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
803
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
804
|
+
const sessionCookieData = {
|
|
805
|
+
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJzdWIiOiAiMTIzNDU2Nzg5MCIsCiAgIm5hbWUiOiAiSm9obiBEb2UiLAogICJpYXQiOiAxNTE2MjM5MDIyLAogICJzaWQiOiAic2Vzc2lvbl8xMjMiLAogICJvcmdfaWQiOiAib3JnXzEyMyIsCiAgInJvbGUiOiAibWVtYmVyIiwKICAicGVybWlzc2lvbnMiOiBbInBvc3RzOmNyZWF0ZSIsICJwb3N0czpkZWxldGUiXQp9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
|
|
806
|
+
refreshToken: 'def456',
|
|
807
|
+
user: {
|
|
808
|
+
object: 'user',
|
|
809
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
810
|
+
email: 'test@example.com',
|
|
811
|
+
},
|
|
812
|
+
};
|
|
813
|
+
const sessionData = yield (0, iron_session_1.sealData)(sessionCookieData, {
|
|
814
|
+
password: cookiePassword,
|
|
815
|
+
});
|
|
816
|
+
yield expect(workos.userManagement.getSessionFromCookie({
|
|
817
|
+
sessionData,
|
|
818
|
+
cookiePassword,
|
|
819
|
+
})).resolves.toEqual(sessionCookieData);
|
|
820
|
+
}));
|
|
323
821
|
});
|
|
324
822
|
describe('getEmailVerification', () => {
|
|
325
823
|
it('sends a Get EmailVerification request', () => __awaiter(void 0, void 0, void 0, function* () {
|
package/lib/workos.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export declare class WorkOS {
|
|
|
16
16
|
readonly options: WorkOSOptions;
|
|
17
17
|
readonly baseURL: string;
|
|
18
18
|
readonly client: HttpClient;
|
|
19
|
+
readonly clientId?: string;
|
|
19
20
|
readonly auditLogs: AuditLogs;
|
|
20
21
|
readonly directorySync: DirectorySync;
|
|
21
22
|
readonly organizations: Organizations;
|
package/lib/workos.js
CHANGED
|
@@ -26,10 +26,11 @@ const bad_request_exception_1 = require("./common/exceptions/bad-request.excepti
|
|
|
26
26
|
const http_client_1 = require("./common/net/http-client");
|
|
27
27
|
const subtle_crypto_provider_1 = require("./common/crypto/subtle-crypto-provider");
|
|
28
28
|
const fetch_client_1 = require("./common/net/fetch-client");
|
|
29
|
-
const VERSION = '7.
|
|
29
|
+
const VERSION = '7.15.0';
|
|
30
30
|
const DEFAULT_HOSTNAME = 'api.workos.com';
|
|
31
31
|
class WorkOS {
|
|
32
32
|
constructor(key, options = {}) {
|
|
33
|
+
var _a;
|
|
33
34
|
this.key = key;
|
|
34
35
|
this.options = options;
|
|
35
36
|
this.auditLogs = new audit_logs_1.AuditLogs(this);
|
|
@@ -41,7 +42,6 @@ class WorkOS {
|
|
|
41
42
|
this.sso = new sso_1.SSO(this);
|
|
42
43
|
this.mfa = new mfa_1.Mfa(this);
|
|
43
44
|
this.events = new events_1.Events(this);
|
|
44
|
-
this.userManagement = new user_management_1.UserManagement(this);
|
|
45
45
|
if (!key) {
|
|
46
46
|
// process might be undefined in some environments
|
|
47
47
|
this.key = process === null || process === void 0 ? void 0 : process.env.WORKOS_API_KEY;
|
|
@@ -52,6 +52,7 @@ class WorkOS {
|
|
|
52
52
|
if (this.options.https === undefined) {
|
|
53
53
|
this.options.https = true;
|
|
54
54
|
}
|
|
55
|
+
this.clientId = (_a = this.options.clientId) !== null && _a !== void 0 ? _a : process === null || process === void 0 ? void 0 : process.env.WORKOS_CLIENT_ID;
|
|
55
56
|
const protocol = this.options.https ? 'https' : 'http';
|
|
56
57
|
const apiHostname = this.options.apiHostname || DEFAULT_HOSTNAME;
|
|
57
58
|
const port = this.options.port;
|
|
@@ -65,6 +66,8 @@ class WorkOS {
|
|
|
65
66
|
userAgent += ` ${name}: ${version}`;
|
|
66
67
|
}
|
|
67
68
|
this.webhooks = this.createWebhookClient();
|
|
69
|
+
// Must initialize UserManagement after baseURL is configured
|
|
70
|
+
this.userManagement = new user_management_1.UserManagement(this);
|
|
68
71
|
this.client = this.createHttpClient(options, userAgent);
|
|
69
72
|
}
|
|
70
73
|
createWebhookClient() {
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "7.
|
|
2
|
+
"version": "7.15.0",
|
|
3
3
|
"name": "@workos-inc/node",
|
|
4
4
|
"author": "WorkOS",
|
|
5
5
|
"description": "A Node wrapper for the WorkOS API",
|
|
@@ -37,6 +37,8 @@
|
|
|
37
37
|
"prepublishOnly": "yarn run build"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
+
"iron-session": "~6.3.1",
|
|
41
|
+
"jose": "~5.6.3",
|
|
40
42
|
"pluralize": "8.0.0"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
@@ -63,4 +65,4 @@
|
|
|
63
65
|
"default": "./lib/index.js"
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
|
-
}
|
|
68
|
+
}
|