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,24 @@
1
+ /**
2
+ * @module core/auth/rateLimit
3
+ * Rate limiting plugin to prevent brute-force attacks
4
+ *
5
+ * This plugin adds rate limiting middleware specifically for authentication
6
+ * to protect against brute-force attacks. It should be loaded BEFORE auth plugins.
7
+ *
8
+ * Uses an Express middleware to check rate limits before processing, and
9
+ * an afterAuth hook to track failed authentication attempts.
10
+ *
11
+ * @author Xavier Guimard <xguimard@linagora.com>
12
+ */
13
+ import type { Express } from 'express';
14
+ import DmPlugin, { type Role } from '../../abstract/plugin';
15
+ export default class RateLimit extends DmPlugin {
16
+ name: string;
17
+ roles: Role[];
18
+ private store;
19
+ private windowMs;
20
+ private maxRequests;
21
+ constructor(...args: ConstructorParameters<typeof DmPlugin>);
22
+ api(app: Express): void;
23
+ private getClientIp;
24
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @module plugins/auth/token
3
+ * @author Xavier Guimard <xguimard@linagora.com>
4
+ *
5
+ * Token-based authentication plugin
6
+ * @group Plugins
7
+ */
8
+ import type { Response } from 'express';
9
+ import AuthBase, { type DmRequest } from '../../lib/auth/base';
10
+ import type { Role } from '../../abstract/plugin';
11
+ export default class AuthToken extends AuthBase {
12
+ name: string;
13
+ roles: Role[];
14
+ private tokenMap;
15
+ constructor(...args: ConstructorParameters<typeof AuthBase>);
16
+ authMethod(req: DmRequest, res: Response, next: () => void): void;
17
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @module plugins/configApi
3
+ * @author Xavier Guimard <xguimard@linagora.com>
4
+ *
5
+ * Plugin that exposes API configuration for LDAP editor applications
6
+ * Provides information about available resources, schemas, and endpoints
7
+ *
8
+ * Uses autodiscovery pattern: plugins with 'configurable' role automatically
9
+ * expose their configuration via getConfigApiData() method
10
+ */
11
+ import type { Express } from 'express';
12
+ import DmPlugin, { type Role } from '../abstract/plugin';
13
+ export default class ConfigApi extends DmPlugin {
14
+ name: string;
15
+ roles: Role[];
16
+ /**
17
+ * API routes
18
+ */
19
+ api(app: Express): void;
20
+ /**
21
+ * Collect configuration from all plugins with 'configurable' role
22
+ */
23
+ private collectPluginConfigs;
24
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @module core/helloworld
3
+ * Demo plugin, add /hello API + consumes 'hello' hook
4
+ * @author Xavier Guimard <xguimard@linagora.com>
5
+ */
6
+ import type { Express } from 'express';
7
+ import DmPlugin, { type Role } from '../../abstract/plugin';
8
+ export default class HelloWorld extends DmPlugin {
9
+ name: string;
10
+ roles: Role[];
11
+ api(app: Express): void;
12
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * LDAP Bulk Import Plugin
3
+ * Provides CSV-based bulk import for LDAP resources based on JSON schemas
4
+ * @author LDAP-Rest Team
5
+ */
6
+ import type { Express } from 'express';
7
+ import DmPlugin, { type Role } from '../../abstract/plugin';
8
+ import type { DM } from '../../bin';
9
+ export default class LdapBulkImport extends DmPlugin {
10
+ name: string;
11
+ roles: Role[];
12
+ private resources;
13
+ private upload;
14
+ constructor(parent: DM);
15
+ api(app: Express): void;
16
+ /**
17
+ * Generate CSV template from schema
18
+ */
19
+ private getTemplate;
20
+ /**
21
+ * Bulk import from CSV file
22
+ */
23
+ private bulkImport;
24
+ /**
25
+ * Process a single CSV record
26
+ */
27
+ private processRecord;
28
+ /**
29
+ * Get editable attributes from schema (exclude fixed and calculated)
30
+ */
31
+ private getEditableAttributes;
32
+ /**
33
+ * Find attribute by role in schema
34
+ */
35
+ private findAttributeByRole;
36
+ /**
37
+ * Fetch organization to get its path
38
+ */
39
+ private fetchOrganization;
40
+ /**
41
+ * Check if entry exists
42
+ */
43
+ private entryExists;
44
+ /**
45
+ * Provide configuration for config API
46
+ */
47
+ getConfigApiData(): Record<string, unknown>;
48
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @module plugins/ldap/departmentSync
3
+ * @author Xavier Guimard <xguimard@linagora.com>
4
+ *
5
+ * Plugin to maintain consistency of department links when organizations are renamed/moved
6
+ * Automatically updates twakeDepartmentLink and twakeDepartmentPath attributes on all
7
+ * resources (users, groups, etc.) when their linked organization DN changes.
8
+ */
9
+ import DmPlugin, { type Role } from '../../abstract/plugin';
10
+ import type { DM } from '../../bin';
11
+ import type { Hooks } from '../../hooks';
12
+ export default class LdapDepartmentSync extends DmPlugin {
13
+ name: string;
14
+ roles: Role[];
15
+ private linkAttr;
16
+ private pathAttr;
17
+ constructor(server: DM);
18
+ hooks: Hooks;
19
+ /**
20
+ * Update resources that are directly linked to the renamed organization
21
+ */
22
+ private updateLinkedResources;
23
+ /**
24
+ * Update resources linked to sub-organizations that were moved
25
+ * When ou=IT moves from ou=IT,ou=Departments to ou=IT,ou=Tech,
26
+ * its child ou=Dev,ou=IT,ou=Departments becomes ou=Dev,ou=IT,ou=Tech
27
+ * We need to update resources pointing to the old child DN
28
+ */
29
+ private updateDescendantReferences;
30
+ /**
31
+ * Get department path from an organization DN
32
+ * Fetches the path attribute directly from the organization entry
33
+ */
34
+ private getDepartmentPath;
35
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @module plugins/ldap/externalUsersInGroups
3
+ * @author Xavier Guimard <xguimard@linagora.com>
4
+ *
5
+ * Creates on-the-fly missing group users into a branch
6
+ * This permits to add external users into mailing lists
7
+ */
8
+ import DmPlugin, { type Role } from '../../abstract/plugin';
9
+ import type { DM } from '../../bin';
10
+ import { Hooks } from '../../hooks';
11
+ import ldapActions from '../../lib/ldapActions';
12
+ export default class ExternalUsersInGroups extends DmPlugin {
13
+ name: string;
14
+ roles: Role[];
15
+ dependencies: {
16
+ ldapGroups: string;
17
+ };
18
+ ldap: ldapActions;
19
+ constructor(server: DM);
20
+ hooks: Hooks;
21
+ }
@@ -0,0 +1,31 @@
1
+ import type { Express } from 'express';
2
+ import DmPlugin, { type Role } from '../../abstract/plugin';
3
+ import LdapFlat from '../../abstract/ldapFlat';
4
+ import type { DM } from '../../bin';
5
+ /**
6
+ * Concrete implementation of LdapFlat for generic instances
7
+ */
8
+ declare class LdapFlatInstance extends LdapFlat {
9
+ name: string;
10
+ roles: Role[];
11
+ dependencies: {
12
+ departmentSync: string;
13
+ };
14
+ constructor(server: DM, config: ConstructorParameters<typeof LdapFlat>[1]);
15
+ }
16
+ export default class LdapFlatGeneric extends DmPlugin {
17
+ name: string;
18
+ roles: Role[];
19
+ instances: LdapFlatInstance[];
20
+ private schemaPaths;
21
+ constructor(server: DM);
22
+ /**
23
+ * Register all instance APIs
24
+ */
25
+ api(app: Express): void;
26
+ /**
27
+ * Provide configuration for config API
28
+ */
29
+ getConfigApiData(): Record<string, unknown>;
30
+ }
31
+ export {};
@@ -0,0 +1,95 @@
1
+ import type { Express, Request, Response } from 'express';
2
+ import DmPlugin, { type Role } from '../../abstract/plugin';
3
+ import type { DM } from '../../bin';
4
+ import type { Hooks } from '../../hooks';
5
+ import type ldapActions from '../../lib/ldapActions';
6
+ import type { AttributesList, AttributeValue, LdapList, ModifyRequest } from '../../lib/ldapActions';
7
+ import type { Schema } from '../../config/schema';
8
+ export interface postAdd {
9
+ cn?: string;
10
+ [key: string]: AttributeValue | undefined;
11
+ }
12
+ export type postModify = ModifyRequest;
13
+ export default class LdapGroups extends DmPlugin {
14
+ name: string;
15
+ roles: Role[];
16
+ base?: string;
17
+ ldap: ldapActions;
18
+ cn: string;
19
+ schema?: Schema;
20
+ constructor(server: DM);
21
+ /**
22
+ * Catch all deletion to remove deleted users from groups
23
+ */
24
+ hooks: Hooks;
25
+ /**
26
+ * API routes
27
+ */
28
+ api(app: Express): void;
29
+ apiGet(req: Request, res: Response): Promise<void>;
30
+ apiAdd(req: Request, res: Response, ...requiredFields: string[]): Promise<void>;
31
+ apiDelete(req: Request, res: Response): Promise<void>;
32
+ apiModify(req: Request, res: Response): Promise<void>;
33
+ /**
34
+ * LDAP group methods
35
+ */
36
+ addGroup(cn: string, members?: string[], additional?: AttributesList): Promise<boolean>;
37
+ modifyGroup(cn: string, changes: {
38
+ add?: AttributesList;
39
+ replace?: AttributesList;
40
+ delete?: string[] | AttributesList;
41
+ }): Promise<boolean>;
42
+ renameGroup(cn: string, newCn: string): Promise<boolean>;
43
+ deleteGroup(cn: string): Promise<boolean>;
44
+ addMember(cn: string, member: string | string[]): Promise<boolean>;
45
+ deleteMember(cn: string, member: string): Promise<boolean>;
46
+ deleteMemberFromAll(memberDn: string): Promise<void>;
47
+ /**
48
+ * Move a group to a different organization by updating organization link and path attributes
49
+ * This method should only be called when organization attributes are configured
50
+ * @param cn Group cn or DN
51
+ * @param targetOrgDn DN of the target organization
52
+ * @returns Success status
53
+ */
54
+ moveGroup(cn: string, targetOrgDn: string, req?: Request): Promise<{
55
+ success: boolean;
56
+ }>;
57
+ /**
58
+ * List groups from LDAP
59
+ * @param param0 {filter, attributes}:
60
+ * - filter: LDAP filter (default '(objectClass=*)')
61
+ * - attributes: attributes to fetch (default ['cn','member'])
62
+ * @returns LdapList (Record<string, AttributesList>)
63
+ */
64
+ listGroups({ filter, attributes, }?: {
65
+ filter?: string;
66
+ attributes?: string[];
67
+ }): Promise<LdapList>;
68
+ /**
69
+ * Simple formatter for listGroups()
70
+ * @param cn main attribute value (partial or full)
71
+ * @param partial boolean, true for partial search (default false)
72
+ * @param attributes array of attributes to return
73
+ * @returns LdapList (means Record<string, AttributesList> where key is the --ldap-user-main-attribute value [default: cn])
74
+ */
75
+ searchGroupsByName(cn: string, partial?: boolean, attributes?: string[]): Promise<LdapList>;
76
+ protected fixDn(dn: string): string | false;
77
+ /**
78
+ * Verify that each member exists in LDAP
79
+ *
80
+ * It calls ldapgroupvalidatemembers hook before validation
81
+ * so that plugins can modify the members list and/or the group DN
82
+ * and/or create missing members on the fly
83
+ * @param dn Group DN (given to hooks)
84
+ * @param members Array of member DNs to check
85
+ * @returns nothing, throw if error
86
+ */
87
+ validateMembers(dn: string, members: string[]): Promise<void>;
88
+ validateNewGroup(dn: string, entry: AttributesList): Promise<boolean>;
89
+ validateChanges(dn: string, changes: ModifyRequest): Promise<boolean>;
90
+ _validateOneChange(field: string, value: AttributeValue | null): Promise<boolean>;
91
+ /**
92
+ * Provide configuration for config API
93
+ */
94
+ getConfigApiData(): Record<string, unknown>;
95
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @module core/onLdapChange
3
+ * Check for ldap modify events and generate hooks:
4
+ * - onLdapChange
5
+ * - onLdapMailChange
6
+ * @author Xavier Guimard <xguimard@linagora.com>
7
+ */
8
+ import { Entry } from 'ldapts';
9
+ import DmPlugin, { type Role } from '../../abstract/plugin';
10
+ import type { Hooks } from '../../hooks';
11
+ import type { AttributeValue } from '../../lib/ldapActions';
12
+ export type ChangesToNotify = Record<string, [
13
+ AttributeValue | null,
14
+ AttributeValue | null
15
+ ]>;
16
+ declare class OnLdapChange extends DmPlugin {
17
+ name: string;
18
+ roles: Role[];
19
+ stack: Record<number, Entry>;
20
+ hooks: Hooks;
21
+ notify(dn: string, changes: ChangesToNotify): void;
22
+ notifyAttributeChange(attribute: string, hookName: keyof Hooks, dn: string, changes: ChangesToNotify, stringOnly?: boolean): void;
23
+ notifyAttributeChangeWithMail(attribute: string, hookName: keyof Hooks, dn: string, changes: ChangesToNotify): Promise<void>;
24
+ /**
25
+ * Reconstruct display name from cn, givenName, and sn attributes
26
+ * @param changes - The changes object
27
+ * @param index - 0 for old value, 1 for new value
28
+ * @returns The reconstructed display name or null
29
+ */
30
+ reconstructDisplayName(changes: ChangesToNotify, index: 0 | 1): string | null;
31
+ }
32
+ export default OnLdapChange;
@@ -0,0 +1,65 @@
1
+ import type { Express, Request, Response } from 'express';
2
+ import DmPlugin, { type Role } from '../../abstract/plugin';
3
+ import { DM } from '../../bin';
4
+ import { Hooks } from '../../hooks';
5
+ import { AttributesList, AttributeValue, ModifyRequest } from '../../lib/ldapActions';
6
+ import type { Schema } from '../../config/schema';
7
+ export default class LdapOrganizations extends DmPlugin {
8
+ name: string;
9
+ roles: Role[];
10
+ pathAttr: string;
11
+ linkAttr: string;
12
+ schema?: Schema;
13
+ constructor(dm: DM);
14
+ /**
15
+ * API routes for LDAP organizations
16
+ * @param app Express application
17
+ */
18
+ api(app: Express): void;
19
+ apiAdd(req: Request, res: Response): Promise<void>;
20
+ apiModify(req: Request, res: Response): Promise<void>;
21
+ apiDelete(req: Request, res: Response): Promise<void>;
22
+ apiMove(req: Request, res: Response): Promise<void>;
23
+ /**
24
+ * Consistency checks on any entry
25
+ */
26
+ hooks: Hooks;
27
+ /**
28
+ * Check if the department link is valid
29
+ * @param entry LDAP entry to check
30
+ */
31
+ checkDeptLink(entry: AttributesList): Promise<void>;
32
+ /**
33
+ * Check if the department path is valid
34
+ * @param entry LDAP entry to check
35
+ */
36
+ checkDeptPath(entry: AttributesList): Promise<void>;
37
+ isEmptyOrganization(dn: string): Promise<void>;
38
+ /**
39
+ * Check if entry is an organisation
40
+ * @param entry LDAP entry to check
41
+ * @returns True if entry is an organisation, false otherwise
42
+ */
43
+ isOu(entry: AttributesList): boolean;
44
+ getOrganisationTop(req?: Request): Promise<AttributesList | AttributesList[]>;
45
+ getOrganisationByDn(dn: string, req?: Request): Promise<AttributesList>;
46
+ getOrganisationSubnodes(dn: string, req?: Request): Promise<AttributesList[]>;
47
+ addOrganization(dn: string, entry: AttributesList, req?: Request): Promise<boolean>;
48
+ modifyOrganization(dn: string, changes: ModifyRequest): Promise<boolean>;
49
+ validateNewOrganization(dn: string, entry: AttributesList): boolean;
50
+ validateChanges(dn: string, changes: ModifyRequest): boolean;
51
+ _validateOneChange(field: string, value: AttributeValue | null): boolean;
52
+ /**
53
+ * Move an organization to a different parent organization
54
+ * Uses LDAP modifyDN to change the DN hierarchy
55
+ */
56
+ moveOrganization(dn: string, targetOrgDn: string, req?: Request): Promise<{
57
+ newDn: string;
58
+ }>;
59
+ deleteOrganization(dn: string): Promise<boolean>;
60
+ searchOrganisationSubnodes(dn: string, query: string): Promise<AttributesList[]>;
61
+ /**
62
+ * Provide configuration for config API
63
+ */
64
+ getConfigApiData(): Record<string, unknown>;
65
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @module core/trash
3
+ * LDAP Trash System - Intercepts delete operations and moves entries to a trash branch
4
+ *
5
+ * When a delete operation occurs on a watched LDAP branch:
6
+ * 1. Check if DN is in a watched branch (configured via DM_TRASH_WATCHED_BASES)
7
+ * 2. Remove any existing entry with same RDN in trash (overwrite old trash)
8
+ * 3. Use LDAP modifyDN to atomically move entry to trash branch
9
+ * 4. Add metadata (deletedAt, originalDN) as description attribute
10
+ * 5. Cancel the native delete operation
11
+ *
12
+ * @author Xavier Guimard <xguimard@linagora.com>
13
+ */
14
+ import DmPlugin, { type Role } from '../../abstract/plugin';
15
+ import type { Hooks } from '../../hooks';
16
+ declare class TrashPlugin extends DmPlugin {
17
+ name: string;
18
+ roles: Role[];
19
+ private watchedBases;
20
+ private trashBase;
21
+ private addMetadata;
22
+ private autoCreateTrash;
23
+ private trashInitialized;
24
+ constructor(dm: typeof DmPlugin.prototype.server);
25
+ /**
26
+ * Check if a DN is in a watched branch
27
+ */
28
+ private isWatched;
29
+ /**
30
+ * Extract RDN from DN (e.g., "uid=john" from "uid=john,ou=users,dc=example,dc=com")
31
+ */
32
+ private extractRDN;
33
+ /**
34
+ * Build trash DN from original DN
35
+ * uid=john,ou=users,dc=example,dc=com -> uid=john,ou=trash,dc=example,dc=com
36
+ */
37
+ private buildTrashDN;
38
+ /**
39
+ * Ensure trash branch exists in LDAP
40
+ */
41
+ private ensureTrashExists;
42
+ /**
43
+ * Remove old entry from trash if it exists (to allow overwrite)
44
+ */
45
+ private removeOldTrashEntry;
46
+ /**
47
+ * Add metadata to trash entry (deletedAt, originalDN)
48
+ */
49
+ private addMetadataToTrash;
50
+ hooks: Hooks;
51
+ }
52
+ export default TrashPlugin;
@@ -0,0 +1,7 @@
1
+ import type { Express } from 'express';
2
+ import DmPlugin, { type Role } from '../abstract/plugin';
3
+ export default class Static extends DmPlugin {
4
+ name: string;
5
+ roles: Role[];
6
+ api(app: Express): void;
7
+ }
@@ -0,0 +1,31 @@
1
+ import TwakePlugin from '../../abstract/twakePlugin';
2
+ import { type Role } from '../../abstract/plugin';
3
+ import { Hooks } from '../../hooks';
4
+ /**
5
+ * Plugin to sync LDAP resources with Twake Calendar
6
+ *
7
+ * Monitors a LDAP branch for resources (meeting rooms, equipment, etc.)
8
+ * and automatically creates/updates/deletes them in Twake Calendar via WebAdmin API
9
+ */
10
+ export default class CalendarResources extends TwakePlugin {
11
+ name: string;
12
+ roles: Role[];
13
+ private resourceBase;
14
+ private resourceObjectClass;
15
+ private resourceCreator;
16
+ private resourceDomain;
17
+ constructor(server: import('../../bin').DM);
18
+ hooks: Hooks;
19
+ /**
20
+ * Check if a LDAP entry is a calendar resource
21
+ */
22
+ private isResource;
23
+ /**
24
+ * Build resource data for Calendar API from LDAP attributes
25
+ */
26
+ private buildResourceData;
27
+ /**
28
+ * Extract resource ID from DN
29
+ */
30
+ private getResourceId;
31
+ }
@@ -0,0 +1,83 @@
1
+ import TwakePlugin from '../../abstract/twakePlugin';
2
+ import { type Role } from '../../abstract/plugin';
3
+ import type { DM } from '../../bin';
4
+ import type { AttributeValue } from '../../lib/ldapActions';
5
+ import { Hooks } from '../../hooks';
6
+ import type { ChangesToNotify } from '../ldap/onChange';
7
+ export default class James extends TwakePlugin {
8
+ name: string;
9
+ roles: Role[];
10
+ dependencies: {
11
+ onLdapChange: string;
12
+ ldapGroups: string;
13
+ };
14
+ private quotaAttr;
15
+ private aliasAttr;
16
+ private mailboxTypeAttr;
17
+ private initDelay;
18
+ constructor(server: DM);
19
+ hooks: Hooks;
20
+ /**
21
+ * Handle mailbox type transitions when twakeMailboxType changes
22
+ */
23
+ private handleMailboxTypeTransition;
24
+ /**
25
+ * Extract display name from LDAP attributes
26
+ * Fallback logic: displayName → cn → givenName+sn → mail
27
+ */
28
+ private getDisplayNameFromAttributes;
29
+ getMailFromDN(dn: string): Promise<string | null>;
30
+ getDisplayNameFromDN(dn: string): Promise<string | null>;
31
+ generateSignature(dn: string): Promise<string | null>;
32
+ updateJamesIdentity(dn: string, mail: string, displayName: string): Promise<void>;
33
+ /**
34
+ * Type guard to check if delete operation is an AttributesList
35
+ */
36
+ private isAttributesList;
37
+ /**
38
+ * Extract mailbox type from group attributes
39
+ * Returns: 'group', 'mailingList', 'teamMailbox', or null if not set
40
+ */
41
+ private getMailboxType;
42
+ /**
43
+ * Validate that a DN is within one of the allowed branches
44
+ */
45
+ private isInAllowedBranches;
46
+ /**
47
+ * Create a mailing list in James
48
+ */
49
+ private createMailingList;
50
+ /**
51
+ * Create a team mailbox in James
52
+ */
53
+ private createTeamMailbox;
54
+ /**
55
+ * Delete a team mailbox from James
56
+ */
57
+ private deleteTeamMailbox;
58
+ /**
59
+ * Remove all members from a team mailbox (without deleting it)
60
+ * This preserves the mailbox for potential future use
61
+ */
62
+ private removeAllTeamMailboxMembers;
63
+ /**
64
+ * Delete a mailing list from James
65
+ */
66
+ private deleteMailingList;
67
+ /**
68
+ * Get email addresses for a list of member DNs
69
+ * Uses p-limit to parallelize LDAP queries while limiting concurrency
70
+ */
71
+ getMemberEmails(memberDns: string[]): Promise<string[]>;
72
+ /**
73
+ * Get the mail address for a group DN
74
+ */
75
+ getGroupMail(groupDn: string): Promise<string | null>;
76
+ /**
77
+ * Get the mailbox type for a group DN
78
+ */
79
+ getGroupMailboxType(groupDn: string): Promise<'group' | 'mailingList' | 'teamMailbox' | null>;
80
+ _handleDelegationChange(dn: string, changes: ChangesToNotify): Promise<void>;
81
+ _getDelegateEmail(dn: string): Promise<string | null>;
82
+ _normalizeToArray(value: AttributeValue | null): string[];
83
+ }
@@ -0,0 +1,8 @@
1
+ import type { Express, Request, Response } from 'express';
2
+ import DmPlugin, { type Role } from '../abstract/plugin';
3
+ export default class WebLogs extends DmPlugin {
4
+ name: string;
5
+ roles: Role[];
6
+ api(app: Express): void;
7
+ log(req: Request, res: Response, start: number, log: Record<string, string | number>): void;
8
+ }