ldap-rest 0.2.2 → 0.3.1

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.
Files changed (53) hide show
  1. package/README.md +1 -1
  2. package/dist/abstract/ldapFlat.js +1 -1
  3. package/dist/bin/index.js +1 -1
  4. package/dist/config/args.js +1 -1
  5. package/dist/lib/expressFormatedResponses.js +1 -1
  6. package/dist/plugins/auth/authzDynamic.js +1 -0
  7. package/dist/plugins/auth/authzDynamicHash.js +1 -0
  8. package/dist/plugins/ldap/organization.js +1 -1
  9. package/dist/plugins/ldap/organizations.js +1 -0
  10. package/dist/plugins/scim/baseResolver.js +1 -0
  11. package/dist/plugins/scim/bulk.js +1 -0
  12. package/dist/plugins/scim/discovery.js +1 -0
  13. package/dist/plugins/scim/errors.js +1 -0
  14. package/dist/plugins/scim/filter.js +1 -0
  15. package/dist/plugins/scim/groups.js +1 -0
  16. package/dist/plugins/scim/mapping.js +1 -0
  17. package/dist/plugins/scim/patch.js +1 -0
  18. package/dist/plugins/scim/scim.js +1 -0
  19. package/dist/plugins/scim/types.js +1 -0
  20. package/dist/plugins/scim/users.js +1 -0
  21. package/dist/src/abstract/ldapFlat.d.ts +127 -0
  22. package/dist/src/config/args.d.ts +24 -0
  23. package/dist/src/plugins/auth/authzDynamic.d.ts +117 -0
  24. package/dist/src/plugins/auth/authzDynamicHash.d.ts +27 -0
  25. package/dist/src/plugins/configApi.d.ts +51 -0
  26. package/dist/src/plugins/demo/helloworld.d.ts +21 -0
  27. package/dist/src/plugins/ldap/bulkImport.d.ts +65 -0
  28. package/dist/src/plugins/ldap/groups.d.ts +68 -0
  29. package/dist/src/plugins/ldap/organization.d.ts +8 -65
  30. package/dist/src/plugins/ldap/organizations.d.ts +155 -0
  31. package/dist/src/plugins/ldap/passwordPolicy.d.ts +178 -0
  32. package/dist/src/plugins/scim/baseResolver.d.ts +23 -0
  33. package/dist/src/plugins/scim/bulk.d.ts +43 -0
  34. package/dist/src/plugins/scim/discovery.d.ts +27 -0
  35. package/dist/src/plugins/scim/errors.d.ts +37 -0
  36. package/dist/src/plugins/scim/filter.d.ts +13 -0
  37. package/dist/src/plugins/scim/groups.d.ts +61 -0
  38. package/dist/src/plugins/scim/mapping.d.ts +52 -0
  39. package/dist/src/plugins/scim/patch.d.ts +39 -0
  40. package/dist/src/plugins/scim/scim.d.ts +412 -0
  41. package/dist/src/plugins/scim/types.d.ts +222 -0
  42. package/dist/src/plugins/scim/users.d.ts +58 -0
  43. package/dist/src/plugins/static.d.ts +33 -0
  44. package/dist/src/plugins/twake/appAccountsApi.d.ts +63 -0
  45. package/dist/src/plugins/twake/james.d.ts +47 -0
  46. package/docs/plugin-development/README.md +2 -1
  47. package/docs/plugin-development/openapi.md +144 -0
  48. package/docs/usage/plugins/auth/authz-dynamic.md +183 -0
  49. package/docs/usage/plugins/integrations/scim.md +567 -0
  50. package/package.json +72 -1
  51. package/static/schemas/scim/Group.json +31 -0
  52. package/static/schemas/scim/User.json +147 -0
  53. package/static/schemas/scim/default-mapping.json +48 -0
@@ -0,0 +1,412 @@
1
+ import type { Express } from 'express';
2
+ import DmPlugin, { type Role } from '../../abstract/plugin';
3
+ import type { DM } from '../../bin';
4
+ import type ldapActions from '../../lib/ldapActions';
5
+ import { writeScimErrorFromException } from './errors';
6
+ /**
7
+ * Reusable SCIM 2.0 schemas surfaced by this plugin.
8
+ * Picked up by scripts/generate-openapi.ts and merged into `components.schemas`.
9
+ *
10
+ * @openapi-component
11
+ * ScimUser:
12
+ * type: object
13
+ * description: |
14
+ * SCIM 2.0 User resource (RFC 7643 §4.1).
15
+ * required: [schemas, userName]
16
+ * properties:
17
+ * schemas:
18
+ * type: array
19
+ * items: { type: string }
20
+ * example: ['urn:ietf:params:scim:schemas:core:2.0:User']
21
+ * id:
22
+ * type: string
23
+ * description: Opaque server-assigned identifier.
24
+ * example: 2819c223-7f76-453a-919d-413861904646
25
+ * externalId:
26
+ * type: string
27
+ * description: Provisioner-assigned identifier.
28
+ * example: 701984
29
+ * userName:
30
+ * type: string
31
+ * description: Unique user identifier (login name).
32
+ * example: bjensen
33
+ * name:
34
+ * type: object
35
+ * properties:
36
+ * formatted: { type: string, example: Ms. Barbara J Jensen III }
37
+ * familyName: { type: string, example: Jensen }
38
+ * givenName: { type: string, example: Barbara }
39
+ * middleName: { type: string, example: Jane }
40
+ * honorificPrefix: { type: string, example: Ms. }
41
+ * honorificSuffix: { type: string, example: III }
42
+ * displayName:
43
+ * type: string
44
+ * example: Babs Jensen
45
+ * nickName:
46
+ * type: string
47
+ * example: Babs
48
+ * profileUrl:
49
+ * type: string
50
+ * example: https://login.example.com/bjensen
51
+ * title:
52
+ * type: string
53
+ * example: Tour Guide
54
+ * userType:
55
+ * type: string
56
+ * example: Employee
57
+ * preferredLanguage:
58
+ * type: string
59
+ * example: en-US
60
+ * locale:
61
+ * type: string
62
+ * example: en-US
63
+ * timezone:
64
+ * type: string
65
+ * example: America/Los_Angeles
66
+ * active:
67
+ * type: boolean
68
+ * example: true
69
+ * emails:
70
+ * type: array
71
+ * items:
72
+ * type: object
73
+ * properties:
74
+ * value: { type: string }
75
+ * display: { type: string }
76
+ * type: { type: string }
77
+ * primary: { type: boolean }
78
+ * example:
79
+ * - value: bjensen@example.com
80
+ * type: work
81
+ * primary: true
82
+ * phoneNumbers:
83
+ * type: array
84
+ * items:
85
+ * type: object
86
+ * properties:
87
+ * value: { type: string }
88
+ * type: { type: string }
89
+ * primary: { type: boolean }
90
+ * addresses:
91
+ * type: array
92
+ * items:
93
+ * type: object
94
+ * properties:
95
+ * streetAddress: { type: string }
96
+ * locality: { type: string }
97
+ * region: { type: string }
98
+ * postalCode: { type: string }
99
+ * country: { type: string }
100
+ * type: { type: string }
101
+ * primary: { type: boolean }
102
+ * groups:
103
+ * type: array
104
+ * description: Groups the user belongs to (read-only).
105
+ * items:
106
+ * type: object
107
+ * properties:
108
+ * value: { type: string }
109
+ * $ref: { type: string }
110
+ * display: { type: string }
111
+ * meta:
112
+ * type: object
113
+ * properties:
114
+ * resourceType: { type: string, example: User }
115
+ * created: { type: string, format: date-time }
116
+ * lastModified: { type: string, format: date-time }
117
+ * location: { type: string }
118
+ * version: { type: string }
119
+ * ScimGroup:
120
+ * type: object
121
+ * description: |
122
+ * SCIM 2.0 Group resource (RFC 7643 §4.2).
123
+ * required: [schemas, displayName]
124
+ * properties:
125
+ * schemas:
126
+ * type: array
127
+ * items: { type: string }
128
+ * example: ['urn:ietf:params:scim:schemas:core:2.0:Group']
129
+ * id:
130
+ * type: string
131
+ * description: Opaque server-assigned identifier.
132
+ * example: e9e30dba-f08f-4109-8486-d5c6a331660a
133
+ * externalId:
134
+ * type: string
135
+ * example: 00g1emaKYZTWRINFRGETl
136
+ * displayName:
137
+ * type: string
138
+ * example: Tour Guides
139
+ * members:
140
+ * type: array
141
+ * description: Members of the group.
142
+ * items:
143
+ * type: object
144
+ * properties:
145
+ * value: { type: string, description: User or Group id }
146
+ * $ref: { type: string }
147
+ * display: { type: string }
148
+ * example:
149
+ * - value: 2819c223-7f76-453a-919d-413861904646
150
+ * display: Babs Jensen
151
+ * - value: 902c246b-6245-4190-8e05-00816be7344a
152
+ * display: Mandy Pepperidge
153
+ * meta:
154
+ * type: object
155
+ * properties:
156
+ * resourceType: { type: string, example: Group }
157
+ * created: { type: string, format: date-time }
158
+ * lastModified: { type: string, format: date-time }
159
+ * location: { type: string }
160
+ * version: { type: string }
161
+ * ScimListResponse:
162
+ * type: object
163
+ * description: |
164
+ * SCIM 2.0 list query response (urn:ietf:params:scim:api:messages:2.0:ListResponse).
165
+ * required: [schemas, totalResults, Resources]
166
+ * properties:
167
+ * schemas:
168
+ * type: array
169
+ * items: { type: string }
170
+ * example: ['urn:ietf:params:scim:api:messages:2.0:ListResponse']
171
+ * totalResults:
172
+ * type: integer
173
+ * description: Total number of matching resources.
174
+ * example: 2
175
+ * startIndex:
176
+ * type: integer
177
+ * description: 1-based index of the first result returned.
178
+ * example: 1
179
+ * itemsPerPage:
180
+ * type: integer
181
+ * description: Number of resources returned in this page.
182
+ * example: 2
183
+ * Resources:
184
+ * type: array
185
+ * items: {}
186
+ * description: The matching resources.
187
+ * ScimError:
188
+ * type: object
189
+ * description: |
190
+ * SCIM 2.0 error response (urn:ietf:params:scim:api:messages:2.0:Error).
191
+ * required: [schemas, status]
192
+ * properties:
193
+ * schemas:
194
+ * type: array
195
+ * items: { type: string }
196
+ * example: ['urn:ietf:params:scim:api:messages:2.0:Error']
197
+ * status:
198
+ * type: string
199
+ * description: HTTP status code as a string.
200
+ * example: '404'
201
+ * scimType:
202
+ * type: string
203
+ * description: |
204
+ * SCIM error type keyword (RFC 7644 §3.12). One of: invalidFilter,
205
+ * tooMany, uniqueness, mutability, invalidSyntax, invalidPath,
206
+ * noTarget, invalidValue, invalidVers, sensitive.
207
+ * example: mutability
208
+ * detail:
209
+ * type: string
210
+ * description: Human-readable error description.
211
+ * example: Resource 2819c223-7f76-453a-919d-413861904646 not found.
212
+ * example:
213
+ * schemas: ['urn:ietf:params:scim:api:messages:2.0:Error']
214
+ * status: '404'
215
+ * detail: Resource 2819c223-7f76-453a-919d-413861904646 not found.
216
+ * ScimPatchOp:
217
+ * type: object
218
+ * description: |
219
+ * SCIM 2.0 patch request body (urn:ietf:params:scim:api:messages:2.0:PatchOp,
220
+ * RFC 7644 §3.5.2).
221
+ * required: [schemas, Operations]
222
+ * properties:
223
+ * schemas:
224
+ * type: array
225
+ * items: { type: string }
226
+ * example: ['urn:ietf:params:scim:api:messages:2.0:PatchOp']
227
+ * Operations:
228
+ * type: array
229
+ * items:
230
+ * type: object
231
+ * required: [op]
232
+ * properties:
233
+ * op:
234
+ * type: string
235
+ * enum: [add, remove, replace, Add, Remove, Replace]
236
+ * path:
237
+ * type: string
238
+ * description: SCIM attribute path (e.g. "emails[type eq \"work\"].value").
239
+ * value:
240
+ * description: New value for the target attribute.
241
+ * example:
242
+ * schemas: ['urn:ietf:params:scim:api:messages:2.0:PatchOp']
243
+ * Operations:
244
+ * - op: replace
245
+ * path: active
246
+ * value: false
247
+ * - op: replace
248
+ * path: emails[type eq "work"].value
249
+ * value: bjensen@newdomain.example.com
250
+ * ScimBulkRequest:
251
+ * type: object
252
+ * description: |
253
+ * SCIM 2.0 Bulk request (urn:ietf:params:scim:api:messages:2.0:BulkRequest,
254
+ * RFC 7644 §3.7).
255
+ * required: [schemas, Operations]
256
+ * properties:
257
+ * schemas:
258
+ * type: array
259
+ * items: { type: string }
260
+ * example: ['urn:ietf:params:scim:api:messages:2.0:BulkRequest']
261
+ * failOnErrors:
262
+ * type: integer
263
+ * description: |
264
+ * Stop processing after this many errors. Omit or set to 0 to
265
+ * continue on errors and process all operations.
266
+ * example: 1
267
+ * Operations:
268
+ * type: array
269
+ * items:
270
+ * type: object
271
+ * required: [method, path]
272
+ * properties:
273
+ * method:
274
+ * type: string
275
+ * enum: [POST, PUT, PATCH, DELETE]
276
+ * bulkId:
277
+ * type: string
278
+ * description: |
279
+ * Temporary client-assigned identifier for this operation.
280
+ * Subsequent operations in the same request may reference the
281
+ * created resource as "bulkId:<value>".
282
+ * path:
283
+ * type: string
284
+ * description: Resource path relative to the SCIM prefix (e.g. /Users or /Groups/123).
285
+ * data:
286
+ * description: Request body for POST/PUT/PATCH operations.
287
+ * example:
288
+ * schemas: ['urn:ietf:params:scim:api:messages:2.0:BulkRequest']
289
+ * failOnErrors: 1
290
+ * Operations:
291
+ * - method: POST
292
+ * bulkId: qwerty
293
+ * path: /Users
294
+ * data:
295
+ * schemas: ['urn:ietf:params:scim:schemas:core:2.0:User']
296
+ * userName: bjensen
297
+ * name:
298
+ * familyName: Jensen
299
+ * givenName: Barbara
300
+ * - method: DELETE
301
+ * path: /Users/2819c223-7f76-453a-919d-413861904646
302
+ * ScimBulkResponse:
303
+ * type: object
304
+ * description: |
305
+ * SCIM 2.0 Bulk response (urn:ietf:params:scim:api:messages:2.0:BulkResponse).
306
+ * required: [schemas, Operations]
307
+ * properties:
308
+ * schemas:
309
+ * type: array
310
+ * items: { type: string }
311
+ * example: ['urn:ietf:params:scim:api:messages:2.0:BulkResponse']
312
+ * Operations:
313
+ * type: array
314
+ * items:
315
+ * type: object
316
+ * required: [method, status]
317
+ * properties:
318
+ * method:
319
+ * type: string
320
+ * enum: [POST, PUT, PATCH, DELETE]
321
+ * bulkId:
322
+ * type: string
323
+ * location:
324
+ * type: string
325
+ * description: URL of the created/modified resource.
326
+ * version:
327
+ * type: string
328
+ * status:
329
+ * type: string
330
+ * description: HTTP status code for this individual operation.
331
+ * response:
332
+ * $ref: '#/components/schemas/ScimError'
333
+ * description: Present only when the operation failed.
334
+ * example:
335
+ * schemas: ['urn:ietf:params:scim:api:messages:2.0:BulkResponse']
336
+ * Operations:
337
+ * - method: POST
338
+ * bulkId: qwerty
339
+ * location: https://example.com/scim/v2/Users/2819c223-7f76-453a-919d-413861904646
340
+ * status: '201'
341
+ * - method: DELETE
342
+ * status: '204'
343
+ * ScimResourceType:
344
+ * type: object
345
+ * description: SCIM 2.0 ResourceType definition (RFC 7643 §6).
346
+ * required: [schemas, id, name, endpoint, schema]
347
+ * properties:
348
+ * schemas:
349
+ * type: array
350
+ * items: { type: string }
351
+ * example: ['urn:ietf:params:scim:schemas:core:2.0:ResourceType']
352
+ * id: { type: string, example: User }
353
+ * name: { type: string, example: User }
354
+ * endpoint: { type: string, example: /Users }
355
+ * description: { type: string, example: User Account }
356
+ * schema:
357
+ * type: string
358
+ * example: urn:ietf:params:scim:schemas:core:2.0:User
359
+ * schemaExtensions:
360
+ * type: array
361
+ * items:
362
+ * type: object
363
+ * properties:
364
+ * schema: { type: string }
365
+ * required: { type: boolean }
366
+ * meta:
367
+ * type: object
368
+ * properties:
369
+ * resourceType: { type: string, example: ResourceType }
370
+ * location: { type: string }
371
+ * ScimSchema:
372
+ * type: object
373
+ * description: SCIM 2.0 Schema definition (RFC 7643 §7).
374
+ * required: [schemas, id, name, attributes]
375
+ * properties:
376
+ * schemas:
377
+ * type: array
378
+ * items: { type: string }
379
+ * example: ['urn:ietf:params:scim:schemas:core:2.0:Schema']
380
+ * id:
381
+ * type: string
382
+ * example: urn:ietf:params:scim:schemas:core:2.0:User
383
+ * name: { type: string, example: User }
384
+ * description: { type: string, example: User Account }
385
+ * attributes:
386
+ * type: array
387
+ * items: {}
388
+ * description: Schema attribute definitions.
389
+ * meta:
390
+ * type: object
391
+ * properties:
392
+ * resourceType: { type: string, example: Schema }
393
+ * location: { type: string }
394
+ */
395
+ export default class Scim extends DmPlugin {
396
+ name: string;
397
+ roles: Role[];
398
+ ldap: ldapActions;
399
+ private readonly scimPrefix;
400
+ private readonly users;
401
+ private readonly groups;
402
+ private readonly bulk;
403
+ private readonly discovery;
404
+ private readonly baseResolver;
405
+ constructor(server: DM);
406
+ private scimJson;
407
+ private readScimBody;
408
+ api(app: Express): void;
409
+ private parseListQuery;
410
+ getConfigApiData(): Record<string, unknown>;
411
+ }
412
+ export { writeScimErrorFromException };
@@ -0,0 +1,222 @@
1
+ /**
2
+ * @module plugins/scim/types
3
+ * @author Xavier Guimard <xguimard@linagora.com>
4
+ *
5
+ * SCIM 2.0 type definitions (RFC 7643 / RFC 7644).
6
+ */
7
+ export declare const SCHEMA_USER = "urn:ietf:params:scim:schemas:core:2.0:User";
8
+ export declare const SCHEMA_GROUP = "urn:ietf:params:scim:schemas:core:2.0:Group";
9
+ export declare const SCHEMA_LIST_RESPONSE = "urn:ietf:params:scim:api:messages:2.0:ListResponse";
10
+ export declare const SCHEMA_ERROR = "urn:ietf:params:scim:api:messages:2.0:Error";
11
+ export declare const SCHEMA_PATCH_OP = "urn:ietf:params:scim:api:messages:2.0:PatchOp";
12
+ export declare const SCHEMA_BULK_REQUEST = "urn:ietf:params:scim:api:messages:2.0:BulkRequest";
13
+ export declare const SCHEMA_BULK_RESPONSE = "urn:ietf:params:scim:api:messages:2.0:BulkResponse";
14
+ export declare const SCHEMA_SERVICE_PROVIDER_CONFIG = "urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig";
15
+ export declare const SCHEMA_RESOURCE_TYPE = "urn:ietf:params:scim:schemas:core:2.0:ResourceType";
16
+ export declare const SCHEMA_SCHEMA = "urn:ietf:params:scim:schemas:core:2.0:Schema";
17
+ export interface Meta {
18
+ resourceType: 'User' | 'Group';
19
+ created?: string;
20
+ lastModified?: string;
21
+ location?: string;
22
+ version?: string;
23
+ }
24
+ export interface MultiValued<T extends string = string> {
25
+ value: T;
26
+ display?: string;
27
+ type?: string;
28
+ primary?: boolean;
29
+ $ref?: string;
30
+ }
31
+ export interface ScimName {
32
+ formatted?: string;
33
+ familyName?: string;
34
+ givenName?: string;
35
+ middleName?: string;
36
+ honorificPrefix?: string;
37
+ honorificSuffix?: string;
38
+ }
39
+ export interface ScimUser {
40
+ schemas: string[];
41
+ id?: string;
42
+ externalId?: string;
43
+ userName?: string;
44
+ name?: ScimName;
45
+ displayName?: string;
46
+ nickName?: string;
47
+ profileUrl?: string;
48
+ title?: string;
49
+ userType?: string;
50
+ preferredLanguage?: string;
51
+ locale?: string;
52
+ timezone?: string;
53
+ active?: boolean;
54
+ password?: string;
55
+ emails?: MultiValued[];
56
+ phoneNumbers?: MultiValued[];
57
+ ims?: MultiValued[];
58
+ photos?: MultiValued[];
59
+ addresses?: ScimAddress[];
60
+ groups?: MultiValued[];
61
+ entitlements?: MultiValued[];
62
+ roles?: MultiValued[];
63
+ x509Certificates?: MultiValued[];
64
+ meta?: Meta;
65
+ [ext: string]: unknown;
66
+ }
67
+ export interface ScimAddress {
68
+ formatted?: string;
69
+ streetAddress?: string;
70
+ locality?: string;
71
+ region?: string;
72
+ postalCode?: string;
73
+ country?: string;
74
+ type?: string;
75
+ primary?: boolean;
76
+ }
77
+ export interface ScimGroup {
78
+ schemas: string[];
79
+ id?: string;
80
+ externalId?: string;
81
+ displayName?: string;
82
+ members?: MultiValued[];
83
+ meta?: Meta;
84
+ [ext: string]: unknown;
85
+ }
86
+ export type ScimResource = ScimUser | ScimGroup;
87
+ export interface ListResponse<T> {
88
+ schemas: [typeof SCHEMA_LIST_RESPONSE];
89
+ totalResults: number;
90
+ startIndex: number;
91
+ itemsPerPage: number;
92
+ Resources: T[];
93
+ }
94
+ export type ScimErrorType = 'invalidFilter' | 'tooMany' | 'uniqueness' | 'mutability' | 'invalidSyntax' | 'invalidPath' | 'noTarget' | 'invalidValue' | 'invalidVers' | 'sensitive';
95
+ export interface ScimErrorResponse {
96
+ schemas: [typeof SCHEMA_ERROR];
97
+ status: string;
98
+ scimType?: ScimErrorType;
99
+ detail?: string;
100
+ }
101
+ export interface PatchOperation {
102
+ op: 'add' | 'remove' | 'replace' | 'Add' | 'Remove' | 'Replace';
103
+ path?: string;
104
+ value?: unknown;
105
+ }
106
+ export interface PatchRequest {
107
+ schemas: string[];
108
+ Operations: PatchOperation[];
109
+ }
110
+ export interface BulkOperationRequest {
111
+ method: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
112
+ bulkId?: string;
113
+ version?: string;
114
+ path: string;
115
+ data?: unknown;
116
+ }
117
+ export interface BulkRequest {
118
+ schemas: string[];
119
+ failOnErrors?: number;
120
+ Operations: BulkOperationRequest[];
121
+ }
122
+ export interface BulkOperationResponse {
123
+ method: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
124
+ bulkId?: string;
125
+ version?: string;
126
+ location?: string;
127
+ status: string;
128
+ response?: ScimErrorResponse;
129
+ }
130
+ export interface BulkResponse {
131
+ schemas: [typeof SCHEMA_BULK_RESPONSE];
132
+ Operations: BulkOperationResponse[];
133
+ }
134
+ /**
135
+ * Internal mapping description: SCIM attribute → LDAP attribute(s).
136
+ *
137
+ * - ldap: one LDAP attribute name (simple mapping)
138
+ * - ldapPrimary/ldapSecondary: primary vs non-primary in multi-valued attr (emails)
139
+ * - sub: nested SCIM attribute name (for name.familyName etc.)
140
+ * - multi: 'single' or 'array' (hint for formatting)
141
+ * - operational: read-only from LDAP operational attribute
142
+ */
143
+ export interface MappingEntry {
144
+ scim: string;
145
+ ldap?: string;
146
+ ldapPrimary?: string;
147
+ ldapSecondary?: string;
148
+ sub?: Record<string, string>;
149
+ multi?: 'single' | 'array';
150
+ readOnly?: boolean;
151
+ operational?: boolean;
152
+ converter?: 'boolean' | 'number' | 'string';
153
+ }
154
+ export interface ResourceMapping {
155
+ resourceType: 'User' | 'Group';
156
+ schemas: string[];
157
+ entries: MappingEntry[];
158
+ }
159
+ export interface ServiceProviderConfig {
160
+ schemas: [typeof SCHEMA_SERVICE_PROVIDER_CONFIG];
161
+ documentationUri?: string;
162
+ patch: {
163
+ supported: boolean;
164
+ };
165
+ bulk: {
166
+ supported: boolean;
167
+ maxOperations: number;
168
+ maxPayloadSize: number;
169
+ };
170
+ filter: {
171
+ supported: boolean;
172
+ maxResults: number;
173
+ };
174
+ changePassword: {
175
+ supported: boolean;
176
+ };
177
+ sort: {
178
+ supported: boolean;
179
+ };
180
+ etag: {
181
+ supported: boolean;
182
+ };
183
+ authenticationSchemes: Array<{
184
+ name: string;
185
+ description: string;
186
+ specUri?: string;
187
+ documentationUri?: string;
188
+ type: string;
189
+ primary?: boolean;
190
+ }>;
191
+ meta?: {
192
+ resourceType: 'ServiceProviderConfig';
193
+ location?: string;
194
+ };
195
+ }
196
+ export interface ResourceTypeDefinition {
197
+ schemas: [typeof SCHEMA_RESOURCE_TYPE];
198
+ id: string;
199
+ name: string;
200
+ endpoint: string;
201
+ description?: string;
202
+ schema: string;
203
+ schemaExtensions?: Array<{
204
+ schema: string;
205
+ required: boolean;
206
+ }>;
207
+ meta?: {
208
+ resourceType: 'ResourceType';
209
+ location?: string;
210
+ };
211
+ }
212
+ export interface SchemaDefinition {
213
+ schemas: [typeof SCHEMA_SCHEMA];
214
+ id: string;
215
+ name: string;
216
+ description?: string;
217
+ attributes: unknown[];
218
+ meta?: {
219
+ resourceType: 'Schema';
220
+ location?: string;
221
+ };
222
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @module plugins/scim/users
3
+ * @author Xavier Guimard <xguimard@linagora.com>
4
+ *
5
+ * SCIM Users resource handler — direct access via ldapActions.
6
+ */
7
+ import type winston from 'winston';
8
+ import type ldapActions from '../../lib/ldapActions';
9
+ import type { Config } from '../../config/args';
10
+ import type { DmRequest } from '../../lib/auth/base';
11
+ import { BaseResolver } from './baseResolver';
12
+ import { type ResourceMapping, type ScimUser, type ListResponse, type PatchRequest } from './types';
13
+ export interface ListQuery {
14
+ filter?: string;
15
+ startIndex?: number;
16
+ count?: number;
17
+ attributes?: string[];
18
+ excludedAttributes?: string[];
19
+ sortBy?: string;
20
+ sortOrder?: 'ascending' | 'descending';
21
+ }
22
+ export interface ScimUsersOptions {
23
+ ldap: ldapActions;
24
+ config: Config;
25
+ logger: winston.Logger;
26
+ baseResolver: BaseResolver;
27
+ hooks: {
28
+ [K: string]: Function[] | undefined;
29
+ };
30
+ }
31
+ export declare class ScimUsers {
32
+ private readonly ldap;
33
+ private readonly config;
34
+ private readonly logger;
35
+ private readonly baseResolver;
36
+ private readonly hooks;
37
+ private readonly mapping;
38
+ private readonly rdnAttribute;
39
+ private readonly objectClass;
40
+ private readonly idAttribute;
41
+ private readonly maxResults;
42
+ private readonly scimPrefix;
43
+ constructor(opts: ScimUsersOptions);
44
+ private ctx;
45
+ private dnForId;
46
+ get(req: DmRequest, id: string): Promise<ScimUser>;
47
+ list(req: DmRequest, query: ListQuery): Promise<ListResponse<ScimUser>>;
48
+ create(req: DmRequest, resource: ScimUser): Promise<ScimUser>;
49
+ replace(req: DmRequest, id: string, resource: ScimUser): Promise<ScimUser>;
50
+ patch(req: DmRequest, id: string, patch: PatchRequest): Promise<ScimUser>;
51
+ delete(req: DmRequest, id: string): Promise<void>;
52
+ /**
53
+ * Given a SCIM member value (typically an id), return the LDAP DN.
54
+ * Used by Groups PATCH and Bulk reference resolution.
55
+ */
56
+ resolveRef(req: DmRequest, value: string): Promise<string | undefined>;
57
+ get userMapping(): ResourceMapping;
58
+ }