@workos-inc/node 7.69.2 → 7.71.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/organizations/interfaces/index.d.ts +0 -1
- package/lib/organizations/interfaces/index.js +0 -1
- package/lib/organizations/organizations.d.ts +1 -1
- package/lib/organizations/organizations.js +1 -1
- package/lib/sso/interfaces/connection-type.enum.d.ts +1 -0
- package/lib/sso/interfaces/connection-type.enum.js +1 -0
- package/lib/user-management/fixtures/list-user-feature-flags.json +33 -0
- package/lib/user-management/fixtures/list-users.json +2 -1
- package/lib/user-management/fixtures/user.json +1 -0
- package/lib/user-management/interfaces/authenticate-with-session-cookie.interface.d.ts +2 -0
- package/lib/user-management/interfaces/authentication-response.interface.d.ts +1 -1
- package/lib/user-management/interfaces/create-organization-membership-options.interface.d.ts +2 -0
- package/lib/user-management/interfaces/identity.interface.d.ts +2 -2
- package/lib/user-management/interfaces/index.d.ts +1 -0
- package/lib/user-management/interfaces/index.js +1 -0
- package/lib/user-management/interfaces/list-user-feature-flags-options.interface.d.ts +4 -0
- package/lib/user-management/interfaces/list-user-feature-flags-options.interface.js +2 -0
- package/lib/user-management/interfaces/organization-membership.interface.d.ts +2 -0
- package/lib/user-management/interfaces/update-organization-membership-options.interface.d.ts +2 -0
- package/lib/user-management/interfaces/update-user-options.interface.d.ts +2 -0
- package/lib/user-management/interfaces/user.interface.d.ts +2 -0
- package/lib/user-management/serializers/create-organization-membership-options.serializer.js +1 -0
- package/lib/user-management/serializers/organization-membership.serializer.js +1 -11
- package/lib/user-management/serializers/update-organization-membership-options.serializer.js +1 -0
- package/lib/user-management/serializers/update-user-options.serializer.js +1 -0
- package/lib/user-management/serializers/user.serializer.js +1 -0
- package/lib/user-management/session.js +4 -2
- package/lib/user-management/session.spec.js +4 -2
- package/lib/user-management/user-management.d.ts +3 -1
- package/lib/user-management/user-management.js +9 -1
- package/lib/user-management/user-management.spec.js +135 -0
- package/lib/workos.js +1 -1
- package/package.json +1 -1
- /package/lib/{organizations → feature-flags}/interfaces/feature-flag.interface.d.ts +0 -0
- /package/lib/{organizations → feature-flags}/interfaces/feature-flag.interface.js +0 -0
- /package/lib/{organizations → feature-flags}/serializers/feature-flag.serializer.d.ts +0 -0
- /package/lib/{organizations → feature-flags}/serializers/feature-flag.serializer.js +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from './create-organization-options.interface';
|
|
2
2
|
export * from './domain-data.interface';
|
|
3
|
-
export * from './feature-flag.interface';
|
|
4
3
|
export * from './list-organization-feature-flags-options.interface';
|
|
5
4
|
export * from './list-organizations-options.interface';
|
|
6
5
|
export * from './organization.interface';
|
|
@@ -16,7 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./create-organization-options.interface"), exports);
|
|
18
18
|
__exportStar(require("./domain-data.interface"), exports);
|
|
19
|
-
__exportStar(require("./feature-flag.interface"), exports);
|
|
20
19
|
__exportStar(require("./list-organization-feature-flags-options.interface"), exports);
|
|
21
20
|
__exportStar(require("./list-organizations-options.interface"), exports);
|
|
22
21
|
__exportStar(require("./organization.interface"), exports);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AutoPaginatable } from '../common/utils/pagination';
|
|
2
2
|
import { WorkOS } from '../workos';
|
|
3
3
|
import { CreateOrganizationOptions, CreateOrganizationRequestOptions, ListOrganizationsOptions, Organization, UpdateOrganizationOptions } from './interfaces';
|
|
4
|
-
import { FeatureFlag } from '
|
|
4
|
+
import { FeatureFlag } from '../feature-flags/interfaces/feature-flag.interface';
|
|
5
5
|
import { RoleList } from '../roles/interfaces';
|
|
6
6
|
import { ListOrganizationRolesOptions } from './interfaces/list-organization-roles-options.interface';
|
|
7
7
|
import { ListOrganizationFeatureFlagsOptions } from './interfaces/list-organization-feature-flags-options.interface';
|
|
@@ -25,7 +25,7 @@ const pagination_1 = require("../common/utils/pagination");
|
|
|
25
25
|
const serializers_1 = require("./serializers");
|
|
26
26
|
const fetch_and_deserialize_1 = require("../common/utils/fetch-and-deserialize");
|
|
27
27
|
const role_serializer_1 = require("../roles/serializers/role.serializer");
|
|
28
|
-
const feature_flag_serializer_1 = require("
|
|
28
|
+
const feature_flag_serializer_1 = require("../feature-flags/serializers/feature-flag.serializer");
|
|
29
29
|
class Organizations {
|
|
30
30
|
constructor(workos) {
|
|
31
31
|
this.workos = workos;
|
|
@@ -28,6 +28,7 @@ export declare enum ConnectionType {
|
|
|
28
28
|
PingFederateSAML = "PingFederateSAML",
|
|
29
29
|
PingOneSAML = "PingOneSAML",
|
|
30
30
|
RipplingSAML = "RipplingSAML",
|
|
31
|
+
SalesforceOAuth = "SalesforceOAuth",
|
|
31
32
|
SalesforceSAML = "SalesforceSAML",
|
|
32
33
|
ShibbolethGenericSAML = "ShibbolethGenericSAML",
|
|
33
34
|
ShibbolethSAML = "ShibbolethSAML",
|
|
@@ -32,6 +32,7 @@ var ConnectionType;
|
|
|
32
32
|
ConnectionType["PingFederateSAML"] = "PingFederateSAML";
|
|
33
33
|
ConnectionType["PingOneSAML"] = "PingOneSAML";
|
|
34
34
|
ConnectionType["RipplingSAML"] = "RipplingSAML";
|
|
35
|
+
ConnectionType["SalesforceOAuth"] = "SalesforceOAuth";
|
|
35
36
|
ConnectionType["SalesforceSAML"] = "SalesforceSAML";
|
|
36
37
|
ConnectionType["ShibbolethGenericSAML"] = "ShibbolethGenericSAML";
|
|
37
38
|
ConnectionType["ShibbolethSAML"] = "ShibbolethSAML";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"object": "list",
|
|
3
|
+
"data": [
|
|
4
|
+
{
|
|
5
|
+
"object": "feature_flag",
|
|
6
|
+
"id": "flag_01EHQMYV6MBK39QC5PZXHY59C5",
|
|
7
|
+
"name": "Advanced Dashboard",
|
|
8
|
+
"slug": "advanced-dashboard",
|
|
9
|
+
"description": "Enable advanced dashboard features",
|
|
10
|
+
"created_at": "2024-01-01T00:00:00.000Z",
|
|
11
|
+
"updated_at": "2024-01-01T00:00:00.000Z"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"object": "feature_flag",
|
|
15
|
+
"id": "flag_01EHQMYV6MBK39QC5PZXHY59C6",
|
|
16
|
+
"name": "Beta Features",
|
|
17
|
+
"slug": "beta-features",
|
|
18
|
+
"description": null,
|
|
19
|
+
"created_at": "2024-01-01T00:00:00.000Z",
|
|
20
|
+
"updated_at": "2024-01-01T00:00:00.000Z"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"object": "feature_flag",
|
|
24
|
+
"id": "flag_01EHQMYV6MBK39QC5PZXHY59C7",
|
|
25
|
+
"name": "Premium Support",
|
|
26
|
+
"slug": "premium-support",
|
|
27
|
+
"description": "Access to premium support features",
|
|
28
|
+
"created_at": "2024-01-01T00:00:00.000Z",
|
|
29
|
+
"updated_at": "2024-01-01T00:00:00.000Z"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"list_metadata": {}
|
|
33
|
+
}
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"updated_at": "2023-07-18T02:07:19.911Z",
|
|
12
12
|
"email_verified": true,
|
|
13
13
|
"profile_picture_url": "https://example.com/profile_picture.jpg",
|
|
14
|
-
"last_sign_in_at": "2023-07-18T02:07:19.911Z"
|
|
14
|
+
"last_sign_in_at": "2023-07-18T02:07:19.911Z",
|
|
15
|
+
"locale": "en-US"
|
|
15
16
|
}
|
|
16
17
|
],
|
|
17
18
|
"list_metadata": {
|
|
@@ -9,6 +9,7 @@ export interface AccessToken {
|
|
|
9
9
|
sid: string;
|
|
10
10
|
org_id?: string;
|
|
11
11
|
role?: string;
|
|
12
|
+
roles?: string[];
|
|
12
13
|
permissions?: string[];
|
|
13
14
|
entitlements?: string[];
|
|
14
15
|
feature_flags?: string[];
|
|
@@ -28,6 +29,7 @@ export type AuthenticateWithSessionCookieSuccessResponse = {
|
|
|
28
29
|
sessionId: string;
|
|
29
30
|
organizationId?: string;
|
|
30
31
|
role?: string;
|
|
32
|
+
roles?: string[];
|
|
31
33
|
permissions?: string[];
|
|
32
34
|
entitlements?: string[];
|
|
33
35
|
featureFlags?: string[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Impersonator, ImpersonatorResponse } from './impersonator.interface';
|
|
2
2
|
import { OauthTokens, OauthTokensResponse } from './oauth-tokens.interface';
|
|
3
3
|
import { User, UserResponse } from './user.interface';
|
|
4
|
-
type AuthenticationMethod = 'SSO' | 'Password' | 'Passkey' | 'AppleOAuth' | 'GitHubOAuth' | 'GoogleOAuth' | 'MicrosoftOAuth' | 'MagicAuth' | 'Impersonation';
|
|
4
|
+
type AuthenticationMethod = 'SSO' | 'Password' | 'Passkey' | 'AppleOAuth' | 'GitHubOAuth' | 'GoogleOAuth' | 'MicrosoftOAuth' | 'SalesforceOAuth' | 'MagicAuth' | 'Impersonation';
|
|
5
5
|
export interface AuthenticationResponse {
|
|
6
6
|
user: User;
|
|
7
7
|
organizationId?: string;
|
package/lib/user-management/interfaces/create-organization-membership-options.interface.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ export interface CreateOrganizationMembershipOptions {
|
|
|
2
2
|
organizationId: string;
|
|
3
3
|
userId: string;
|
|
4
4
|
roleSlug?: string;
|
|
5
|
+
roleSlugs?: string[];
|
|
5
6
|
}
|
|
6
7
|
export interface SerializedCreateOrganizationMembershipOptions {
|
|
7
8
|
organization_id: string;
|
|
8
9
|
user_id: string;
|
|
9
10
|
role_slug?: string;
|
|
11
|
+
role_slugs?: string[];
|
|
10
12
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export interface Identity {
|
|
2
2
|
idpId: string;
|
|
3
3
|
type: 'OAuth';
|
|
4
|
-
provider: 'AppleOAuth' | 'GoogleOAuth' | 'GitHubOAuth' | 'MicrosoftOAuth';
|
|
4
|
+
provider: 'AppleOAuth' | 'GoogleOAuth' | 'GitHubOAuth' | 'MicrosoftOAuth' | 'SalesforceOAuth';
|
|
5
5
|
}
|
|
6
6
|
export interface IdentityResponse {
|
|
7
7
|
idp_id: string;
|
|
8
8
|
type: 'OAuth';
|
|
9
|
-
provider: 'AppleOAuth' | 'GoogleOAuth' | 'GitHubOAuth' | 'MicrosoftOAuth';
|
|
9
|
+
provider: 'AppleOAuth' | 'GoogleOAuth' | 'GitHubOAuth' | 'MicrosoftOAuth' | 'SalesforceOAuth';
|
|
10
10
|
}
|
|
@@ -26,6 +26,7 @@ export * from './list-auth-factors-options.interface';
|
|
|
26
26
|
export * from './list-invitations-options.interface';
|
|
27
27
|
export * from './list-organization-memberships-options.interface';
|
|
28
28
|
export * from './list-sessions-options.interface';
|
|
29
|
+
export * from './list-user-feature-flags-options.interface';
|
|
29
30
|
export * from './list-users-options.interface';
|
|
30
31
|
export * from './magic-auth.interface';
|
|
31
32
|
export * from './oauth-tokens.interface';
|
|
@@ -42,6 +42,7 @@ __exportStar(require("./list-auth-factors-options.interface"), exports);
|
|
|
42
42
|
__exportStar(require("./list-invitations-options.interface"), exports);
|
|
43
43
|
__exportStar(require("./list-organization-memberships-options.interface"), exports);
|
|
44
44
|
__exportStar(require("./list-sessions-options.interface"), exports);
|
|
45
|
+
__exportStar(require("./list-user-feature-flags-options.interface"), exports);
|
|
45
46
|
__exportStar(require("./list-users-options.interface"), exports);
|
|
46
47
|
__exportStar(require("./magic-auth.interface"), exports);
|
|
47
48
|
__exportStar(require("./oauth-tokens.interface"), exports);
|
|
@@ -10,6 +10,7 @@ export interface OrganizationMembership {
|
|
|
10
10
|
createdAt: string;
|
|
11
11
|
updatedAt: string;
|
|
12
12
|
role: RoleResponse;
|
|
13
|
+
roles?: RoleResponse[];
|
|
13
14
|
}
|
|
14
15
|
export interface OrganizationMembershipResponse {
|
|
15
16
|
object: 'organization_membership';
|
|
@@ -21,4 +22,5 @@ export interface OrganizationMembershipResponse {
|
|
|
21
22
|
created_at: string;
|
|
22
23
|
updated_at: string;
|
|
23
24
|
role: RoleResponse;
|
|
25
|
+
roles?: RoleResponse[];
|
|
24
26
|
}
|
|
@@ -9,6 +9,7 @@ export interface UpdateUserOptions {
|
|
|
9
9
|
passwordHash?: string;
|
|
10
10
|
passwordHashType?: PasswordHashType;
|
|
11
11
|
externalId?: string;
|
|
12
|
+
locale?: string;
|
|
12
13
|
metadata?: Record<string, string | null>;
|
|
13
14
|
}
|
|
14
15
|
export interface SerializedUpdateUserOptions {
|
|
@@ -20,5 +21,6 @@ export interface SerializedUpdateUserOptions {
|
|
|
20
21
|
password_hash?: string;
|
|
21
22
|
password_hash_type?: PasswordHashType;
|
|
22
23
|
external_id?: string;
|
|
24
|
+
locale?: string;
|
|
23
25
|
metadata?: Record<string, string | null>;
|
|
24
26
|
}
|
|
@@ -7,6 +7,7 @@ export interface User {
|
|
|
7
7
|
firstName: string | null;
|
|
8
8
|
lastName: string | null;
|
|
9
9
|
lastSignInAt: string | null;
|
|
10
|
+
locale: string | null;
|
|
10
11
|
createdAt: string;
|
|
11
12
|
updatedAt: string;
|
|
12
13
|
externalId: string | null;
|
|
@@ -21,6 +22,7 @@ export interface UserResponse {
|
|
|
21
22
|
first_name: string | null;
|
|
22
23
|
last_name: string | null;
|
|
23
24
|
last_sign_in_at: string | null;
|
|
25
|
+
locale: string | null;
|
|
24
26
|
created_at: string;
|
|
25
27
|
updated_at: string;
|
|
26
28
|
external_id?: string;
|
package/lib/user-management/serializers/create-organization-membership-options.serializer.js
CHANGED
|
@@ -5,5 +5,6 @@ const serializeCreateOrganizationMembershipOptions = (options) => ({
|
|
|
5
5
|
organization_id: options.organizationId,
|
|
6
6
|
user_id: options.userId,
|
|
7
7
|
role_slug: options.roleSlug,
|
|
8
|
+
role_slugs: options.roleSlugs,
|
|
8
9
|
});
|
|
9
10
|
exports.serializeCreateOrganizationMembershipOptions = serializeCreateOrganizationMembershipOptions;
|
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.deserializeOrganizationMembership = void 0;
|
|
4
|
-
const deserializeOrganizationMembership = (organizationMembership) => ({
|
|
5
|
-
object: organizationMembership.object,
|
|
6
|
-
id: organizationMembership.id,
|
|
7
|
-
userId: organizationMembership.user_id,
|
|
8
|
-
organizationId: organizationMembership.organization_id,
|
|
9
|
-
organizationName: organizationMembership.organization_name,
|
|
10
|
-
status: organizationMembership.status,
|
|
11
|
-
createdAt: organizationMembership.created_at,
|
|
12
|
-
updatedAt: organizationMembership.updated_at,
|
|
13
|
-
role: organizationMembership.role,
|
|
14
|
-
});
|
|
4
|
+
const deserializeOrganizationMembership = (organizationMembership) => (Object.assign({ object: organizationMembership.object, id: organizationMembership.id, userId: organizationMembership.user_id, organizationId: organizationMembership.organization_id, organizationName: organizationMembership.organization_name, status: organizationMembership.status, createdAt: organizationMembership.created_at, updatedAt: organizationMembership.updated_at, role: organizationMembership.role }, (organizationMembership.roles && { roles: organizationMembership.roles })));
|
|
15
5
|
exports.deserializeOrganizationMembership = deserializeOrganizationMembership;
|
package/lib/user-management/serializers/update-organization-membership-options.serializer.js
CHANGED
|
@@ -3,5 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.serializeUpdateOrganizationMembershipOptions = void 0;
|
|
4
4
|
const serializeUpdateOrganizationMembershipOptions = (options) => ({
|
|
5
5
|
role_slug: options.roleSlug,
|
|
6
|
+
role_slugs: options.roleSlugs,
|
|
6
7
|
});
|
|
7
8
|
exports.serializeUpdateOrganizationMembershipOptions = serializeUpdateOrganizationMembershipOptions;
|
|
@@ -10,6 +10,7 @@ const serializeUpdateUserOptions = (options) => ({
|
|
|
10
10
|
password_hash: options.passwordHash,
|
|
11
11
|
password_hash_type: options.passwordHashType,
|
|
12
12
|
external_id: options.externalId,
|
|
13
|
+
locale: options.locale,
|
|
13
14
|
metadata: options.metadata,
|
|
14
15
|
});
|
|
15
16
|
exports.serializeUpdateUserOptions = serializeUpdateUserOptions;
|
|
@@ -12,6 +12,7 @@ const deserializeUser = (user) => {
|
|
|
12
12
|
profilePictureUrl: user.profile_picture_url,
|
|
13
13
|
lastName: user.last_name,
|
|
14
14
|
lastSignInAt: user.last_sign_in_at,
|
|
15
|
+
locale: user.locale,
|
|
15
16
|
createdAt: user.created_at,
|
|
16
17
|
updatedAt: user.updated_at,
|
|
17
18
|
externalId: (_a = user.external_id) !== null && _a !== void 0 ? _a : null,
|
|
@@ -61,12 +61,13 @@ class CookieSession {
|
|
|
61
61
|
reason: interfaces_1.AuthenticateWithSessionCookieFailureReason.INVALID_JWT,
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
|
-
const { sid: sessionId, org_id: organizationId, role, permissions, entitlements, feature_flags: featureFlags, } = (0, jose_1.decodeJwt)(session.accessToken);
|
|
64
|
+
const { sid: sessionId, org_id: organizationId, role, roles, permissions, entitlements, feature_flags: featureFlags, } = (0, jose_1.decodeJwt)(session.accessToken);
|
|
65
65
|
return {
|
|
66
66
|
authenticated: true,
|
|
67
67
|
sessionId,
|
|
68
68
|
organizationId,
|
|
69
69
|
role,
|
|
70
|
+
roles,
|
|
70
71
|
permissions,
|
|
71
72
|
entitlements,
|
|
72
73
|
featureFlags,
|
|
@@ -114,7 +115,7 @@ class CookieSession {
|
|
|
114
115
|
this.cookiePassword = options.cookiePassword;
|
|
115
116
|
}
|
|
116
117
|
this.sessionData = authenticationResponse.sealedSession;
|
|
117
|
-
const { sid: sessionId, org_id: organizationId, role, permissions, entitlements, feature_flags: featureFlags, } = (0, jose_1.decodeJwt)(authenticationResponse.accessToken);
|
|
118
|
+
const { sid: sessionId, org_id: organizationId, role, roles, permissions, entitlements, feature_flags: featureFlags, } = (0, jose_1.decodeJwt)(authenticationResponse.accessToken);
|
|
118
119
|
// TODO: Returning `session` here means there's some duplicated data.
|
|
119
120
|
// Slim down the return type in a future major version.
|
|
120
121
|
return {
|
|
@@ -124,6 +125,7 @@ class CookieSession {
|
|
|
124
125
|
sessionId,
|
|
125
126
|
organizationId,
|
|
126
127
|
role,
|
|
128
|
+
roles,
|
|
127
129
|
permissions,
|
|
128
130
|
entitlements,
|
|
129
131
|
featureFlags,
|
|
@@ -119,7 +119,7 @@ describe('Session', () => {
|
|
|
119
119
|
.spyOn(jose, 'jwtVerify')
|
|
120
120
|
.mockResolvedValue({});
|
|
121
121
|
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
122
|
-
const accessToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
|
|
122
|
+
const accessToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdXRoZW50aWNhdGVkIjp0cnVlLCJpbXBlcnNvbmF0b3IiOnsiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSIsInJlYXNvbiI6InRlc3QifSwic2lkIjoic2Vzc2lvbl8xMjMiLCJvcmdfaWQiOiJvcmdfMTIzIiwicm9sZSI6Im1lbWJlciIsInJvbGVzIjpbIm1lbWJlciIsImFkbWluIl0sInBlcm1pc3Npb25zIjpbInBvc3RzOmNyZWF0ZSIsInBvc3RzOmRlbGV0ZSJdLCJlbnRpdGxlbWVudHMiOlsiYXVkaXQtbG9ncyJdLCJmZWF0dXJlX2ZsYWdzIjpbImRhcmstbW9kZSIsImJldGEtZmVhdHVyZXMiXSwidXNlciI6eyJvYmplY3QiOiJ1c2VyIiwiaWQiOiJ1c2VyXzAxSDVKUURWN1I3QVRFWVpERUcwVzVQUllTIiwiZW1haWwiOiJ0ZXN0QGV4YW1wbGUuY29tIn19.TNUzJYn6lzLWFFsiWiKEgIshyUs-bKJQf1VxwNr1cGI';
|
|
123
123
|
const sessionData = yield (0, iron_session_1.sealData)({
|
|
124
124
|
accessToken,
|
|
125
125
|
refreshToken: 'def456',
|
|
@@ -146,6 +146,7 @@ describe('Session', () => {
|
|
|
146
146
|
sessionId: 'session_123',
|
|
147
147
|
organizationId: 'org_123',
|
|
148
148
|
role: 'member',
|
|
149
|
+
roles: ['member', 'admin'],
|
|
149
150
|
permissions: ['posts:create', 'posts:delete'],
|
|
150
151
|
entitlements: ['audit-logs'],
|
|
151
152
|
featureFlags: ['dark-mode', 'beta-features'],
|
|
@@ -173,7 +174,7 @@ describe('Session', () => {
|
|
|
173
174
|
}));
|
|
174
175
|
describe('when the session data is valid', () => {
|
|
175
176
|
it('returns a successful response with a sealed and unsealed session', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
176
|
-
const accessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
|
|
177
|
+
const accessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJzaWQiOiJzZXNzaW9uXzEyMyIsIm9yZ19pZCI6Im9yZ18xMjMiLCJyb2xlIjoibWVtYmVyIiwicm9sZXMiOlsibWVtYmVyIiwiYWRtaW4iXSwicGVybWlzc2lvbnMiOlsicG9zdHM6Y3JlYXRlIiwicG9zdHM6ZGVsZXRlIl19.N5zveP149QhRR5zNvzGJPiCX098uXaN8VM1_lwsMg4A';
|
|
177
178
|
const refreshToken = 'def456';
|
|
178
179
|
(0, test_utils_1.fetchOnce)({
|
|
179
180
|
user: user_json_1.default,
|
|
@@ -216,6 +217,7 @@ describe('Session', () => {
|
|
|
216
217
|
entitlements: undefined,
|
|
217
218
|
permissions: ['posts:create', 'posts:delete'],
|
|
218
219
|
role: 'member',
|
|
220
|
+
roles: ['member', 'admin'],
|
|
219
221
|
sessionId: 'session_123',
|
|
220
222
|
user: expect.objectContaining({
|
|
221
223
|
email: 'test01@example.com',
|
|
@@ -2,8 +2,9 @@ import { createRemoteJWKSet } from 'jose';
|
|
|
2
2
|
import { IronSessionProvider } from '../common/iron-session/iron-session-provider';
|
|
3
3
|
import { AutoPaginatable } from '../common/utils/pagination';
|
|
4
4
|
import { Challenge } from '../mfa/interfaces';
|
|
5
|
+
import { FeatureFlag } from '../feature-flags/interfaces/feature-flag.interface';
|
|
5
6
|
import { WorkOS } from '../workos';
|
|
6
|
-
import { AuthenticateWithCodeOptions, AuthenticateWithCodeAndVerifierOptions, AuthenticateWithMagicAuthOptions, AuthenticateWithPasswordOptions, AuthenticateWithRefreshTokenOptions, AuthenticateWithTotpOptions, AuthenticationResponse, CreateMagicAuthOptions, CreatePasswordResetOptions, CreateUserOptions, EmailVerification, EnrollAuthFactorOptions, ListAuthFactorsOptions, ListSessionsOptions, ListUsersOptions, MagicAuth, PasswordReset, ResetPasswordOptions, SendMagicAuthCodeOptions, SendPasswordResetEmailOptions, SendVerificationEmailOptions, Session, UpdateUserOptions, User, VerifyEmailOptions } from './interfaces';
|
|
7
|
+
import { AuthenticateWithCodeOptions, AuthenticateWithCodeAndVerifierOptions, AuthenticateWithMagicAuthOptions, AuthenticateWithPasswordOptions, AuthenticateWithRefreshTokenOptions, AuthenticateWithTotpOptions, AuthenticationResponse, CreateMagicAuthOptions, CreatePasswordResetOptions, CreateUserOptions, EmailVerification, EnrollAuthFactorOptions, ListAuthFactorsOptions, ListSessionsOptions, ListUsersOptions, ListUserFeatureFlagsOptions, MagicAuth, PasswordReset, ResetPasswordOptions, SendMagicAuthCodeOptions, SendPasswordResetEmailOptions, SendVerificationEmailOptions, Session, UpdateUserOptions, User, VerifyEmailOptions } from './interfaces';
|
|
7
8
|
import { AuthenticateWithEmailVerificationOptions } from './interfaces/authenticate-with-email-verification-options.interface';
|
|
8
9
|
import { AuthenticateWithOrganizationSelectionOptions } from './interfaces/authenticate-with-organization-selection.interface';
|
|
9
10
|
import { AuthenticateWithSessionCookieFailedResponse, AuthenticateWithSessionCookieOptions, AuthenticateWithSessionCookieSuccessResponse, SessionCookieData } from './interfaces/authenticate-with-session-cookie.interface';
|
|
@@ -91,6 +92,7 @@ export declare class UserManagement {
|
|
|
91
92
|
authenticationChallenge: Challenge;
|
|
92
93
|
}>;
|
|
93
94
|
listAuthFactors(options: ListAuthFactorsOptions): Promise<AutoPaginatable<Factor>>;
|
|
95
|
+
listUserFeatureFlags(options: ListUserFeatureFlagsOptions): Promise<AutoPaginatable<FeatureFlag>>;
|
|
94
96
|
listSessions(userId: string, options?: ListSessionsOptions): Promise<AutoPaginatable<Session>>;
|
|
95
97
|
deleteUser(userId: string): Promise<void>;
|
|
96
98
|
getUserIdentities(userId: string): Promise<Identity[]>;
|
|
@@ -30,6 +30,7 @@ const oauth_exception_1 = require("../common/exceptions/oauth.exception");
|
|
|
30
30
|
const fetch_and_deserialize_1 = require("../common/utils/fetch-and-deserialize");
|
|
31
31
|
const pagination_1 = require("../common/utils/pagination");
|
|
32
32
|
const serializers_1 = require("../mfa/serializers");
|
|
33
|
+
const feature_flag_serializer_1 = require("../feature-flags/serializers/feature-flag.serializer");
|
|
33
34
|
const authenticate_with_session_cookie_interface_1 = require("./interfaces/authenticate-with-session-cookie.interface");
|
|
34
35
|
const refresh_and_seal_session_data_interface_1 = require("./interfaces/refresh-and-seal-session-data.interface");
|
|
35
36
|
const revoke_session_options_interface_1 = require("./interfaces/revoke-session-options.interface");
|
|
@@ -217,12 +218,13 @@ class UserManagement {
|
|
|
217
218
|
reason: authenticate_with_session_cookie_interface_1.AuthenticateWithSessionCookieFailureReason.INVALID_JWT,
|
|
218
219
|
};
|
|
219
220
|
}
|
|
220
|
-
const { sid: sessionId, org_id: organizationId, role, permissions, entitlements, feature_flags: featureFlags, } = (0, jose_1.decodeJwt)(session.accessToken);
|
|
221
|
+
const { sid: sessionId, org_id: organizationId, role, roles, permissions, entitlements, feature_flags: featureFlags, } = (0, jose_1.decodeJwt)(session.accessToken);
|
|
221
222
|
return {
|
|
222
223
|
authenticated: true,
|
|
223
224
|
sessionId,
|
|
224
225
|
organizationId,
|
|
225
226
|
role,
|
|
227
|
+
roles,
|
|
226
228
|
user: session.user,
|
|
227
229
|
permissions,
|
|
228
230
|
entitlements,
|
|
@@ -434,6 +436,12 @@ class UserManagement {
|
|
|
434
436
|
return new pagination_1.AutoPaginatable(yield (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, `/user_management/users/${userId}/auth_factors`, factor_serializer_1.deserializeFactor, restOfOptions), (params) => (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, `/user_management/users/${userId}/auth_factors`, factor_serializer_1.deserializeFactor, params), restOfOptions);
|
|
435
437
|
});
|
|
436
438
|
}
|
|
439
|
+
listUserFeatureFlags(options) {
|
|
440
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
441
|
+
const { userId } = options, paginationOptions = __rest(options, ["userId"]);
|
|
442
|
+
return new pagination_1.AutoPaginatable(yield (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, `/user_management/users/${userId}/feature-flags`, feature_flag_serializer_1.deserializeFeatureFlag, paginationOptions), (params) => (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, `/user_management/users/${userId}/feature-flags`, feature_flag_serializer_1.deserializeFeatureFlag, params), paginationOptions);
|
|
443
|
+
});
|
|
444
|
+
}
|
|
437
445
|
listSessions(userId, options) {
|
|
438
446
|
return __awaiter(this, void 0, void 0, function* () {
|
|
439
447
|
return new pagination_1.AutoPaginatable(yield (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, `/user_management/users/${userId}/sessions`, serializers_2.deserializeSession, options ? (0, serializers_2.serializeListSessionsOptions)(options) : undefined), (params) => (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, `/user_management/users/${userId}/sessions`, serializers_2.deserializeSession, params), options ? (0, serializers_2.serializeListSessionsOptions)(options) : undefined);
|
|
@@ -45,6 +45,7 @@ const list_factors_json_1 = __importDefault(require("./fixtures/list-factors.jso
|
|
|
45
45
|
const list_invitations_json_1 = __importDefault(require("./fixtures/list-invitations.json"));
|
|
46
46
|
const list_organization_memberships_json_1 = __importDefault(require("./fixtures/list-organization-memberships.json"));
|
|
47
47
|
const list_sessions_json_1 = __importDefault(require("./fixtures/list-sessions.json"));
|
|
48
|
+
const list_user_feature_flags_json_1 = __importDefault(require("./fixtures/list-user-feature-flags.json"));
|
|
48
49
|
const list_users_json_1 = __importDefault(require("./fixtures/list-users.json"));
|
|
49
50
|
const magic_auth_json_1 = __importDefault(require("./fixtures/magic_auth.json"));
|
|
50
51
|
const organization_membership_json_1 = __importDefault(require("./fixtures/organization-membership.json"));
|
|
@@ -83,6 +84,7 @@ describe('UserManagement', () => {
|
|
|
83
84
|
lastName: 'User',
|
|
84
85
|
emailVerified: true,
|
|
85
86
|
lastSignInAt: '2023-07-18T02:07:19.911Z',
|
|
87
|
+
locale: 'en-US',
|
|
86
88
|
});
|
|
87
89
|
}));
|
|
88
90
|
});
|
|
@@ -101,6 +103,7 @@ describe('UserManagement', () => {
|
|
|
101
103
|
lastName: 'User',
|
|
102
104
|
emailVerified: true,
|
|
103
105
|
lastSignInAt: '2023-07-18T02:07:19.911Z',
|
|
106
|
+
locale: 'en-US',
|
|
104
107
|
externalId,
|
|
105
108
|
});
|
|
106
109
|
}));
|
|
@@ -889,6 +892,39 @@ describe('UserManagement', () => {
|
|
|
889
892
|
accessToken,
|
|
890
893
|
});
|
|
891
894
|
}));
|
|
895
|
+
it('returns the JWT claims when provided a valid JWT with multiple roles', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
896
|
+
jest
|
|
897
|
+
.spyOn(jose, 'jwtVerify')
|
|
898
|
+
.mockResolvedValue({});
|
|
899
|
+
const cookiePassword = 'alongcookiesecretmadefortestingsessions';
|
|
900
|
+
const accessToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdXRoZW50aWNhdGVkIjp0cnVlLCJpbXBlcnNvbmF0b3IiOnsiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSIsInJlYXNvbiI6InRlc3QifSwic2lkIjoic2Vzc2lvbl8xMjMiLCJvcmdfaWQiOiJvcmdfMTIzIiwicm9sZSI6ImFkbWluIiwicm9sZXMiOlsiYWRtaW4iLCJtZW1iZXIiXSwicGVybWlzc2lvbnMiOlsicG9zdHM6Y3JlYXRlIiwicG9zdHM6ZGVsZXRlIl0sImVudGl0bGVtZW50cyI6WyJhdWRpdC1sb2dzIl0sImZlYXR1cmVfZmxhZ3MiOlsiZGFyay1tb2RlIiwiYmV0YS1mZWF0dXJlcyJdLCJ1c2VyIjp7Im9iamVjdCI6InVzZXIiLCJpZCI6InVzZXJfMDFINUpRRFY3UjdBVEVZWkRFRzBXNVBSWVMiLCJlbWFpbCI6InRlc3RAZXhhbXBsZS5jb20ifX0.hsMptIB7PmbF5pxxtgTtCdUyOAhA11ZIAP-JY5zU5fE';
|
|
901
|
+
const sessionData = yield (0, iron_session_1.sealData)({
|
|
902
|
+
accessToken,
|
|
903
|
+
refreshToken: 'def456',
|
|
904
|
+
user: {
|
|
905
|
+
object: 'user',
|
|
906
|
+
id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
|
|
907
|
+
email: 'test@example.com',
|
|
908
|
+
},
|
|
909
|
+
}, { password: cookiePassword });
|
|
910
|
+
yield expect(workos.userManagement.authenticateWithSessionCookie({
|
|
911
|
+
sessionData,
|
|
912
|
+
cookiePassword,
|
|
913
|
+
})).resolves.toEqual({
|
|
914
|
+
authenticated: true,
|
|
915
|
+
sessionId: 'session_123',
|
|
916
|
+
organizationId: 'org_123',
|
|
917
|
+
role: 'admin',
|
|
918
|
+
roles: ['admin', 'member'],
|
|
919
|
+
permissions: ['posts:create', 'posts:delete'],
|
|
920
|
+
entitlements: ['audit-logs'],
|
|
921
|
+
featureFlags: ['dark-mode', 'beta-features'],
|
|
922
|
+
user: expect.objectContaining({
|
|
923
|
+
email: 'test@example.com',
|
|
924
|
+
}),
|
|
925
|
+
accessToken,
|
|
926
|
+
});
|
|
927
|
+
}));
|
|
892
928
|
});
|
|
893
929
|
describe('refreshAndSealSessionData', () => {
|
|
894
930
|
it('throws an error when the cookie password is undefined', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -1208,6 +1244,21 @@ describe('UserManagement', () => {
|
|
|
1208
1244
|
metadata: {},
|
|
1209
1245
|
});
|
|
1210
1246
|
}));
|
|
1247
|
+
it('updates user locale', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1248
|
+
(0, test_utils_1.fetchOnce)(user_json_1.default);
|
|
1249
|
+
const resp = yield workos.userManagement.updateUser({
|
|
1250
|
+
userId,
|
|
1251
|
+
locale: 'en-US',
|
|
1252
|
+
});
|
|
1253
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/user_management/users/${userId}`);
|
|
1254
|
+
expect((0, test_utils_1.fetchBody)()).toEqual({
|
|
1255
|
+
locale: 'en-US',
|
|
1256
|
+
});
|
|
1257
|
+
expect(resp).toMatchObject({
|
|
1258
|
+
id: userId,
|
|
1259
|
+
locale: 'en-US',
|
|
1260
|
+
});
|
|
1261
|
+
}));
|
|
1211
1262
|
});
|
|
1212
1263
|
describe('enrollAuthFactor', () => {
|
|
1213
1264
|
it('sends an enrollAuthFactor request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -1298,6 +1349,90 @@ describe('UserManagement', () => {
|
|
|
1298
1349
|
});
|
|
1299
1350
|
}));
|
|
1300
1351
|
});
|
|
1352
|
+
describe('listUserFeatureFlags', () => {
|
|
1353
|
+
it('returns feature flags for the user', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1354
|
+
(0, test_utils_1.fetchOnce)(list_user_feature_flags_json_1.default);
|
|
1355
|
+
const { data, object, listMetadata } = yield workos.userManagement.listUserFeatureFlags({ userId });
|
|
1356
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/user_management/users/${userId}/feature-flags`);
|
|
1357
|
+
expect(object).toEqual('list');
|
|
1358
|
+
expect(listMetadata).toEqual({});
|
|
1359
|
+
expect(data).toHaveLength(3);
|
|
1360
|
+
expect(data).toEqual([
|
|
1361
|
+
{
|
|
1362
|
+
object: 'feature_flag',
|
|
1363
|
+
id: 'flag_01EHQMYV6MBK39QC5PZXHY59C5',
|
|
1364
|
+
name: 'Advanced Dashboard',
|
|
1365
|
+
slug: 'advanced-dashboard',
|
|
1366
|
+
description: 'Enable advanced dashboard features',
|
|
1367
|
+
createdAt: '2024-01-01T00:00:00.000Z',
|
|
1368
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
1369
|
+
},
|
|
1370
|
+
{
|
|
1371
|
+
object: 'feature_flag',
|
|
1372
|
+
id: 'flag_01EHQMYV6MBK39QC5PZXHY59C6',
|
|
1373
|
+
name: 'Beta Features',
|
|
1374
|
+
slug: 'beta-features',
|
|
1375
|
+
description: null,
|
|
1376
|
+
createdAt: '2024-01-01T00:00:00.000Z',
|
|
1377
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
1378
|
+
},
|
|
1379
|
+
{
|
|
1380
|
+
object: 'feature_flag',
|
|
1381
|
+
id: 'flag_01EHQMYV6MBK39QC5PZXHY59C7',
|
|
1382
|
+
name: 'Premium Support',
|
|
1383
|
+
slug: 'premium-support',
|
|
1384
|
+
description: 'Access to premium support features',
|
|
1385
|
+
createdAt: '2024-01-01T00:00:00.000Z',
|
|
1386
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
1387
|
+
},
|
|
1388
|
+
]);
|
|
1389
|
+
}));
|
|
1390
|
+
describe('with the before option', () => {
|
|
1391
|
+
it('forms the proper request to the API', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1392
|
+
(0, test_utils_1.fetchOnce)(list_user_feature_flags_json_1.default);
|
|
1393
|
+
const { data } = yield workos.userManagement.listUserFeatureFlags({
|
|
1394
|
+
userId,
|
|
1395
|
+
before: 'flag_before_id',
|
|
1396
|
+
});
|
|
1397
|
+
expect((0, test_utils_1.fetchSearchParams)()).toEqual({
|
|
1398
|
+
before: 'flag_before_id',
|
|
1399
|
+
order: 'desc',
|
|
1400
|
+
});
|
|
1401
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/user_management/users/${userId}/feature-flags`);
|
|
1402
|
+
expect(data).toHaveLength(3);
|
|
1403
|
+
}));
|
|
1404
|
+
});
|
|
1405
|
+
describe('with the after option', () => {
|
|
1406
|
+
it('forms the proper request to the API', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1407
|
+
(0, test_utils_1.fetchOnce)(list_user_feature_flags_json_1.default);
|
|
1408
|
+
const { data } = yield workos.userManagement.listUserFeatureFlags({
|
|
1409
|
+
userId,
|
|
1410
|
+
after: 'flag_after_id',
|
|
1411
|
+
});
|
|
1412
|
+
expect((0, test_utils_1.fetchSearchParams)()).toEqual({
|
|
1413
|
+
after: 'flag_after_id',
|
|
1414
|
+
order: 'desc',
|
|
1415
|
+
});
|
|
1416
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/user_management/users/${userId}/feature-flags`);
|
|
1417
|
+
expect(data).toHaveLength(3);
|
|
1418
|
+
}));
|
|
1419
|
+
});
|
|
1420
|
+
describe('with the limit option', () => {
|
|
1421
|
+
it('forms the proper request to the API', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1422
|
+
(0, test_utils_1.fetchOnce)(list_user_feature_flags_json_1.default);
|
|
1423
|
+
const { data } = yield workos.userManagement.listUserFeatureFlags({
|
|
1424
|
+
userId,
|
|
1425
|
+
limit: 3,
|
|
1426
|
+
});
|
|
1427
|
+
expect((0, test_utils_1.fetchSearchParams)()).toEqual({
|
|
1428
|
+
limit: '3',
|
|
1429
|
+
order: 'desc',
|
|
1430
|
+
});
|
|
1431
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/user_management/users/${userId}/feature-flags`);
|
|
1432
|
+
expect(data).toHaveLength(3);
|
|
1433
|
+
}));
|
|
1434
|
+
});
|
|
1435
|
+
});
|
|
1301
1436
|
describe('listSessions', () => {
|
|
1302
1437
|
it('sends a listSessions request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1303
1438
|
(0, test_utils_1.fetchOnce)(list_sessions_json_1.default);
|
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.71.0';
|
|
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
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|