ldap-rest 1.2.0 → 1.3.0

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 (342) hide show
  1. package/bin/sync-james.mjs +13 -2
  2. package/dist/abstract/ldapFlat.js +1 -1
  3. package/dist/abstract/plugin.js +1 -1
  4. package/dist/abstract/twakePlugin.js +1 -1
  5. package/dist/bin/index.js +1 -1
  6. package/dist/config/args.js +1 -1
  7. package/dist/config/options.js +1 -0
  8. package/dist/config/schema.js +1 -1
  9. package/dist/lib/auth/base.js +1 -1
  10. package/dist/lib/authz/base.js +1 -1
  11. package/dist/lib/entitySchema/validator.js +1 -1
  12. package/dist/lib/errors.js +1 -1
  13. package/dist/lib/expressFormatedResponses.js +1 -1
  14. package/dist/lib/health.js +1 -1
  15. package/dist/lib/hookBus.js +1 -0
  16. package/dist/lib/instanceProviders.js +1 -1
  17. package/dist/lib/ldapActions.js +1 -1
  18. package/dist/lib/ldapSchema.js +1 -1
  19. package/dist/lib/parseConfig.js +1 -1
  20. package/dist/lib/route.js +1 -0
  21. package/dist/lib/schemaFile.js +1 -1
  22. package/dist/lib/storage/store.js +1 -1
  23. package/dist/lib/utils.js +1 -1
  24. package/dist/lib/version.js +1 -0
  25. package/dist/logger/winston.js +1 -1
  26. package/dist/plugins/auth/auth.options.js +1 -0
  27. package/dist/plugins/auth/authzDynamic.js +1 -1
  28. package/dist/plugins/auth/authzLinid1.js +1 -1
  29. package/dist/plugins/auth/authzPerBranch.js +1 -1
  30. package/dist/plugins/auth/authzPerRoute.js +1 -1
  31. package/dist/plugins/auth/authzScope.js +1 -1
  32. package/dist/plugins/auth/crowdsec.js +1 -1
  33. package/dist/plugins/auth/fake.js +1 -1
  34. package/dist/plugins/auth/hmac.js +1 -1
  35. package/dist/plugins/auth/llng.js +1 -1
  36. package/dist/plugins/auth/openidconnect.js +1 -1
  37. package/dist/plugins/auth/rateLimit.js +1 -1
  38. package/dist/plugins/auth/token.js +1 -1
  39. package/dist/plugins/auth/totp.js +1 -1
  40. package/dist/plugins/auth/trustedProxy.js +1 -1
  41. package/dist/plugins/bcl.js +1 -1
  42. package/dist/plugins/bcl.options.js +1 -0
  43. package/dist/plugins/configApi.js +1 -1
  44. package/dist/plugins/demo/helloworld.js +1 -1
  45. package/dist/plugins/ldap/accountLifecycle.js +1 -1
  46. package/dist/plugins/ldap/bulkImport.js +1 -1
  47. package/dist/plugins/ldap/departmentSync.js +1 -1
  48. package/dist/plugins/ldap/enterpriseRules.js +1 -1
  49. package/dist/plugins/ldap/externalUsersInGroups.js +1 -1
  50. package/dist/plugins/ldap/flatGeneric.js +1 -1
  51. package/dist/plugins/ldap/groups.js +1 -1
  52. package/dist/plugins/ldap/ldap.options.js +1 -0
  53. package/dist/plugins/ldap/onChange.js +1 -1
  54. package/dist/plugins/ldap/organizations.js +1 -1
  55. package/dist/plugins/ldap/passwordPolicy.js +1 -1
  56. package/dist/plugins/ldap/raw.js +1 -1
  57. package/dist/plugins/ldap/trash.js +1 -1
  58. package/dist/plugins/metrics.js +1 -1
  59. package/dist/plugins/metrics.options.js +1 -0
  60. package/dist/plugins/rabbitmq.js +1 -1
  61. package/dist/plugins/rabbitmq.options.js +1 -0
  62. package/dist/plugins/scim/baseResolver.js +1 -1
  63. package/dist/plugins/scim/bulk.js +1 -1
  64. package/dist/plugins/scim/discovery.js +1 -1
  65. package/dist/plugins/scim/errors.js +1 -1
  66. package/dist/plugins/scim/filter.js +1 -1
  67. package/dist/plugins/scim/groups.js +1 -1
  68. package/dist/plugins/scim/mapping.js +1 -1
  69. package/dist/plugins/scim/patch.js +1 -1
  70. package/dist/plugins/scim/projection.js +1 -1
  71. package/dist/plugins/scim/scim.js +1 -1
  72. package/dist/plugins/scim/scim.options.js +1 -0
  73. package/dist/plugins/scim/users.js +1 -1
  74. package/dist/plugins/static.js +1 -1
  75. package/dist/plugins/static.options.js +1 -0
  76. package/dist/plugins/storage/file.js +1 -1
  77. package/dist/plugins/storage/ldap.js +1 -1
  78. package/dist/plugins/storage/postgres.js +1 -1
  79. package/dist/plugins/storage/valkey.js +1 -1
  80. package/dist/plugins/storage.js +1 -1
  81. package/dist/plugins/storage.options.js +1 -0
  82. package/dist/plugins/twake/appAccounts.options.js +1 -0
  83. package/dist/plugins/twake/appAccountsApi.js +1 -1
  84. package/dist/plugins/twake/appAccountsConsistency.js +1 -1
  85. package/dist/plugins/twake/calendar.js +1 -1
  86. package/dist/plugins/twake/calendar.options.js +1 -0
  87. package/dist/plugins/twake/calendarResources.js +1 -1
  88. package/dist/plugins/twake/cloudery.options.js +1 -0
  89. package/dist/plugins/twake/clouderyProvision.js +1 -1
  90. package/dist/plugins/twake/cozy.options.js +1 -0
  91. package/dist/plugins/twake/cozyProvision.js +1 -1
  92. package/dist/plugins/twake/drive.js +1 -1
  93. package/dist/plugins/twake/drive.options.js +1 -0
  94. package/dist/plugins/twake/groups.js +1 -1
  95. package/dist/plugins/twake/instances.js +1 -1
  96. package/dist/plugins/twake/james.js +1 -1
  97. package/dist/plugins/twake/james.options.js +1 -0
  98. package/dist/plugins/twake/lifecycleAttributes.js +1 -1
  99. package/dist/plugins/twake/lifecycleEvents.js +1 -1
  100. package/dist/plugins/twake/migrationProxy.js +1 -1
  101. package/dist/plugins/twake/migrationProxy.options.js +1 -0
  102. package/dist/plugins/twake/spaces.js +1 -1
  103. package/dist/plugins/twake/tombstone.js +1 -1
  104. package/dist/plugins/twake/twakeGroups.options.js +1 -0
  105. package/dist/plugins/twake/twakeInstances.options.js +1 -0
  106. package/dist/plugins/twake/twakeLifecycle.options.js +1 -0
  107. package/dist/plugins/twake/twakeSpaces.options.js +1 -0
  108. package/dist/plugins/twake/twakeTombstone.options.js +1 -0
  109. package/dist/plugins/weblogs.js +1 -1
  110. package/dist/src/abstract/ldapFlat.d.ts +28 -10
  111. package/dist/src/abstract/plugin.d.ts +10 -5
  112. package/dist/src/abstract/twakePlugin.d.ts +14 -4
  113. package/dist/src/bin/index.d.ts +17 -4
  114. package/dist/src/config/args.d.ts +2 -4
  115. package/dist/src/config/options.d.ts +89 -0
  116. package/dist/src/config/schema.d.ts +50 -1
  117. package/dist/src/hooks.d.ts +60 -22
  118. package/dist/src/lib/authz/base.d.ts +4 -51
  119. package/dist/src/lib/authz/composition.d.ts +2 -2
  120. package/dist/src/lib/entitySchema/validator.d.ts +63 -6
  121. package/dist/src/lib/errors.d.ts +56 -1
  122. package/dist/src/lib/expressFormatedResponses.d.ts +49 -7
  123. package/dist/src/lib/hookBus.d.ts +226 -0
  124. package/dist/src/lib/instanceProviders.d.ts +0 -8
  125. package/dist/src/lib/ldapActions.d.ts +11 -2
  126. package/dist/src/lib/parseConfig.d.ts +5 -0
  127. package/dist/src/lib/route.d.ts +99 -0
  128. package/dist/src/lib/utils.d.ts +37 -36
  129. package/dist/src/lib/version.d.ts +12 -0
  130. package/dist/src/plugins/auth/auth.options.d.ts +88 -0
  131. package/dist/src/plugins/auth/authzDynamic.d.ts +10 -1
  132. package/dist/src/plugins/auth/authzLinid1.d.ts +6 -0
  133. package/dist/src/plugins/auth/authzPerBranch.d.ts +9 -0
  134. package/dist/src/plugins/auth/authzPerRoute.d.ts +3 -0
  135. package/dist/src/plugins/auth/authzScope.d.ts +23 -14
  136. package/dist/src/plugins/auth/crowdsec.d.ts +5 -0
  137. package/dist/src/plugins/auth/fake.d.ts +3 -0
  138. package/dist/src/plugins/auth/hmac.d.ts +4 -0
  139. package/dist/src/plugins/auth/llng.d.ts +4 -0
  140. package/dist/src/plugins/auth/openidconnect.d.ts +7 -0
  141. package/dist/src/plugins/auth/rateLimit.d.ts +4 -0
  142. package/dist/src/plugins/auth/token.d.ts +3 -0
  143. package/dist/src/plugins/auth/totp.d.ts +5 -0
  144. package/dist/src/plugins/auth/trustedProxy.d.ts +4 -0
  145. package/dist/src/plugins/bcl.d.ts +3 -0
  146. package/dist/src/plugins/bcl.options.d.ts +8 -0
  147. package/dist/src/plugins/configApi.d.ts +24 -5
  148. package/dist/src/plugins/demo/helloworld.d.ts +8 -19
  149. package/dist/src/plugins/ldap/accountLifecycle.d.ts +17 -0
  150. package/dist/src/plugins/ldap/bulkImport.d.ts +6 -76
  151. package/dist/src/plugins/ldap/departmentSync.d.ts +1 -0
  152. package/dist/src/plugins/ldap/enterpriseRules.d.ts +8 -1
  153. package/dist/src/plugins/ldap/externalUsersInGroups.d.ts +4 -0
  154. package/dist/src/plugins/ldap/flatGeneric.d.ts +4 -0
  155. package/dist/src/plugins/ldap/groups.d.ts +27 -11
  156. package/dist/src/plugins/ldap/ldap.options.d.ts +75 -0
  157. package/dist/src/plugins/ldap/onChange.d.ts +10 -2
  158. package/dist/src/plugins/ldap/organizations.d.ts +16 -0
  159. package/dist/src/plugins/ldap/passwordPolicy.d.ts +32 -1
  160. package/dist/src/plugins/ldap/raw.d.ts +50 -19
  161. package/dist/src/plugins/ldap/trash.d.ts +6 -0
  162. package/dist/src/plugins/metrics.d.ts +3 -0
  163. package/dist/src/plugins/metrics.options.d.ts +8 -0
  164. package/dist/src/plugins/rabbitmq.d.ts +3 -0
  165. package/dist/src/plugins/rabbitmq.options.d.ts +8 -0
  166. package/dist/src/plugins/scim/baseResolver.d.ts +2 -1
  167. package/dist/src/plugins/scim/bulk.d.ts +6 -7
  168. package/dist/src/plugins/scim/discovery.d.ts +3 -0
  169. package/dist/src/plugins/scim/errors.d.ts +4 -1
  170. package/dist/src/plugins/scim/groups.d.ts +6 -4
  171. package/dist/src/plugins/scim/scim.d.ts +37 -3
  172. package/dist/src/plugins/scim/scim.options.d.ts +35 -0
  173. package/dist/src/plugins/scim/types.d.ts +2 -1
  174. package/dist/src/plugins/scim/users.d.ts +6 -7
  175. package/dist/src/plugins/static.d.ts +9 -0
  176. package/dist/src/plugins/static.options.d.ts +13 -0
  177. package/dist/src/plugins/storage.d.ts +12 -1
  178. package/dist/src/plugins/storage.options.d.ts +16 -0
  179. package/dist/src/plugins/twake/appAccounts.options.d.ts +13 -0
  180. package/dist/src/plugins/twake/appAccountsApi.d.ts +18 -0
  181. package/dist/src/plugins/twake/appAccountsConsistency.d.ts +8 -0
  182. package/dist/src/plugins/twake/calendar.d.ts +25 -2
  183. package/dist/src/plugins/twake/calendar.options.d.ts +19 -0
  184. package/dist/src/plugins/twake/cloudery.options.d.ts +26 -0
  185. package/dist/src/plugins/twake/clouderyProvision.d.ts +18 -0
  186. package/dist/src/plugins/twake/cozy.options.d.ts +23 -0
  187. package/dist/src/plugins/twake/cozyProvision.d.ts +14 -0
  188. package/dist/src/plugins/twake/drive.d.ts +7 -0
  189. package/dist/src/plugins/twake/drive.options.d.ts +15 -0
  190. package/dist/src/plugins/twake/groups.d.ts +30 -3
  191. package/dist/src/plugins/twake/instances.d.ts +43 -10
  192. package/dist/src/plugins/twake/james.d.ts +17 -0
  193. package/dist/src/plugins/twake/james.options.d.ts +21 -0
  194. package/dist/src/plugins/twake/lifecycleEvents.d.ts +12 -0
  195. package/dist/src/plugins/twake/migrationProxy.d.ts +11 -11
  196. package/dist/src/plugins/twake/migrationProxy.options.d.ts +16 -0
  197. package/dist/src/plugins/twake/spaces.d.ts +30 -0
  198. package/dist/src/plugins/twake/tombstone.d.ts +16 -14
  199. package/dist/src/plugins/twake/twakeGroups.options.d.ts +20 -0
  200. package/dist/src/plugins/twake/twakeInstances.options.d.ts +43 -0
  201. package/dist/src/plugins/twake/twakeLifecycle.options.d.ts +21 -0
  202. package/dist/src/plugins/twake/twakeSpaces.options.d.ts +19 -0
  203. package/dist/src/plugins/twake/twakeTombstone.options.d.ts +17 -0
  204. package/docs/README.md +1 -0
  205. package/docs/client-development/api/rest-api.md +9 -3
  206. package/docs/client-development/schemas/README.md +96 -32
  207. package/docs/plugin-development/README.md +45 -94
  208. package/docs/plugin-development/dependencies.md +11 -6
  209. package/docs/plugin-development/hooks.md +142 -23
  210. package/docs/plugin-development/openapi.md +14 -1
  211. package/docs/plugin-development/options.md +109 -0
  212. package/docs/plugin-development/routes.md +152 -0
  213. package/docs/plugin-development/testing.md +3 -3
  214. package/docs/usage/configuration.md +31 -24
  215. package/docs/usage/operations.md +19 -4
  216. package/docs/usage/plugins/integrations/groups.md +2 -2
  217. package/docs/usage/plugins/integrations/scim.md +12 -1
  218. package/docs/usage/plugins/integrations/spaces.md +1 -1
  219. package/docs/usage/plugins/ldap/enterprise-rules.md +10 -1
  220. package/docs/usage/plugins/ldap/flat-generic.md +4 -0
  221. package/docs/usage/plugins/ldap/raw.md +17 -1
  222. package/docs/usage/upgrading.md +207 -0
  223. package/package.json +358 -277
  224. package/static/browser/ldap-browser/LdapBrowser.js +8 -6
  225. package/static/browser/ldap-browser/LdapBrowser.js.map +1 -1
  226. package/static/browser/ldap-browser/api/RawApiClient.js +2 -0
  227. package/static/browser/ldap-browser/api/RawApiClient.js.map +1 -1
  228. package/static/browser/ldap-browser/components/EntryTree.js +9 -5
  229. package/static/browser/ldap-browser/components/EntryTree.js.map +1 -1
  230. package/static/browser/ldap-browser/components/EntryView.js +2 -0
  231. package/static/browser/ldap-browser/components/EntryView.js.map +1 -1
  232. package/static/browser/ldap-browser/schema.js +3 -2
  233. package/static/browser/ldap-browser/schema.js.map +1 -1
  234. package/static/browser/ldap-browser.esm.js +27 -18
  235. package/static/browser/ldap-browser.esm.js.map +1 -1
  236. package/static/browser/ldap-browser.js +27 -18
  237. package/static/browser/ldap-browser.js.map +1 -1
  238. package/static/browser/ldap-browser.min.js +1 -1
  239. package/static/browser/ldap-browser.min.js.map +1 -1
  240. package/static/browser/ldap-group-editor/LdapGroupEditor.js +8 -6
  241. package/static/browser/ldap-group-editor/LdapGroupEditor.js.map +1 -1
  242. package/static/browser/ldap-group-editor/api/GroupApiClient.js +1 -0
  243. package/static/browser/ldap-group-editor/api/GroupApiClient.js.map +1 -1
  244. package/static/browser/ldap-group-editor/components/CreateGroupModal.js +5 -1
  245. package/static/browser/ldap-group-editor/components/CreateGroupModal.js.map +1 -1
  246. package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js +6 -3
  247. package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js.map +1 -1
  248. package/static/browser/ldap-group-editor/components/GroupTree.js +6 -3
  249. package/static/browser/ldap-group-editor/components/GroupTree.js.map +1 -1
  250. package/static/browser/ldap-group-editor/components/MoveGroupModal.js +6 -3
  251. package/static/browser/ldap-group-editor/components/MoveGroupModal.js.map +1 -1
  252. package/static/browser/ldap-group-editor.esm.js +32 -16
  253. package/static/browser/ldap-group-editor.esm.js.map +1 -1
  254. package/static/browser/ldap-group-editor.js +32 -16
  255. package/static/browser/ldap-group-editor.js.map +1 -1
  256. package/static/browser/ldap-group-editor.min.js +1 -1
  257. package/static/browser/ldap-group-editor.min.js.map +1 -1
  258. package/static/browser/ldap-resource-editor/api/ResourceApiClient.js +3 -0
  259. package/static/browser/ldap-resource-editor/api/ResourceApiClient.js.map +1 -1
  260. package/static/browser/ldap-resource-editor/cache/CacheManager.js +3 -1
  261. package/static/browser/ldap-resource-editor/cache/CacheManager.js.map +1 -1
  262. package/static/browser/ldap-tree-viewer/LdapTreeViewer.js +6 -1
  263. package/static/browser/ldap-tree-viewer/LdapTreeViewer.js.map +1 -1
  264. package/static/browser/ldap-tree-viewer/api/LdapApiClient.js +2 -0
  265. package/static/browser/ldap-tree-viewer/api/LdapApiClient.js.map +1 -1
  266. package/static/browser/ldap-tree-viewer/components/TreeNode.js +4 -0
  267. package/static/browser/ldap-tree-viewer/components/TreeNode.js.map +1 -1
  268. package/static/browser/ldap-tree-viewer/components/TreeRoot.js +3 -0
  269. package/static/browser/ldap-tree-viewer/components/TreeRoot.js.map +1 -1
  270. package/static/browser/ldap-tree-viewer/store/Store.js +3 -1
  271. package/static/browser/ldap-tree-viewer/store/Store.js.map +1 -1
  272. package/static/browser/ldap-tree-viewer.esm.js +18 -2
  273. package/static/browser/ldap-tree-viewer.esm.js.map +1 -1
  274. package/static/browser/ldap-tree-viewer.js +18 -2
  275. package/static/browser/ldap-tree-viewer.js.map +1 -1
  276. package/static/browser/ldap-tree-viewer.min.js +1 -1
  277. package/static/browser/ldap-tree-viewer.min.js.map +1 -1
  278. package/static/browser/ldap-unit-editor/LdapUnitEditor.js +7 -5
  279. package/static/browser/ldap-unit-editor/LdapUnitEditor.js.map +1 -1
  280. package/static/browser/ldap-unit-editor/api/UnitApiClient.js +1 -0
  281. package/static/browser/ldap-unit-editor/api/UnitApiClient.js.map +1 -1
  282. package/static/browser/ldap-unit-editor/components/MoveUnitModal.js +7 -4
  283. package/static/browser/ldap-unit-editor/components/MoveUnitModal.js.map +1 -1
  284. package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js +7 -4
  285. package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js.map +1 -1
  286. package/static/browser/ldap-unit-editor/components/UnitTree.js +6 -3
  287. package/static/browser/ldap-unit-editor/components/UnitTree.js.map +1 -1
  288. package/static/browser/ldap-unit-editor.esm.js +28 -16
  289. package/static/browser/ldap-unit-editor.esm.js.map +1 -1
  290. package/static/browser/ldap-unit-editor.js +28 -16
  291. package/static/browser/ldap-unit-editor.js.map +1 -1
  292. package/static/browser/ldap-unit-editor.min.js +1 -1
  293. package/static/browser/ldap-unit-editor.min.js.map +1 -1
  294. package/static/browser/ldap-user-editor/LdapUserEditor.js +9 -7
  295. package/static/browser/ldap-user-editor/LdapUserEditor.js.map +1 -1
  296. package/static/browser/ldap-user-editor/api/UserApiClient.js +2 -0
  297. package/static/browser/ldap-user-editor/api/UserApiClient.js.map +1 -1
  298. package/static/browser/ldap-user-editor/cache/CacheManager.js +3 -1
  299. package/static/browser/ldap-user-editor/cache/CacheManager.js.map +1 -1
  300. package/static/browser/ldap-user-editor/components/MoveUserModal.js +7 -4
  301. package/static/browser/ldap-user-editor/components/MoveUserModal.js.map +1 -1
  302. package/static/browser/ldap-user-editor/components/PointerField.js +6 -1
  303. package/static/browser/ldap-user-editor/components/PointerField.js.map +1 -1
  304. package/static/browser/ldap-user-editor/components/UserEditor.js +10 -5
  305. package/static/browser/ldap-user-editor/components/UserEditor.js.map +1 -1
  306. package/static/browser/ldap-user-editor/components/UserList.js +8 -4
  307. package/static/browser/ldap-user-editor/components/UserList.js.map +1 -1
  308. package/static/browser/ldap-user-editor/components/UserTree.js +7 -3
  309. package/static/browser/ldap-user-editor/components/UserTree.js.map +1 -1
  310. package/static/browser/ldap-user-editor.esm.js +55 -30
  311. package/static/browser/ldap-user-editor.esm.js.map +1 -1
  312. package/static/browser/ldap-user-editor.js +55 -30
  313. package/static/browser/ldap-user-editor.js.map +1 -1
  314. package/static/browser/ldap-user-editor.min.js +1 -1
  315. package/static/browser/ldap-user-editor.min.js.map +1 -1
  316. package/static/browser/shared/components/DisposableComponent.js +3 -5
  317. package/static/browser/shared/components/DisposableComponent.js.map +1 -1
  318. package/static/browser/shared/components/Modal.js +2 -1
  319. package/static/browser/shared/components/Modal.js.map +1 -1
  320. package/static/browser/shared/components/StatusMessage.js +3 -2
  321. package/static/browser/shared/components/StatusMessage.js.map +1 -1
  322. package/static/browser/shared/utils/form.js.map +1 -1
  323. package/static/browser/shared/utils/hmac.js +1 -0
  324. package/static/browser/shared/utils/hmac.js.map +1 -1
  325. package/static/browser/shared/utils/totp.js +1 -0
  326. package/static/browser/shared/utils/totp.js.map +1 -1
  327. package/static/browser/shared.esm.js +9 -8
  328. package/static/browser/shared.esm.js.map +1 -1
  329. package/static/browser/shared.js +9 -8
  330. package/static/browser/shared.js.map +1 -1
  331. package/static/browser/shared.min.js +1 -1
  332. package/static/browser/shared.min.js.map +1 -1
  333. package/static/schemas/ad/groups.json +1 -1
  334. package/static/schemas/ad/users.json +3 -3
  335. package/static/schemas/example/organizations.json +2 -2
  336. package/static/schemas/example/users.json +2 -2
  337. package/static/schemas/obm/users.json +2 -2
  338. package/static/schemas/standard/groups.json +1 -1
  339. package/static/schemas/standard/users.json +2 -2
  340. package/static/schemas/twake/groups.json +4 -4
  341. package/static/schemas/twake/teamMailboxes.json +3 -3
  342. package/static/schemas/twake/users.json +7 -7
@@ -10,8 +10,9 @@ import type { SearchOptions } from 'ldapts';
10
10
  import DmPlugin, { type Role } from '../../abstract/plugin';
11
11
  import type { DM } from '../../bin';
12
12
  import type { BranchPermissions } from '../../config/args';
13
+ import type { Hooks } from '../../hooks';
13
14
  import { type DmRequest } from '../auth/base';
14
- import type { AttributesList, ModifyRequest, SearchResult } from '../ldapActions';
15
+ import type { ModifyRequest } from '../ldapActions';
15
16
  /**
16
17
  * The rule of the most specific configured branch holding `target`.
17
18
  *
@@ -311,7 +312,7 @@ export default abstract class AuthzBase extends DmPlugin {
311
312
  *
312
313
  * @param req the request being authorized, which carries an identity
313
314
  * @returns the resolved user, or null when the policy is to allow it
314
- * @throws ForbiddenError when the policy is to deny it
315
+ * @throws AuthzRefusedError when the policy is to deny it
315
316
  */
316
317
  /** Said once: a rule keyed on a value the authenticator did not publish. */
317
318
  private fallbackWarned;
@@ -382,53 +383,5 @@ export default abstract class AuthzBase extends DmPlugin {
382
383
  /**
383
384
  * Common hooks for all authorization plugins
384
385
  */
385
- hooks: {
386
- /**
387
- * A rename moves the entry an identity resolves to, so what was
388
- * resolved is dropped.
389
- *
390
- * `authzLinid1` keys its permissions on the administrator's DN: renamed
391
- * or moved, they resolve to a DN no organization names any more, and
392
- * every operation of theirs is refused until the TTL runs out. The
393
- * whole map goes rather than one key, since what is cached is
394
- * identity → DN and the hook carries DNs: a handful of lookups is
395
- * cheaper than working out which identity moved.
396
- */
397
- ldaprenamedone: () => void;
398
- /**
399
- * A delete removes the entry an identity resolves to, exactly as a
400
- * rename moves it, so what was resolved is dropped the same way.
401
- *
402
- * An administrator deleted through the API is, for `authzLinid1`, still
403
- * resolved to the former DN where the organization still names them:
404
- * their session keeps its rights until the TTL runs out. Like the rename
405
- * hook, the whole map goes rather than one key — the hook carries the
406
- * deleted DN, and the cache keys identities, so a handful of lookups is
407
- * cheaper than working out which identity the DN held.
408
- */
409
- ldapdeletedone: () => void;
410
- ldapmodifyrequest: ([dn, changes, opNumber, req]: [string, ModifyRequest, number, DmRequest?]) => Promise<[string, ModifyRequest, number, DmRequest?]>;
411
- ldapaddrequest: ([dn, entry, req]: [string, AttributesList, DmRequest?]) => Promise<[string, AttributesList, DmRequest?]>;
412
- ldapsearchrequest: ([base, opts, req]: [string, SearchOptions, DmRequest?]) => Promise<[string, SearchOptions, DmRequest?]>;
413
- /**
414
- * Drop what this caller may not read from a search it was granted.
415
- *
416
- * Judged by branch, the search was granted on its base: each entry is
417
- * kept only where the caller may read it, a rule narrower than the base
418
- * refusing part of what it holds. Judged by attachment, the accounts
419
- * attached outside the branches this caller manages are dropped.
420
- *
421
- * Runs after the cache and carries the request, so what one caller may
422
- * not see never reaches another. An entry with no organization link —
423
- * an organization, a group, a nomenclature value — is left alone: those
424
- * are the reference data every administrator reads.
425
- *
426
- * So is an entry attached to the transit branch: it is waiting for an
427
- * administrator to claim it.
428
- */
429
- ldapsearchfilter: ([result, req, opts]: [SearchResult, DmRequest?, SearchOptions?]) => Promise<[SearchResult, DmRequest?, SearchOptions?]>;
430
- getOrganisationTop: ([req, defaultTop]: [DmRequest | undefined, AttributesList | null]) => Promise<[DmRequest | undefined, AttributesList | null]>;
431
- ldaprenamerequest: ([oldDn, newDn, req]: [string, string, DmRequest?]) => Promise<[string, string, DmRequest?]>;
432
- ldapdeleterequest: ([dn, req]: [string | string[], DmRequest?]) => Promise<[string | string[], DmRequest?]>;
433
- };
386
+ hooks: Hooks;
434
387
  }
@@ -5,8 +5,8 @@
5
5
  * How authorization plugins loaded together compose, and the configurations
6
6
  * where that composition is nobody's decision.
7
7
  *
8
- * Every plugin judging LDAP operations registers the same hooks, and
9
- * `launchHooksChained` runs them all: two of them compose as an AND, the
8
+ * Every plugin judging LDAP operations registers the same hooks, and the
9
+ * chain runs them all: two of them compose as an AND, the
10
10
  * first refusal winning. That is a sound rule when it is meant. It is a
11
11
  * refusal nobody can explain when it is not — `authzPerBranch` beside
12
12
  * `authzDynamic` judges a machine token by a branch configuration written
@@ -22,19 +22,76 @@ export declare class EntityValidator {
22
22
  private readonly deps;
23
23
  constructor(schema: Schema | undefined, deps: EntityValidatorDeps);
24
24
  /**
25
- * Check a new entry, then convert it in place for the directory.
25
+ * Check a new entry, then convert it for the directory. Every attribute
26
+ * the schema declares is named as the schema does, a form the defaults,
27
+ * the required check and the conversion all read.
26
28
  *
27
29
  * @param entry entry as the client sent it, `objectClass` included
30
+ * @returns the entry to write: the one given, or a copy under the schema's
31
+ * spellings
28
32
  */
29
- validateNew(entry: AttributesList): Promise<void>;
33
+ validateNew(entry: AttributesList): Promise<AttributesList>;
30
34
  /**
31
- * Check the parts of a change, then convert them in place. No value under
32
- * a name is the empty list for the directory layer, which clears the
33
- * attribute in a `replace` and refuses it in an `add`.
35
+ * Check the parts of a change, then convert them. Under a name the schema
36
+ * declares, no value becomes the empty list, which clears the attribute
37
+ * in a `replace` and is refused in an `add`; under a name it does not
38
+ * declare, a `null` is dropped from an `add` and becomes that empty list
39
+ * in a `replace`.
34
40
  *
35
41
  * @param changes change as the client sent it
42
+ * @returns the same change, under the schema's spellings
36
43
  */
37
- validateChanges(changes: ModifyRequest): Promise<void>;
44
+ validateChanges(changes: ModifyRequest): Promise<ModifyRequest>;
45
+ /**
46
+ * Name every key the schema declares as the schema does, and refuse two
47
+ * keys naming one attribute. The conversion, the required check and the
48
+ * defaults look a declared attribute up by its own name: a field they
49
+ * would leave out is one the client sent under another case or with a
50
+ * `;binary` option.
51
+ *
52
+ * @returns the same attributes, renamed: the map itself when nothing
53
+ * changes, a copy renamed otherwise
54
+ * @throws BadRequestError when two keys name the same attribute
55
+ */
56
+ private renameDeclared;
57
+ /**
58
+ * {@link renameDeclared} on a list of names, such as a `delete`.
59
+ *
60
+ * Two names of one attribute are refused as the routes refuse them: as
61
+ * the schema declares it, or as this server knows the attribute by its
62
+ * name, which makes `l;binary` and `L` one attribute.
63
+ */
64
+ private renameDeclaredNames;
65
+ /**
66
+ * The attribute a name holds, case and option aside: the option is a
67
+ * transfer syntax, and `l;binary` is the `l` a plain `L` names.
68
+ */
69
+ private attributeIdentity;
70
+ /**
71
+ * The schema's spelling of a declared attribute, with the `;binary`
72
+ * option, the only one a write takes, written as the directory writes it.
73
+ */
74
+ private schemaSpelling;
75
+ /**
76
+ * Drop, in place, the keys a creation or an `add` carries with `null` or
77
+ * `undefined` under a name the schema does not declare. A declared
78
+ * attribute is left to the schema, which turns no value into the empty
79
+ * list, refused for a `required` one; an undeclared one has no such step,
80
+ * and without a schema none exists. The write would otherwise carry
81
+ * `[null]`, which ldapts cannot send.
82
+ */
83
+ private dropUndeclaredEmpty;
84
+ /**
85
+ * Check every value of a creation or of a part of a change, then write the
86
+ * shape each one is stored in, in place: no value becomes the empty list,
87
+ * which clears the attribute in a `replace`. A value the schema does not
88
+ * declare is left as sent on a change, and on a creation as the directory
89
+ * layer takes it.
90
+ *
91
+ * @param values entry of a creation, or `add` / `replace` of a change
92
+ * @param part the part of a change, undefined for a creation
93
+ */
94
+ private checkValues;
38
95
  /**
39
96
  * Check one value against its attribute's rules: its shape, then the
40
97
  * entries a pointer names, then the pattern.
@@ -59,6 +59,61 @@ export declare const errorBody: (err: unknown, message: string) => {
59
59
  export declare class ForbiddenError extends HttpError {
60
60
  constructor(message?: string);
61
61
  }
62
+ /**
63
+ * An authorization plugin's refusal.
64
+ *
65
+ * Its message is for the operator, not for the client: it names the model
66
+ * and the branch it judged, which the caller may not know of. Its class is
67
+ * what says an authorization plugin refused, so the 403 is recognised
68
+ * through the `new Error(\`…\`, { cause })` wrappers along the way — see
69
+ * {@link isAuthzRefusal} — and the client is told {@link AUTHZ_REFUSED}.
70
+ */
71
+ export declare class AuthzRefusedError extends ForbiddenError {
72
+ /**
73
+ * Read instead of the class and the name: a plugin loaded from `dist` holds
74
+ * another copy of this module, where `instanceof` answers false, and a
75
+ * subclass may replace `name`.
76
+ */
77
+ readonly authzRefusal: true;
78
+ constructor(message: string);
79
+ }
80
+ /**
81
+ * Every error in a chain of `cause`s, the outermost first.
82
+ *
83
+ * A plugin wrapping what the directory or an authorization hook threw as
84
+ * `new Error(\`…\`, { cause: err })` keeps the reason and what it carries:
85
+ * its class, its status, the database's refusal. The serializers read the
86
+ * whole chain rather than the wrapper alone.
87
+ *
88
+ * @param err what was thrown, which need not be an error
89
+ * @returns the errors of the chain, the outermost first
90
+ */
91
+ export declare const errorChain: (err: unknown) => Error[];
92
+ /**
93
+ * Whether an error is, or wraps through `cause`, an authorization plugin's
94
+ * refusal.
95
+ *
96
+ * Read by the `authzRefusal` marker rather than by class: a plugin loaded
97
+ * from `dist` while its caller runs from `src` throws a `AuthzRefusedError`
98
+ * whose `instanceof` answers false, and a subclass that replaces `name`
99
+ * would escape a name test — the refusal would then be answered as the
100
+ * wrapper's own error.
101
+ *
102
+ * @param err what was thrown
103
+ * @returns true for a refusal, or for an error wrapping one
104
+ */
105
+ export declare const isAuthzRefusal: (err: unknown) => boolean;
106
+ /**
107
+ * The status a thrown thing is answered with.
108
+ *
109
+ * The first error from the outside that names one decides: a wrapper names
110
+ * none, so the error it wraps is read; a layer that translates an inner error
111
+ * keeps its own status.
112
+ *
113
+ * @param err what was thrown
114
+ * @returns its status code, 500 when it names none
115
+ */
116
+ export declare const statusCodeOf: (err: unknown) => number;
62
117
  /**
63
118
  * An identity that names more than one directory entry.
64
119
  *
@@ -69,7 +124,7 @@ export declare class ForbiddenError extends HttpError {
69
124
  * rather than a `null`: a `null` resolution is what
70
125
  * `--authz-unresolved-user allow` lets through unchecked.
71
126
  */
72
- export declare class AmbiguousIdentityError extends ForbiddenError {
127
+ export declare class AmbiguousIdentityError extends AuthzRefusedError {
73
128
  identity: string;
74
129
  count: number;
75
130
  constructor(identity: string, count: number);
@@ -1,9 +1,6 @@
1
- /**
2
- * Standard express responses and express utilities
3
- * @author Xavier Guimard <xguimard@linagora.com>
4
- */
5
1
  import type { Request, Response } from 'express';
6
2
  import type winston from 'winston';
3
+ import { type Refusal } from './errors';
7
4
  /**
8
5
  * Install the logger, or remove it: a test restores the state it found,
9
6
  * which before any `DM` is none.
@@ -21,9 +18,47 @@ export declare const getLogger: () => winston.Logger | undefined;
21
18
  */
22
19
  export declare const setDebug: (debug: boolean) => void;
23
20
  /**
24
- * The body of a 5xx answer, for the error middleware of `DM` and
25
- * `serverError` alike. The failure is for the logs: the message names it
26
- * only under `--debug`.
21
+ * The sentence a client is told of a client error: an authorization
22
+ * plugin's refusal says nothing of the branch it judged.
23
+ *
24
+ * Any other client error keeps the sentence of the outermost error, the one
25
+ * the route threw when it gave up: it says what the caller's request was
26
+ * about, which the `HttpError` several layers down does not.
27
+ *
28
+ * @param err what was thrown
29
+ * @returns the sentence to answer
30
+ */
31
+ export declare const clientMessageOf: (err: unknown) => string;
32
+ /**
33
+ * The message of a thrown thing, read the way the log reads it.
34
+ *
35
+ * @param err what was thrown
36
+ * @returns its message, or the value as a string
37
+ */
38
+ export declare const messageOf: (err: unknown) => string;
39
+ /**
40
+ * What an error is answered with, for the error middleware of `DM` and
41
+ * `serverError` alike: one status and one body, wherever the handler called
42
+ * a helper or threw.
43
+ *
44
+ * An authorization plugin's refusal loses its status when a plugin wraps it
45
+ * as a plain `Error`; it is still a 403, whatever the wrapper says. The
46
+ * failure of a 5xx is for the logs, and is named in the body only under
47
+ * `--debug`.
48
+ *
49
+ * @param err what failed
50
+ * @param debug whether to name a failure in the answer
51
+ * @returns the status and body to answer
52
+ */
53
+ export declare const errorResponse: (err: unknown, debug?: boolean) => {
54
+ status: number;
55
+ body: {
56
+ error: string;
57
+ } & Partial<Refusal>;
58
+ };
59
+ /**
60
+ * The body of a 5xx answer, for every status answered when the failure is
61
+ * the server's: the message names the failure only under `--debug`.
27
62
  *
28
63
  * @param err what failed
29
64
  * @param debug whether to name the failure; `serverError`'s setting by default
@@ -34,6 +69,13 @@ export declare const serverErrorBody: (err: unknown, debug?: boolean) => {
34
69
  };
35
70
  export declare const tryMethod: (res: Response, method: Function, ...args: unknown[]) => Promise<void>;
36
71
  export declare const tryMethodData: (res: Response, method: Function, ...args: unknown[]) => Promise<void>;
72
+ /**
73
+ * The answer of a route that changed something and returned nothing: the
74
+ * shape every write route declares as its 200.
75
+ */
76
+ export declare const WriteResponse: import("@sinclair/typebox").TObject<{
77
+ success: import("@sinclair/typebox").TBoolean;
78
+ }>;
37
79
  export declare const ok: (res: Response, data?: object) => void;
38
80
  export declare const created: (res: Response, data?: object) => void;
39
81
  export declare const noContent: (res: Response) => void;
@@ -0,0 +1,226 @@
1
+ /**
2
+ * The hooks of the server, typed by `Hooks`, with one calling convention per
3
+ * kind.
4
+ *
5
+ * The three kinds are told apart by what their subscriber answers:
6
+ * chained hooks get a value and pass it — possibly changed — along the
7
+ * chain; notified hooks answer nothing, are not waited for, and their
8
+ * failures are logged; several hooks answer a value each.
9
+ *
10
+ * @see docs/plugin-development/hooks.md
11
+ */
12
+ import type { Hooks } from '../hooks';
13
+ export type HookFn = Function;
14
+ /** A promise, or the value itself */
15
+ type Settled<T> = T extends Promise<infer P> ? P : T;
16
+ /** Whether `F` answers nothing: `void`, or a promise of it */
17
+ export type AnswersVoid<F> = [
18
+ Settled<F extends (...args: never[]) => infer R ? R : never>
19
+ ] extends [void | undefined] ? true : false;
20
+ /** The values of `Hooks` a chain threads: the ones whose answer is a value */
21
+ export type ChainedName = {
22
+ [K in keyof Hooks]-?: AnswersVoid<NonNullable<Hooks[K]>> extends true ? never : K;
23
+ }[keyof Hooks];
24
+ /** The `Hooks` a notification fires: the ones whose subscriber answers nothing */
25
+ export type NotifiedName = Exclude<keyof Hooks, ChainedName>;
26
+ /** A chained hook is declared with the value it threads */
27
+ export type ChainedNameOf<K extends keyof Hooks> = K extends ChainedName ? K : never;
28
+ /** The arguments a hook expects */
29
+ export type Args<K extends keyof Hooks> = NonNullable<Hooks[K]> extends (...args: infer A) => unknown ? A : never;
30
+ /** What a chained hook threads */
31
+ export type ChainedValue<K extends keyof Hooks> = NonNullable<Hooks[K]> extends (arg: infer A) => unknown ? A : never;
32
+ /**
33
+ * Record the plugin a hook function belongs to.
34
+ *
35
+ * @param fn the registered function
36
+ * @param plugin the plugin's instance name
37
+ * @param hook the hook it is registered under
38
+ */
39
+ export declare const recordHookOwner: (fn: HookFn, plugin: string, hook: string) => void;
40
+ /**
41
+ * The plugin a hook function belongs to, and the hook it is registered
42
+ * under, when `registerPlugin` registered it.
43
+ *
44
+ * @param fn a hook function
45
+ * @returns its plugin's instance name and hook name, or undefined
46
+ */
47
+ export declare const hookOwner: (fn: HookFn) => {
48
+ plugin: string;
49
+ hook: string;
50
+ } | undefined;
51
+ /**
52
+ * Run a hook under its plugin's name and its own, for the lines it logs.
53
+ *
54
+ * @param hook the registered function
55
+ * @param fn its run
56
+ * @returns what `fn` returns
57
+ */
58
+ export declare const runAsHookOwner: <T>(hook: HookFn, fn: () => T) => T;
59
+ /**
60
+ * A hook's list, as `server.hooks` spells it: `undefined` when nothing is
61
+ * subscribed, a function for one subscriber, a list for several, and
62
+ * anything else when a test writes a list through the hook and walks it.
63
+ */
64
+ export type HookValue<K extends keyof Hooks = keyof Hooks> = Hooks[K] | Function[] | undefined;
65
+ /** The functions a subscriber value holds, one or many */
66
+ export declare const asHooks: <K extends keyof Hooks>(value: HookValue<K>) => HookFn[];
67
+ /**
68
+ * How a flat entity raises its own hooks, see `abstract/ldapFlat.ts`: the
69
+ * prefix it names them under, added to the suffix of each. They are not
70
+ * `Hooks`' own, see {@link FlatHookPrefix}.
71
+ */
72
+ export interface FlatHookBus {
73
+ /** Thread a value through `{prefix}{suffix}`, as {@link HookBus.chain} */
74
+ chain<T>(suffix: string, value: T): Promise<T>;
75
+ /** Notify `{prefix}{suffix}`, as {@link HookBus.notify} */
76
+ notify(suffix: string, ...args: unknown[]): void;
77
+ }
78
+ export default class HookBus implements FlatHookBus {
79
+ /**
80
+ * What `server.hooks` holds, shared by reference. A plugin reaching it
81
+ * directly is not told by its type whether the hook exists, nor how it
82
+ * is called; this bus is.
83
+ */
84
+ private readonly hooks;
85
+ private readonly tracked;
86
+ /**
87
+ * @param hooks the server's hook lists, shared by reference
88
+ */
89
+ constructor(hooks: {
90
+ [K in keyof Hooks]?: HookValue<K>;
91
+ });
92
+ /** Whether anything is subscribed to a hook */
93
+ has(name: keyof Hooks): boolean;
94
+ /**
95
+ * The subscribers of a hook, in the order they run.
96
+ *
97
+ * @param name the hook
98
+ * @returns its subscribers, empty when nothing subscribed
99
+ */
100
+ subscribers(name: keyof Hooks): readonly HookFn[];
101
+ /**
102
+ * Subscribe a function to a hook, or forget its subscribers when given
103
+ * none, as a plugin declaring `hooks` would.
104
+ *
105
+ * @param name the hook
106
+ * @param fn what to run, none to unsubscribe every subscriber
107
+ */
108
+ set<K extends keyof Hooks>(name: K, ...fn: NonNullable<Hooks[K]>[]): void;
109
+ /**
110
+ * Add a subscriber to a hook, after the ones already there.
111
+ *
112
+ * @param name the hook
113
+ * @param fn what to run
114
+ */
115
+ subscribe<K extends keyof Hooks>(name: K, fn: NonNullable<Hooks[K]>): void;
116
+ /**
117
+ * Put a subscriber at a given place in a hook's list, as
118
+ * `registerPlugin` does for an authorization hook.
119
+ *
120
+ * @param name the hook
121
+ * @param fn what to run
122
+ * @param at its place, the end when past it
123
+ */
124
+ insert<K extends keyof Hooks>(name: K, fn: NonNullable<Hooks[K]>, at: number): void;
125
+ /**
126
+ * Remove a subscriber from a hook, wherever it sits.
127
+ *
128
+ * @param name the hook
129
+ * @param fn the subscriber
130
+ */
131
+ unsubscribe<K extends keyof Hooks>(name: K, fn: NonNullable<Hooks[K]>): void;
132
+ /**
133
+ * Move a subscriber to the end of its hook's list, keeping it registered,
134
+ * for a plugin that must run after every other one.
135
+ *
136
+ * @param name the hook
137
+ * @param hook the subscriber
138
+ * @returns whether it was subscribed to the hook
139
+ */
140
+ toLast(name: keyof Hooks, hook: HookFn): boolean;
141
+ /**
142
+ * Thread a value through every subscriber of a chained hook, each getting
143
+ * what the one before answered. The first failure stops the chain and
144
+ * travels up: a refusal is a refusal, and the caller must not go on as if
145
+ * the chain had said yes.
146
+ *
147
+ * Hooks run outside the request being served: what a hook reads or writes
148
+ * to validate, complete or keep track of an operation is the server's
149
+ * (#385). The request is in the arguments of the hooks that judge, which
150
+ * judge by it; a hook acting as the caller names it.
151
+ *
152
+ * @param name the hook
153
+ * @param value the value to thread
154
+ * @returns the last value in the chain
155
+ */
156
+ chain<K extends keyof Hooks>(name: ChainedNameOf<K>, value: ChainedValue<K>): Promise<ChainedValue<K>>;
157
+ /**
158
+ * Notify every subscriber of a hook, one after the other, outside the
159
+ * request that caused it: they are told what happened, and was judged, and
160
+ * react as the server — synchronizing, publishing, keeping invariants —
161
+ * whoever asked.
162
+ *
163
+ * Not awaited, and not failed: the write the subscribers react to is done,
164
+ * and a subscriber's failure is logged and goes no further. `settled`
165
+ * waits for them.
166
+ *
167
+ * @param name the hook
168
+ * @param args what its subscribers are told
169
+ */
170
+ notify<K extends NotifiedName>(name: K, ...args: Args<K>): void;
171
+ /**
172
+ * Run every subscriber of a hook and let their failures go to the caller,
173
+ * for the rare hook whose subscribers are part of the answer: a logout
174
+ * token reaches the provider only once what it closes is recorded, so the
175
+ * failure has to reach the library, which answers 400 and lets the
176
+ * provider retry.
177
+ *
178
+ * Every subscriber runs even when one fails, one after the other as
179
+ * `notify` runs them, and the first failure is raised once they all have:
180
+ * stopping at the first would cost the others their turn — a session the
181
+ * provider considers closed would keep working against the store that
182
+ * would have killed it.
183
+ *
184
+ * @param name the hook
185
+ * @param args what its subscribers are told
186
+ */
187
+ notifyStrict<K extends NotifiedName>(name: K, ...args: Args<K>): Promise<void>;
188
+ /**
189
+ * Notify, then wait for the subscribers: a caller that has to know the
190
+ * consequences have run, a test instead of a sleep.
191
+ *
192
+ * @param name the hook
193
+ * @param args what its subscribers are told
194
+ * @returns once they have returned
195
+ */
196
+ notifyAndWait<K extends NotifiedName>(name: K, ...args: Args<K>): Promise<void>;
197
+ /**
198
+ * Run every hook the server holds and answer what each gives, in order.
199
+ * For the hooks nothing decided the answer of: `hello` is a demo of one.
200
+ *
201
+ * @param name the hook
202
+ * @param args what its subscribers are given
203
+ * @returns one answer per subscriber
204
+ */
205
+ call<K extends keyof Hooks>(name: K, ...args: Args<K>): Promise<unknown[]>;
206
+ /**
207
+ * A view raising `{prefix}{suffix}` hooks, for an entity whose hooks are
208
+ * named dynamically.
209
+ *
210
+ * @param prefix the entity's prefix
211
+ * @returns the bus, raising its hooks
212
+ */
213
+ prefixed(prefix: string): FlatHookBus;
214
+ /**
215
+ * Resolves when every notification started so far has run, the ones
216
+ * started while waiting included.
217
+ */
218
+ settled(): Promise<void>;
219
+ /**
220
+ * Write a hook's subscribers the way `server.hooks` spells them: no entry
221
+ * when nothing is subscribed, the function itself for one subscriber.
222
+ */
223
+ private store;
224
+ private fire;
225
+ }
226
+ export {};
@@ -1,11 +1,3 @@
1
- /**
2
- * @module lib/instanceProviders
3
- *
4
- * The two places a workplace instance can be created: the Cloudery, which
5
- * answers at once and builds the instance afterwards, and the cozy-stack
6
- * admin API, which builds it before answering.
7
- */
8
- import { type RequestInit, type Response } from 'node-fetch';
9
1
  /**
10
2
  * Reduce a name to what the Cloudery takes in a slug; it refused `_` or `@`
11
3
  * with "Slug is invalid". `-` is kept, except at either end where no host
@@ -100,6 +100,8 @@ declare class ldapActions {
100
100
  private attrSignatureCache;
101
101
  private waitingResolvers;
102
102
  private availableConnections;
103
+ /** Connections being opened, not yet in `connectionPool` */
104
+ private opening;
103
105
  private isCleaningUp;
104
106
  /** See {@link declareObjectClasses}. */
105
107
  private declaredClasses;
@@ -156,9 +158,14 @@ declare class ldapActions {
156
158
  busy: number;
157
159
  idle: number;
158
160
  waiting: number;
161
+ opening: number;
159
162
  max: number;
160
163
  };
161
164
  private takeConnection;
165
+ /** Refuse every queued request with `error` */
166
+ private refuseWaiters;
167
+ /** Let one queued request take a place that freed with no connection */
168
+ private wakeWaiter;
162
169
  /**
163
170
  * Release a connection back to the pool
164
171
  * If there are waiting requests, hand off the connection directly
@@ -363,10 +370,12 @@ declare class ldapActions {
363
370
  * the directory applies both, and only one would have been judged.
364
371
  *
365
372
  * Without the schema, the case is still set, and a name given as an OID,
366
- * which nothing here could resolve, is refused.
373
+ * which nothing here could resolve, is refused. So is, with or without
374
+ * it, a name that is neither a descriptor nor a numeric OID.
367
375
  *
368
376
  * @param entry attributes of an add, or one part of a modify
369
- * @throws BadRequestError on an option, or on one attribute named twice
377
+ * @throws BadRequestError on an option, on a name that describes no
378
+ * attribute, or on one attribute named twice
370
379
  */
371
380
  canonicalAttributes(entry: AttributesList | undefined): Promise<void>;
372
381
  /**
@@ -17,9 +17,14 @@ export type ConfigEntry = [
17
17
  ];
18
18
  export declare class ConfigParser {
19
19
  private config;
20
+ /** CLI arguments no entry declared, kept in `Config` by the parser */
21
+ private unknownArgs;
22
+ get unknownOptions(): string[];
20
23
  constructor(config: ConfigTemplate);
21
24
  parse(argv?: string[]): Config;
22
25
  private parseCliArgs;
23
26
  private getKeyFromCliArg;
24
27
  }
28
+ export declare function splitValue(value: string, kind: ArrayKind | undefined, form: 'singular' | 'plural'): string[];
29
+ export declare function parseNumber(value: string): number;
25
30
  export declare function parseConfig(config: ConfigEntry[], argv?: string[]): Config;