@linagora/ldap-rest-client 1.0.2 → 1.0.4
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/README.md +47 -1
- package/dist/index.d.mts +172 -24
- package/dist/index.d.ts +172 -24
- package/dist/index.js +45 -6
- package/dist/index.mjs +45 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,6 +66,11 @@ client.organizations.createAdmin(orgId, { username, mail })
|
|
|
66
66
|
client.organizations.list()
|
|
67
67
|
client.organizations.get(orgId)
|
|
68
68
|
client.organizations.update(orgId, updates)
|
|
69
|
+
|
|
70
|
+
// Organization ownership management
|
|
71
|
+
client.organizations.getOwner(orgId)
|
|
72
|
+
client.organizations.setOwner(orgId, { username, mail })
|
|
73
|
+
client.organizations.transferOwnership(orgId, { newOwnerUsername })
|
|
69
74
|
```
|
|
70
75
|
|
|
71
76
|
### B2B Users (within Organizations)
|
|
@@ -75,8 +80,10 @@ client.organizations.updateUser(orgId, userId, updates)
|
|
|
75
80
|
client.organizations.disableUser(orgId, userId)
|
|
76
81
|
client.organizations.deleteUser(orgId, userId)
|
|
77
82
|
client.organizations.getUser(orgId, { by, value })
|
|
78
|
-
client.organizations.listUsers(orgId, { page, limit, status, search })
|
|
83
|
+
client.organizations.listUsers(orgId, { page, limit, status, search, sortBy, sortOrder })
|
|
79
84
|
client.organizations.checkUserAvailability(orgId, { field, value })
|
|
85
|
+
|
|
86
|
+
// User role management ('owner', 'admin', 'moderator', 'member')
|
|
80
87
|
client.organizations.changeUserRole(orgId, userId, { role })
|
|
81
88
|
```
|
|
82
89
|
|
|
@@ -91,6 +98,45 @@ client.groups.addMembers(orgId, groupId, { usernames })
|
|
|
91
98
|
client.groups.removeMember(orgId, groupId, userId)
|
|
92
99
|
```
|
|
93
100
|
|
|
101
|
+
## Configuration
|
|
102
|
+
|
|
103
|
+
### Client Options
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
const client = new LdapRestClient({
|
|
107
|
+
baseUrl: 'https://ldap-rest.example.com',
|
|
108
|
+
auth: {
|
|
109
|
+
type: 'hmac',
|
|
110
|
+
serviceId: 'my-service',
|
|
111
|
+
secret: 'your-secret-key-at-least-32-chars-long',
|
|
112
|
+
},
|
|
113
|
+
timeout: 30000, // Request timeout in milliseconds (default: 30000)
|
|
114
|
+
logger: {
|
|
115
|
+
// Optional tslog configuration for custom logging
|
|
116
|
+
minLevel: 'info',
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Authentication Types
|
|
122
|
+
|
|
123
|
+
**HMAC (Backend Services)**
|
|
124
|
+
```typescript
|
|
125
|
+
auth: {
|
|
126
|
+
type: 'hmac',
|
|
127
|
+
serviceId: 'registration-service',
|
|
128
|
+
secret: 'your-secret-key', // Minimum 32 characters recommended
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Cookie (Browser/SSO)**
|
|
133
|
+
```typescript
|
|
134
|
+
auth: {
|
|
135
|
+
type: 'cookie', // Uses cookies set by authentication service
|
|
136
|
+
}
|
|
137
|
+
// Or omit auth entirely (defaults to cookie)
|
|
138
|
+
```
|
|
139
|
+
|
|
94
140
|
## Error Handling
|
|
95
141
|
|
|
96
142
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -2,16 +2,22 @@ import { ISettingsParam, Logger } from 'tslog';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* HMAC authentication configuration for backend services
|
|
5
|
+
* Uses HMAC-SHA256 signatures as per ADR-024
|
|
5
6
|
*/
|
|
6
7
|
interface HmacAuthConfig {
|
|
8
|
+
/** Authentication type */
|
|
7
9
|
type: 'hmac';
|
|
10
|
+
/** Service identifier (e.g., 'registration-service') */
|
|
8
11
|
serviceId: string;
|
|
12
|
+
/** Shared secret key (minimum 32 characters recommended) */
|
|
9
13
|
secret: string;
|
|
10
14
|
}
|
|
11
15
|
/**
|
|
12
16
|
* SSO Cookie authentication configuration for browser requests
|
|
17
|
+
* Relies on cookies set by the authentication service
|
|
13
18
|
*/
|
|
14
19
|
interface CookieAuthConfig {
|
|
20
|
+
/** Authentication type */
|
|
15
21
|
type: 'cookie';
|
|
16
22
|
}
|
|
17
23
|
/**
|
|
@@ -22,16 +28,23 @@ type AuthConfig = HmacAuthConfig | CookieAuthConfig;
|
|
|
22
28
|
* Configuration for LDAP-REST client
|
|
23
29
|
*/
|
|
24
30
|
interface ClientConfig {
|
|
31
|
+
/** Base URL of the LDAP-REST API (e.g., 'https://ldap-rest.example.com') */
|
|
25
32
|
baseUrl: string;
|
|
33
|
+
/** Authentication configuration (defaults to cookie auth if not provided) */
|
|
26
34
|
auth?: AuthConfig;
|
|
35
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
27
36
|
timeout?: number;
|
|
37
|
+
/** tslog logger configuration for custom logging */
|
|
28
38
|
logger?: ISettingsParam<unknown>;
|
|
29
39
|
}
|
|
30
40
|
/**
|
|
31
41
|
* HTTP client configuration
|
|
42
|
+
* Subset of configuration passed to the HTTP client
|
|
32
43
|
*/
|
|
33
44
|
interface HttpConfig {
|
|
45
|
+
/** Base URL of the API */
|
|
34
46
|
baseUrl: string;
|
|
47
|
+
/** Request timeout in milliseconds */
|
|
35
48
|
timeout: number;
|
|
36
49
|
}
|
|
37
50
|
|
|
@@ -209,112 +222,236 @@ declare abstract class BaseResource {
|
|
|
209
222
|
protected buildQueryString: (params: Record<string, string | number | boolean | undefined>) => string;
|
|
210
223
|
}
|
|
211
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Email address with optional type and label
|
|
227
|
+
*/
|
|
212
228
|
interface EmailAddress {
|
|
229
|
+
/** Email address */
|
|
213
230
|
address: string;
|
|
231
|
+
/** Type of email (e.g., 'work', 'personal') */
|
|
214
232
|
type?: string;
|
|
233
|
+
/** Custom label for the email */
|
|
215
234
|
label?: string;
|
|
235
|
+
/** Whether this is the primary email */
|
|
216
236
|
primary?: string;
|
|
217
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Instant messaging contact information
|
|
240
|
+
*/
|
|
218
241
|
interface InstantMessaging {
|
|
242
|
+
/** IM protocol URI (e.g., 'xmpp:user@example.com', 'skype:username') */
|
|
219
243
|
uri: string;
|
|
244
|
+
/** Protocol name (e.g., 'xmpp', 'skype', 'slack') */
|
|
220
245
|
protocol?: string;
|
|
246
|
+
/** Custom label for the IM account */
|
|
221
247
|
label?: string;
|
|
248
|
+
/** Whether this is the primary IM contact */
|
|
222
249
|
primary?: string;
|
|
223
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Phone number with optional type and label
|
|
253
|
+
*/
|
|
224
254
|
interface PhoneNumber {
|
|
255
|
+
/** Phone number (preferably in international format, e.g., '+33612345678') */
|
|
225
256
|
number: string;
|
|
257
|
+
/** Type of phone (e.g., 'mobile', 'home', 'work', 'fax') */
|
|
226
258
|
type?: string;
|
|
259
|
+
/** Custom label for the phone number */
|
|
227
260
|
label?: string;
|
|
261
|
+
/** Whether this is the primary phone number */
|
|
228
262
|
primary?: boolean;
|
|
229
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Extended address details for buildings and apartments
|
|
266
|
+
*/
|
|
230
267
|
interface ExtendedAddress {
|
|
268
|
+
/** Locality or neighborhood name */
|
|
231
269
|
locality?: string;
|
|
270
|
+
/** Building name or number */
|
|
232
271
|
building?: string;
|
|
272
|
+
/** Staircase identifier */
|
|
233
273
|
stairs?: string;
|
|
274
|
+
/** Floor number */
|
|
234
275
|
floor?: string;
|
|
276
|
+
/** Apartment number */
|
|
235
277
|
apartment?: string;
|
|
278
|
+
/** Entry code or access code */
|
|
236
279
|
entrycode?: string;
|
|
237
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* Geographic location with coordinates
|
|
283
|
+
*/
|
|
238
284
|
interface GeoLocation {
|
|
285
|
+
/** Geographic coordinates as [latitude, longitude] */
|
|
239
286
|
geo?: [number, number];
|
|
287
|
+
/** Category for Cozy Cloud integration */
|
|
240
288
|
cozyCategory?: string;
|
|
241
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Physical address with comprehensive location details
|
|
292
|
+
*/
|
|
242
293
|
interface Address {
|
|
294
|
+
/** Unique identifier for the address */
|
|
243
295
|
id?: string;
|
|
296
|
+
/** Street name */
|
|
244
297
|
street?: string;
|
|
298
|
+
/** Post office box number */
|
|
245
299
|
pobox?: string;
|
|
300
|
+
/** City name */
|
|
246
301
|
city?: string;
|
|
302
|
+
/** State, province, or region */
|
|
247
303
|
region?: string;
|
|
304
|
+
/** Street number */
|
|
248
305
|
number?: string;
|
|
306
|
+
/** Postal or ZIP code */
|
|
249
307
|
code?: string;
|
|
308
|
+
/** Country name or code */
|
|
250
309
|
country?: string;
|
|
310
|
+
/** Type of address (e.g., 'home', 'work', 'billing') */
|
|
251
311
|
type?: string;
|
|
312
|
+
/** Custom label for the address */
|
|
252
313
|
label?: string;
|
|
314
|
+
/** Whether this is the primary address */
|
|
253
315
|
primary?: boolean;
|
|
316
|
+
/** Extended address details (building, floor, apartment, etc.) */
|
|
254
317
|
extendedAddress?: ExtendedAddress;
|
|
318
|
+
/** Single-line formatted address string */
|
|
255
319
|
formattedAddress?: string;
|
|
320
|
+
/** Geographic location with coordinates */
|
|
256
321
|
geo?: GeoLocation;
|
|
257
322
|
}
|
|
323
|
+
/**
|
|
324
|
+
* Structured name components for a user
|
|
325
|
+
*/
|
|
258
326
|
interface UserName {
|
|
327
|
+
/** Family name or last name */
|
|
259
328
|
familyName?: string;
|
|
329
|
+
/** Given name or first name */
|
|
260
330
|
givenName?: string;
|
|
331
|
+
/** Middle name or additional names */
|
|
261
332
|
additionalName?: string;
|
|
333
|
+
/** Name prefix (e.g., 'Dr.', 'Mr.', 'Ms.') */
|
|
262
334
|
namePrefix?: string;
|
|
335
|
+
/** Name suffix (e.g., 'Jr.', 'Sr.', 'III') */
|
|
263
336
|
nameSuffix?: string;
|
|
337
|
+
/** Surname (alternative to familyName) */
|
|
264
338
|
surname?: string;
|
|
265
339
|
}
|
|
340
|
+
/**
|
|
341
|
+
* Complete user model with all profile fields, credentials, and encryption keys
|
|
342
|
+
*/
|
|
266
343
|
interface User {
|
|
344
|
+
/** Common name (username) */
|
|
267
345
|
cn: string;
|
|
346
|
+
/** Surname or last name */
|
|
268
347
|
sn: string;
|
|
348
|
+
/** Given name or first name */
|
|
269
349
|
givenName: string;
|
|
350
|
+
/** Display name shown in UI */
|
|
270
351
|
displayName: string;
|
|
352
|
+
/** Primary email address */
|
|
271
353
|
mail: string;
|
|
354
|
+
/** Primary mobile phone number */
|
|
272
355
|
mobile: string;
|
|
356
|
+
/** Encrypted user password */
|
|
273
357
|
userPassword: string;
|
|
358
|
+
/** Scrypt parameter: block size */
|
|
274
359
|
scryptR: number;
|
|
360
|
+
/** Scrypt parameter: CPU/memory cost */
|
|
275
361
|
scryptN: number;
|
|
362
|
+
/** Scrypt parameter: parallelization */
|
|
276
363
|
scryptP: number;
|
|
364
|
+
/** Salt for password encryption */
|
|
277
365
|
scryptSalt: string;
|
|
366
|
+
/** Derived key length for scrypt */
|
|
278
367
|
scryptDKLength: number;
|
|
368
|
+
/** Number of iterations for key derivation */
|
|
279
369
|
iterations: number;
|
|
370
|
+
/** User's domain */
|
|
280
371
|
domain: string;
|
|
372
|
+
/** User's public encryption key */
|
|
281
373
|
publicKey: string;
|
|
374
|
+
/** User's private encryption key */
|
|
282
375
|
privateKey: string;
|
|
376
|
+
/** Protected encryption key */
|
|
283
377
|
protectedKey: string;
|
|
378
|
+
/** Whether two-factor authentication is enabled */
|
|
284
379
|
twoFactorEnabled?: string;
|
|
380
|
+
/** URL of user's workspace */
|
|
285
381
|
workspaceUrl?: string;
|
|
382
|
+
/** Recovery email for account recovery */
|
|
286
383
|
recoveryEmail?: string;
|
|
384
|
+
/** Timestamp when password account was locked */
|
|
287
385
|
pwdAccountLockedTime?: string;
|
|
386
|
+
/** User's role in Twake organization ('owner', 'admin', 'moderator', 'member') */
|
|
288
387
|
twakeOrganizationRole?: string;
|
|
388
|
+
/** Full name as a single string */
|
|
289
389
|
fullname?: string;
|
|
390
|
+
/** Structured name components */
|
|
290
391
|
name?: UserName;
|
|
392
|
+
/** Birthday in ISO 8601 format (YYYY-MM-DD) */
|
|
291
393
|
birthday?: string;
|
|
394
|
+
/** Gender */
|
|
292
395
|
gender?: string;
|
|
396
|
+
/** Personal note or description */
|
|
293
397
|
note?: string;
|
|
398
|
+
/** Array of email addresses */
|
|
294
399
|
email?: EmailAddress[];
|
|
400
|
+
/** Array of instant messaging contacts */
|
|
295
401
|
impp?: InstantMessaging[];
|
|
402
|
+
/** Place of birth */
|
|
296
403
|
birthplace?: string;
|
|
404
|
+
/** Job title or position */
|
|
297
405
|
jobTitle?: string;
|
|
406
|
+
/** Company or organization name */
|
|
298
407
|
company?: string;
|
|
408
|
+
/** Array of phone numbers */
|
|
299
409
|
phone?: PhoneNumber[];
|
|
410
|
+
/** Array of physical addresses */
|
|
300
411
|
address?: Address[];
|
|
301
412
|
}
|
|
413
|
+
/**
|
|
414
|
+
* User password credentials with scrypt encryption parameters
|
|
415
|
+
*/
|
|
302
416
|
interface UserCredentials {
|
|
417
|
+
/** Encrypted password */
|
|
303
418
|
userPassword: string;
|
|
419
|
+
/** Scrypt CPU/memory cost parameter (power of 2, e.g., 16384) */
|
|
304
420
|
scryptN: number;
|
|
421
|
+
/** Scrypt parallelization parameter (typically 1) */
|
|
305
422
|
scryptP: number;
|
|
423
|
+
/** Scrypt block size parameter (typically 8) */
|
|
306
424
|
scryptR: number;
|
|
425
|
+
/** Random salt for password hashing */
|
|
307
426
|
scryptSalt: string;
|
|
427
|
+
/** Derived key length in bytes (typically 32) */
|
|
308
428
|
scryptDKLength: number;
|
|
429
|
+
/** Number of PBKDF2 iterations */
|
|
309
430
|
iterations: number;
|
|
310
431
|
}
|
|
432
|
+
/**
|
|
433
|
+
* User's cryptographic keys for end-to-end encryption
|
|
434
|
+
*/
|
|
311
435
|
interface UserKeys {
|
|
436
|
+
/** User's private encryption key */
|
|
312
437
|
privateKey: string;
|
|
438
|
+
/** User's public encryption key */
|
|
313
439
|
publicKey: string;
|
|
440
|
+
/** Password-protected version of the private key */
|
|
314
441
|
protectedKey: string;
|
|
315
442
|
}
|
|
443
|
+
/**
|
|
444
|
+
* User account status
|
|
445
|
+
*/
|
|
316
446
|
type UserStatus = 'active' | 'disabled';
|
|
447
|
+
/**
|
|
448
|
+
* Fields that can be used to search for users
|
|
449
|
+
*/
|
|
317
450
|
type UserSearchField = 'username' | 'phone' | 'email' | 'recoveryEmail';
|
|
451
|
+
/**
|
|
452
|
+
* Request payload for creating a new B2C user
|
|
453
|
+
* Includes all required fields plus optional profile information
|
|
454
|
+
*/
|
|
318
455
|
interface CreateUserRequest extends UserCredentials, UserKeys {
|
|
319
456
|
cn: string;
|
|
320
457
|
uid: string;
|
|
@@ -342,6 +479,10 @@ interface CreateUserRequest extends UserCredentials, UserKeys {
|
|
|
342
479
|
phone?: PhoneNumber[];
|
|
343
480
|
address?: Address[];
|
|
344
481
|
}
|
|
482
|
+
/**
|
|
483
|
+
* Request payload for updating a user's profile
|
|
484
|
+
* All fields are optional and only provided fields will be updated
|
|
485
|
+
*/
|
|
345
486
|
interface UpdateUserRequest {
|
|
346
487
|
mobile?: string;
|
|
347
488
|
userPassword?: string;
|
|
@@ -420,13 +561,6 @@ interface ListUsersResponse {
|
|
|
420
561
|
hasPreviousPage: boolean;
|
|
421
562
|
};
|
|
422
563
|
}
|
|
423
|
-
/**
|
|
424
|
-
* Response from creating a B2B user in an organization
|
|
425
|
-
*/
|
|
426
|
-
interface CreateB2BUserResponse {
|
|
427
|
-
/** Base DN of the created user */
|
|
428
|
-
baseDN: string;
|
|
429
|
-
}
|
|
430
564
|
|
|
431
565
|
/**
|
|
432
566
|
* Organization domain model representing a B2B organization
|
|
@@ -595,13 +729,6 @@ interface CreateGroupRequest {
|
|
|
595
729
|
/** Optional group description */
|
|
596
730
|
description?: string;
|
|
597
731
|
}
|
|
598
|
-
/**
|
|
599
|
-
* Response from creating a group
|
|
600
|
-
*/
|
|
601
|
-
interface CreateGroupResponse {
|
|
602
|
-
success: true;
|
|
603
|
-
group: Group;
|
|
604
|
-
}
|
|
605
732
|
/**
|
|
606
733
|
* Request parameters for updating a group
|
|
607
734
|
*/
|
|
@@ -754,6 +881,27 @@ declare class UsersResource extends BaseResource {
|
|
|
754
881
|
* ```
|
|
755
882
|
*/
|
|
756
883
|
fetch: (params: FetchUserRequest) => Promise<User>;
|
|
884
|
+
/**
|
|
885
|
+
* Gets organizations where a user has a role
|
|
886
|
+
*
|
|
887
|
+
* Returns organizations where the user is an admin or owner.
|
|
888
|
+
* Optionally filter by specific role.
|
|
889
|
+
*
|
|
890
|
+
* @param {string} userId - User identifier (username)
|
|
891
|
+
* @param {string} [role] - Optional role filter ('owner', 'admin', 'moderator', 'member')
|
|
892
|
+
* @returns {Promise<Organization[]>} Array of organizations
|
|
893
|
+
* @throws {ApiError} On API errors
|
|
894
|
+
*
|
|
895
|
+
* @example
|
|
896
|
+
* ```typescript
|
|
897
|
+
* // Get all organizations where user has any role
|
|
898
|
+
* const orgs = await client.users.getUserOrganizations('johndoe');
|
|
899
|
+
*
|
|
900
|
+
* // Get only organizations where user is owner
|
|
901
|
+
* const ownedOrgs = await client.users.getUserOrganizations('johndoe', 'owner');
|
|
902
|
+
* ```
|
|
903
|
+
*/
|
|
904
|
+
getUserOrganizations: (userId: string, role?: string) => Promise<Organization[]>;
|
|
757
905
|
}
|
|
758
906
|
|
|
759
907
|
/**
|
|
@@ -982,7 +1130,7 @@ declare class OrganizationsResource extends BaseResource {
|
|
|
982
1130
|
*
|
|
983
1131
|
* @param {string} organizationId - Organization identifier
|
|
984
1132
|
* @param {CreateUserRequest} data - User data including credentials and profile
|
|
985
|
-
* @returns {Promise<
|
|
1133
|
+
* @returns {Promise<User>} The created user object
|
|
986
1134
|
* @throws {ForbiddenError} When user lacks admin privileges
|
|
987
1135
|
* @throws {NotFoundError} When organization is not found
|
|
988
1136
|
* @throws {ConflictError} When username/email/phone already exists
|
|
@@ -990,14 +1138,14 @@ declare class OrganizationsResource extends BaseResource {
|
|
|
990
1138
|
*
|
|
991
1139
|
* @example
|
|
992
1140
|
* ```typescript
|
|
993
|
-
* const
|
|
1141
|
+
* const user = await client.organizations.createUser('org_abc123', {
|
|
994
1142
|
* cn: 'john.doe',
|
|
995
1143
|
* uid: 'john.doe',
|
|
996
1144
|
* // ... other user fields
|
|
997
1145
|
* });
|
|
998
1146
|
* ```
|
|
999
1147
|
*/
|
|
1000
|
-
createUser: (organizationId: string, data: CreateUserRequest) => Promise<
|
|
1148
|
+
createUser: (organizationId: string, data: CreateUserRequest) => Promise<User>;
|
|
1001
1149
|
/**
|
|
1002
1150
|
* Updates a user in an organization
|
|
1003
1151
|
*
|
|
@@ -1006,19 +1154,19 @@ declare class OrganizationsResource extends BaseResource {
|
|
|
1006
1154
|
* @param {string} organizationId - Organization identifier
|
|
1007
1155
|
* @param {string} userId - User identifier (username)
|
|
1008
1156
|
* @param {UpdateUserRequest} data - Fields to update
|
|
1009
|
-
* @returns {Promise<{ success: true }>}
|
|
1157
|
+
* @returns {Promise<User | { success: true }>} Updated user object or success response
|
|
1010
1158
|
* @throws {NotFoundError} When user or organization is not found
|
|
1011
1159
|
* @throws {ForbiddenError} When user lacks admin privileges
|
|
1012
1160
|
* @throws {ApiError} On other API errors
|
|
1013
1161
|
*
|
|
1014
1162
|
* @example
|
|
1015
1163
|
* ```typescript
|
|
1016
|
-
* await client.organizations.updateUser('org_abc123', 'john.doe', {
|
|
1164
|
+
* const result = await client.organizations.updateUser('org_abc123', 'john.doe', {
|
|
1017
1165
|
* mobile: '+33687654321'
|
|
1018
1166
|
* });
|
|
1019
1167
|
* ```
|
|
1020
1168
|
*/
|
|
1021
|
-
updateUser: (organizationId: string, userId: string, data: UpdateUserRequest) => Promise<{
|
|
1169
|
+
updateUser: (organizationId: string, userId: string, data: UpdateUserRequest) => Promise<User | {
|
|
1022
1170
|
success: true;
|
|
1023
1171
|
}>;
|
|
1024
1172
|
/**
|
|
@@ -1189,7 +1337,7 @@ declare class GroupsResource extends BaseResource {
|
|
|
1189
1337
|
*
|
|
1190
1338
|
* @param {string} organizationId - Organization identifier
|
|
1191
1339
|
* @param {CreateGroupRequest} data - Group data (name and optional description)
|
|
1192
|
-
* @returns {Promise<
|
|
1340
|
+
* @returns {Promise<Group>} Created group object
|
|
1193
1341
|
* @throws {ForbiddenError} When user lacks admin privileges
|
|
1194
1342
|
* @throws {NotFoundError} When organization is not found
|
|
1195
1343
|
* @throws {ConflictError} When group name already exists
|
|
@@ -1197,13 +1345,13 @@ declare class GroupsResource extends BaseResource {
|
|
|
1197
1345
|
*
|
|
1198
1346
|
* @examples
|
|
1199
1347
|
* ```typescript
|
|
1200
|
-
* const
|
|
1348
|
+
* const group = await client.groups.create('org_abc123', {
|
|
1201
1349
|
* name: 'engineering',
|
|
1202
1350
|
* description: 'Engineering team'
|
|
1203
1351
|
* });
|
|
1204
1352
|
* ```
|
|
1205
1353
|
*/
|
|
1206
|
-
create: (organizationId: string, data: CreateGroupRequest) => Promise<
|
|
1354
|
+
create: (organizationId: string, data: CreateGroupRequest) => Promise<Group>;
|
|
1207
1355
|
/**
|
|
1208
1356
|
* Lists all groups in an organization with pagination
|
|
1209
1357
|
*
|
|
@@ -1542,4 +1690,4 @@ declare class NetworkError extends LdapRestError {
|
|
|
1542
1690
|
constructor(message: string, cause?: Error);
|
|
1543
1691
|
}
|
|
1544
1692
|
|
|
1545
|
-
export { type AddGroupMembersRequest, type Address, ApiError, AuthenticationError, AuthorizationError, type ChangeUserRoleRequest, type CheckAvailabilityParams, type CheckAvailabilityResponse, type CheckOrganizationAvailabilityParams, type ClientConfig, ConflictError, type CreateAdminRequest, type
|
|
1693
|
+
export { type AddGroupMembersRequest, type Address, ApiError, AuthenticationError, AuthorizationError, type ChangeUserRoleRequest, type CheckAvailabilityParams, type CheckAvailabilityResponse, type CheckOrganizationAvailabilityParams, type ClientConfig, ConflictError, type CreateAdminRequest, type CreateGroupRequest, type CreateOrganizationRequest, type CreateOrganizationResponse, type CreateUserRequest, type EmailAddress, type ExtendedAddress, type FetchUserRequest, type GeoLocation, type GetOwnerResponse, type Group, GroupsResource, type InstantMessaging, LdapRestClient, LdapRestError, type ListGroupsParams, type ListGroupsResponse, type ListUsersParams, type ListUsersResponse, NetworkError, NotFoundError, type Organization, type OrganizationMetadata, type OrganizationOwner, type OrganizationRole, type OrganizationSearchField, type OrganizationStatus, OrganizationsResource, type PhoneNumber, RateLimitError, type SetOwnerRequest, type TransferOwnershipRequest, type UpdateGroupRequest, type UpdateOrganizationRequest, type UpdateUserRequest, type User, type UserCredentials, type UserKeys, type UserName, type UserSearchField, type UserStatus, UsersResource, ValidationError };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,16 +2,22 @@ import { ISettingsParam, Logger } from 'tslog';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* HMAC authentication configuration for backend services
|
|
5
|
+
* Uses HMAC-SHA256 signatures as per ADR-024
|
|
5
6
|
*/
|
|
6
7
|
interface HmacAuthConfig {
|
|
8
|
+
/** Authentication type */
|
|
7
9
|
type: 'hmac';
|
|
10
|
+
/** Service identifier (e.g., 'registration-service') */
|
|
8
11
|
serviceId: string;
|
|
12
|
+
/** Shared secret key (minimum 32 characters recommended) */
|
|
9
13
|
secret: string;
|
|
10
14
|
}
|
|
11
15
|
/**
|
|
12
16
|
* SSO Cookie authentication configuration for browser requests
|
|
17
|
+
* Relies on cookies set by the authentication service
|
|
13
18
|
*/
|
|
14
19
|
interface CookieAuthConfig {
|
|
20
|
+
/** Authentication type */
|
|
15
21
|
type: 'cookie';
|
|
16
22
|
}
|
|
17
23
|
/**
|
|
@@ -22,16 +28,23 @@ type AuthConfig = HmacAuthConfig | CookieAuthConfig;
|
|
|
22
28
|
* Configuration for LDAP-REST client
|
|
23
29
|
*/
|
|
24
30
|
interface ClientConfig {
|
|
31
|
+
/** Base URL of the LDAP-REST API (e.g., 'https://ldap-rest.example.com') */
|
|
25
32
|
baseUrl: string;
|
|
33
|
+
/** Authentication configuration (defaults to cookie auth if not provided) */
|
|
26
34
|
auth?: AuthConfig;
|
|
35
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
27
36
|
timeout?: number;
|
|
37
|
+
/** tslog logger configuration for custom logging */
|
|
28
38
|
logger?: ISettingsParam<unknown>;
|
|
29
39
|
}
|
|
30
40
|
/**
|
|
31
41
|
* HTTP client configuration
|
|
42
|
+
* Subset of configuration passed to the HTTP client
|
|
32
43
|
*/
|
|
33
44
|
interface HttpConfig {
|
|
45
|
+
/** Base URL of the API */
|
|
34
46
|
baseUrl: string;
|
|
47
|
+
/** Request timeout in milliseconds */
|
|
35
48
|
timeout: number;
|
|
36
49
|
}
|
|
37
50
|
|
|
@@ -209,112 +222,236 @@ declare abstract class BaseResource {
|
|
|
209
222
|
protected buildQueryString: (params: Record<string, string | number | boolean | undefined>) => string;
|
|
210
223
|
}
|
|
211
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Email address with optional type and label
|
|
227
|
+
*/
|
|
212
228
|
interface EmailAddress {
|
|
229
|
+
/** Email address */
|
|
213
230
|
address: string;
|
|
231
|
+
/** Type of email (e.g., 'work', 'personal') */
|
|
214
232
|
type?: string;
|
|
233
|
+
/** Custom label for the email */
|
|
215
234
|
label?: string;
|
|
235
|
+
/** Whether this is the primary email */
|
|
216
236
|
primary?: string;
|
|
217
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Instant messaging contact information
|
|
240
|
+
*/
|
|
218
241
|
interface InstantMessaging {
|
|
242
|
+
/** IM protocol URI (e.g., 'xmpp:user@example.com', 'skype:username') */
|
|
219
243
|
uri: string;
|
|
244
|
+
/** Protocol name (e.g., 'xmpp', 'skype', 'slack') */
|
|
220
245
|
protocol?: string;
|
|
246
|
+
/** Custom label for the IM account */
|
|
221
247
|
label?: string;
|
|
248
|
+
/** Whether this is the primary IM contact */
|
|
222
249
|
primary?: string;
|
|
223
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Phone number with optional type and label
|
|
253
|
+
*/
|
|
224
254
|
interface PhoneNumber {
|
|
255
|
+
/** Phone number (preferably in international format, e.g., '+33612345678') */
|
|
225
256
|
number: string;
|
|
257
|
+
/** Type of phone (e.g., 'mobile', 'home', 'work', 'fax') */
|
|
226
258
|
type?: string;
|
|
259
|
+
/** Custom label for the phone number */
|
|
227
260
|
label?: string;
|
|
261
|
+
/** Whether this is the primary phone number */
|
|
228
262
|
primary?: boolean;
|
|
229
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Extended address details for buildings and apartments
|
|
266
|
+
*/
|
|
230
267
|
interface ExtendedAddress {
|
|
268
|
+
/** Locality or neighborhood name */
|
|
231
269
|
locality?: string;
|
|
270
|
+
/** Building name or number */
|
|
232
271
|
building?: string;
|
|
272
|
+
/** Staircase identifier */
|
|
233
273
|
stairs?: string;
|
|
274
|
+
/** Floor number */
|
|
234
275
|
floor?: string;
|
|
276
|
+
/** Apartment number */
|
|
235
277
|
apartment?: string;
|
|
278
|
+
/** Entry code or access code */
|
|
236
279
|
entrycode?: string;
|
|
237
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* Geographic location with coordinates
|
|
283
|
+
*/
|
|
238
284
|
interface GeoLocation {
|
|
285
|
+
/** Geographic coordinates as [latitude, longitude] */
|
|
239
286
|
geo?: [number, number];
|
|
287
|
+
/** Category for Cozy Cloud integration */
|
|
240
288
|
cozyCategory?: string;
|
|
241
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Physical address with comprehensive location details
|
|
292
|
+
*/
|
|
242
293
|
interface Address {
|
|
294
|
+
/** Unique identifier for the address */
|
|
243
295
|
id?: string;
|
|
296
|
+
/** Street name */
|
|
244
297
|
street?: string;
|
|
298
|
+
/** Post office box number */
|
|
245
299
|
pobox?: string;
|
|
300
|
+
/** City name */
|
|
246
301
|
city?: string;
|
|
302
|
+
/** State, province, or region */
|
|
247
303
|
region?: string;
|
|
304
|
+
/** Street number */
|
|
248
305
|
number?: string;
|
|
306
|
+
/** Postal or ZIP code */
|
|
249
307
|
code?: string;
|
|
308
|
+
/** Country name or code */
|
|
250
309
|
country?: string;
|
|
310
|
+
/** Type of address (e.g., 'home', 'work', 'billing') */
|
|
251
311
|
type?: string;
|
|
312
|
+
/** Custom label for the address */
|
|
252
313
|
label?: string;
|
|
314
|
+
/** Whether this is the primary address */
|
|
253
315
|
primary?: boolean;
|
|
316
|
+
/** Extended address details (building, floor, apartment, etc.) */
|
|
254
317
|
extendedAddress?: ExtendedAddress;
|
|
318
|
+
/** Single-line formatted address string */
|
|
255
319
|
formattedAddress?: string;
|
|
320
|
+
/** Geographic location with coordinates */
|
|
256
321
|
geo?: GeoLocation;
|
|
257
322
|
}
|
|
323
|
+
/**
|
|
324
|
+
* Structured name components for a user
|
|
325
|
+
*/
|
|
258
326
|
interface UserName {
|
|
327
|
+
/** Family name or last name */
|
|
259
328
|
familyName?: string;
|
|
329
|
+
/** Given name or first name */
|
|
260
330
|
givenName?: string;
|
|
331
|
+
/** Middle name or additional names */
|
|
261
332
|
additionalName?: string;
|
|
333
|
+
/** Name prefix (e.g., 'Dr.', 'Mr.', 'Ms.') */
|
|
262
334
|
namePrefix?: string;
|
|
335
|
+
/** Name suffix (e.g., 'Jr.', 'Sr.', 'III') */
|
|
263
336
|
nameSuffix?: string;
|
|
337
|
+
/** Surname (alternative to familyName) */
|
|
264
338
|
surname?: string;
|
|
265
339
|
}
|
|
340
|
+
/**
|
|
341
|
+
* Complete user model with all profile fields, credentials, and encryption keys
|
|
342
|
+
*/
|
|
266
343
|
interface User {
|
|
344
|
+
/** Common name (username) */
|
|
267
345
|
cn: string;
|
|
346
|
+
/** Surname or last name */
|
|
268
347
|
sn: string;
|
|
348
|
+
/** Given name or first name */
|
|
269
349
|
givenName: string;
|
|
350
|
+
/** Display name shown in UI */
|
|
270
351
|
displayName: string;
|
|
352
|
+
/** Primary email address */
|
|
271
353
|
mail: string;
|
|
354
|
+
/** Primary mobile phone number */
|
|
272
355
|
mobile: string;
|
|
356
|
+
/** Encrypted user password */
|
|
273
357
|
userPassword: string;
|
|
358
|
+
/** Scrypt parameter: block size */
|
|
274
359
|
scryptR: number;
|
|
360
|
+
/** Scrypt parameter: CPU/memory cost */
|
|
275
361
|
scryptN: number;
|
|
362
|
+
/** Scrypt parameter: parallelization */
|
|
276
363
|
scryptP: number;
|
|
364
|
+
/** Salt for password encryption */
|
|
277
365
|
scryptSalt: string;
|
|
366
|
+
/** Derived key length for scrypt */
|
|
278
367
|
scryptDKLength: number;
|
|
368
|
+
/** Number of iterations for key derivation */
|
|
279
369
|
iterations: number;
|
|
370
|
+
/** User's domain */
|
|
280
371
|
domain: string;
|
|
372
|
+
/** User's public encryption key */
|
|
281
373
|
publicKey: string;
|
|
374
|
+
/** User's private encryption key */
|
|
282
375
|
privateKey: string;
|
|
376
|
+
/** Protected encryption key */
|
|
283
377
|
protectedKey: string;
|
|
378
|
+
/** Whether two-factor authentication is enabled */
|
|
284
379
|
twoFactorEnabled?: string;
|
|
380
|
+
/** URL of user's workspace */
|
|
285
381
|
workspaceUrl?: string;
|
|
382
|
+
/** Recovery email for account recovery */
|
|
286
383
|
recoveryEmail?: string;
|
|
384
|
+
/** Timestamp when password account was locked */
|
|
287
385
|
pwdAccountLockedTime?: string;
|
|
386
|
+
/** User's role in Twake organization ('owner', 'admin', 'moderator', 'member') */
|
|
288
387
|
twakeOrganizationRole?: string;
|
|
388
|
+
/** Full name as a single string */
|
|
289
389
|
fullname?: string;
|
|
390
|
+
/** Structured name components */
|
|
290
391
|
name?: UserName;
|
|
392
|
+
/** Birthday in ISO 8601 format (YYYY-MM-DD) */
|
|
291
393
|
birthday?: string;
|
|
394
|
+
/** Gender */
|
|
292
395
|
gender?: string;
|
|
396
|
+
/** Personal note or description */
|
|
293
397
|
note?: string;
|
|
398
|
+
/** Array of email addresses */
|
|
294
399
|
email?: EmailAddress[];
|
|
400
|
+
/** Array of instant messaging contacts */
|
|
295
401
|
impp?: InstantMessaging[];
|
|
402
|
+
/** Place of birth */
|
|
296
403
|
birthplace?: string;
|
|
404
|
+
/** Job title or position */
|
|
297
405
|
jobTitle?: string;
|
|
406
|
+
/** Company or organization name */
|
|
298
407
|
company?: string;
|
|
408
|
+
/** Array of phone numbers */
|
|
299
409
|
phone?: PhoneNumber[];
|
|
410
|
+
/** Array of physical addresses */
|
|
300
411
|
address?: Address[];
|
|
301
412
|
}
|
|
413
|
+
/**
|
|
414
|
+
* User password credentials with scrypt encryption parameters
|
|
415
|
+
*/
|
|
302
416
|
interface UserCredentials {
|
|
417
|
+
/** Encrypted password */
|
|
303
418
|
userPassword: string;
|
|
419
|
+
/** Scrypt CPU/memory cost parameter (power of 2, e.g., 16384) */
|
|
304
420
|
scryptN: number;
|
|
421
|
+
/** Scrypt parallelization parameter (typically 1) */
|
|
305
422
|
scryptP: number;
|
|
423
|
+
/** Scrypt block size parameter (typically 8) */
|
|
306
424
|
scryptR: number;
|
|
425
|
+
/** Random salt for password hashing */
|
|
307
426
|
scryptSalt: string;
|
|
427
|
+
/** Derived key length in bytes (typically 32) */
|
|
308
428
|
scryptDKLength: number;
|
|
429
|
+
/** Number of PBKDF2 iterations */
|
|
309
430
|
iterations: number;
|
|
310
431
|
}
|
|
432
|
+
/**
|
|
433
|
+
* User's cryptographic keys for end-to-end encryption
|
|
434
|
+
*/
|
|
311
435
|
interface UserKeys {
|
|
436
|
+
/** User's private encryption key */
|
|
312
437
|
privateKey: string;
|
|
438
|
+
/** User's public encryption key */
|
|
313
439
|
publicKey: string;
|
|
440
|
+
/** Password-protected version of the private key */
|
|
314
441
|
protectedKey: string;
|
|
315
442
|
}
|
|
443
|
+
/**
|
|
444
|
+
* User account status
|
|
445
|
+
*/
|
|
316
446
|
type UserStatus = 'active' | 'disabled';
|
|
447
|
+
/**
|
|
448
|
+
* Fields that can be used to search for users
|
|
449
|
+
*/
|
|
317
450
|
type UserSearchField = 'username' | 'phone' | 'email' | 'recoveryEmail';
|
|
451
|
+
/**
|
|
452
|
+
* Request payload for creating a new B2C user
|
|
453
|
+
* Includes all required fields plus optional profile information
|
|
454
|
+
*/
|
|
318
455
|
interface CreateUserRequest extends UserCredentials, UserKeys {
|
|
319
456
|
cn: string;
|
|
320
457
|
uid: string;
|
|
@@ -342,6 +479,10 @@ interface CreateUserRequest extends UserCredentials, UserKeys {
|
|
|
342
479
|
phone?: PhoneNumber[];
|
|
343
480
|
address?: Address[];
|
|
344
481
|
}
|
|
482
|
+
/**
|
|
483
|
+
* Request payload for updating a user's profile
|
|
484
|
+
* All fields are optional and only provided fields will be updated
|
|
485
|
+
*/
|
|
345
486
|
interface UpdateUserRequest {
|
|
346
487
|
mobile?: string;
|
|
347
488
|
userPassword?: string;
|
|
@@ -420,13 +561,6 @@ interface ListUsersResponse {
|
|
|
420
561
|
hasPreviousPage: boolean;
|
|
421
562
|
};
|
|
422
563
|
}
|
|
423
|
-
/**
|
|
424
|
-
* Response from creating a B2B user in an organization
|
|
425
|
-
*/
|
|
426
|
-
interface CreateB2BUserResponse {
|
|
427
|
-
/** Base DN of the created user */
|
|
428
|
-
baseDN: string;
|
|
429
|
-
}
|
|
430
564
|
|
|
431
565
|
/**
|
|
432
566
|
* Organization domain model representing a B2B organization
|
|
@@ -595,13 +729,6 @@ interface CreateGroupRequest {
|
|
|
595
729
|
/** Optional group description */
|
|
596
730
|
description?: string;
|
|
597
731
|
}
|
|
598
|
-
/**
|
|
599
|
-
* Response from creating a group
|
|
600
|
-
*/
|
|
601
|
-
interface CreateGroupResponse {
|
|
602
|
-
success: true;
|
|
603
|
-
group: Group;
|
|
604
|
-
}
|
|
605
732
|
/**
|
|
606
733
|
* Request parameters for updating a group
|
|
607
734
|
*/
|
|
@@ -754,6 +881,27 @@ declare class UsersResource extends BaseResource {
|
|
|
754
881
|
* ```
|
|
755
882
|
*/
|
|
756
883
|
fetch: (params: FetchUserRequest) => Promise<User>;
|
|
884
|
+
/**
|
|
885
|
+
* Gets organizations where a user has a role
|
|
886
|
+
*
|
|
887
|
+
* Returns organizations where the user is an admin or owner.
|
|
888
|
+
* Optionally filter by specific role.
|
|
889
|
+
*
|
|
890
|
+
* @param {string} userId - User identifier (username)
|
|
891
|
+
* @param {string} [role] - Optional role filter ('owner', 'admin', 'moderator', 'member')
|
|
892
|
+
* @returns {Promise<Organization[]>} Array of organizations
|
|
893
|
+
* @throws {ApiError} On API errors
|
|
894
|
+
*
|
|
895
|
+
* @example
|
|
896
|
+
* ```typescript
|
|
897
|
+
* // Get all organizations where user has any role
|
|
898
|
+
* const orgs = await client.users.getUserOrganizations('johndoe');
|
|
899
|
+
*
|
|
900
|
+
* // Get only organizations where user is owner
|
|
901
|
+
* const ownedOrgs = await client.users.getUserOrganizations('johndoe', 'owner');
|
|
902
|
+
* ```
|
|
903
|
+
*/
|
|
904
|
+
getUserOrganizations: (userId: string, role?: string) => Promise<Organization[]>;
|
|
757
905
|
}
|
|
758
906
|
|
|
759
907
|
/**
|
|
@@ -982,7 +1130,7 @@ declare class OrganizationsResource extends BaseResource {
|
|
|
982
1130
|
*
|
|
983
1131
|
* @param {string} organizationId - Organization identifier
|
|
984
1132
|
* @param {CreateUserRequest} data - User data including credentials and profile
|
|
985
|
-
* @returns {Promise<
|
|
1133
|
+
* @returns {Promise<User>} The created user object
|
|
986
1134
|
* @throws {ForbiddenError} When user lacks admin privileges
|
|
987
1135
|
* @throws {NotFoundError} When organization is not found
|
|
988
1136
|
* @throws {ConflictError} When username/email/phone already exists
|
|
@@ -990,14 +1138,14 @@ declare class OrganizationsResource extends BaseResource {
|
|
|
990
1138
|
*
|
|
991
1139
|
* @example
|
|
992
1140
|
* ```typescript
|
|
993
|
-
* const
|
|
1141
|
+
* const user = await client.organizations.createUser('org_abc123', {
|
|
994
1142
|
* cn: 'john.doe',
|
|
995
1143
|
* uid: 'john.doe',
|
|
996
1144
|
* // ... other user fields
|
|
997
1145
|
* });
|
|
998
1146
|
* ```
|
|
999
1147
|
*/
|
|
1000
|
-
createUser: (organizationId: string, data: CreateUserRequest) => Promise<
|
|
1148
|
+
createUser: (organizationId: string, data: CreateUserRequest) => Promise<User>;
|
|
1001
1149
|
/**
|
|
1002
1150
|
* Updates a user in an organization
|
|
1003
1151
|
*
|
|
@@ -1006,19 +1154,19 @@ declare class OrganizationsResource extends BaseResource {
|
|
|
1006
1154
|
* @param {string} organizationId - Organization identifier
|
|
1007
1155
|
* @param {string} userId - User identifier (username)
|
|
1008
1156
|
* @param {UpdateUserRequest} data - Fields to update
|
|
1009
|
-
* @returns {Promise<{ success: true }>}
|
|
1157
|
+
* @returns {Promise<User | { success: true }>} Updated user object or success response
|
|
1010
1158
|
* @throws {NotFoundError} When user or organization is not found
|
|
1011
1159
|
* @throws {ForbiddenError} When user lacks admin privileges
|
|
1012
1160
|
* @throws {ApiError} On other API errors
|
|
1013
1161
|
*
|
|
1014
1162
|
* @example
|
|
1015
1163
|
* ```typescript
|
|
1016
|
-
* await client.organizations.updateUser('org_abc123', 'john.doe', {
|
|
1164
|
+
* const result = await client.organizations.updateUser('org_abc123', 'john.doe', {
|
|
1017
1165
|
* mobile: '+33687654321'
|
|
1018
1166
|
* });
|
|
1019
1167
|
* ```
|
|
1020
1168
|
*/
|
|
1021
|
-
updateUser: (organizationId: string, userId: string, data: UpdateUserRequest) => Promise<{
|
|
1169
|
+
updateUser: (organizationId: string, userId: string, data: UpdateUserRequest) => Promise<User | {
|
|
1022
1170
|
success: true;
|
|
1023
1171
|
}>;
|
|
1024
1172
|
/**
|
|
@@ -1189,7 +1337,7 @@ declare class GroupsResource extends BaseResource {
|
|
|
1189
1337
|
*
|
|
1190
1338
|
* @param {string} organizationId - Organization identifier
|
|
1191
1339
|
* @param {CreateGroupRequest} data - Group data (name and optional description)
|
|
1192
|
-
* @returns {Promise<
|
|
1340
|
+
* @returns {Promise<Group>} Created group object
|
|
1193
1341
|
* @throws {ForbiddenError} When user lacks admin privileges
|
|
1194
1342
|
* @throws {NotFoundError} When organization is not found
|
|
1195
1343
|
* @throws {ConflictError} When group name already exists
|
|
@@ -1197,13 +1345,13 @@ declare class GroupsResource extends BaseResource {
|
|
|
1197
1345
|
*
|
|
1198
1346
|
* @examples
|
|
1199
1347
|
* ```typescript
|
|
1200
|
-
* const
|
|
1348
|
+
* const group = await client.groups.create('org_abc123', {
|
|
1201
1349
|
* name: 'engineering',
|
|
1202
1350
|
* description: 'Engineering team'
|
|
1203
1351
|
* });
|
|
1204
1352
|
* ```
|
|
1205
1353
|
*/
|
|
1206
|
-
create: (organizationId: string, data: CreateGroupRequest) => Promise<
|
|
1354
|
+
create: (organizationId: string, data: CreateGroupRequest) => Promise<Group>;
|
|
1207
1355
|
/**
|
|
1208
1356
|
* Lists all groups in an organization with pagination
|
|
1209
1357
|
*
|
|
@@ -1542,4 +1690,4 @@ declare class NetworkError extends LdapRestError {
|
|
|
1542
1690
|
constructor(message: string, cause?: Error);
|
|
1543
1691
|
}
|
|
1544
1692
|
|
|
1545
|
-
export { type AddGroupMembersRequest, type Address, ApiError, AuthenticationError, AuthorizationError, type ChangeUserRoleRequest, type CheckAvailabilityParams, type CheckAvailabilityResponse, type CheckOrganizationAvailabilityParams, type ClientConfig, ConflictError, type CreateAdminRequest, type
|
|
1693
|
+
export { type AddGroupMembersRequest, type Address, ApiError, AuthenticationError, AuthorizationError, type ChangeUserRoleRequest, type CheckAvailabilityParams, type CheckAvailabilityResponse, type CheckOrganizationAvailabilityParams, type ClientConfig, ConflictError, type CreateAdminRequest, type CreateGroupRequest, type CreateOrganizationRequest, type CreateOrganizationResponse, type CreateUserRequest, type EmailAddress, type ExtendedAddress, type FetchUserRequest, type GeoLocation, type GetOwnerResponse, type Group, GroupsResource, type InstantMessaging, LdapRestClient, LdapRestError, type ListGroupsParams, type ListGroupsResponse, type ListUsersParams, type ListUsersResponse, NetworkError, NotFoundError, type Organization, type OrganizationMetadata, type OrganizationOwner, type OrganizationRole, type OrganizationSearchField, type OrganizationStatus, OrganizationsResource, type PhoneNumber, RateLimitError, type SetOwnerRequest, type TransferOwnershipRequest, type UpdateGroupRequest, type UpdateOrganizationRequest, type UpdateUserRequest, type User, type UserCredentials, type UserKeys, type UserName, type UserSearchField, type UserStatus, UsersResource, ValidationError };
|
package/dist/index.js
CHANGED
|
@@ -38,6 +38,11 @@ module.exports = __toCommonJS(index_exports);
|
|
|
38
38
|
|
|
39
39
|
// src/config/ClientConfig.ts
|
|
40
40
|
var ConfigValidator = class {
|
|
41
|
+
/**
|
|
42
|
+
* Validates the client configuration
|
|
43
|
+
* @param {ClientConfig} config - Configuration to validate
|
|
44
|
+
* @throws {Error} If configuration is invalid
|
|
45
|
+
*/
|
|
41
46
|
static validate(config) {
|
|
42
47
|
if (!config.baseUrl || config.baseUrl.trim().length === 0) {
|
|
43
48
|
throw new Error("baseUrl is required");
|
|
@@ -64,6 +69,11 @@ var ConfigValidator = class {
|
|
|
64
69
|
throw new Error("timeout must be a positive number");
|
|
65
70
|
}
|
|
66
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Normalizes the client configuration by applying defaults
|
|
74
|
+
* @param {ClientConfig} config - Configuration to normalize
|
|
75
|
+
* @returns {NormalizedClientConfig} Normalized configuration with defaults applied
|
|
76
|
+
*/
|
|
67
77
|
static normalize(config) {
|
|
68
78
|
return {
|
|
69
79
|
baseUrl: config.baseUrl.replace(/\/$/, ""),
|
|
@@ -72,6 +82,11 @@ var ConfigValidator = class {
|
|
|
72
82
|
logger: config.logger
|
|
73
83
|
};
|
|
74
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Extracts HTTP-specific configuration from normalized config
|
|
87
|
+
* @param {NormalizedClientConfig} config - Normalized configuration
|
|
88
|
+
* @returns {HttpConfig} HTTP client configuration
|
|
89
|
+
*/
|
|
75
90
|
static toHttpConfig(config) {
|
|
76
91
|
return {
|
|
77
92
|
baseUrl: config.baseUrl,
|
|
@@ -617,6 +632,30 @@ var UsersResource = class extends BaseResource {
|
|
|
617
632
|
const query = this.buildQueryString(params);
|
|
618
633
|
return this.http.get(`/api/v1/users${query}`);
|
|
619
634
|
};
|
|
635
|
+
/**
|
|
636
|
+
* Gets organizations where a user has a role
|
|
637
|
+
*
|
|
638
|
+
* Returns organizations where the user is an admin or owner.
|
|
639
|
+
* Optionally filter by specific role.
|
|
640
|
+
*
|
|
641
|
+
* @param {string} userId - User identifier (username)
|
|
642
|
+
* @param {string} [role] - Optional role filter ('owner', 'admin', 'moderator', 'member')
|
|
643
|
+
* @returns {Promise<Organization[]>} Array of organizations
|
|
644
|
+
* @throws {ApiError} On API errors
|
|
645
|
+
*
|
|
646
|
+
* @example
|
|
647
|
+
* ```typescript
|
|
648
|
+
* // Get all organizations where user has any role
|
|
649
|
+
* const orgs = await client.users.getUserOrganizations('johndoe');
|
|
650
|
+
*
|
|
651
|
+
* // Get only organizations where user is owner
|
|
652
|
+
* const ownedOrgs = await client.users.getUserOrganizations('johndoe', 'owner');
|
|
653
|
+
* ```
|
|
654
|
+
*/
|
|
655
|
+
getUserOrganizations = async (userId, role) => {
|
|
656
|
+
const query = role ? this.buildQueryString({ role }) : "";
|
|
657
|
+
return this.http.get(`/api/v1/users/${encodeURIComponent(userId)}/organizations${query}`);
|
|
658
|
+
};
|
|
620
659
|
};
|
|
621
660
|
|
|
622
661
|
// src/resources/OrganizationsResource.ts
|
|
@@ -839,7 +878,7 @@ var OrganizationsResource = class extends BaseResource {
|
|
|
839
878
|
*
|
|
840
879
|
* @param {string} organizationId - Organization identifier
|
|
841
880
|
* @param {CreateUserRequest} data - User data including credentials and profile
|
|
842
|
-
* @returns {Promise<
|
|
881
|
+
* @returns {Promise<User>} The created user object
|
|
843
882
|
* @throws {ForbiddenError} When user lacks admin privileges
|
|
844
883
|
* @throws {NotFoundError} When organization is not found
|
|
845
884
|
* @throws {ConflictError} When username/email/phone already exists
|
|
@@ -847,7 +886,7 @@ var OrganizationsResource = class extends BaseResource {
|
|
|
847
886
|
*
|
|
848
887
|
* @example
|
|
849
888
|
* ```typescript
|
|
850
|
-
* const
|
|
889
|
+
* const user = await client.organizations.createUser('org_abc123', {
|
|
851
890
|
* cn: 'john.doe',
|
|
852
891
|
* uid: 'john.doe',
|
|
853
892
|
* // ... other user fields
|
|
@@ -868,14 +907,14 @@ var OrganizationsResource = class extends BaseResource {
|
|
|
868
907
|
* @param {string} organizationId - Organization identifier
|
|
869
908
|
* @param {string} userId - User identifier (username)
|
|
870
909
|
* @param {UpdateUserRequest} data - Fields to update
|
|
871
|
-
* @returns {Promise<{ success: true }>}
|
|
910
|
+
* @returns {Promise<User | { success: true }>} Updated user object or success response
|
|
872
911
|
* @throws {NotFoundError} When user or organization is not found
|
|
873
912
|
* @throws {ForbiddenError} When user lacks admin privileges
|
|
874
913
|
* @throws {ApiError} On other API errors
|
|
875
914
|
*
|
|
876
915
|
* @example
|
|
877
916
|
* ```typescript
|
|
878
|
-
* await client.organizations.updateUser('org_abc123', 'john.doe', {
|
|
917
|
+
* const result = await client.organizations.updateUser('org_abc123', 'john.doe', {
|
|
879
918
|
* mobile: '+33687654321'
|
|
880
919
|
* });
|
|
881
920
|
* ```
|
|
@@ -1054,7 +1093,7 @@ var GroupsResource = class extends BaseResource {
|
|
|
1054
1093
|
*
|
|
1055
1094
|
* @param {string} organizationId - Organization identifier
|
|
1056
1095
|
* @param {CreateGroupRequest} data - Group data (name and optional description)
|
|
1057
|
-
* @returns {Promise<
|
|
1096
|
+
* @returns {Promise<Group>} Created group object
|
|
1058
1097
|
* @throws {ForbiddenError} When user lacks admin privileges
|
|
1059
1098
|
* @throws {NotFoundError} When organization is not found
|
|
1060
1099
|
* @throws {ConflictError} When group name already exists
|
|
@@ -1062,7 +1101,7 @@ var GroupsResource = class extends BaseResource {
|
|
|
1062
1101
|
*
|
|
1063
1102
|
* @examples
|
|
1064
1103
|
* ```typescript
|
|
1065
|
-
* const
|
|
1104
|
+
* const group = await client.groups.create('org_abc123', {
|
|
1066
1105
|
* name: 'engineering',
|
|
1067
1106
|
* description: 'Engineering team'
|
|
1068
1107
|
* });
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
// src/config/ClientConfig.ts
|
|
2
2
|
var ConfigValidator = class {
|
|
3
|
+
/**
|
|
4
|
+
* Validates the client configuration
|
|
5
|
+
* @param {ClientConfig} config - Configuration to validate
|
|
6
|
+
* @throws {Error} If configuration is invalid
|
|
7
|
+
*/
|
|
3
8
|
static validate(config) {
|
|
4
9
|
if (!config.baseUrl || config.baseUrl.trim().length === 0) {
|
|
5
10
|
throw new Error("baseUrl is required");
|
|
@@ -26,6 +31,11 @@ var ConfigValidator = class {
|
|
|
26
31
|
throw new Error("timeout must be a positive number");
|
|
27
32
|
}
|
|
28
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Normalizes the client configuration by applying defaults
|
|
36
|
+
* @param {ClientConfig} config - Configuration to normalize
|
|
37
|
+
* @returns {NormalizedClientConfig} Normalized configuration with defaults applied
|
|
38
|
+
*/
|
|
29
39
|
static normalize(config) {
|
|
30
40
|
return {
|
|
31
41
|
baseUrl: config.baseUrl.replace(/\/$/, ""),
|
|
@@ -34,6 +44,11 @@ var ConfigValidator = class {
|
|
|
34
44
|
logger: config.logger
|
|
35
45
|
};
|
|
36
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Extracts HTTP-specific configuration from normalized config
|
|
49
|
+
* @param {NormalizedClientConfig} config - Normalized configuration
|
|
50
|
+
* @returns {HttpConfig} HTTP client configuration
|
|
51
|
+
*/
|
|
37
52
|
static toHttpConfig(config) {
|
|
38
53
|
return {
|
|
39
54
|
baseUrl: config.baseUrl,
|
|
@@ -579,6 +594,30 @@ var UsersResource = class extends BaseResource {
|
|
|
579
594
|
const query = this.buildQueryString(params);
|
|
580
595
|
return this.http.get(`/api/v1/users${query}`);
|
|
581
596
|
};
|
|
597
|
+
/**
|
|
598
|
+
* Gets organizations where a user has a role
|
|
599
|
+
*
|
|
600
|
+
* Returns organizations where the user is an admin or owner.
|
|
601
|
+
* Optionally filter by specific role.
|
|
602
|
+
*
|
|
603
|
+
* @param {string} userId - User identifier (username)
|
|
604
|
+
* @param {string} [role] - Optional role filter ('owner', 'admin', 'moderator', 'member')
|
|
605
|
+
* @returns {Promise<Organization[]>} Array of organizations
|
|
606
|
+
* @throws {ApiError} On API errors
|
|
607
|
+
*
|
|
608
|
+
* @example
|
|
609
|
+
* ```typescript
|
|
610
|
+
* // Get all organizations where user has any role
|
|
611
|
+
* const orgs = await client.users.getUserOrganizations('johndoe');
|
|
612
|
+
*
|
|
613
|
+
* // Get only organizations where user is owner
|
|
614
|
+
* const ownedOrgs = await client.users.getUserOrganizations('johndoe', 'owner');
|
|
615
|
+
* ```
|
|
616
|
+
*/
|
|
617
|
+
getUserOrganizations = async (userId, role) => {
|
|
618
|
+
const query = role ? this.buildQueryString({ role }) : "";
|
|
619
|
+
return this.http.get(`/api/v1/users/${encodeURIComponent(userId)}/organizations${query}`);
|
|
620
|
+
};
|
|
582
621
|
};
|
|
583
622
|
|
|
584
623
|
// src/resources/OrganizationsResource.ts
|
|
@@ -801,7 +840,7 @@ var OrganizationsResource = class extends BaseResource {
|
|
|
801
840
|
*
|
|
802
841
|
* @param {string} organizationId - Organization identifier
|
|
803
842
|
* @param {CreateUserRequest} data - User data including credentials and profile
|
|
804
|
-
* @returns {Promise<
|
|
843
|
+
* @returns {Promise<User>} The created user object
|
|
805
844
|
* @throws {ForbiddenError} When user lacks admin privileges
|
|
806
845
|
* @throws {NotFoundError} When organization is not found
|
|
807
846
|
* @throws {ConflictError} When username/email/phone already exists
|
|
@@ -809,7 +848,7 @@ var OrganizationsResource = class extends BaseResource {
|
|
|
809
848
|
*
|
|
810
849
|
* @example
|
|
811
850
|
* ```typescript
|
|
812
|
-
* const
|
|
851
|
+
* const user = await client.organizations.createUser('org_abc123', {
|
|
813
852
|
* cn: 'john.doe',
|
|
814
853
|
* uid: 'john.doe',
|
|
815
854
|
* // ... other user fields
|
|
@@ -830,14 +869,14 @@ var OrganizationsResource = class extends BaseResource {
|
|
|
830
869
|
* @param {string} organizationId - Organization identifier
|
|
831
870
|
* @param {string} userId - User identifier (username)
|
|
832
871
|
* @param {UpdateUserRequest} data - Fields to update
|
|
833
|
-
* @returns {Promise<{ success: true }>}
|
|
872
|
+
* @returns {Promise<User | { success: true }>} Updated user object or success response
|
|
834
873
|
* @throws {NotFoundError} When user or organization is not found
|
|
835
874
|
* @throws {ForbiddenError} When user lacks admin privileges
|
|
836
875
|
* @throws {ApiError} On other API errors
|
|
837
876
|
*
|
|
838
877
|
* @example
|
|
839
878
|
* ```typescript
|
|
840
|
-
* await client.organizations.updateUser('org_abc123', 'john.doe', {
|
|
879
|
+
* const result = await client.organizations.updateUser('org_abc123', 'john.doe', {
|
|
841
880
|
* mobile: '+33687654321'
|
|
842
881
|
* });
|
|
843
882
|
* ```
|
|
@@ -1016,7 +1055,7 @@ var GroupsResource = class extends BaseResource {
|
|
|
1016
1055
|
*
|
|
1017
1056
|
* @param {string} organizationId - Organization identifier
|
|
1018
1057
|
* @param {CreateGroupRequest} data - Group data (name and optional description)
|
|
1019
|
-
* @returns {Promise<
|
|
1058
|
+
* @returns {Promise<Group>} Created group object
|
|
1020
1059
|
* @throws {ForbiddenError} When user lacks admin privileges
|
|
1021
1060
|
* @throws {NotFoundError} When organization is not found
|
|
1022
1061
|
* @throws {ConflictError} When group name already exists
|
|
@@ -1024,7 +1063,7 @@ var GroupsResource = class extends BaseResource {
|
|
|
1024
1063
|
*
|
|
1025
1064
|
* @examples
|
|
1026
1065
|
* ```typescript
|
|
1027
|
-
* const
|
|
1066
|
+
* const group = await client.groups.create('org_abc123', {
|
|
1028
1067
|
* name: 'engineering',
|
|
1029
1068
|
* description: 'Engineering team'
|
|
1030
1069
|
* });
|