@scalekit-sdk/node 1.0.13 → 2.0.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/buf.gen.yaml +2 -1
- package/lib/core.js +1 -1
- package/lib/core.js.map +1 -1
- package/lib/pkg/grpc/scalekit/v1/commons/commons_pb.d.ts +217 -0
- package/lib/pkg/grpc/scalekit/v1/commons/commons_pb.js +289 -1
- package/lib/pkg/grpc/scalekit/v1/commons/commons_pb.js.map +1 -1
- package/lib/pkg/grpc/scalekit/v1/users/users_connect.d.ts +117 -0
- package/lib/pkg/grpc/scalekit/v1/users/users_connect.js +125 -0
- package/lib/pkg/grpc/scalekit/v1/users/users_connect.js.map +1 -0
- package/lib/pkg/grpc/scalekit/v1/users/users_pb.d.ts +806 -0
- package/lib/pkg/grpc/scalekit/v1/users/users_pb.js +1048 -0
- package/lib/pkg/grpc/scalekit/v1/users/users_pb.js.map +1 -0
- package/lib/scalekit.d.ts +31 -2
- package/lib/scalekit.js +71 -4
- package/lib/scalekit.js.map +1 -1
- package/lib/types/auth.d.ts +1 -0
- package/lib/types/scalekit.d.ts +11 -0
- package/lib/types/user.d.ts +20 -0
- package/lib/types/user.js +3 -0
- package/lib/types/user.js.map +1 -0
- package/lib/user.d.ts +95 -0
- package/lib/user.js +218 -0
- package/lib/user.js.map +1 -0
- package/package.json +8 -3
- package/src/core.ts +1 -1
- package/src/pkg/grpc/scalekit/v1/commons/commons_pb.ts +351 -1
- package/src/pkg/grpc/scalekit/v1/users/users_connect.ts +124 -0
- package/src/pkg/grpc/scalekit/v1/users/users_pb.ts +1440 -0
- package/src/scalekit.ts +87 -7
- package/src/types/auth.ts +1 -0
- package/src/types/scalekit.ts +13 -0
- package/src/types/user.ts +21 -0
- package/src/user.ts +291 -0
package/src/scalekit.ts
CHANGED
|
@@ -9,10 +9,12 @@ import DirectoryClient from './directory';
|
|
|
9
9
|
import DomainClient from './domain';
|
|
10
10
|
import OrganizationClient from './organization';
|
|
11
11
|
import PasswordlessClient from './passwordless';
|
|
12
|
+
import UserClient from './user';
|
|
12
13
|
import { IdpInitiatedLoginClaims, IdTokenClaim, User } from './types/auth';
|
|
13
|
-
import { AuthenticationOptions, AuthenticationResponse, AuthorizationUrlOptions, GrantType } from './types/scalekit';
|
|
14
|
+
import { AuthenticationOptions, AuthenticationResponse, AuthorizationUrlOptions, GrantType, LogoutUrlOptions, RefreshTokenResponse } from './types/scalekit';
|
|
14
15
|
|
|
15
16
|
const authorizeEndpoint = "oauth/authorize";
|
|
17
|
+
const logoutEndpoint = "oidc/logout";
|
|
16
18
|
const WEBHOOK_TOLERANCE_IN_SECONDS = 5 * 60; // 5 minutes
|
|
17
19
|
const WEBHOOK_SIGNATURE_VERSION = "v1";
|
|
18
20
|
|
|
@@ -33,6 +35,7 @@ export default class ScalekitClient {
|
|
|
33
35
|
readonly domain: DomainClient;
|
|
34
36
|
readonly directory: DirectoryClient;
|
|
35
37
|
readonly passwordless: PasswordlessClient;
|
|
38
|
+
readonly user: UserClient;
|
|
36
39
|
constructor(
|
|
37
40
|
envUrl: string,
|
|
38
41
|
clientId: string,
|
|
@@ -67,6 +70,10 @@ export default class ScalekitClient {
|
|
|
67
70
|
this.grpcConnect,
|
|
68
71
|
this.coreClient
|
|
69
72
|
);
|
|
73
|
+
this.user = new UserClient(
|
|
74
|
+
this.grpcConnect,
|
|
75
|
+
this.coreClient
|
|
76
|
+
);
|
|
70
77
|
}
|
|
71
78
|
|
|
72
79
|
/**
|
|
@@ -83,10 +90,14 @@ export default class ScalekitClient {
|
|
|
83
90
|
* @param {string} options.provider Provider i.e. google, github, etc.
|
|
84
91
|
* @param {string} options.codeChallenge Code challenge parameter in case of PKCE
|
|
85
92
|
* @param {string} options.codeChallengeMethod Code challenge method parameter in case of PKCE
|
|
93
|
+
* @param {string} options.prompt Prompt parameter to control the authorization server's authentication behavior
|
|
86
94
|
*
|
|
87
95
|
* @example
|
|
88
96
|
* const scalekit = new Scalekit(envUrl, clientId, clientSecret);
|
|
89
|
-
* const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, {
|
|
97
|
+
* const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, {
|
|
98
|
+
* scopes: ['openid', 'profile'],
|
|
99
|
+
* prompt: 'create'
|
|
100
|
+
* });
|
|
90
101
|
* @returns {string} authorization url
|
|
91
102
|
*/
|
|
92
103
|
getAuthorizationUrl(
|
|
@@ -114,7 +125,8 @@ export default class ScalekitClient {
|
|
|
114
125
|
...(options.organizationId && { organization_id: options.organizationId }),
|
|
115
126
|
...(options.codeChallenge && { code_challenge: options.codeChallenge }),
|
|
116
127
|
...(options.codeChallengeMethod && { code_challenge_method: options.codeChallengeMethod }),
|
|
117
|
-
...(options.provider && { provider: options.provider })
|
|
128
|
+
...(options.provider && { provider: options.provider }),
|
|
129
|
+
...(options.prompt && { prompt: options.prompt })
|
|
118
130
|
})
|
|
119
131
|
|
|
120
132
|
return `${this.coreClient.envUrl}/${authorizeEndpoint}?${qs}`
|
|
@@ -141,7 +153,7 @@ export default class ScalekitClient {
|
|
|
141
153
|
client_secret: this.coreClient.clientSecret,
|
|
142
154
|
...(options?.codeVerifier && { code_verifier: options.codeVerifier })
|
|
143
155
|
}))
|
|
144
|
-
const { id_token, access_token, expires_in } = res.data;
|
|
156
|
+
const { id_token, access_token, expires_in , refresh_token } = res.data;
|
|
145
157
|
const claims = jose.decodeJwt<IdTokenClaim>(id_token);
|
|
146
158
|
const user = <User>{};
|
|
147
159
|
for (const [k, v] of Object.entries(claims)) {
|
|
@@ -154,7 +166,8 @@ export default class ScalekitClient {
|
|
|
154
166
|
user,
|
|
155
167
|
idToken: id_token,
|
|
156
168
|
accessToken: access_token,
|
|
157
|
-
expiresIn: expires_in
|
|
169
|
+
expiresIn: expires_in,
|
|
170
|
+
refreshToken: refresh_token
|
|
158
171
|
}
|
|
159
172
|
}
|
|
160
173
|
|
|
@@ -169,7 +182,7 @@ export default class ScalekitClient {
|
|
|
169
182
|
}
|
|
170
183
|
|
|
171
184
|
/**
|
|
172
|
-
* Validates the access token.
|
|
185
|
+
* Validates the access token.
|
|
173
186
|
*
|
|
174
187
|
* @param {string} token The token to be validated.
|
|
175
188
|
* @return {Promise<boolean>} Returns true if the token is valid, false otherwise.
|
|
@@ -183,6 +196,31 @@ export default class ScalekitClient {
|
|
|
183
196
|
}
|
|
184
197
|
}
|
|
185
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Returns the logout URL that can be used to log out the user.
|
|
201
|
+
* @param {LogoutUrlOptions} options Logout URL options
|
|
202
|
+
* @param {string} options.idTokenHint The ID Token previously issued to the client
|
|
203
|
+
* @param {string} options.postLogoutRedirectUri URL to redirect after logout
|
|
204
|
+
* @param {string} options.state Opaque value to maintain state between request and callback
|
|
205
|
+
* @returns {string} The logout URL
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* const scalekit = new Scalekit(envUrl, clientId, clientSecret);
|
|
209
|
+
* const logoutUrl = scalekit.getLogoutUrl({
|
|
210
|
+
* postLogoutRedirectUri: 'https://example.com',
|
|
211
|
+
* state: 'some-state'
|
|
212
|
+
* });
|
|
213
|
+
*/
|
|
214
|
+
getLogoutUrl(options?: LogoutUrlOptions): string {
|
|
215
|
+
const qs = QueryString.stringify({
|
|
216
|
+
...(options?.idTokenHint && { id_token_hint: options.idTokenHint }),
|
|
217
|
+
...(options?.postLogoutRedirectUri && { post_logout_redirect_uri: options.postLogoutRedirectUri }),
|
|
218
|
+
...(options?.state && { state: options.state })
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
return `${this.coreClient.envUrl}/${logoutEndpoint}${qs ? `?${qs}` : ''}`;
|
|
222
|
+
}
|
|
223
|
+
|
|
186
224
|
/**
|
|
187
225
|
* Verifies the payload of the webhook
|
|
188
226
|
*
|
|
@@ -267,6 +305,48 @@ export default class ScalekitClient {
|
|
|
267
305
|
private computeSignature(secretBytes: Buffer, data: string): string {
|
|
268
306
|
return crypto.createHmac('sha256', secretBytes).update(data).digest('base64');
|
|
269
307
|
}
|
|
270
|
-
}
|
|
271
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Refresh access token using a refresh token
|
|
311
|
+
* @param {string} refreshToken The refresh token to use
|
|
312
|
+
* @returns {Promise<RefreshTokenResponse>} Returns new access token, refresh token and other details
|
|
313
|
+
* @throws {Error} When authentication fails or response data is invalid
|
|
314
|
+
*/
|
|
315
|
+
async refreshAccessToken(refreshToken: string): Promise<RefreshTokenResponse> {
|
|
316
|
+
if (!refreshToken) {
|
|
317
|
+
throw new Error("Refresh token is required");
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
let res;
|
|
321
|
+
try {
|
|
322
|
+
res = await this.coreClient.authenticate(QueryString.stringify({
|
|
323
|
+
grant_type: GrantType.RefreshToken,
|
|
324
|
+
client_id: this.coreClient.clientId,
|
|
325
|
+
client_secret: this.coreClient.clientSecret,
|
|
326
|
+
refresh_token: refreshToken
|
|
327
|
+
}));
|
|
328
|
+
} catch (error) {
|
|
329
|
+
throw new Error(`Failed to refresh token: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (!res || !res.data) {
|
|
333
|
+
throw new Error("Invalid response from authentication server");
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const { access_token, refresh_token } = res.data;
|
|
337
|
+
|
|
338
|
+
// Validate that all required properties exist
|
|
339
|
+
if (!access_token) {
|
|
340
|
+
throw new Error("Missing access_token in authentication response");
|
|
341
|
+
}
|
|
342
|
+
if (!refresh_token) {
|
|
343
|
+
throw new Error("Missing refresh_token in authentication response");
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return {
|
|
347
|
+
accessToken: access_token,
|
|
348
|
+
refreshToken: refresh_token
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
}
|
|
272
352
|
|
package/src/types/auth.ts
CHANGED
package/src/types/scalekit.ts
CHANGED
|
@@ -17,6 +17,7 @@ export type AuthorizationUrlOptions = {
|
|
|
17
17
|
codeChallenge?: string;
|
|
18
18
|
codeChallengeMethod?: string;
|
|
19
19
|
provider?: string;
|
|
20
|
+
prompt?: string;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export type AuthenticationOptions = {
|
|
@@ -28,4 +29,16 @@ export type AuthenticationResponse = {
|
|
|
28
29
|
idToken: string;
|
|
29
30
|
accessToken: string;
|
|
30
31
|
expiresIn: number;
|
|
32
|
+
refreshToken: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type RefreshTokenResponse = {
|
|
36
|
+
accessToken: string;
|
|
37
|
+
refreshToken: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface LogoutUrlOptions {
|
|
41
|
+
idTokenHint?: string;
|
|
42
|
+
postLogoutRedirectUri?: string;
|
|
43
|
+
state?: string;
|
|
31
44
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface CreateUserRequest {
|
|
2
|
+
email: string;
|
|
3
|
+
externalId?: string;
|
|
4
|
+
phoneNumber?: string;
|
|
5
|
+
userProfile?: {
|
|
6
|
+
firstName?: string;
|
|
7
|
+
lastName?: string;
|
|
8
|
+
};
|
|
9
|
+
metadata?: Record<string, string>;
|
|
10
|
+
sendActivationEmail?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface UpdateUserRequest {
|
|
14
|
+
email?: string;
|
|
15
|
+
externalId?: string;
|
|
16
|
+
userProfile?: {
|
|
17
|
+
firstName?: string;
|
|
18
|
+
lastName?: string;
|
|
19
|
+
};
|
|
20
|
+
metadata?: Record<string, string>;
|
|
21
|
+
}
|
package/src/user.ts
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { Empty, PartialMessage } from '@bufbuild/protobuf';
|
|
2
|
+
import { PromiseClient } from '@connectrpc/connect';
|
|
3
|
+
import GrpcConnect from './connect';
|
|
4
|
+
import CoreClient from './core';
|
|
5
|
+
import { UserService } from './pkg/grpc/scalekit/v1/users/users_connect';
|
|
6
|
+
import {
|
|
7
|
+
CreateUserAndMembershipRequest,
|
|
8
|
+
CreateUserAndMembershipResponse,
|
|
9
|
+
DeleteUserRequest,
|
|
10
|
+
GetUserRequest,
|
|
11
|
+
GetUserResponse,
|
|
12
|
+
ListUsersRequest,
|
|
13
|
+
ListUsersResponse,
|
|
14
|
+
UpdateUserRequest,
|
|
15
|
+
UpdateUserResponse,
|
|
16
|
+
User,
|
|
17
|
+
UpdateUser,
|
|
18
|
+
CreateUser,
|
|
19
|
+
CreateUserProfile,
|
|
20
|
+
CreateMembershipRequest,
|
|
21
|
+
CreateMembershipResponse,
|
|
22
|
+
DeleteMembershipRequest,
|
|
23
|
+
UpdateMembershipRequest,
|
|
24
|
+
UpdateMembershipResponse,
|
|
25
|
+
ListOrganizationUsersRequest,
|
|
26
|
+
ListOrganizationUsersResponse,
|
|
27
|
+
CreateMembership,
|
|
28
|
+
UpdateMembership
|
|
29
|
+
} from './pkg/grpc/scalekit/v1/users/users_pb';
|
|
30
|
+
import { CreateUserRequest, UpdateUserRequest as UpdateUserRequestType } from './types/user';
|
|
31
|
+
|
|
32
|
+
export default class UserClient {
|
|
33
|
+
private client: PromiseClient<typeof UserService>;
|
|
34
|
+
|
|
35
|
+
constructor(
|
|
36
|
+
private readonly grpcConnect: GrpcConnect,
|
|
37
|
+
private readonly coreClient: CoreClient
|
|
38
|
+
) {
|
|
39
|
+
this.client = this.grpcConnect.createClient(UserService);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Create a new user and add them to an organization
|
|
44
|
+
* @param {string} organizationId The organization id
|
|
45
|
+
* @param {CreateUserRequest} options The user creation options
|
|
46
|
+
* @returns {Promise<CreateUserAndMembershipResponse>} The created user
|
|
47
|
+
*/
|
|
48
|
+
async createUserAndMembership(organizationId: string, options: CreateUserRequest): Promise<CreateUserAndMembershipResponse> {
|
|
49
|
+
if (!organizationId) {
|
|
50
|
+
throw new Error('organizationId is required');
|
|
51
|
+
}
|
|
52
|
+
if (!options.email) {
|
|
53
|
+
throw new Error('email is required');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const user = new CreateUser({
|
|
57
|
+
email: options.email,
|
|
58
|
+
userProfile: options.userProfile ? new CreateUserProfile({
|
|
59
|
+
firstName: options.userProfile.firstName,
|
|
60
|
+
lastName: options.userProfile.lastName
|
|
61
|
+
}) : undefined,
|
|
62
|
+
metadata: options.metadata
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const request: PartialMessage<CreateUserAndMembershipRequest> = {
|
|
66
|
+
organizationId,
|
|
67
|
+
user
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
if (options.sendActivationEmail !== undefined) {
|
|
71
|
+
request.sendActivationEmail = options.sendActivationEmail;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const response = await this.coreClient.connectExec(
|
|
75
|
+
this.client.createUserAndMembership,
|
|
76
|
+
request
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
if (!response.user) {
|
|
80
|
+
throw new Error('Failed to create user');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return response;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get a user by id
|
|
88
|
+
* @param {string} userId The user id
|
|
89
|
+
* @returns {Promise<GetUserResponse>} The user
|
|
90
|
+
*/
|
|
91
|
+
async getUser(userId: string): Promise<GetUserResponse> {
|
|
92
|
+
return this.coreClient.connectExec(
|
|
93
|
+
this.client.getUser,
|
|
94
|
+
{
|
|
95
|
+
identities: {
|
|
96
|
+
case: 'id',
|
|
97
|
+
value: userId
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* List users with pagination
|
|
105
|
+
* @param {object} options The pagination options
|
|
106
|
+
* @param {number} options.pageSize The page size
|
|
107
|
+
* @param {string} options.pageToken The page token
|
|
108
|
+
* @returns {Promise<ListUsersResponse>} The list of users
|
|
109
|
+
*/
|
|
110
|
+
async listUsers(options?: {
|
|
111
|
+
pageSize?: number,
|
|
112
|
+
pageToken?: string
|
|
113
|
+
}): Promise<ListUsersResponse> {
|
|
114
|
+
return this.coreClient.connectExec(
|
|
115
|
+
this.client.listUsers,
|
|
116
|
+
{
|
|
117
|
+
pageSize: options?.pageSize,
|
|
118
|
+
pageToken: options?.pageToken
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Update a user
|
|
125
|
+
* @param {string} userId The user id
|
|
126
|
+
* @param {UpdateUserRequestType} options The update options
|
|
127
|
+
* @returns {Promise<UpdateUserResponse>} The updated user
|
|
128
|
+
*/
|
|
129
|
+
async updateUser(userId: string, options: UpdateUserRequestType): Promise<UpdateUserResponse> {
|
|
130
|
+
const updateUser = new UpdateUser({
|
|
131
|
+
userProfile: options.userProfile ? {
|
|
132
|
+
firstName: options.userProfile.firstName,
|
|
133
|
+
lastName: options.userProfile.lastName
|
|
134
|
+
} : undefined,
|
|
135
|
+
metadata: options.metadata
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
return this.coreClient.connectExec(
|
|
139
|
+
this.client.updateUser,
|
|
140
|
+
{
|
|
141
|
+
identities: {
|
|
142
|
+
case: 'id',
|
|
143
|
+
value: userId
|
|
144
|
+
},
|
|
145
|
+
user: updateUser
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Delete a user
|
|
152
|
+
* @param {string} userId The user id
|
|
153
|
+
* @returns {Promise<Empty>} Empty response
|
|
154
|
+
*/
|
|
155
|
+
async deleteUser(userId: string): Promise<Empty> {
|
|
156
|
+
return this.coreClient.connectExec(
|
|
157
|
+
this.client.deleteUser,
|
|
158
|
+
{
|
|
159
|
+
identities: {
|
|
160
|
+
case: 'id',
|
|
161
|
+
value: userId
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Create a membership for a user in an organization
|
|
169
|
+
* @param {string} organizationId The organization id
|
|
170
|
+
* @param {string} userId The user id
|
|
171
|
+
* @param {object} options The membership options
|
|
172
|
+
* @param {string[]} options.roles The roles to assign
|
|
173
|
+
* @param {Record<string, string>} options.metadata Optional metadata
|
|
174
|
+
* @param {boolean} options.sendActivationEmail Whether to send activation email
|
|
175
|
+
* @returns {Promise<CreateMembershipResponse>} The response with updated user
|
|
176
|
+
*/
|
|
177
|
+
async createMembership(
|
|
178
|
+
organizationId: string,
|
|
179
|
+
userId: string,
|
|
180
|
+
options: {
|
|
181
|
+
roles?: string[],
|
|
182
|
+
metadata?: Record<string, string>,
|
|
183
|
+
sendActivationEmail?: boolean
|
|
184
|
+
} = {}
|
|
185
|
+
): Promise<CreateMembershipResponse> {
|
|
186
|
+
const membership = new CreateMembership({
|
|
187
|
+
roles: options.roles?.map(role => ({ name: role })) || [],
|
|
188
|
+
metadata: options.metadata || {}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const request: PartialMessage<CreateMembershipRequest> = {
|
|
192
|
+
organizationId,
|
|
193
|
+
identities: {
|
|
194
|
+
case: 'id',
|
|
195
|
+
value: userId
|
|
196
|
+
},
|
|
197
|
+
membership
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
if (options.sendActivationEmail !== undefined) {
|
|
201
|
+
request.sendActivationEmail = options.sendActivationEmail;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return this.coreClient.connectExec(
|
|
205
|
+
this.client.createMembership,
|
|
206
|
+
request
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Delete a user's membership from an organization
|
|
212
|
+
* @param {string} organizationId The organization id
|
|
213
|
+
* @param {string} userId The user id
|
|
214
|
+
* @returns {Promise<Empty>} Empty response
|
|
215
|
+
*/
|
|
216
|
+
async deleteMembership(
|
|
217
|
+
organizationId: string,
|
|
218
|
+
userId: string
|
|
219
|
+
): Promise<Empty> {
|
|
220
|
+
return this.coreClient.connectExec(
|
|
221
|
+
this.client.deleteMembership,
|
|
222
|
+
{
|
|
223
|
+
organizationId,
|
|
224
|
+
identities: {
|
|
225
|
+
case: 'id',
|
|
226
|
+
value: userId
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Update a user's membership in an organization
|
|
234
|
+
* @param {string} organizationId The organization id
|
|
235
|
+
* @param {string} userId The user id
|
|
236
|
+
* @param {object} options The update options
|
|
237
|
+
* @param {string[]} options.roles The roles to assign
|
|
238
|
+
* @param {Record<string, string>} options.metadata Optional metadata
|
|
239
|
+
* @returns {Promise<UpdateMembershipResponse>} The response with updated user
|
|
240
|
+
*/
|
|
241
|
+
async updateMembership(
|
|
242
|
+
organizationId: string,
|
|
243
|
+
userId: string,
|
|
244
|
+
options: {
|
|
245
|
+
roles?: string[],
|
|
246
|
+
metadata?: Record<string, string>
|
|
247
|
+
} = {}
|
|
248
|
+
): Promise<UpdateMembershipResponse> {
|
|
249
|
+
const membership = new UpdateMembership({
|
|
250
|
+
roles: options.roles?.map(role => ({ name: role })) || [],
|
|
251
|
+
metadata: options.metadata || {}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
return this.coreClient.connectExec(
|
|
255
|
+
this.client.updateMembership,
|
|
256
|
+
{
|
|
257
|
+
organizationId,
|
|
258
|
+
identities: {
|
|
259
|
+
case: 'id',
|
|
260
|
+
value: userId
|
|
261
|
+
},
|
|
262
|
+
membership
|
|
263
|
+
}
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* List users in an organization with pagination
|
|
269
|
+
* @param {string} organizationId The organization id
|
|
270
|
+
* @param {object} options The pagination options
|
|
271
|
+
* @param {number} options.pageSize The page size
|
|
272
|
+
* @param {string} options.pageToken The page token
|
|
273
|
+
* @returns {Promise<ListOrganizationUsersResponse>} The list of users in the organization
|
|
274
|
+
*/
|
|
275
|
+
async listOrganizationUsers(
|
|
276
|
+
organizationId: string,
|
|
277
|
+
options?: {
|
|
278
|
+
pageSize?: number,
|
|
279
|
+
pageToken?: string
|
|
280
|
+
}
|
|
281
|
+
): Promise<ListOrganizationUsersResponse> {
|
|
282
|
+
return this.coreClient.connectExec(
|
|
283
|
+
this.client.listOrganizationUsers,
|
|
284
|
+
{
|
|
285
|
+
organizationId,
|
|
286
|
+
pageSize: options?.pageSize,
|
|
287
|
+
pageToken: options?.pageToken
|
|
288
|
+
}
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
}
|