ldap-rest 1.2.1 → 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.
- package/bin/sync-james.mjs +13 -2
- package/dist/abstract/ldapFlat.js +1 -1
- package/dist/abstract/plugin.js +1 -1
- package/dist/abstract/twakePlugin.js +1 -1
- package/dist/bin/index.js +1 -1
- package/dist/config/args.js +1 -1
- package/dist/config/options.js +1 -0
- package/dist/config/schema.js +1 -1
- package/dist/lib/auth/base.js +1 -1
- package/dist/lib/authz/base.js +1 -1
- package/dist/lib/entitySchema/validator.js +1 -1
- package/dist/lib/errors.js +1 -1
- package/dist/lib/expressFormatedResponses.js +1 -1
- package/dist/lib/health.js +1 -1
- package/dist/lib/hookBus.js +1 -0
- package/dist/lib/instanceProviders.js +1 -1
- package/dist/lib/ldapActions.js +1 -1
- package/dist/lib/ldapSchema.js +1 -1
- package/dist/lib/parseConfig.js +1 -1
- package/dist/lib/route.js +1 -0
- package/dist/lib/schemaFile.js +1 -1
- package/dist/lib/storage/store.js +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/lib/version.js +1 -0
- package/dist/logger/winston.js +1 -1
- package/dist/plugins/auth/auth.options.js +1 -0
- package/dist/plugins/auth/authzDynamic.js +1 -1
- package/dist/plugins/auth/authzLinid1.js +1 -1
- package/dist/plugins/auth/authzPerBranch.js +1 -1
- package/dist/plugins/auth/authzPerRoute.js +1 -1
- package/dist/plugins/auth/authzScope.js +1 -1
- package/dist/plugins/auth/crowdsec.js +1 -1
- package/dist/plugins/auth/fake.js +1 -1
- package/dist/plugins/auth/hmac.js +1 -1
- package/dist/plugins/auth/llng.js +1 -1
- package/dist/plugins/auth/openidconnect.js +1 -1
- package/dist/plugins/auth/rateLimit.js +1 -1
- package/dist/plugins/auth/token.js +1 -1
- package/dist/plugins/auth/totp.js +1 -1
- package/dist/plugins/auth/trustedProxy.js +1 -1
- package/dist/plugins/bcl.js +1 -1
- package/dist/plugins/bcl.options.js +1 -0
- package/dist/plugins/configApi.js +1 -1
- package/dist/plugins/demo/helloworld.js +1 -1
- package/dist/plugins/ldap/accountLifecycle.js +1 -1
- package/dist/plugins/ldap/bulkImport.js +1 -1
- package/dist/plugins/ldap/departmentSync.js +1 -1
- package/dist/plugins/ldap/enterpriseRules.js +1 -1
- package/dist/plugins/ldap/externalUsersInGroups.js +1 -1
- package/dist/plugins/ldap/flatGeneric.js +1 -1
- package/dist/plugins/ldap/groups.js +1 -1
- package/dist/plugins/ldap/ldap.options.js +1 -0
- package/dist/plugins/ldap/onChange.js +1 -1
- package/dist/plugins/ldap/organizations.js +1 -1
- package/dist/plugins/ldap/passwordPolicy.js +1 -1
- package/dist/plugins/ldap/raw.js +1 -1
- package/dist/plugins/ldap/trash.js +1 -1
- package/dist/plugins/metrics.js +1 -1
- package/dist/plugins/metrics.options.js +1 -0
- package/dist/plugins/rabbitmq.js +1 -1
- package/dist/plugins/rabbitmq.options.js +1 -0
- package/dist/plugins/scim/baseResolver.js +1 -1
- package/dist/plugins/scim/bulk.js +1 -1
- package/dist/plugins/scim/discovery.js +1 -1
- package/dist/plugins/scim/errors.js +1 -1
- package/dist/plugins/scim/filter.js +1 -1
- package/dist/plugins/scim/groups.js +1 -1
- package/dist/plugins/scim/mapping.js +1 -1
- package/dist/plugins/scim/patch.js +1 -1
- package/dist/plugins/scim/scim.js +1 -1
- package/dist/plugins/scim/scim.options.js +1 -0
- package/dist/plugins/scim/users.js +1 -1
- package/dist/plugins/static.js +1 -1
- package/dist/plugins/static.options.js +1 -0
- package/dist/plugins/storage/file.js +1 -1
- package/dist/plugins/storage/ldap.js +1 -1
- package/dist/plugins/storage/postgres.js +1 -1
- package/dist/plugins/storage/valkey.js +1 -1
- package/dist/plugins/storage.js +1 -1
- package/dist/plugins/storage.options.js +1 -0
- package/dist/plugins/twake/appAccounts.options.js +1 -0
- package/dist/plugins/twake/appAccountsApi.js +1 -1
- package/dist/plugins/twake/appAccountsConsistency.js +1 -1
- package/dist/plugins/twake/calendar.js +1 -1
- package/dist/plugins/twake/calendar.options.js +1 -0
- package/dist/plugins/twake/calendarResources.js +1 -1
- package/dist/plugins/twake/cloudery.options.js +1 -0
- package/dist/plugins/twake/clouderyProvision.js +1 -1
- package/dist/plugins/twake/cozy.options.js +1 -0
- package/dist/plugins/twake/cozyProvision.js +1 -1
- package/dist/plugins/twake/drive.js +1 -1
- package/dist/plugins/twake/drive.options.js +1 -0
- package/dist/plugins/twake/groups.js +1 -1
- package/dist/plugins/twake/instances.js +1 -1
- package/dist/plugins/twake/james.js +1 -1
- package/dist/plugins/twake/james.options.js +1 -0
- package/dist/plugins/twake/lifecycleAttributes.js +1 -1
- package/dist/plugins/twake/lifecycleEvents.js +1 -1
- package/dist/plugins/twake/migrationProxy.js +1 -1
- package/dist/plugins/twake/migrationProxy.options.js +1 -0
- package/dist/plugins/twake/spaces.js +1 -1
- package/dist/plugins/twake/tombstone.js +1 -1
- package/dist/plugins/twake/twakeGroups.options.js +1 -0
- package/dist/plugins/twake/twakeInstances.options.js +1 -0
- package/dist/plugins/twake/twakeLifecycle.options.js +1 -0
- package/dist/plugins/twake/twakeSpaces.options.js +1 -0
- package/dist/plugins/twake/twakeTombstone.options.js +1 -0
- package/dist/plugins/weblogs.js +1 -1
- package/dist/src/abstract/ldapFlat.d.ts +28 -10
- package/dist/src/abstract/plugin.d.ts +10 -5
- package/dist/src/abstract/twakePlugin.d.ts +14 -4
- package/dist/src/bin/index.d.ts +17 -4
- package/dist/src/config/args.d.ts +2 -4
- package/dist/src/config/options.d.ts +89 -0
- package/dist/src/config/schema.d.ts +50 -1
- package/dist/src/hooks.d.ts +60 -22
- package/dist/src/lib/authz/base.d.ts +4 -51
- package/dist/src/lib/authz/composition.d.ts +2 -2
- package/dist/src/lib/entitySchema/validator.d.ts +63 -6
- package/dist/src/lib/errors.d.ts +56 -1
- package/dist/src/lib/expressFormatedResponses.d.ts +49 -7
- package/dist/src/lib/hookBus.d.ts +226 -0
- package/dist/src/lib/instanceProviders.d.ts +0 -8
- package/dist/src/lib/ldapActions.d.ts +7 -0
- package/dist/src/lib/parseConfig.d.ts +5 -0
- package/dist/src/lib/route.d.ts +99 -0
- package/dist/src/lib/utils.d.ts +31 -36
- package/dist/src/lib/version.d.ts +12 -0
- package/dist/src/plugins/auth/auth.options.d.ts +88 -0
- package/dist/src/plugins/auth/authzDynamic.d.ts +10 -1
- package/dist/src/plugins/auth/authzLinid1.d.ts +6 -0
- package/dist/src/plugins/auth/authzPerBranch.d.ts +9 -0
- package/dist/src/plugins/auth/authzPerRoute.d.ts +3 -0
- package/dist/src/plugins/auth/authzScope.d.ts +23 -14
- package/dist/src/plugins/auth/crowdsec.d.ts +5 -0
- package/dist/src/plugins/auth/fake.d.ts +3 -0
- package/dist/src/plugins/auth/hmac.d.ts +4 -0
- package/dist/src/plugins/auth/llng.d.ts +4 -0
- package/dist/src/plugins/auth/openidconnect.d.ts +7 -0
- package/dist/src/plugins/auth/rateLimit.d.ts +4 -0
- package/dist/src/plugins/auth/token.d.ts +3 -0
- package/dist/src/plugins/auth/totp.d.ts +5 -0
- package/dist/src/plugins/auth/trustedProxy.d.ts +4 -0
- package/dist/src/plugins/bcl.d.ts +3 -0
- package/dist/src/plugins/bcl.options.d.ts +8 -0
- package/dist/src/plugins/configApi.d.ts +24 -5
- package/dist/src/plugins/demo/helloworld.d.ts +8 -19
- package/dist/src/plugins/ldap/accountLifecycle.d.ts +17 -0
- package/dist/src/plugins/ldap/bulkImport.d.ts +6 -76
- package/dist/src/plugins/ldap/departmentSync.d.ts +1 -0
- package/dist/src/plugins/ldap/enterpriseRules.d.ts +8 -1
- package/dist/src/plugins/ldap/externalUsersInGroups.d.ts +4 -0
- package/dist/src/plugins/ldap/flatGeneric.d.ts +4 -0
- package/dist/src/plugins/ldap/groups.d.ts +27 -11
- package/dist/src/plugins/ldap/ldap.options.d.ts +75 -0
- package/dist/src/plugins/ldap/onChange.d.ts +10 -2
- package/dist/src/plugins/ldap/organizations.d.ts +16 -0
- package/dist/src/plugins/ldap/passwordPolicy.d.ts +32 -1
- package/dist/src/plugins/ldap/raw.d.ts +50 -19
- package/dist/src/plugins/ldap/trash.d.ts +6 -0
- package/dist/src/plugins/metrics.d.ts +3 -0
- package/dist/src/plugins/metrics.options.d.ts +8 -0
- package/dist/src/plugins/rabbitmq.d.ts +3 -0
- package/dist/src/plugins/rabbitmq.options.d.ts +8 -0
- package/dist/src/plugins/scim/baseResolver.d.ts +2 -1
- package/dist/src/plugins/scim/bulk.d.ts +6 -7
- package/dist/src/plugins/scim/discovery.d.ts +3 -0
- package/dist/src/plugins/scim/errors.d.ts +2 -1
- package/dist/src/plugins/scim/groups.d.ts +6 -4
- package/dist/src/plugins/scim/scim.d.ts +37 -3
- package/dist/src/plugins/scim/scim.options.d.ts +35 -0
- package/dist/src/plugins/scim/users.d.ts +6 -7
- package/dist/src/plugins/static.d.ts +9 -0
- package/dist/src/plugins/static.options.d.ts +13 -0
- package/dist/src/plugins/storage.d.ts +12 -1
- package/dist/src/plugins/storage.options.d.ts +16 -0
- package/dist/src/plugins/twake/appAccounts.options.d.ts +13 -0
- package/dist/src/plugins/twake/appAccountsApi.d.ts +18 -0
- package/dist/src/plugins/twake/appAccountsConsistency.d.ts +8 -0
- package/dist/src/plugins/twake/calendar.d.ts +25 -2
- package/dist/src/plugins/twake/calendar.options.d.ts +19 -0
- package/dist/src/plugins/twake/cloudery.options.d.ts +26 -0
- package/dist/src/plugins/twake/clouderyProvision.d.ts +18 -0
- package/dist/src/plugins/twake/cozy.options.d.ts +23 -0
- package/dist/src/plugins/twake/cozyProvision.d.ts +14 -0
- package/dist/src/plugins/twake/drive.d.ts +7 -0
- package/dist/src/plugins/twake/drive.options.d.ts +15 -0
- package/dist/src/plugins/twake/groups.d.ts +29 -1
- package/dist/src/plugins/twake/instances.d.ts +43 -10
- package/dist/src/plugins/twake/james.d.ts +17 -0
- package/dist/src/plugins/twake/james.options.d.ts +21 -0
- package/dist/src/plugins/twake/lifecycleEvents.d.ts +12 -0
- package/dist/src/plugins/twake/migrationProxy.d.ts +11 -11
- package/dist/src/plugins/twake/migrationProxy.options.d.ts +16 -0
- package/dist/src/plugins/twake/spaces.d.ts +30 -0
- package/dist/src/plugins/twake/tombstone.d.ts +16 -14
- package/dist/src/plugins/twake/twakeGroups.options.d.ts +20 -0
- package/dist/src/plugins/twake/twakeInstances.options.d.ts +43 -0
- package/dist/src/plugins/twake/twakeLifecycle.options.d.ts +21 -0
- package/dist/src/plugins/twake/twakeSpaces.options.d.ts +19 -0
- package/dist/src/plugins/twake/twakeTombstone.options.d.ts +17 -0
- package/docs/README.md +1 -0
- package/docs/client-development/api/rest-api.md +9 -3
- package/docs/client-development/schemas/README.md +96 -32
- package/docs/plugin-development/README.md +45 -94
- package/docs/plugin-development/dependencies.md +11 -6
- package/docs/plugin-development/hooks.md +142 -23
- package/docs/plugin-development/openapi.md +14 -1
- package/docs/plugin-development/options.md +109 -0
- package/docs/plugin-development/routes.md +152 -0
- package/docs/plugin-development/testing.md +3 -3
- package/docs/usage/configuration.md +18 -11
- package/docs/usage/operations.md +19 -4
- package/docs/usage/plugins/ldap/enterprise-rules.md +10 -1
- package/docs/usage/plugins/ldap/flat-generic.md +4 -0
- package/docs/usage/plugins/ldap/raw.md +17 -1
- package/docs/usage/upgrading.md +194 -0
- package/package.json +358 -277
- package/static/browser/ldap-browser/LdapBrowser.js +8 -6
- package/static/browser/ldap-browser/LdapBrowser.js.map +1 -1
- package/static/browser/ldap-browser/api/RawApiClient.js +2 -0
- package/static/browser/ldap-browser/api/RawApiClient.js.map +1 -1
- package/static/browser/ldap-browser/components/EntryTree.js +9 -5
- package/static/browser/ldap-browser/components/EntryTree.js.map +1 -1
- package/static/browser/ldap-browser/components/EntryView.js +2 -0
- package/static/browser/ldap-browser/components/EntryView.js.map +1 -1
- package/static/browser/ldap-browser/schema.js +3 -2
- package/static/browser/ldap-browser/schema.js.map +1 -1
- package/static/browser/ldap-browser.esm.js +27 -18
- package/static/browser/ldap-browser.esm.js.map +1 -1
- package/static/browser/ldap-browser.js +27 -18
- package/static/browser/ldap-browser.js.map +1 -1
- package/static/browser/ldap-browser.min.js +1 -1
- package/static/browser/ldap-browser.min.js.map +1 -1
- package/static/browser/ldap-group-editor/LdapGroupEditor.js +8 -6
- package/static/browser/ldap-group-editor/LdapGroupEditor.js.map +1 -1
- package/static/browser/ldap-group-editor/api/GroupApiClient.js +1 -0
- package/static/browser/ldap-group-editor/api/GroupApiClient.js.map +1 -1
- package/static/browser/ldap-group-editor/components/CreateGroupModal.js +5 -1
- package/static/browser/ldap-group-editor/components/CreateGroupModal.js.map +1 -1
- package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js +6 -3
- package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js.map +1 -1
- package/static/browser/ldap-group-editor/components/GroupTree.js +6 -3
- package/static/browser/ldap-group-editor/components/GroupTree.js.map +1 -1
- package/static/browser/ldap-group-editor/components/MoveGroupModal.js +6 -3
- package/static/browser/ldap-group-editor/components/MoveGroupModal.js.map +1 -1
- package/static/browser/ldap-group-editor.esm.js +32 -16
- package/static/browser/ldap-group-editor.esm.js.map +1 -1
- package/static/browser/ldap-group-editor.js +32 -16
- package/static/browser/ldap-group-editor.js.map +1 -1
- package/static/browser/ldap-group-editor.min.js +1 -1
- package/static/browser/ldap-group-editor.min.js.map +1 -1
- package/static/browser/ldap-resource-editor/api/ResourceApiClient.js +3 -0
- package/static/browser/ldap-resource-editor/api/ResourceApiClient.js.map +1 -1
- package/static/browser/ldap-resource-editor/cache/CacheManager.js +3 -1
- package/static/browser/ldap-resource-editor/cache/CacheManager.js.map +1 -1
- package/static/browser/ldap-tree-viewer/LdapTreeViewer.js +6 -1
- package/static/browser/ldap-tree-viewer/LdapTreeViewer.js.map +1 -1
- package/static/browser/ldap-tree-viewer/api/LdapApiClient.js +2 -0
- package/static/browser/ldap-tree-viewer/api/LdapApiClient.js.map +1 -1
- package/static/browser/ldap-tree-viewer/components/TreeNode.js +4 -0
- package/static/browser/ldap-tree-viewer/components/TreeNode.js.map +1 -1
- package/static/browser/ldap-tree-viewer/components/TreeRoot.js +3 -0
- package/static/browser/ldap-tree-viewer/components/TreeRoot.js.map +1 -1
- package/static/browser/ldap-tree-viewer/store/Store.js +3 -1
- package/static/browser/ldap-tree-viewer/store/Store.js.map +1 -1
- package/static/browser/ldap-tree-viewer.esm.js +18 -2
- package/static/browser/ldap-tree-viewer.esm.js.map +1 -1
- package/static/browser/ldap-tree-viewer.js +18 -2
- package/static/browser/ldap-tree-viewer.js.map +1 -1
- package/static/browser/ldap-tree-viewer.min.js +1 -1
- package/static/browser/ldap-tree-viewer.min.js.map +1 -1
- package/static/browser/ldap-unit-editor/LdapUnitEditor.js +7 -5
- package/static/browser/ldap-unit-editor/LdapUnitEditor.js.map +1 -1
- package/static/browser/ldap-unit-editor/api/UnitApiClient.js +1 -0
- package/static/browser/ldap-unit-editor/api/UnitApiClient.js.map +1 -1
- package/static/browser/ldap-unit-editor/components/MoveUnitModal.js +7 -4
- package/static/browser/ldap-unit-editor/components/MoveUnitModal.js.map +1 -1
- package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js +7 -4
- package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js.map +1 -1
- package/static/browser/ldap-unit-editor/components/UnitTree.js +6 -3
- package/static/browser/ldap-unit-editor/components/UnitTree.js.map +1 -1
- package/static/browser/ldap-unit-editor.esm.js +28 -16
- package/static/browser/ldap-unit-editor.esm.js.map +1 -1
- package/static/browser/ldap-unit-editor.js +28 -16
- package/static/browser/ldap-unit-editor.js.map +1 -1
- package/static/browser/ldap-unit-editor.min.js +1 -1
- package/static/browser/ldap-unit-editor.min.js.map +1 -1
- package/static/browser/ldap-user-editor/LdapUserEditor.js +9 -7
- package/static/browser/ldap-user-editor/LdapUserEditor.js.map +1 -1
- package/static/browser/ldap-user-editor/api/UserApiClient.js +2 -0
- package/static/browser/ldap-user-editor/api/UserApiClient.js.map +1 -1
- package/static/browser/ldap-user-editor/cache/CacheManager.js +3 -1
- package/static/browser/ldap-user-editor/cache/CacheManager.js.map +1 -1
- package/static/browser/ldap-user-editor/components/MoveUserModal.js +7 -4
- package/static/browser/ldap-user-editor/components/MoveUserModal.js.map +1 -1
- package/static/browser/ldap-user-editor/components/PointerField.js +6 -1
- package/static/browser/ldap-user-editor/components/PointerField.js.map +1 -1
- package/static/browser/ldap-user-editor/components/UserEditor.js +10 -5
- package/static/browser/ldap-user-editor/components/UserEditor.js.map +1 -1
- package/static/browser/ldap-user-editor/components/UserList.js +8 -4
- package/static/browser/ldap-user-editor/components/UserList.js.map +1 -1
- package/static/browser/ldap-user-editor/components/UserTree.js +7 -3
- package/static/browser/ldap-user-editor/components/UserTree.js.map +1 -1
- package/static/browser/ldap-user-editor.esm.js +55 -30
- package/static/browser/ldap-user-editor.esm.js.map +1 -1
- package/static/browser/ldap-user-editor.js +55 -30
- package/static/browser/ldap-user-editor.js.map +1 -1
- package/static/browser/ldap-user-editor.min.js +1 -1
- package/static/browser/ldap-user-editor.min.js.map +1 -1
- package/static/browser/shared/components/DisposableComponent.js +3 -5
- package/static/browser/shared/components/DisposableComponent.js.map +1 -1
- package/static/browser/shared/components/Modal.js +2 -1
- package/static/browser/shared/components/Modal.js.map +1 -1
- package/static/browser/shared/components/StatusMessage.js +3 -2
- package/static/browser/shared/components/StatusMessage.js.map +1 -1
- package/static/browser/shared/utils/form.js.map +1 -1
- package/static/browser/shared/utils/hmac.js +1 -0
- package/static/browser/shared/utils/hmac.js.map +1 -1
- package/static/browser/shared/utils/totp.js +1 -0
- package/static/browser/shared/utils/totp.js.map +1 -1
- package/static/browser/shared.esm.js +9 -8
- package/static/browser/shared.esm.js.map +1 -1
- package/static/browser/shared.js +9 -8
- package/static/browser/shared.js.map +1 -1
- package/static/browser/shared.min.js +1 -1
- package/static/browser/shared.min.js.map +1 -1
- package/static/schemas/ad/groups.json +1 -1
- package/static/schemas/ad/users.json +3 -3
- package/static/schemas/example/organizations.json +2 -2
- package/static/schemas/example/users.json +2 -2
- package/static/schemas/obm/users.json +2 -2
- package/static/schemas/standard/groups.json +1 -1
- package/static/schemas/standard/users.json +2 -2
- package/static/schemas/twake/groups.json +4 -4
- package/static/schemas/twake/teamMailboxes.json +3 -3
- package/static/schemas/twake/users.json +7 -7
|
@@ -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
|
|
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<
|
|
33
|
+
validateNew(entry: AttributesList): Promise<AttributesList>;
|
|
30
34
|
/**
|
|
31
|
-
* Check the parts of a change, then convert them
|
|
32
|
-
*
|
|
33
|
-
*
|
|
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<
|
|
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.
|
package/dist/src/lib/errors.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
25
|
-
*
|
|
26
|
-
*
|
|
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
|
|
@@ -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;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module lib/route
|
|
3
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
4
|
+
*
|
|
5
|
+
* One declaration per HTTP route: its input schemas, the handler that
|
|
6
|
+
* receives the checked values, and what the OpenAPI document says of it.
|
|
7
|
+
* @group Libraries
|
|
8
|
+
*/
|
|
9
|
+
import type { Static, TSchema } from '@sinclair/typebox';
|
|
10
|
+
import type { Express, NextFunction, Request, RequestHandler, Response } from 'express';
|
|
11
|
+
export type RouteMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
|
|
12
|
+
/** What the handler receives for a part it declared no schema for. */
|
|
13
|
+
type Input<T> = T extends TSchema ? Static<T> : unknown;
|
|
14
|
+
/** What a handler receives once its request has been checked. */
|
|
15
|
+
export interface RouteInput<P extends TSchema | undefined, Q extends TSchema | undefined, B extends TSchema | undefined> {
|
|
16
|
+
req: Request;
|
|
17
|
+
res: Response;
|
|
18
|
+
/** Express's own, for a handler that answers a failure itself */
|
|
19
|
+
next: NextFunction;
|
|
20
|
+
params: Input<P>;
|
|
21
|
+
query: Input<Q>;
|
|
22
|
+
body: Input<B>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* An answer: its schema, and the sentence the document gives it. A bare
|
|
26
|
+
* schema is described by its status (`Successful response`, `Bad request`…).
|
|
27
|
+
*/
|
|
28
|
+
export interface RouteResponse {
|
|
29
|
+
schema: TSchema;
|
|
30
|
+
description?: string;
|
|
31
|
+
}
|
|
32
|
+
/** A route, as declared and as recorded for the OpenAPI document. */
|
|
33
|
+
export interface RouteDefinition<P extends TSchema | undefined = undefined, Q extends TSchema | undefined = undefined, B extends TSchema | undefined = undefined> {
|
|
34
|
+
method: RouteMethod;
|
|
35
|
+
path: string;
|
|
36
|
+
/** The path parameters, checked and converted from their string form */
|
|
37
|
+
params?: P;
|
|
38
|
+
/** The query parameters, checked and converted from their string form */
|
|
39
|
+
query?: Q;
|
|
40
|
+
/** The parsed body */
|
|
41
|
+
body?: B;
|
|
42
|
+
/**
|
|
43
|
+
* Whether a caller that does not accept JSON is refused before the handler
|
|
44
|
+
* (default). A route answering another media type sets it false.
|
|
45
|
+
*/
|
|
46
|
+
json?: boolean;
|
|
47
|
+
/** Handlers run before the declaration's, as Express mounts them */
|
|
48
|
+
middleware?: RequestHandler | RequestHandler[];
|
|
49
|
+
/** The answers, for the OpenAPI document */
|
|
50
|
+
responses?: Partial<Record<number, TSchema | RouteResponse>>;
|
|
51
|
+
summary?: string;
|
|
52
|
+
description?: string;
|
|
53
|
+
tags?: string[];
|
|
54
|
+
handler: (input: RouteInput<P, Q, B>) => void | Promise<void>;
|
|
55
|
+
}
|
|
56
|
+
/** A route recorded on an app, with its schemas kept for the document. */
|
|
57
|
+
export type RegisteredRoute = Omit<RouteDefinition<TSchema, TSchema, TSchema>, 'handler' | 'middleware'>;
|
|
58
|
+
/**
|
|
59
|
+
* The routes `defineRoute` registered on an app, in declaration order.
|
|
60
|
+
*
|
|
61
|
+
* @param app the express app the plugin was given
|
|
62
|
+
* @returns its routes
|
|
63
|
+
*/
|
|
64
|
+
export declare const registeredRoutes: (app: Express) => readonly RegisteredRoute[];
|
|
65
|
+
/** A route Express carries, as the stack spells it. */
|
|
66
|
+
export interface StackRoute {
|
|
67
|
+
method: string;
|
|
68
|
+
path: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The routes an app carries that `defineRoute` did not declare.
|
|
72
|
+
*
|
|
73
|
+
* The stack is walked at any depth, so a mounted router's routes are seen
|
|
74
|
+
* too. A route is matched on its method and path, which is what the
|
|
75
|
+
* declaration records; a router's routes are router-relative (`/nested`,
|
|
76
|
+
* whatever the mount path), as Express keeps no mount path on a router, and
|
|
77
|
+
* `app.all` comes back as `_ALL`.
|
|
78
|
+
*
|
|
79
|
+
* @param app the express app
|
|
80
|
+
* @returns the undeclared routes, in stack order
|
|
81
|
+
*/
|
|
82
|
+
export declare const unregisteredRoutes: (app: Express) => StackRoute[];
|
|
83
|
+
/**
|
|
84
|
+
* Declare an HTTP route.
|
|
85
|
+
*
|
|
86
|
+
* The declared schemas are checked before the handler runs; a request that
|
|
87
|
+
* fails them is a {@link BadRequestError} naming every failing path, so the
|
|
88
|
+
* middleware answers it as any other client error. The handler receives the
|
|
89
|
+
* checked values and answers through `res`, as with `asyncHandler`, whose
|
|
90
|
+
* rejections it still forwards.
|
|
91
|
+
*
|
|
92
|
+
* The declaration is recorded on the app, with its schemas, for the OpenAPI
|
|
93
|
+
* document and for the check that no route escapes it.
|
|
94
|
+
*
|
|
95
|
+
* @param app the express app the plugin was given
|
|
96
|
+
* @param route the declaration
|
|
97
|
+
*/
|
|
98
|
+
export declare const defineRoute: <P extends TSchema | undefined = undefined, Q extends TSchema | undefined = undefined, B extends TSchema | undefined = undefined>(app: Express, route: RouteDefinition<P, Q, B>) => void;
|
|
99
|
+
export {};
|