ldap-rest 0.0.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 (296) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +48 -0
  3. package/bin/cleanup-external-users.mjs +219 -0
  4. package/bin/index.mjs +54 -0
  5. package/bin/sync-james.mjs +190 -0
  6. package/dist/abstract/ldapFlat.js +1 -0
  7. package/dist/abstract/plugin.js +1 -0
  8. package/dist/abstract/twakePlugin.js +1 -0
  9. package/dist/bin/index.js +1 -0
  10. package/dist/config/args.js +1 -0
  11. package/dist/lib/auth/base.js +1 -0
  12. package/dist/lib/authz/base.js +1 -0
  13. package/dist/lib/expressFormatedResponses.js +1 -0
  14. package/dist/lib/ldapActions.js +1 -0
  15. package/dist/lib/parseConfig.js +1 -0
  16. package/dist/lib/utils.js +1 -0
  17. package/dist/logger/winston.js +1 -0
  18. package/dist/plugins/auth/authzLinid1.js +1 -0
  19. package/dist/plugins/auth/authzPerBranch.js +1 -0
  20. package/dist/plugins/auth/crowdsec.js +1 -0
  21. package/dist/plugins/auth/llng.js +1 -0
  22. package/dist/plugins/auth/openidconnect.js +1 -0
  23. package/dist/plugins/auth/rateLimit.js +1 -0
  24. package/dist/plugins/auth/token.js +1 -0
  25. package/dist/plugins/configApi.js +1 -0
  26. package/dist/plugins/demo/helloworld.js +1 -0
  27. package/dist/plugins/ldap/bulkImport.js +1 -0
  28. package/dist/plugins/ldap/departmentSync.js +1 -0
  29. package/dist/plugins/ldap/externalUsersInGroups.js +1 -0
  30. package/dist/plugins/ldap/flatGeneric.js +1 -0
  31. package/dist/plugins/ldap/groups.js +1 -0
  32. package/dist/plugins/ldap/onChange.js +1 -0
  33. package/dist/plugins/ldap/organization.js +1 -0
  34. package/dist/plugins/ldap/trash.js +1 -0
  35. package/dist/plugins/priority.json.js +1 -0
  36. package/dist/plugins/static.js +1 -0
  37. package/dist/plugins/twake/calendarResources.js +1 -0
  38. package/dist/plugins/twake/james.js +1 -0
  39. package/dist/plugins/weblogs.js +1 -0
  40. package/dist/src/abstract/ldapFlat.d.ts +94 -0
  41. package/dist/src/abstract/plugin.d.ts +43 -0
  42. package/dist/src/abstract/twakePlugin.d.ts +90 -0
  43. package/dist/src/bin/index.d.ts +43 -0
  44. package/dist/src/browser/ldap-group-editor/LdapGroupEditor.d.ts +31 -0
  45. package/dist/src/browser/ldap-group-editor/api/GroupApiClient.d.ts +23 -0
  46. package/dist/src/browser/ldap-group-editor/components/CreateGroupModal.d.ts +19 -0
  47. package/dist/src/browser/ldap-group-editor/components/GroupPropertyEditor.d.ts +30 -0
  48. package/dist/src/browser/ldap-group-editor/components/GroupTree.d.ts +17 -0
  49. package/dist/src/browser/ldap-group-editor/components/MoveGroupModal.d.ts +20 -0
  50. package/dist/src/browser/ldap-group-editor/index.d.ts +6 -0
  51. package/dist/src/browser/ldap-group-editor/types.d.ts +58 -0
  52. package/dist/src/browser/ldap-resource-editor/api/ResourceApiClient.d.ts +53 -0
  53. package/dist/src/browser/ldap-resource-editor/cache/CacheManager.d.ts +65 -0
  54. package/dist/src/browser/ldap-resource-editor/index.d.ts +6 -0
  55. package/dist/src/browser/ldap-resource-editor/types.d.ts +78 -0
  56. package/dist/src/browser/ldap-tree-viewer/LdapTreeViewer.d.ts +26 -0
  57. package/dist/src/browser/ldap-tree-viewer/api/LdapApiClient.d.ts +30 -0
  58. package/dist/src/browser/ldap-tree-viewer/components/TreeNode.d.ts +17 -0
  59. package/dist/src/browser/ldap-tree-viewer/components/TreeRoot.d.ts +14 -0
  60. package/dist/src/browser/ldap-tree-viewer/index.d.ts +7 -0
  61. package/dist/src/browser/ldap-tree-viewer/store/Store.d.ts +18 -0
  62. package/dist/src/browser/ldap-tree-viewer/store/actions.d.ts +28 -0
  63. package/dist/src/browser/ldap-tree-viewer/store/reducers.d.ts +7 -0
  64. package/dist/src/browser/ldap-tree-viewer/types.d.ts +34 -0
  65. package/dist/src/browser/ldap-unit-editor/LdapUnitEditor.d.ts +27 -0
  66. package/dist/src/browser/ldap-unit-editor/api/UnitApiClient.d.ts +24 -0
  67. package/dist/src/browser/ldap-unit-editor/components/MoveUnitModal.d.ts +28 -0
  68. package/dist/src/browser/ldap-unit-editor/components/UnitPropertyEditor.d.ts +28 -0
  69. package/dist/src/browser/ldap-unit-editor/components/UnitTree.d.ts +18 -0
  70. package/dist/src/browser/ldap-unit-editor/index.d.ts +6 -0
  71. package/dist/src/browser/ldap-unit-editor/types.d.ts +55 -0
  72. package/dist/src/browser/ldap-user-editor/LdapUserEditor.d.ts +32 -0
  73. package/dist/src/browser/ldap-user-editor/api/UserApiClient.d.ts +55 -0
  74. package/dist/src/browser/ldap-user-editor/cache/CacheManager.d.ts +65 -0
  75. package/dist/src/browser/ldap-user-editor/components/MoveUserModal.d.ts +28 -0
  76. package/dist/src/browser/ldap-user-editor/components/PointerField.d.ts +22 -0
  77. package/dist/src/browser/ldap-user-editor/components/UserEditor.d.ts +46 -0
  78. package/dist/src/browser/ldap-user-editor/components/UserList.d.ts +24 -0
  79. package/dist/src/browser/ldap-user-editor/components/UserTree.d.ts +24 -0
  80. package/dist/src/browser/ldap-user-editor/index.d.ts +7 -0
  81. package/dist/src/browser/ldap-user-editor/types.d.ts +67 -0
  82. package/dist/src/browser/shared/components/Modal.d.ts +38 -0
  83. package/dist/src/browser/shared/components/StatusMessage.d.ts +48 -0
  84. package/dist/src/browser/shared/index.d.ts +10 -0
  85. package/dist/src/browser/shared/types/index.d.ts +65 -0
  86. package/dist/src/browser/shared/utils/dom.d.ts +33 -0
  87. package/dist/src/browser/shared/utils/form.d.ts +28 -0
  88. package/dist/src/browser/shared/utils/schema.d.ts +29 -0
  89. package/dist/src/config/args.d.ts +128 -0
  90. package/dist/src/config/schema.d.ts +18 -0
  91. package/dist/src/hooks.d.ts +76 -0
  92. package/dist/src/lib/auth/base.d.ts +9 -0
  93. package/dist/src/lib/authz/base.d.ts +63 -0
  94. package/dist/src/lib/expressFormatedResponses.d.ts +26 -0
  95. package/dist/src/lib/ldapActions.d.ts +91 -0
  96. package/dist/src/lib/parseConfig.d.ts +23 -0
  97. package/dist/src/lib/utils.d.ts +73 -0
  98. package/dist/src/logger/winston.d.ts +3 -0
  99. package/dist/src/plugins/auth/authzLinid1.d.ts +46 -0
  100. package/dist/src/plugins/auth/authzPerBranch.d.ts +59 -0
  101. package/dist/src/plugins/auth/crowdsec.d.ts +29 -0
  102. package/dist/src/plugins/auth/llng.d.ts +8 -0
  103. package/dist/src/plugins/auth/openidconnect.d.ts +11 -0
  104. package/dist/src/plugins/auth/rateLimit.d.ts +24 -0
  105. package/dist/src/plugins/auth/token.d.ts +17 -0
  106. package/dist/src/plugins/configApi.d.ts +24 -0
  107. package/dist/src/plugins/demo/helloworld.d.ts +12 -0
  108. package/dist/src/plugins/ldap/bulkImport.d.ts +48 -0
  109. package/dist/src/plugins/ldap/departmentSync.d.ts +35 -0
  110. package/dist/src/plugins/ldap/externalUsersInGroups.d.ts +21 -0
  111. package/dist/src/plugins/ldap/flatGeneric.d.ts +31 -0
  112. package/dist/src/plugins/ldap/groups.d.ts +95 -0
  113. package/dist/src/plugins/ldap/onChange.d.ts +32 -0
  114. package/dist/src/plugins/ldap/organization.d.ts +65 -0
  115. package/dist/src/plugins/ldap/trash.d.ts +52 -0
  116. package/dist/src/plugins/static.d.ts +7 -0
  117. package/dist/src/plugins/twake/calendarResources.d.ts +31 -0
  118. package/dist/src/plugins/twake/james.d.ts +83 -0
  119. package/dist/src/plugins/weblogs.d.ts +8 -0
  120. package/docs/DEVELOPER_GUIDE.md +298 -0
  121. package/docs/OPENAPI.md +440 -0
  122. package/docs/PLUGIN_DEPENDENCIES.md +612 -0
  123. package/docs/README.md +466 -0
  124. package/docs/api/REFERENCE.md +983 -0
  125. package/docs/api/REST_API.md +1237 -0
  126. package/docs/authentication.md +469 -0
  127. package/docs/authzLinid1.md +521 -0
  128. package/docs/authzPerBranch.md +596 -0
  129. package/docs/browser/LIBRARIES.md +1196 -0
  130. package/docs/examples/EXAMPLES.md +1659 -0
  131. package/docs/examples/twake-mailbox-type-nomenclature.ldif +37 -0
  132. package/docs/examples/twake-mailbox-type-schema-amendment.ldif +30 -0
  133. package/docs/jamesTeamMailboxes.md +343 -0
  134. package/docs/ldapBulkImport.md +722 -0
  135. package/docs/ldapExternalUsersInGroups.md +325 -0
  136. package/docs/ldapFlatGeneric.md +444 -0
  137. package/docs/ldapGroups.md +589 -0
  138. package/docs/ldapOrganizations.md +659 -0
  139. package/docs/ldapTrash.md +260 -0
  140. package/docs/linagora.png +0 -0
  141. package/docs/onChange.md +318 -0
  142. package/docs/plugins/DEVELOPMENT.md +1219 -0
  143. package/docs/presenterm-fr.md +721 -0
  144. package/docs/presenterm.md +721 -0
  145. package/docs/schemas/SCHEMAS.md +1212 -0
  146. package/docs/static.md +410 -0
  147. package/docs/twakeCalendarResources.md +148 -0
  148. package/docs/twakeJames.md +661 -0
  149. package/docs/weblogs.md +399 -0
  150. package/examples/web/ldap-group-editor.html +113 -0
  151. package/examples/web/ldap-tree-viewer.html +368 -0
  152. package/examples/web/ldap-unit-editor.html +108 -0
  153. package/examples/web/ldap-user-editor.html +412 -0
  154. package/package.json +458 -0
  155. package/static/browser/common-demo.css +450 -0
  156. package/static/browser/ldap-group-editor/LdapGroupEditor.js +207 -0
  157. package/static/browser/ldap-group-editor/LdapGroupEditor.js.map +1 -0
  158. package/static/browser/ldap-group-editor/api/GroupApiClient.js +112 -0
  159. package/static/browser/ldap-group-editor/api/GroupApiClient.js.map +1 -0
  160. package/static/browser/ldap-group-editor/components/CreateGroupModal.js +212 -0
  161. package/static/browser/ldap-group-editor/components/CreateGroupModal.js.map +1 -0
  162. package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js +497 -0
  163. package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js.map +1 -0
  164. package/static/browser/ldap-group-editor/components/GroupTree.js +153 -0
  165. package/static/browser/ldap-group-editor/components/GroupTree.js.map +1 -0
  166. package/static/browser/ldap-group-editor/components/MoveGroupModal.js +235 -0
  167. package/static/browser/ldap-group-editor/components/MoveGroupModal.js.map +1 -0
  168. package/static/browser/ldap-group-editor/index.js +2 -0
  169. package/static/browser/ldap-group-editor/index.js.map +1 -0
  170. package/static/browser/ldap-group-editor/types.js +2 -0
  171. package/static/browser/ldap-group-editor/types.js.map +1 -0
  172. package/static/browser/ldap-group-editor.esm.js +1399 -0
  173. package/static/browser/ldap-group-editor.esm.js.map +1 -0
  174. package/static/browser/ldap-group-editor.js +1407 -0
  175. package/static/browser/ldap-group-editor.js.map +1 -0
  176. package/static/browser/ldap-group-editor.min.js +2 -0
  177. package/static/browser/ldap-group-editor.min.js.map +1 -0
  178. package/static/browser/ldap-resource-editor/api/ResourceApiClient.js +226 -0
  179. package/static/browser/ldap-resource-editor/api/ResourceApiClient.js.map +1 -0
  180. package/static/browser/ldap-resource-editor/cache/CacheManager.js +123 -0
  181. package/static/browser/ldap-resource-editor/cache/CacheManager.js.map +1 -0
  182. package/static/browser/ldap-resource-editor/index.js +2 -0
  183. package/static/browser/ldap-resource-editor/index.js.map +1 -0
  184. package/static/browser/ldap-resource-editor/types.js +2 -0
  185. package/static/browser/ldap-resource-editor/types.js.map +1 -0
  186. package/static/browser/ldap-tree-viewer/LdapTreeViewer.js +187 -0
  187. package/static/browser/ldap-tree-viewer/LdapTreeViewer.js.map +1 -0
  188. package/static/browser/ldap-tree-viewer/api/LdapApiClient.js +50 -0
  189. package/static/browser/ldap-tree-viewer/api/LdapApiClient.js.map +1 -0
  190. package/static/browser/ldap-tree-viewer/components/TreeNode.js +140 -0
  191. package/static/browser/ldap-tree-viewer/components/TreeNode.js.map +1 -0
  192. package/static/browser/ldap-tree-viewer/components/TreeRoot.js +98 -0
  193. package/static/browser/ldap-tree-viewer/components/TreeRoot.js.map +1 -0
  194. package/static/browser/ldap-tree-viewer/index.js +2 -0
  195. package/static/browser/ldap-tree-viewer/index.js.map +1 -0
  196. package/static/browser/ldap-tree-viewer/store/Store.js +29 -0
  197. package/static/browser/ldap-tree-viewer/store/Store.js.map +1 -0
  198. package/static/browser/ldap-tree-viewer/store/actions.js +53 -0
  199. package/static/browser/ldap-tree-viewer/store/actions.js.map +1 -0
  200. package/static/browser/ldap-tree-viewer/store/reducers.js +79 -0
  201. package/static/browser/ldap-tree-viewer/store/reducers.js.map +1 -0
  202. package/static/browser/ldap-tree-viewer/types.js +2 -0
  203. package/static/browser/ldap-tree-viewer/types.js.map +1 -0
  204. package/static/browser/ldap-tree-viewer.css +2 -0
  205. package/static/browser/ldap-tree-viewer.css.map +1 -0
  206. package/static/browser/ldap-tree-viewer.esm.js +606 -0
  207. package/static/browser/ldap-tree-viewer.esm.js.map +1 -0
  208. package/static/browser/ldap-tree-viewer.js +614 -0
  209. package/static/browser/ldap-tree-viewer.js.map +1 -0
  210. package/static/browser/ldap-tree-viewer.min.js +2 -0
  211. package/static/browser/ldap-tree-viewer.min.js.map +1 -0
  212. package/static/browser/ldap-unit-editor/LdapUnitEditor.js +119 -0
  213. package/static/browser/ldap-unit-editor/LdapUnitEditor.js.map +1 -0
  214. package/static/browser/ldap-unit-editor/api/UnitApiClient.js +95 -0
  215. package/static/browser/ldap-unit-editor/api/UnitApiClient.js.map +1 -0
  216. package/static/browser/ldap-unit-editor/components/MoveUnitModal.js +295 -0
  217. package/static/browser/ldap-unit-editor/components/MoveUnitModal.js.map +1 -0
  218. package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js +321 -0
  219. package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js.map +1 -0
  220. package/static/browser/ldap-unit-editor/components/UnitTree.js +197 -0
  221. package/static/browser/ldap-unit-editor/components/UnitTree.js.map +1 -0
  222. package/static/browser/ldap-unit-editor/index.js +2 -0
  223. package/static/browser/ldap-unit-editor/index.js.map +1 -0
  224. package/static/browser/ldap-unit-editor/types.js +2 -0
  225. package/static/browser/ldap-unit-editor/types.js.map +1 -0
  226. package/static/browser/ldap-unit-editor.esm.js +1013 -0
  227. package/static/browser/ldap-unit-editor.esm.js.map +1 -0
  228. package/static/browser/ldap-unit-editor.js +1021 -0
  229. package/static/browser/ldap-unit-editor.js.map +1 -0
  230. package/static/browser/ldap-unit-editor.min.js +2 -0
  231. package/static/browser/ldap-unit-editor.min.js.map +1 -0
  232. package/static/browser/ldap-user-editor/LdapUserEditor.js +184 -0
  233. package/static/browser/ldap-user-editor/LdapUserEditor.js.map +1 -0
  234. package/static/browser/ldap-user-editor/api/UserApiClient.js +209 -0
  235. package/static/browser/ldap-user-editor/api/UserApiClient.js.map +1 -0
  236. package/static/browser/ldap-user-editor/cache/CacheManager.js +123 -0
  237. package/static/browser/ldap-user-editor/cache/CacheManager.js.map +1 -0
  238. package/static/browser/ldap-user-editor/components/MoveUserModal.js +302 -0
  239. package/static/browser/ldap-user-editor/components/MoveUserModal.js.map +1 -0
  240. package/static/browser/ldap-user-editor/components/PointerField.js +152 -0
  241. package/static/browser/ldap-user-editor/components/PointerField.js.map +1 -0
  242. package/static/browser/ldap-user-editor/components/UserEditor.js +608 -0
  243. package/static/browser/ldap-user-editor/components/UserEditor.js.map +1 -0
  244. package/static/browser/ldap-user-editor/components/UserList.js +181 -0
  245. package/static/browser/ldap-user-editor/components/UserList.js.map +1 -0
  246. package/static/browser/ldap-user-editor/components/UserTree.js +164 -0
  247. package/static/browser/ldap-user-editor/components/UserTree.js.map +1 -0
  248. package/static/browser/ldap-user-editor/index.js +2 -0
  249. package/static/browser/ldap-user-editor/index.js.map +1 -0
  250. package/static/browser/ldap-user-editor/types.js +2 -0
  251. package/static/browser/ldap-user-editor/types.js.map +1 -0
  252. package/static/browser/ldap-user-editor.css +2 -0
  253. package/static/browser/ldap-user-editor.css.map +1 -0
  254. package/static/browser/ldap-user-editor.esm.js +1897 -0
  255. package/static/browser/ldap-user-editor.esm.js.map +1 -0
  256. package/static/browser/ldap-user-editor.js +1905 -0
  257. package/static/browser/ldap-user-editor.js.map +1 -0
  258. package/static/browser/ldap-user-editor.min.js +2 -0
  259. package/static/browser/ldap-user-editor.min.js.map +1 -0
  260. package/static/browser/shared/components/Modal.js +121 -0
  261. package/static/browser/shared/components/Modal.js.map +1 -0
  262. package/static/browser/shared/components/StatusMessage.js +119 -0
  263. package/static/browser/shared/components/StatusMessage.js.map +1 -0
  264. package/static/browser/shared/index.js +7 -0
  265. package/static/browser/shared/index.js.map +1 -0
  266. package/static/browser/shared/types/index.js +37 -0
  267. package/static/browser/shared/types/index.js.map +1 -0
  268. package/static/browser/shared/utils/dom.js +78 -0
  269. package/static/browser/shared/utils/dom.js.map +1 -0
  270. package/static/browser/shared/utils/form.js +234 -0
  271. package/static/browser/shared/utils/form.js.map +1 -0
  272. package/static/browser/shared/utils/schema.js +121 -0
  273. package/static/browser/shared/utils/schema.js.map +1 -0
  274. package/static/browser/shared.esm.js +694 -0
  275. package/static/browser/shared.esm.js.map +1 -0
  276. package/static/browser/shared.js +723 -0
  277. package/static/browser/shared.js.map +1 -0
  278. package/static/browser/shared.min.js +2 -0
  279. package/static/browser/shared.min.js.map +1 -0
  280. package/static/schemas/ad/computers.json +92 -0
  281. package/static/schemas/ad/groups.json +55 -0
  282. package/static/schemas/ad/organizations.json +66 -0
  283. package/static/schemas/ad/users.json +116 -0
  284. package/static/schemas/standard/devices.json +72 -0
  285. package/static/schemas/standard/groups.json +54 -0
  286. package/static/schemas/standard/organizations.json +49 -0
  287. package/static/schemas/standard/users.json +86 -0
  288. package/static/schemas/twake/groups.json +75 -0
  289. package/static/schemas/twake/nomenclature/twakeAccountStatus.json +31 -0
  290. package/static/schemas/twake/nomenclature/twakeDeliveryMode.json +31 -0
  291. package/static/schemas/twake/nomenclature/twakeListType.json +31 -0
  292. package/static/schemas/twake/nomenclature/twakeMailboxType.json +31 -0
  293. package/static/schemas/twake/nomenclature/twakeTitle.json +31 -0
  294. package/static/schemas/twake/organizations.json +52 -0
  295. package/static/schemas/twake/positions.json +32 -0
  296. package/static/schemas/twake/users.json +112 -0
@@ -0,0 +1,1212 @@
1
+ # JSON Schemas Documentation
2
+
3
+ LDAP-Rest uses JSON schemas to define LDAP entity structure, validation rules, and UI behavior. Schemas are the foundation for API operations, data validation, and automatic user interface generation.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ - [Schema Structure](#schema-structure)
10
+ - [Entity Metadata](#entity-metadata)
11
+ - [Attribute Types](#attribute-types)
12
+ - [Attribute Properties](#attribute-properties)
13
+ - [Semantic Roles](#semantic-roles)
14
+ - [Validation Rules](#validation-rules)
15
+ - [Predefined Schemas](#predefined-schemas)
16
+
17
+ ---
18
+
19
+ ## Schema Structure
20
+
21
+ A complete schema consists of two main sections: entity metadata and attribute definitions.
22
+
23
+ ### Complete Example
24
+
25
+ ```json
26
+ {
27
+ "entity": {
28
+ "name": "standardUser",
29
+ "mainAttribute": "uid",
30
+ "objectClass": ["top", "inetOrgPerson", "organizationalPerson", "person"],
31
+ "singularName": "user",
32
+ "pluralName": "users",
33
+ "base": "ou=users,dc=example,dc=com",
34
+ "defaultAttributes": {
35
+ "cn": "New User",
36
+ "sn": "User"
37
+ }
38
+ },
39
+ "strict": true,
40
+ "attributes": {
41
+ "objectClass": {
42
+ "type": "array",
43
+ "items": {
44
+ "type": "string",
45
+ "test": "^[a-zA-Z][a-zA-Z0-9-]*$"
46
+ },
47
+ "default": ["top", "inetOrgPerson", "organizationalPerson", "person"],
48
+ "required": true,
49
+ "fixed": true
50
+ },
51
+ "uid": {
52
+ "type": "string",
53
+ "test": "^[a-zA-Z0-9._-]{1,255}$",
54
+ "required": true,
55
+ "role": "identifier"
56
+ },
57
+ "cn": {
58
+ "type": "string",
59
+ "required": true,
60
+ "role": "displayName"
61
+ },
62
+ "sn": {
63
+ "type": "string",
64
+ "required": true
65
+ },
66
+ "mail": {
67
+ "type": "string",
68
+ "test": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
69
+ "required": false,
70
+ "role": "primaryEmail"
71
+ },
72
+ "mailAlternateAddress": {
73
+ "type": "array",
74
+ "items": {
75
+ "type": "string",
76
+ "test": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"
77
+ },
78
+ "required": false,
79
+ "role": "emailAliases"
80
+ },
81
+ "mailQuota": {
82
+ "type": "number",
83
+ "required": false,
84
+ "role": "emailQuota"
85
+ },
86
+ "givenName": {
87
+ "type": "string",
88
+ "required": false
89
+ },
90
+ "displayName": {
91
+ "type": "string",
92
+ "required": false
93
+ },
94
+ "telephoneNumber": {
95
+ "type": "string",
96
+ "required": false
97
+ },
98
+ "mobile": {
99
+ "type": "string",
100
+ "required": false
101
+ },
102
+ "userPassword": {
103
+ "type": "string",
104
+ "required": false
105
+ },
106
+ "departmentNumber": {
107
+ "type": "string",
108
+ "test": "^.*,dc=example,dc=com$",
109
+ "required": false
110
+ }
111
+ }
112
+ }
113
+ ```
114
+
115
+ ---
116
+
117
+ ## Entity Metadata
118
+
119
+ The `entity` section defines metadata about the LDAP entity type.
120
+
121
+ ### Entity Properties Table
122
+
123
+ | Property | Type | Required | Description | Example |
124
+ | ------------------- | -------- | -------- | ---------------------------------------- | ------------------------------------ |
125
+ | `name` | string | Yes | Internal entity identifier | `"standardUser"`, `"twakeGroup"` |
126
+ | `mainAttribute` | string | Yes | Primary identifier attribute (RDN) | `"uid"`, `"cn"`, `"sAMAccountName"` |
127
+ | `objectClass` | string[] | Yes | LDAP objectClass values for new entries | `["top", "inetOrgPerson"]` |
128
+ | `singularName` | string | Yes | Singular name for API routes | `"user"`, `"group"`, `"position"` |
129
+ | `pluralName` | string | Yes | Plural name for API routes | `"users"`, `"groups"`, `"positions"` |
130
+ | `base` | string | Yes | LDAP base DN for this entity type | `"ou=users,dc=example,dc=com"` |
131
+ | `defaultAttributes` | object | No | Default attribute values for new entries | `{"cn": "New User", "sn": "User"}` |
132
+
133
+ ### Entity Metadata Example
134
+
135
+ ```json
136
+ {
137
+ "entity": {
138
+ "name": "twakeUser",
139
+ "mainAttribute": "uid",
140
+ "objectClass": ["top", "twakeAccount", "twakeWhitePages"],
141
+ "singularName": "user",
142
+ "pluralName": "users",
143
+ "base": "ou=users,dc=example,dc=com",
144
+ "defaultAttributes": {
145
+ "cn": "New User",
146
+ "sn": "User",
147
+ "twakeAccountStatus": "active"
148
+ }
149
+ }
150
+ }
151
+ ```
152
+
153
+ ### Base DN Variable Substitution
154
+
155
+ Use `{ldap_base}` or `__ldap_base__` in the base DN to reference the configured LDAP base:
156
+
157
+ ```json
158
+ {
159
+ "entity": {
160
+ "base": "ou=users,{ldap_base}"
161
+ }
162
+ }
163
+ ```
164
+
165
+ This will be replaced with the actual LDAP base at runtime (e.g., `ou=users,dc=example,dc=com`).
166
+
167
+ ---
168
+
169
+ ## Attribute Types
170
+
171
+ LDAP-Rest supports three main attribute types: `string`, `array`, and `pointer`.
172
+
173
+ ### String Type
174
+
175
+ Simple text values.
176
+
177
+ **Properties:**
178
+
179
+ - `type`: `"string"`
180
+ - `test`: Optional regex pattern for validation
181
+ - `required`: Whether the attribute is mandatory
182
+ - `default`: Default value for new entries
183
+
184
+ **Example:**
185
+
186
+ ```json
187
+ {
188
+ "uid": {
189
+ "type": "string",
190
+ "test": "^[a-zA-Z0-9._-]{1,255}$",
191
+ "required": true,
192
+ "role": "identifier"
193
+ },
194
+ "mail": {
195
+ "type": "string",
196
+ "test": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
197
+ "required": false,
198
+ "role": "primaryEmail"
199
+ },
200
+ "telephoneNumber": {
201
+ "type": "string",
202
+ "required": false
203
+ }
204
+ }
205
+ ```
206
+
207
+ ### Array Type
208
+
209
+ Multi-valued attributes containing multiple items of the same type.
210
+
211
+ **Properties:**
212
+
213
+ - `type`: `"array"`
214
+ - `items`: Object defining the type and validation for array elements
215
+ - `required`: Whether the attribute is mandatory
216
+ - `default`: Default array value for new entries
217
+
218
+ **Example:**
219
+
220
+ ```json
221
+ {
222
+ "objectClass": {
223
+ "type": "array",
224
+ "items": {
225
+ "type": "string",
226
+ "test": "^[a-zA-Z][a-zA-Z0-9-]*$"
227
+ },
228
+ "default": ["top", "inetOrgPerson", "organizationalPerson", "person"],
229
+ "required": true,
230
+ "fixed": true
231
+ },
232
+ "mailAlternateAddress": {
233
+ "type": "array",
234
+ "items": {
235
+ "type": "string",
236
+ "test": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"
237
+ },
238
+ "required": false,
239
+ "role": "emailAliases"
240
+ },
241
+ "member": {
242
+ "type": "array",
243
+ "items": {
244
+ "type": "string",
245
+ "test": "^[a-zA-Z]+=.*,dc=example,dc=com$"
246
+ },
247
+ "required": false
248
+ }
249
+ }
250
+ ```
251
+
252
+ ### Pointer Type
253
+
254
+ References to other LDAP entries (DN pointers). Used for relationships like group membership, organizational units, or nomenclature references.
255
+
256
+ **Properties:**
257
+
258
+ - `type`: `"pointer"`
259
+ - `branch`: Array of LDAP base DNs where referenced entries can be found
260
+ - `ui`: Optional UI configuration for pointer selection (not yet implemented)
261
+ - `required`: Whether the pointer is mandatory
262
+
263
+ **Example:**
264
+
265
+ ```json
266
+ {
267
+ "twakeAccountStatus": {
268
+ "type": "pointer",
269
+ "branch": ["ou=twakeAccountStatus,ou=nomenclature,dc=example,dc=com"],
270
+ "required": true
271
+ },
272
+ "twakeDeliveryMode": {
273
+ "type": "pointer",
274
+ "branch": ["ou=twakeDeliveryMode,ou=nomenclature,dc=example,dc=com"],
275
+ "required": true
276
+ },
277
+ "twakeDelegatedUsers": {
278
+ "type": "array",
279
+ "items": {
280
+ "type": "pointer",
281
+ "branch": ["ou=users,dc=example,dc=com"]
282
+ },
283
+ "required": false
284
+ }
285
+ }
286
+ ```
287
+
288
+ **Pointer Arrays:**
289
+
290
+ Pointer types can also be used within arrays to create multi-valued references:
291
+
292
+ ```json
293
+ {
294
+ "twakeDelegatedUsers": {
295
+ "type": "array",
296
+ "items": {
297
+ "type": "pointer",
298
+ "branch": ["ou=users,dc=example,dc=com"]
299
+ },
300
+ "required": false
301
+ }
302
+ }
303
+ ```
304
+
305
+ ### Number and Integer Types
306
+
307
+ Numeric values for counters, IDs, or quota management.
308
+
309
+ **Example:**
310
+
311
+ ```json
312
+ {
313
+ "mailQuota": {
314
+ "type": "number",
315
+ "required": false,
316
+ "role": "emailQuota"
317
+ },
318
+ "mailQuotaSize": {
319
+ "type": "integer",
320
+ "required": false
321
+ },
322
+ "userAccountControl": {
323
+ "type": "number",
324
+ "required": false
325
+ }
326
+ }
327
+ ```
328
+
329
+ ---
330
+
331
+ ## Attribute Properties
332
+
333
+ Complete reference for all attribute properties.
334
+
335
+ ### Attribute Properties Table
336
+
337
+ | Property | Type | Applies To | Description | Example |
338
+ | ---------- | ------------ | ------------------- | -------------------------------------------------------------------------------- | ----------------------------------- |
339
+ | `type` | string | All | Attribute data type: `"string"`, `"array"`, `"pointer"`, `"number"`, `"integer"` | `"string"` |
340
+ | `required` | boolean | All | Whether the attribute must be present | `true` |
341
+ | `fixed` | boolean | All | Whether the attribute value cannot be changed after creation | `true` |
342
+ | `role` | string | String | Semantic role for special handling (see [Semantic Roles](#semantic-roles)) | `"identifier"` |
343
+ | `test` | string/regex | String, Array items | Regular expression for validation | `"^[a-zA-Z0-9._-]{1,255}$"` |
344
+ | `branch` | string[] | Pointer | LDAP branches where referenced entries exist | `["ou=users,dc=example,dc=com"]` |
345
+ | `ui` | object | Pointer | UI configuration for pointer selection (future feature) | `{}` |
346
+ | `group` | string | All | UI grouping for form organization (future feature) | `"contact"` |
347
+ | `default` | any | All | Default value for new entries | `["top", "person"]` |
348
+ | `items` | object | Array | Schema for array element validation | `{"type": "string", "test": "..."}` |
349
+
350
+ ### Property Details
351
+
352
+ #### `type` (Required)
353
+
354
+ Defines the data type of the attribute. Supported values:
355
+
356
+ - `"string"`: Single text value
357
+ - `"array"`: Multiple values of the same type
358
+ - `"pointer"`: Reference to another LDAP entry (DN)
359
+ - `"number"`: Numeric value (integer or float)
360
+ - `"integer"`: Integer value only
361
+
362
+ #### `required` (Optional, default: `false`)
363
+
364
+ Specifies whether the attribute is mandatory when creating or updating entries.
365
+
366
+ ```json
367
+ {
368
+ "uid": {
369
+ "type": "string",
370
+ "required": true
371
+ },
372
+ "description": {
373
+ "type": "string",
374
+ "required": false
375
+ }
376
+ }
377
+ ```
378
+
379
+ #### `fixed` (Optional, default: `false`)
380
+
381
+ Marks the attribute as immutable after creation. Useful for objectClass or identifier attributes.
382
+
383
+ ```json
384
+ {
385
+ "objectClass": {
386
+ "type": "array",
387
+ "required": true,
388
+ "fixed": true,
389
+ "default": ["top", "inetOrgPerson"]
390
+ }
391
+ }
392
+ ```
393
+
394
+ #### `role` (Optional)
395
+
396
+ Assigns semantic meaning to attributes for special handling by the application. See [Semantic Roles](#semantic-roles).
397
+
398
+ ```json
399
+ {
400
+ "uid": {
401
+ "type": "string",
402
+ "required": true,
403
+ "role": "identifier"
404
+ },
405
+ "cn": {
406
+ "type": "string",
407
+ "required": true,
408
+ "role": "displayName"
409
+ },
410
+ "mail": {
411
+ "type": "string",
412
+ "role": "primaryEmail"
413
+ }
414
+ }
415
+ ```
416
+
417
+ #### `test` (Optional)
418
+
419
+ Regular expression pattern for validating attribute values.
420
+
421
+ ```json
422
+ {
423
+ "uid": {
424
+ "type": "string",
425
+ "test": "^[a-zA-Z0-9._-]{1,255}$"
426
+ },
427
+ "mail": {
428
+ "type": "string",
429
+ "test": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"
430
+ }
431
+ }
432
+ ```
433
+
434
+ **For arrays**, the test applies to each item:
435
+
436
+ ```json
437
+ {
438
+ "mailAlternateAddress": {
439
+ "type": "array",
440
+ "items": {
441
+ "type": "string",
442
+ "test": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"
443
+ }
444
+ }
445
+ }
446
+ ```
447
+
448
+ #### `branch` (Required for Pointers)
449
+
450
+ Specifies one or more LDAP base DNs where referenced entries can be found.
451
+
452
+ ```json
453
+ {
454
+ "twakeAccountStatus": {
455
+ "type": "pointer",
456
+ "branch": ["ou=twakeAccountStatus,ou=nomenclature,dc=example,dc=com"]
457
+ }
458
+ }
459
+ ```
460
+
461
+ Use variable substitution for dynamic bases:
462
+
463
+ ```json
464
+ {
465
+ "departmentNumber": {
466
+ "type": "pointer",
467
+ "branch": ["ou=departments,__ldap_base__"]
468
+ }
469
+ }
470
+ ```
471
+
472
+ #### `default` (Optional)
473
+
474
+ Provides a default value for new entries. Commonly used with objectClass and fixed attributes.
475
+
476
+ ```json
477
+ {
478
+ "objectClass": {
479
+ "type": "array",
480
+ "default": ["top", "inetOrgPerson", "organizationalPerson", "person"],
481
+ "required": true,
482
+ "fixed": true
483
+ }
484
+ }
485
+ ```
486
+
487
+ #### `items` (Required for Arrays)
488
+
489
+ Defines the schema for array elements, including type and validation.
490
+
491
+ ```json
492
+ {
493
+ "member": {
494
+ "type": "array",
495
+ "items": {
496
+ "type": "string",
497
+ "test": "^[a-zA-Z]+=.*,dc=example,dc=com$"
498
+ }
499
+ }
500
+ }
501
+ ```
502
+
503
+ ---
504
+
505
+ ## Semantic Roles
506
+
507
+ Semantic roles assign special meaning to attributes for UI and business logic handling.
508
+
509
+ ### Available Roles
510
+
511
+ | Role | Description | Example Attribute | Usage |
512
+ | -------------- | ---------------------------------- | ---------------------------------------- | ------------------------------------- |
513
+ | `identifier` | Primary identifier (RDN attribute) | `uid`, `cn`, `sAMAccountName` | Used as the entry's unique identifier |
514
+ | `displayName` | Human-readable display name | `cn`, `displayName` | Shown in lists and UI elements |
515
+ | `primaryEmail` | Main email address | `mail`, `userPrincipalName` | Primary contact email |
516
+ | `emailAliases` | Additional email addresses | `mailAlternateAddress`, `proxyAddresses` | Alternative email addresses |
517
+ | `emailQuota` | Email storage quota | `mailQuota`, `mailQuotaSize` | Storage limit for mailbox |
518
+
519
+ ### Role Usage Examples
520
+
521
+ #### Identifier Role
522
+
523
+ The `identifier` role marks the attribute used as the RDN (Relative Distinguished Name) component of the entry's DN.
524
+
525
+ ```json
526
+ {
527
+ "uid": {
528
+ "type": "string",
529
+ "test": "^[a-zA-Z0-9._-]{1,255}$",
530
+ "required": true,
531
+ "role": "identifier"
532
+ }
533
+ }
534
+ ```
535
+
536
+ For a user with `uid=jdoe`, the full DN would be `uid=jdoe,ou=users,dc=example,dc=com`.
537
+
538
+ #### Display Name Role
539
+
540
+ The `displayName` role indicates which attribute should be shown in UI lists and summaries.
541
+
542
+ ```json
543
+ {
544
+ "cn": {
545
+ "type": "string",
546
+ "required": true,
547
+ "role": "displayName"
548
+ }
549
+ }
550
+ ```
551
+
552
+ #### Email Roles
553
+
554
+ Email-related roles help applications handle email addresses consistently across different LDAP schemas.
555
+
556
+ **Primary Email:**
557
+
558
+ ```json
559
+ {
560
+ "mail": {
561
+ "type": "string",
562
+ "test": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
563
+ "required": false,
564
+ "role": "primaryEmail"
565
+ }
566
+ }
567
+ ```
568
+
569
+ **Email Aliases:**
570
+
571
+ ```json
572
+ {
573
+ "mailAlternateAddress": {
574
+ "type": "array",
575
+ "items": {
576
+ "type": "string",
577
+ "test": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"
578
+ },
579
+ "required": false,
580
+ "role": "emailAliases"
581
+ }
582
+ }
583
+ ```
584
+
585
+ **Email Quota:**
586
+
587
+ ```json
588
+ {
589
+ "mailQuota": {
590
+ "type": "number",
591
+ "required": false,
592
+ "role": "emailQuota"
593
+ }
594
+ }
595
+ ```
596
+
597
+ ---
598
+
599
+ ## Validation Rules
600
+
601
+ LDAP-Rest validates LDAP entries against schemas using the following rules:
602
+
603
+ ### Strict Mode
604
+
605
+ The `strict` property controls validation behavior:
606
+
607
+ ```json
608
+ {
609
+ "strict": true,
610
+ "attributes": { ... }
611
+ }
612
+ ```
613
+
614
+ - **`strict: true`**: Only attributes defined in the schema are allowed
615
+ - **`strict: false`** or omitted: Additional attributes are permitted
616
+
617
+ ### Required Attributes
618
+
619
+ Attributes with `"required": true` must be present in all create and update operations.
620
+
621
+ ```json
622
+ {
623
+ "uid": {
624
+ "type": "string",
625
+ "required": true
626
+ }
627
+ }
628
+ ```
629
+
630
+ ### Pattern Validation
631
+
632
+ The `test` property enforces regular expression validation:
633
+
634
+ ```json
635
+ {
636
+ "uid": {
637
+ "type": "string",
638
+ "test": "^[a-zA-Z0-9._-]{1,255}$"
639
+ }
640
+ }
641
+ ```
642
+
643
+ Common validation patterns:
644
+
645
+ **Username/UID:**
646
+
647
+ ```regex
648
+ ^[a-zA-Z0-9._-]{1,255}$
649
+ ```
650
+
651
+ **Email:**
652
+
653
+ ```regex
654
+ ^[^@\s]+@[^@\s]+\.[^@\s]+$
655
+ ```
656
+
657
+ **DN (Distinguished Name):**
658
+
659
+ ```regex
660
+ ^[a-zA-Z]+=.*,dc=example,dc=com$
661
+ ```
662
+
663
+ **ObjectClass name:**
664
+
665
+ ```regex
666
+ ^[a-zA-Z][a-zA-Z0-9-]*$
667
+ ```
668
+
669
+ ### Type Validation
670
+
671
+ Attribute values must match their declared type:
672
+
673
+ - **String**: Single text value
674
+ - **Array**: Multiple values (may be empty unless required)
675
+ - **Number**: Numeric value (integer or float)
676
+ - **Integer**: Integer value only
677
+ - **Pointer**: Valid DN string
678
+
679
+ ### Fixed Attributes
680
+
681
+ Attributes with `"fixed": true` cannot be modified after creation.
682
+
683
+ ```json
684
+ {
685
+ "objectClass": {
686
+ "type": "array",
687
+ "fixed": true,
688
+ "default": ["top", "inetOrgPerson"]
689
+ }
690
+ }
691
+ ```
692
+
693
+ ---
694
+
695
+ ## Predefined Schemas
696
+
697
+ LDAP-Rest includes three sets of predefined schemas for common LDAP directory types.
698
+
699
+ ### Schema Structure Overview
700
+
701
+ ```
702
+ static/schemas/
703
+ ├── twake/ # Twake Mail schemas
704
+ │ ├── users.json
705
+ │ ├── groups.json
706
+ │ ├── organizations.json
707
+ │ ├── positions.json
708
+ │ └── nomenclature/
709
+ │ ├── twakeAccountStatus.json
710
+ │ ├── twakeDeliveryMode.json
711
+ │ ├── twakeListType.json
712
+ │ └── twakeTitle.json
713
+ ├── ad/ # Active Directory schemas
714
+ │ ├── users.json
715
+ │ ├── groups.json
716
+ │ └── organizations.json
717
+ └── standard/ # Standard LDAP schemas
718
+ ├── users.json
719
+ ├── groups.json
720
+ └── organizations.json
721
+ ```
722
+
723
+ ---
724
+
725
+ ### Twake Schemas
726
+
727
+ Schemas for Twake Mail directories with extended attributes for collaboration and messaging.
728
+
729
+ #### Twake Schema Tree
730
+
731
+ ```
732
+ twake/
733
+ ├── users.json # Twake user accounts
734
+ │ ├── Entity: twakeUser
735
+ │ ├── ObjectClasses: top, twakeAccount, twakeWhitePages
736
+ │ ├── Main Attribute: uid
737
+ │ └── Special Attributes:
738
+ │ ├── twakeAccountStatus (pointer to nomenclature)
739
+ │ ├── twakeDeliveryMode (pointer to nomenclature)
740
+ │ ├── twakeDelegatedUsers (pointer array)
741
+ │ ├── twakeDepartmentLink (DN reference)
742
+ │ └── twakeDepartmentPath (organizational path)
743
+ │
744
+ ├── groups.json # Twake groups
745
+ │ ├── Entity: twakeGroup
746
+ │ ├── ObjectClasses: top, groupOfNames, twakeStaticGroup
747
+ │ ├── Main Attribute: cn
748
+ │ └── Special Attributes:
749
+ │ ├── twakeDepartmentLink
750
+ │ └── twakeDepartmentPath
751
+ │
752
+ ├── organizations.json # Twake departments/OUs
753
+ │ ├── Entity: (organization schema)
754
+ │ ├── ObjectClasses: top, organizationalUnit, twakeDepartment
755
+ │ ├── Main Attribute: ou
756
+ │ └── Special Attributes:
757
+ │ ├── twakeDepartmentPath
758
+ │ └── twakeLocalAdminLink (array)
759
+ │
760
+ ├── positions.json # Job positions
761
+ │ ├── Entity: twakePosition
762
+ │ ├── ObjectClasses: top, twakePosition
763
+ │ └── Main Attribute: cn
764
+ │
765
+ └── nomenclature/ # Controlled vocabularies
766
+ ├── twakeAccountStatus.json # Account status values
767
+ ├── twakeDeliveryMode.json # Email delivery modes
768
+ ├── twakeListType.json # Mailing list types
769
+ └── twakeTitle.json # Job titles
770
+ ```
771
+
772
+ **Usage:**
773
+
774
+ ```bash
775
+ npx ldap-rest \
776
+ --ldap-base 'dc=example,dc=com' \
777
+ --plugin core/ldap/flatGeneric \
778
+ --ldap-flat-schema ./static/schemas/twake/users.json \
779
+ --plugin core/ldap/groups \
780
+ --ldap-groups-schema ./static/schemas/twake/groups.json \
781
+ --plugin core/ldap/organization \
782
+ --ldap-org-schema ./static/schemas/twake/organizations.json
783
+ ```
784
+
785
+ ---
786
+
787
+ ### Active Directory Schemas
788
+
789
+ Schemas for Microsoft Active Directory with Windows-specific attributes.
790
+
791
+ #### Active Directory Schema Tree
792
+
793
+ ```
794
+ ad/
795
+ ├── users.json # AD user accounts
796
+ │ ├── Entity: adUser
797
+ │ ├── ObjectClasses: top, person, organizationalPerson, user
798
+ │ ├── Main Attribute: sAMAccountName
799
+ │ └── Special Attributes:
800
+ │ ├── sAMAccountName (Windows logon name, max 20 chars)
801
+ │ ├── userPrincipalName (UPN format)
802
+ │ ├── proxyAddresses (SMTP email aliases)
803
+ │ ├── userAccountControl (account flags)
804
+ │ ├── unicodePwd (password attribute)
805
+ │ ├── accountExpires (expiration timestamp)
806
+ │ ├── pwdLastSet (password change timestamp)
807
+ │ └── manager (DN reference)
808
+ │
809
+ ├── groups.json # AD security/distribution groups
810
+ │ ├── Entity: (AD group schema)
811
+ │ ├── ObjectClasses: top, group
812
+ │ ├── Main Attribute: cn
813
+ │ └── Special Attributes:
814
+ │ ├── sAMAccountName (group name, max 256 chars)
815
+ │ ├── groupType (security/distribution flags)
816
+ │ ├── managedBy (DN reference)
817
+ │ └── member (DN array, CN-based)
818
+ │
819
+ └── organizations.json # AD organizational units
820
+ ├── Entity: (AD OU schema)
821
+ ├── ObjectClasses: top, organizationalUnit
822
+ └── Main Attribute: ou
823
+ ```
824
+
825
+ **Key Differences from Standard LDAP:**
826
+
827
+ - Uses `sAMAccountName` instead of `uid` for user identification
828
+ - Uses `CN=` based DNs instead of `uid=` or `ou=`
829
+ - Includes Windows-specific attributes (userAccountControl, unicodePwd)
830
+ - ProxyAddresses use `SMTP:` or `smtp:` prefixes
831
+ - Maximum 20 characters for user sAMAccountName
832
+ - Maximum 256 characters for group sAMAccountName
833
+
834
+ **Usage:**
835
+
836
+ ```bash
837
+ npx ldap-rest \
838
+ --ldap-base 'dc=example,dc=com' \
839
+ --plugin core/ldap/flatGeneric \
840
+ --ldap-flat-schema ./static/schemas/ad/users.json \
841
+ --plugin core/ldap/groups \
842
+ --ldap-groups-schema ./static/schemas/ad/groups.json
843
+ ```
844
+
845
+ ---
846
+
847
+ ### Standard LDAP Schemas
848
+
849
+ Schemas for standard LDAP directories using inetOrgPerson and organizationalUnit.
850
+
851
+ #### Standard LDAP Schema Tree
852
+
853
+ ```
854
+ standard/
855
+ ├── users.json # Standard LDAP users
856
+ │ ├── Entity: standardUser
857
+ │ ├── ObjectClasses: top, inetOrgPerson, organizationalPerson, person
858
+ │ ├── Main Attribute: uid
859
+ │ └── Attributes:
860
+ │ ├── uid (identifier)
861
+ │ ├── cn (common name, displayName role)
862
+ │ ├── sn (surname, required)
863
+ │ ├── mail (primary email)
864
+ │ ├── mailAlternateAddress (email aliases)
865
+ │ ├── mailQuota (email quota)
866
+ │ ├── givenName
867
+ │ ├── displayName
868
+ │ ├── telephoneNumber
869
+ │ ├── mobile
870
+ │ ├── userPassword
871
+ │ ├── departmentNumber (DN reference)
872
+ │ └── ou (organizational unit)
873
+ │
874
+ ├── groups.json # Standard LDAP groups
875
+ │ ├── Entity: (standard group schema)
876
+ │ ├── ObjectClasses: top, groupOfNames
877
+ │ ├── Main Attribute: cn
878
+ │ └── Attributes:
879
+ │ ├── cn (group name)
880
+ │ ├── description
881
+ │ ├── mail (group email)
882
+ │ ├── member (DN array)
883
+ │ ├── owner (DN array)
884
+ │ ├── businessCategory (DN reference)
885
+ │ └── ou
886
+ │
887
+ └── organizations.json # Standard LDAP OUs
888
+ ├── Entity: (standard OU schema)
889
+ ├── ObjectClasses: top, organizationalUnit
890
+ ├── Main Attribute: ou
891
+ └── Attributes:
892
+ ├── ou (organizational unit name)
893
+ ├── description
894
+ ├── telephoneNumber
895
+ ├── facsimileTelephoneNumber
896
+ ├── l (locality)
897
+ ├── postalAddress
898
+ ├── businessCategory (DN reference)
899
+ └── seeAlso
900
+ ```
901
+
902
+ **Usage:**
903
+
904
+ ```bash
905
+ npx ldap-rest \
906
+ --ldap-base 'dc=example,dc=com' \
907
+ --plugin core/ldap/flatGeneric \
908
+ --ldap-flat-schema ./static/schemas/standard/users.json \
909
+ --plugin core/ldap/groups \
910
+ --ldap-groups-schema ./static/schemas/standard/groups.json \
911
+ --plugin core/ldap/organization \
912
+ --ldap-org-schema ./static/schemas/standard/organizations.json
913
+ ```
914
+
915
+ ---
916
+
917
+ ## Schema Comparison
918
+
919
+ ### User Schemas Comparison
920
+
921
+ | Feature | Twake | Active Directory | Standard LDAP |
922
+ | ----------------- | --------------------------------- | ---------------------------------- | ------------------------ |
923
+ | Main Attribute | `uid` | `sAMAccountName` | `uid` |
924
+ | Display Name Role | `cn` | `cn` | `cn` |
925
+ | ObjectClasses | twakeAccount, twakeWhitePages | user, person | inetOrgPerson, person |
926
+ | Primary Email | `mail` | `mail` | `mail` |
927
+ | Email Aliases | `mailAlternateAddress` | `proxyAddresses` | `mailAlternateAddress` |
928
+ | Department Link | `twakeDepartmentLink` (DN) | `manager` (DN) | `departmentNumber` (DN) |
929
+ | Special Features | Nomenclature pointers, delegation | AD-specific (UPN, account control) | Standard attributes only |
930
+
931
+ ### Group Schemas Comparison
932
+
933
+ | Feature | Twake | Active Directory | Standard LDAP |
934
+ | ---------------- | ------------------------------ | ------------------------- | ------------------- |
935
+ | Main Attribute | `cn` | `cn` | `cn` |
936
+ | ObjectClasses | groupOfNames, twakeStaticGroup | group | groupOfNames |
937
+ | Member Attribute | `member` (DN array) | `member` (DN array) | `member` (DN array) |
938
+ | Owner Attribute | `owner` (DN array) | `managedBy` (single DN) | `owner` (DN array) |
939
+ | Special Features | Department links | groupType, sAMAccountName | Business category |
940
+
941
+ ---
942
+
943
+ ## Creating Custom Schemas
944
+
945
+ To create a custom schema for your specific LDAP directory:
946
+
947
+ ### Step 1: Choose a Base Schema
948
+
949
+ Start with the schema that most closely matches your directory type:
950
+
951
+ - **Twake**: For Twake Mail or similar collaborative directories
952
+ - **Active Directory**: For Microsoft AD
953
+ - **Standard LDAP**: For OpenLDAP, 389 Directory Server, etc.
954
+
955
+ ### Step 2: Define Entity Metadata
956
+
957
+ ```json
958
+ {
959
+ "entity": {
960
+ "name": "customUser",
961
+ "mainAttribute": "uid",
962
+ "objectClass": ["top", "inetOrgPerson", "customPerson"],
963
+ "singularName": "user",
964
+ "pluralName": "users",
965
+ "base": "ou=users,{ldap_base}",
966
+ "defaultAttributes": {
967
+ "cn": "New User",
968
+ "sn": "User"
969
+ }
970
+ }
971
+ }
972
+ ```
973
+
974
+ ### Step 3: Define Required Attributes
975
+
976
+ ```json
977
+ {
978
+ "strict": true,
979
+ "attributes": {
980
+ "objectClass": {
981
+ "type": "array",
982
+ "items": {
983
+ "type": "string"
984
+ },
985
+ "default": ["top", "inetOrgPerson", "customPerson"],
986
+ "required": true,
987
+ "fixed": true
988
+ },
989
+ "uid": {
990
+ "type": "string",
991
+ "test": "^[a-zA-Z0-9._-]{1,255}$",
992
+ "required": true,
993
+ "role": "identifier"
994
+ },
995
+ "cn": {
996
+ "type": "string",
997
+ "required": true,
998
+ "role": "displayName"
999
+ },
1000
+ "sn": {
1001
+ "type": "string",
1002
+ "required": true
1003
+ }
1004
+ }
1005
+ }
1006
+ ```
1007
+
1008
+ ### Step 4: Add Optional Attributes
1009
+
1010
+ ```json
1011
+ {
1012
+ "attributes": {
1013
+ "mail": {
1014
+ "type": "string",
1015
+ "test": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
1016
+ "required": false,
1017
+ "role": "primaryEmail"
1018
+ },
1019
+ "telephoneNumber": {
1020
+ "type": "string",
1021
+ "required": false
1022
+ },
1023
+ "customAttribute": {
1024
+ "type": "string",
1025
+ "required": false
1026
+ }
1027
+ }
1028
+ }
1029
+ ```
1030
+
1031
+ ### Step 5: Add Pointer Attributes (if needed)
1032
+
1033
+ ```json
1034
+ {
1035
+ "attributes": {
1036
+ "customStatus": {
1037
+ "type": "pointer",
1038
+ "branch": ["ou=status,ou=nomenclature,{ldap_base}"],
1039
+ "required": true
1040
+ }
1041
+ }
1042
+ }
1043
+ ```
1044
+
1045
+ ### Step 6: Test and Deploy
1046
+
1047
+ Save your schema and reference it when starting LDAP-Rest:
1048
+
1049
+ ```bash
1050
+ npx ldap-rest \
1051
+ --ldap-base 'dc=example,dc=com' \
1052
+ --plugin core/ldap/flatGeneric \
1053
+ --ldap-flat-schema ./path/to/custom-users.json
1054
+ ```
1055
+
1056
+ ---
1057
+
1058
+ ## Best Practices
1059
+
1060
+ ### 1. Always Define ObjectClass
1061
+
1062
+ Include objectClass with fixed default values:
1063
+
1064
+ ```json
1065
+ {
1066
+ "objectClass": {
1067
+ "type": "array",
1068
+ "items": {
1069
+ "type": "string"
1070
+ },
1071
+ "default": ["top", "inetOrgPerson"],
1072
+ "required": true,
1073
+ "fixed": true
1074
+ }
1075
+ }
1076
+ ```
1077
+
1078
+ ### 2. Use Semantic Roles
1079
+
1080
+ Assign roles to key attributes for proper handling:
1081
+
1082
+ ```json
1083
+ {
1084
+ "uid": {
1085
+ "type": "string",
1086
+ "role": "identifier"
1087
+ },
1088
+ "cn": {
1089
+ "type": "string",
1090
+ "role": "displayName"
1091
+ },
1092
+ "mail": {
1093
+ "type": "string",
1094
+ "role": "primaryEmail"
1095
+ }
1096
+ }
1097
+ ```
1098
+
1099
+ ### 3. Validate with Regular Expressions
1100
+
1101
+ Use `test` patterns to enforce data quality:
1102
+
1103
+ ```json
1104
+ {
1105
+ "uid": {
1106
+ "type": "string",
1107
+ "test": "^[a-zA-Z0-9._-]{1,255}$"
1108
+ },
1109
+ "mail": {
1110
+ "type": "string",
1111
+ "test": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"
1112
+ }
1113
+ }
1114
+ ```
1115
+
1116
+ ### 4. Use Variable Substitution
1117
+
1118
+ Reference the LDAP base dynamically:
1119
+
1120
+ ```json
1121
+ {
1122
+ "entity": {
1123
+ "base": "ou=users,{ldap_base}"
1124
+ },
1125
+ "attributes": {
1126
+ "departmentNumber": {
1127
+ "type": "string",
1128
+ "test": "^.*,__ldap_base__$"
1129
+ }
1130
+ }
1131
+ }
1132
+ ```
1133
+
1134
+ ### 5. Enable Strict Mode
1135
+
1136
+ Prevent unwanted attributes:
1137
+
1138
+ ```json
1139
+ {
1140
+ "strict": true
1141
+ }
1142
+ ```
1143
+
1144
+ ### 6. Document Custom Attributes
1145
+
1146
+ Add comments in your schema documentation (not in JSON) explaining custom attributes and their purpose.
1147
+
1148
+ ---
1149
+
1150
+ ## Troubleshooting
1151
+
1152
+ ### Schema Not Loading
1153
+
1154
+ **Problem**: Schema file not found or fails to parse.
1155
+
1156
+ **Solution**:
1157
+
1158
+ - Verify the file path is correct
1159
+ - Check JSON syntax with a validator
1160
+ - Review server logs for detailed error messages
1161
+
1162
+ ```bash
1163
+ npx ldap-rest --log-level debug ...
1164
+ ```
1165
+
1166
+ ### Validation Errors
1167
+
1168
+ **Problem**: Entries fail validation when creating or updating.
1169
+
1170
+ **Solution**:
1171
+
1172
+ - Check that required attributes are provided
1173
+ - Verify attribute values match `test` patterns
1174
+ - Ensure DN pointers reference valid entries
1175
+ - Check that array items match their item schema
1176
+
1177
+ ### Pointer Attributes Not Working
1178
+
1179
+ **Problem**: Pointer attributes don't reference entries correctly.
1180
+
1181
+ **Solution**:
1182
+
1183
+ - Verify the `branch` DN is correct
1184
+ - Ensure referenced entries exist in LDAP
1185
+ - Check that DN format matches the `test` pattern
1186
+ - Use variable substitution for dynamic bases
1187
+
1188
+ ### Attribute Not Appearing in API
1189
+
1190
+ **Problem**: Custom attribute doesn't appear in API responses.
1191
+
1192
+ **Solution**:
1193
+
1194
+ - Verify the attribute is in the schema
1195
+ - Check that `strict` mode isn't preventing it
1196
+ - Ensure the attribute exists in LDAP entries
1197
+ - Request it explicitly with the `attributes` query parameter
1198
+
1199
+ ---
1200
+
1201
+ ## Additional Resources
1202
+
1203
+ - **[REST API Documentation](../api/REST_API.md)** - Using schemas with the API
1204
+ - **[Browser Libraries](../browser/LIBRARIES.md)** - Schema-driven UI components
1205
+ - **[Plugin Development](../plugins/DEVELOPMENT.md)** - Creating schema-aware plugins
1206
+ - **[Integration Examples](../examples/EXAMPLES.md)** - Working with schemas in applications
1207
+
1208
+ ---
1209
+
1210
+ ## License
1211
+
1212
+ AGPL-3.0 - Copyright 2025-present LINAGORA