ldap-rest 0.3.0 → 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.
- package/README.md +1 -1
- package/dist/plugins/ldap/organization.js +1 -1
- package/dist/plugins/ldap/organizations.js +1 -0
- package/dist/src/abstract/ldapFlat.d.ts +107 -0
- package/dist/src/plugins/configApi.d.ts +51 -0
- package/dist/src/plugins/demo/helloworld.d.ts +21 -0
- package/dist/src/plugins/ldap/bulkImport.d.ts +65 -0
- package/dist/src/plugins/ldap/groups.d.ts +68 -0
- package/dist/src/plugins/ldap/organization.d.ts +8 -65
- package/dist/src/plugins/ldap/organizations.d.ts +155 -0
- package/dist/src/plugins/ldap/passwordPolicy.d.ts +178 -0
- package/dist/src/plugins/scim/scim.d.ts +389 -0
- package/dist/src/plugins/static.d.ts +33 -0
- package/dist/src/plugins/twake/appAccountsApi.d.ts +63 -0
- package/dist/src/plugins/twake/james.d.ts +47 -0
- package/docs/plugin-development/README.md +2 -1
- package/docs/plugin-development/openapi.md +144 -0
- package/package.json +8 -1
|
@@ -11,6 +11,184 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import type { Express } from 'express';
|
|
13
13
|
import DmPlugin, { type Role } from '../../abstract/plugin';
|
|
14
|
+
/**
|
|
15
|
+
* Shared OpenAPI schemas surfaced by this plugin. Picked up by
|
|
16
|
+
* scripts/generate-openapi.ts and merged into `components.schemas`.
|
|
17
|
+
*
|
|
18
|
+
* @openapi-component
|
|
19
|
+
* PasswordPolicy:
|
|
20
|
+
* type: object
|
|
21
|
+
* description: |
|
|
22
|
+
* Active OpenLDAP ppolicy configuration. All duration fields are in
|
|
23
|
+
* **seconds**. Absent fields mean the policy attribute is not set.
|
|
24
|
+
* properties:
|
|
25
|
+
* dn:
|
|
26
|
+
* type: string
|
|
27
|
+
* description: DN of the ppolicy entry.
|
|
28
|
+
* example: cn=default,ou=policies,dc=example,dc=com
|
|
29
|
+
* pwdMaxAge:
|
|
30
|
+
* type: integer
|
|
31
|
+
* description: Maximum password age in seconds (0 = never expires).
|
|
32
|
+
* example: 7776000
|
|
33
|
+
* pwdMinAge:
|
|
34
|
+
* type: integer
|
|
35
|
+
* description: Minimum password age in seconds before it may be changed.
|
|
36
|
+
* example: 0
|
|
37
|
+
* pwdInHistory:
|
|
38
|
+
* type: integer
|
|
39
|
+
* description: Number of previous passwords stored.
|
|
40
|
+
* example: 5
|
|
41
|
+
* pwdCheckQuality:
|
|
42
|
+
* type: integer
|
|
43
|
+
* description: Password quality enforcement level (0-2).
|
|
44
|
+
* example: 1
|
|
45
|
+
* pwdMinLength:
|
|
46
|
+
* type: integer
|
|
47
|
+
* description: Minimum password length.
|
|
48
|
+
* example: 12
|
|
49
|
+
* pwdMaxFailure:
|
|
50
|
+
* type: integer
|
|
51
|
+
* description: Maximum bind failures before lockout.
|
|
52
|
+
* example: 5
|
|
53
|
+
* pwdLockout:
|
|
54
|
+
* type: boolean
|
|
55
|
+
* description: Whether account lockout is enabled.
|
|
56
|
+
* example: true
|
|
57
|
+
* pwdLockoutDuration:
|
|
58
|
+
* type: integer
|
|
59
|
+
* description: Lockout duration in seconds (0 = permanent until admin reset).
|
|
60
|
+
* example: 300
|
|
61
|
+
* pwdGraceAuthNLimit:
|
|
62
|
+
* type: integer
|
|
63
|
+
* description: Number of grace logins allowed after password expires.
|
|
64
|
+
* example: 0
|
|
65
|
+
* pwdExpireWarning:
|
|
66
|
+
* type: integer
|
|
67
|
+
* description: Seconds before expiry at which a warning is issued.
|
|
68
|
+
* example: 1209600
|
|
69
|
+
* pwdMustChange:
|
|
70
|
+
* type: boolean
|
|
71
|
+
* description: If true, users must change their password after an admin reset.
|
|
72
|
+
* example: true
|
|
73
|
+
* pwdAllowUserChange:
|
|
74
|
+
* type: boolean
|
|
75
|
+
* description: Whether users are allowed to change their own password.
|
|
76
|
+
* example: true
|
|
77
|
+
* PasswordStatus:
|
|
78
|
+
* type: object
|
|
79
|
+
* description: Current password status for a specific user account.
|
|
80
|
+
* required: [dn, passwordSet, isExpired, isExpiringSoon, mustChange, isLocked, failureCount, graceLoginsUsed]
|
|
81
|
+
* properties:
|
|
82
|
+
* dn:
|
|
83
|
+
* type: string
|
|
84
|
+
* description: Fully-qualified DN of the user.
|
|
85
|
+
* example: uid=alice,ou=users,dc=example,dc=com
|
|
86
|
+
* passwordSet:
|
|
87
|
+
* type: boolean
|
|
88
|
+
* description: Whether a userPassword attribute is present.
|
|
89
|
+
* example: true
|
|
90
|
+
* lastChanged:
|
|
91
|
+
* type: string
|
|
92
|
+
* format: date-time
|
|
93
|
+
* nullable: true
|
|
94
|
+
* description: ISO-8601 timestamp of last password change, or null if never set.
|
|
95
|
+
* example: '2026-01-15T10:00:00.000Z'
|
|
96
|
+
* expiresAt:
|
|
97
|
+
* type: string
|
|
98
|
+
* format: date-time
|
|
99
|
+
* nullable: true
|
|
100
|
+
* description: ISO-8601 expiry timestamp, or null if no max age is configured.
|
|
101
|
+
* example: '2026-04-15T10:00:00.000Z'
|
|
102
|
+
* daysUntilExpiration:
|
|
103
|
+
* type: integer
|
|
104
|
+
* nullable: true
|
|
105
|
+
* description: Remaining days until expiry (negative means already expired).
|
|
106
|
+
* example: 80
|
|
107
|
+
* isExpired:
|
|
108
|
+
* type: boolean
|
|
109
|
+
* example: false
|
|
110
|
+
* isExpiringSoon:
|
|
111
|
+
* type: boolean
|
|
112
|
+
* description: True when expiry is within the configured warning window.
|
|
113
|
+
* example: false
|
|
114
|
+
* mustChange:
|
|
115
|
+
* type: boolean
|
|
116
|
+
* description: True when `pwdReset` is set (admin forced change).
|
|
117
|
+
* example: false
|
|
118
|
+
* isLocked:
|
|
119
|
+
* type: boolean
|
|
120
|
+
* description: True when the account is currently locked.
|
|
121
|
+
* example: false
|
|
122
|
+
* lockedAt:
|
|
123
|
+
* type: string
|
|
124
|
+
* format: date-time
|
|
125
|
+
* nullable: true
|
|
126
|
+
* description: ISO-8601 timestamp of lockout, or null.
|
|
127
|
+
* example: null
|
|
128
|
+
* failureCount:
|
|
129
|
+
* type: integer
|
|
130
|
+
* description: Number of recorded bind failures still within the window.
|
|
131
|
+
* example: 0
|
|
132
|
+
* graceLoginsUsed:
|
|
133
|
+
* type: integer
|
|
134
|
+
* description: Number of grace logins already consumed.
|
|
135
|
+
* example: 0
|
|
136
|
+
* ExpiringAccount:
|
|
137
|
+
* type: object
|
|
138
|
+
* description: User whose password is expiring within the warning window.
|
|
139
|
+
* required: [dn, expiresAt, daysUntilExpiration]
|
|
140
|
+
* properties:
|
|
141
|
+
* dn: { type: string, example: uid=bob,ou=users,dc=example,dc=com }
|
|
142
|
+
* uid: { type: string, example: bob }
|
|
143
|
+
* displayName: { type: string, example: Bob Builder }
|
|
144
|
+
* mail: { type: string, example: bob@example.com }
|
|
145
|
+
* expiresAt:
|
|
146
|
+
* type: string
|
|
147
|
+
* format: date-time
|
|
148
|
+
* example: '2026-05-01T08:00:00.000Z'
|
|
149
|
+
* daysUntilExpiration: { type: integer, example: 6 }
|
|
150
|
+
* LockedAccount:
|
|
151
|
+
* type: object
|
|
152
|
+
* description: User account that is currently locked.
|
|
153
|
+
* required: [dn, failureCount]
|
|
154
|
+
* properties:
|
|
155
|
+
* dn: { type: string, example: uid=charlie,ou=users,dc=example,dc=com }
|
|
156
|
+
* uid: { type: string, example: charlie }
|
|
157
|
+
* displayName: { type: string, example: Charlie Chaplin }
|
|
158
|
+
* mail: { type: string, example: charlie@example.com }
|
|
159
|
+
* lockedAt:
|
|
160
|
+
* type: string
|
|
161
|
+
* format: date-time
|
|
162
|
+
* nullable: true
|
|
163
|
+
* example: '2026-04-24T14:30:00.000Z'
|
|
164
|
+
* failureCount: { type: integer, example: 5 }
|
|
165
|
+
* PasswordValidationRequest:
|
|
166
|
+
* type: object
|
|
167
|
+
* required: [password]
|
|
168
|
+
* properties:
|
|
169
|
+
* password:
|
|
170
|
+
* type: string
|
|
171
|
+
* format: password
|
|
172
|
+
* description: The candidate password to validate.
|
|
173
|
+
* example: 'S3cur3P@ss!'
|
|
174
|
+
* dn:
|
|
175
|
+
* type: string
|
|
176
|
+
* description: Optional user DN for context (not used in local validation).
|
|
177
|
+
* example: uid=alice,ou=users,dc=example,dc=com
|
|
178
|
+
* PasswordValidationResponse:
|
|
179
|
+
* type: object
|
|
180
|
+
* required: [valid, errors]
|
|
181
|
+
* properties:
|
|
182
|
+
* valid:
|
|
183
|
+
* type: boolean
|
|
184
|
+
* description: True when the password meets all complexity rules.
|
|
185
|
+
* example: true
|
|
186
|
+
* errors:
|
|
187
|
+
* type: array
|
|
188
|
+
* items: { type: string }
|
|
189
|
+
* description: List of failed rule descriptions (empty when valid).
|
|
190
|
+
* example: []
|
|
191
|
+
*/
|
|
14
192
|
export default class PasswordPolicy extends DmPlugin {
|
|
15
193
|
name: string;
|
|
16
194
|
roles: Role[];
|
|
@@ -3,6 +3,395 @@ import DmPlugin, { type Role } from '../../abstract/plugin';
|
|
|
3
3
|
import type { DM } from '../../bin';
|
|
4
4
|
import type ldapActions from '../../lib/ldapActions';
|
|
5
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
|
+
*/
|
|
6
395
|
export default class Scim extends DmPlugin {
|
|
7
396
|
name: string;
|
|
8
397
|
roles: Role[];
|
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
import type { Express } from 'express';
|
|
2
2
|
import DmPlugin, { type Role } from '../abstract/plugin';
|
|
3
|
+
/**
|
|
4
|
+
* @openapi-component
|
|
5
|
+
* LdapSchema:
|
|
6
|
+
* type: object
|
|
7
|
+
* description: |
|
|
8
|
+
* A JSON schema file served from the `schemas/` sub-directory of the
|
|
9
|
+
* static path. These schemas describe LDAP entity types (users, groups,
|
|
10
|
+
* organizations, …) and are consumed by browser-embedded editors to
|
|
11
|
+
* render attribute forms and validate input before submission.
|
|
12
|
+
*
|
|
13
|
+
* The server replaces `__FOO_BAR__` placeholders on the fly with the
|
|
14
|
+
* value of the corresponding `--foo-bar` CLI option so that a single
|
|
15
|
+
* schema file can be shared between server-side validation and
|
|
16
|
+
* client-side rendering.
|
|
17
|
+
* additionalProperties: true
|
|
18
|
+
* example:
|
|
19
|
+
* entity:
|
|
20
|
+
* name: standardUser
|
|
21
|
+
* mainAttribute: uid
|
|
22
|
+
* objectClass: [top, inetOrgPerson]
|
|
23
|
+
* singularName: user
|
|
24
|
+
* pluralName: users
|
|
25
|
+
* base: ou=users,dc=example,dc=com
|
|
26
|
+
* strict: true
|
|
27
|
+
* attributes:
|
|
28
|
+
* uid:
|
|
29
|
+
* type: string
|
|
30
|
+
* required: true
|
|
31
|
+
* role: identifier
|
|
32
|
+
* cn:
|
|
33
|
+
* type: string
|
|
34
|
+
* required: true
|
|
35
|
+
*/
|
|
3
36
|
export default class Static extends DmPlugin {
|
|
4
37
|
name: string;
|
|
5
38
|
roles: Role[];
|
|
@@ -1,6 +1,69 @@
|
|
|
1
1
|
import type { Express } from 'express';
|
|
2
2
|
import DmPlugin, { type Role } from '../../abstract/plugin';
|
|
3
3
|
import type { DM } from '../../bin';
|
|
4
|
+
/**
|
|
5
|
+
* @openapi-component
|
|
6
|
+
* AppAccount:
|
|
7
|
+
* type: object
|
|
8
|
+
* description: |
|
|
9
|
+
* An application-specific identity attached to a user. App accounts
|
|
10
|
+
* allow a single principal user to authenticate as different named
|
|
11
|
+
* "devices" or "applications" each with its own credential, while
|
|
12
|
+
* sharing the same mail address.
|
|
13
|
+
* required: [uid]
|
|
14
|
+
* properties:
|
|
15
|
+
* uid:
|
|
16
|
+
* type: string
|
|
17
|
+
* description: |
|
|
18
|
+
* Unique identifier of the app account. Format:
|
|
19
|
+
* `<username>_c<8-digits>` (e.g. `alice_c04729183`).
|
|
20
|
+
* example: alice_c04729183
|
|
21
|
+
* name:
|
|
22
|
+
* type: string
|
|
23
|
+
* description: Human-readable label (stored as LDAP `description`).
|
|
24
|
+
* example: Work laptop
|
|
25
|
+
* example:
|
|
26
|
+
* uid: alice_c04729183
|
|
27
|
+
* name: Work laptop
|
|
28
|
+
* AppAccountCreated:
|
|
29
|
+
* type: object
|
|
30
|
+
* description: |
|
|
31
|
+
* Response returned when a new app account is successfully created.
|
|
32
|
+
* The one-time cleartext password is included here and never returned
|
|
33
|
+
* again — callers must store it immediately.
|
|
34
|
+
* required: [uid, pwd, mail]
|
|
35
|
+
* properties:
|
|
36
|
+
* uid:
|
|
37
|
+
* type: string
|
|
38
|
+
* description: Identifier of the newly created app account.
|
|
39
|
+
* example: alice_c04729183
|
|
40
|
+
* pwd:
|
|
41
|
+
* type: string
|
|
42
|
+
* description: |
|
|
43
|
+
* One-time cleartext password generated for this account.
|
|
44
|
+
* Format: 6 blocks of 4 characters separated by `-`
|
|
45
|
+
* (e.g. `Ab3@-xYz!-9pQ#-Sv4$-mN8!-pQ5@`).
|
|
46
|
+
* OpenLDAP hashes it via ppolicy before storage.
|
|
47
|
+
* example: Ab3@-xYz!-9pQ#-Sv4$-mN8!-pQ5@
|
|
48
|
+
* mail:
|
|
49
|
+
* type: string
|
|
50
|
+
* description: Mail address of the principal account this app account belongs to.
|
|
51
|
+
* example: alice@example.com
|
|
52
|
+
* example:
|
|
53
|
+
* uid: alice_c04729183
|
|
54
|
+
* pwd: Ab3@-xYz!-9pQ#-Sv4$-mN8!-pQ5@
|
|
55
|
+
* mail: alice@example.com
|
|
56
|
+
* AppAccountCreate:
|
|
57
|
+
* type: object
|
|
58
|
+
* description: Request body for creating a new app account.
|
|
59
|
+
* properties:
|
|
60
|
+
* name:
|
|
61
|
+
* type: string
|
|
62
|
+
* description: Optional human-readable label for the new account.
|
|
63
|
+
* example: Work laptop
|
|
64
|
+
* example:
|
|
65
|
+
* name: Work laptop
|
|
66
|
+
*/
|
|
4
67
|
export default class AppAccountsApi extends DmPlugin {
|
|
5
68
|
name: string;
|
|
6
69
|
roles: Role[];
|