ldap-rest 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +48 -0
- package/bin/cleanup-external-users.mjs +219 -0
- package/bin/index.mjs +54 -0
- package/bin/sync-james.mjs +190 -0
- package/dist/abstract/ldapFlat.js +1 -0
- package/dist/abstract/plugin.js +1 -0
- package/dist/abstract/twakePlugin.js +1 -0
- package/dist/bin/index.js +1 -0
- package/dist/config/args.js +1 -0
- package/dist/lib/auth/base.js +1 -0
- package/dist/lib/authz/base.js +1 -0
- package/dist/lib/expressFormatedResponses.js +1 -0
- package/dist/lib/ldapActions.js +1 -0
- package/dist/lib/parseConfig.js +1 -0
- package/dist/lib/utils.js +1 -0
- package/dist/logger/winston.js +1 -0
- package/dist/plugins/auth/authzLinid1.js +1 -0
- package/dist/plugins/auth/authzPerBranch.js +1 -0
- package/dist/plugins/auth/crowdsec.js +1 -0
- package/dist/plugins/auth/llng.js +1 -0
- package/dist/plugins/auth/openidconnect.js +1 -0
- package/dist/plugins/auth/rateLimit.js +1 -0
- package/dist/plugins/auth/token.js +1 -0
- package/dist/plugins/configApi.js +1 -0
- package/dist/plugins/demo/helloworld.js +1 -0
- package/dist/plugins/ldap/bulkImport.js +1 -0
- package/dist/plugins/ldap/departmentSync.js +1 -0
- package/dist/plugins/ldap/externalUsersInGroups.js +1 -0
- package/dist/plugins/ldap/flatGeneric.js +1 -0
- package/dist/plugins/ldap/groups.js +1 -0
- package/dist/plugins/ldap/onChange.js +1 -0
- package/dist/plugins/ldap/organization.js +1 -0
- package/dist/plugins/ldap/trash.js +1 -0
- package/dist/plugins/priority.json.js +1 -0
- package/dist/plugins/static.js +1 -0
- package/dist/plugins/twake/calendarResources.js +1 -0
- package/dist/plugins/twake/james.js +1 -0
- package/dist/plugins/weblogs.js +1 -0
- package/dist/src/abstract/ldapFlat.d.ts +94 -0
- package/dist/src/abstract/plugin.d.ts +43 -0
- package/dist/src/abstract/twakePlugin.d.ts +90 -0
- package/dist/src/bin/index.d.ts +43 -0
- package/dist/src/browser/ldap-group-editor/LdapGroupEditor.d.ts +31 -0
- package/dist/src/browser/ldap-group-editor/api/GroupApiClient.d.ts +23 -0
- package/dist/src/browser/ldap-group-editor/components/CreateGroupModal.d.ts +19 -0
- package/dist/src/browser/ldap-group-editor/components/GroupPropertyEditor.d.ts +30 -0
- package/dist/src/browser/ldap-group-editor/components/GroupTree.d.ts +17 -0
- package/dist/src/browser/ldap-group-editor/components/MoveGroupModal.d.ts +20 -0
- package/dist/src/browser/ldap-group-editor/index.d.ts +6 -0
- package/dist/src/browser/ldap-group-editor/types.d.ts +58 -0
- package/dist/src/browser/ldap-resource-editor/api/ResourceApiClient.d.ts +53 -0
- package/dist/src/browser/ldap-resource-editor/cache/CacheManager.d.ts +65 -0
- package/dist/src/browser/ldap-resource-editor/index.d.ts +6 -0
- package/dist/src/browser/ldap-resource-editor/types.d.ts +78 -0
- package/dist/src/browser/ldap-tree-viewer/LdapTreeViewer.d.ts +26 -0
- package/dist/src/browser/ldap-tree-viewer/api/LdapApiClient.d.ts +30 -0
- package/dist/src/browser/ldap-tree-viewer/components/TreeNode.d.ts +17 -0
- package/dist/src/browser/ldap-tree-viewer/components/TreeRoot.d.ts +14 -0
- package/dist/src/browser/ldap-tree-viewer/index.d.ts +7 -0
- package/dist/src/browser/ldap-tree-viewer/store/Store.d.ts +18 -0
- package/dist/src/browser/ldap-tree-viewer/store/actions.d.ts +28 -0
- package/dist/src/browser/ldap-tree-viewer/store/reducers.d.ts +7 -0
- package/dist/src/browser/ldap-tree-viewer/types.d.ts +34 -0
- package/dist/src/browser/ldap-unit-editor/LdapUnitEditor.d.ts +27 -0
- package/dist/src/browser/ldap-unit-editor/api/UnitApiClient.d.ts +24 -0
- package/dist/src/browser/ldap-unit-editor/components/MoveUnitModal.d.ts +28 -0
- package/dist/src/browser/ldap-unit-editor/components/UnitPropertyEditor.d.ts +28 -0
- package/dist/src/browser/ldap-unit-editor/components/UnitTree.d.ts +18 -0
- package/dist/src/browser/ldap-unit-editor/index.d.ts +6 -0
- package/dist/src/browser/ldap-unit-editor/types.d.ts +55 -0
- package/dist/src/browser/ldap-user-editor/LdapUserEditor.d.ts +32 -0
- package/dist/src/browser/ldap-user-editor/api/UserApiClient.d.ts +55 -0
- package/dist/src/browser/ldap-user-editor/cache/CacheManager.d.ts +65 -0
- package/dist/src/browser/ldap-user-editor/components/MoveUserModal.d.ts +28 -0
- package/dist/src/browser/ldap-user-editor/components/PointerField.d.ts +22 -0
- package/dist/src/browser/ldap-user-editor/components/UserEditor.d.ts +46 -0
- package/dist/src/browser/ldap-user-editor/components/UserList.d.ts +24 -0
- package/dist/src/browser/ldap-user-editor/components/UserTree.d.ts +24 -0
- package/dist/src/browser/ldap-user-editor/index.d.ts +7 -0
- package/dist/src/browser/ldap-user-editor/types.d.ts +67 -0
- package/dist/src/browser/shared/components/Modal.d.ts +38 -0
- package/dist/src/browser/shared/components/StatusMessage.d.ts +48 -0
- package/dist/src/browser/shared/index.d.ts +10 -0
- package/dist/src/browser/shared/types/index.d.ts +65 -0
- package/dist/src/browser/shared/utils/dom.d.ts +33 -0
- package/dist/src/browser/shared/utils/form.d.ts +28 -0
- package/dist/src/browser/shared/utils/schema.d.ts +29 -0
- package/dist/src/config/args.d.ts +128 -0
- package/dist/src/config/schema.d.ts +18 -0
- package/dist/src/hooks.d.ts +76 -0
- package/dist/src/lib/auth/base.d.ts +9 -0
- package/dist/src/lib/authz/base.d.ts +63 -0
- package/dist/src/lib/expressFormatedResponses.d.ts +26 -0
- package/dist/src/lib/ldapActions.d.ts +91 -0
- package/dist/src/lib/parseConfig.d.ts +23 -0
- package/dist/src/lib/utils.d.ts +73 -0
- package/dist/src/logger/winston.d.ts +3 -0
- package/dist/src/plugins/auth/authzLinid1.d.ts +46 -0
- package/dist/src/plugins/auth/authzPerBranch.d.ts +59 -0
- package/dist/src/plugins/auth/crowdsec.d.ts +29 -0
- package/dist/src/plugins/auth/llng.d.ts +8 -0
- package/dist/src/plugins/auth/openidconnect.d.ts +11 -0
- package/dist/src/plugins/auth/rateLimit.d.ts +24 -0
- package/dist/src/plugins/auth/token.d.ts +17 -0
- package/dist/src/plugins/configApi.d.ts +24 -0
- package/dist/src/plugins/demo/helloworld.d.ts +12 -0
- package/dist/src/plugins/ldap/bulkImport.d.ts +48 -0
- package/dist/src/plugins/ldap/departmentSync.d.ts +35 -0
- package/dist/src/plugins/ldap/externalUsersInGroups.d.ts +21 -0
- package/dist/src/plugins/ldap/flatGeneric.d.ts +31 -0
- package/dist/src/plugins/ldap/groups.d.ts +95 -0
- package/dist/src/plugins/ldap/onChange.d.ts +32 -0
- package/dist/src/plugins/ldap/organization.d.ts +65 -0
- package/dist/src/plugins/ldap/trash.d.ts +52 -0
- package/dist/src/plugins/static.d.ts +7 -0
- package/dist/src/plugins/twake/calendarResources.d.ts +31 -0
- package/dist/src/plugins/twake/james.d.ts +83 -0
- package/dist/src/plugins/weblogs.d.ts +8 -0
- package/docs/DEVELOPER_GUIDE.md +298 -0
- package/docs/OPENAPI.md +440 -0
- package/docs/PLUGIN_DEPENDENCIES.md +612 -0
- package/docs/README.md +466 -0
- package/docs/api/REFERENCE.md +983 -0
- package/docs/api/REST_API.md +1237 -0
- package/docs/authentication.md +469 -0
- package/docs/authzLinid1.md +521 -0
- package/docs/authzPerBranch.md +596 -0
- package/docs/browser/LIBRARIES.md +1196 -0
- package/docs/examples/EXAMPLES.md +1659 -0
- package/docs/examples/twake-mailbox-type-nomenclature.ldif +37 -0
- package/docs/examples/twake-mailbox-type-schema-amendment.ldif +30 -0
- package/docs/jamesTeamMailboxes.md +343 -0
- package/docs/ldapBulkImport.md +722 -0
- package/docs/ldapExternalUsersInGroups.md +325 -0
- package/docs/ldapFlatGeneric.md +444 -0
- package/docs/ldapGroups.md +589 -0
- package/docs/ldapOrganizations.md +659 -0
- package/docs/ldapTrash.md +260 -0
- package/docs/linagora.png +0 -0
- package/docs/onChange.md +318 -0
- package/docs/plugins/DEVELOPMENT.md +1219 -0
- package/docs/presenterm-fr.md +721 -0
- package/docs/presenterm.md +721 -0
- package/docs/schemas/SCHEMAS.md +1212 -0
- package/docs/static.md +410 -0
- package/docs/twakeCalendarResources.md +148 -0
- package/docs/twakeJames.md +661 -0
- package/docs/weblogs.md +399 -0
- package/examples/web/ldap-group-editor.html +113 -0
- package/examples/web/ldap-tree-viewer.html +368 -0
- package/examples/web/ldap-unit-editor.html +108 -0
- package/examples/web/ldap-user-editor.html +412 -0
- package/package.json +458 -0
- package/static/browser/common-demo.css +450 -0
- package/static/browser/ldap-group-editor/LdapGroupEditor.js +207 -0
- package/static/browser/ldap-group-editor/LdapGroupEditor.js.map +1 -0
- package/static/browser/ldap-group-editor/api/GroupApiClient.js +112 -0
- package/static/browser/ldap-group-editor/api/GroupApiClient.js.map +1 -0
- package/static/browser/ldap-group-editor/components/CreateGroupModal.js +212 -0
- package/static/browser/ldap-group-editor/components/CreateGroupModal.js.map +1 -0
- package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js +497 -0
- package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js.map +1 -0
- package/static/browser/ldap-group-editor/components/GroupTree.js +153 -0
- package/static/browser/ldap-group-editor/components/GroupTree.js.map +1 -0
- package/static/browser/ldap-group-editor/components/MoveGroupModal.js +235 -0
- package/static/browser/ldap-group-editor/components/MoveGroupModal.js.map +1 -0
- package/static/browser/ldap-group-editor/index.js +2 -0
- package/static/browser/ldap-group-editor/index.js.map +1 -0
- package/static/browser/ldap-group-editor/types.js +2 -0
- package/static/browser/ldap-group-editor/types.js.map +1 -0
- package/static/browser/ldap-group-editor.esm.js +1399 -0
- package/static/browser/ldap-group-editor.esm.js.map +1 -0
- package/static/browser/ldap-group-editor.js +1407 -0
- package/static/browser/ldap-group-editor.js.map +1 -0
- package/static/browser/ldap-group-editor.min.js +2 -0
- package/static/browser/ldap-group-editor.min.js.map +1 -0
- package/static/browser/ldap-resource-editor/api/ResourceApiClient.js +226 -0
- package/static/browser/ldap-resource-editor/api/ResourceApiClient.js.map +1 -0
- package/static/browser/ldap-resource-editor/cache/CacheManager.js +123 -0
- package/static/browser/ldap-resource-editor/cache/CacheManager.js.map +1 -0
- package/static/browser/ldap-resource-editor/index.js +2 -0
- package/static/browser/ldap-resource-editor/index.js.map +1 -0
- package/static/browser/ldap-resource-editor/types.js +2 -0
- package/static/browser/ldap-resource-editor/types.js.map +1 -0
- package/static/browser/ldap-tree-viewer/LdapTreeViewer.js +187 -0
- package/static/browser/ldap-tree-viewer/LdapTreeViewer.js.map +1 -0
- package/static/browser/ldap-tree-viewer/api/LdapApiClient.js +50 -0
- package/static/browser/ldap-tree-viewer/api/LdapApiClient.js.map +1 -0
- package/static/browser/ldap-tree-viewer/components/TreeNode.js +140 -0
- package/static/browser/ldap-tree-viewer/components/TreeNode.js.map +1 -0
- package/static/browser/ldap-tree-viewer/components/TreeRoot.js +98 -0
- package/static/browser/ldap-tree-viewer/components/TreeRoot.js.map +1 -0
- package/static/browser/ldap-tree-viewer/index.js +2 -0
- package/static/browser/ldap-tree-viewer/index.js.map +1 -0
- package/static/browser/ldap-tree-viewer/store/Store.js +29 -0
- package/static/browser/ldap-tree-viewer/store/Store.js.map +1 -0
- package/static/browser/ldap-tree-viewer/store/actions.js +53 -0
- package/static/browser/ldap-tree-viewer/store/actions.js.map +1 -0
- package/static/browser/ldap-tree-viewer/store/reducers.js +79 -0
- package/static/browser/ldap-tree-viewer/store/reducers.js.map +1 -0
- package/static/browser/ldap-tree-viewer/types.js +2 -0
- package/static/browser/ldap-tree-viewer/types.js.map +1 -0
- package/static/browser/ldap-tree-viewer.css +2 -0
- package/static/browser/ldap-tree-viewer.css.map +1 -0
- package/static/browser/ldap-tree-viewer.esm.js +606 -0
- package/static/browser/ldap-tree-viewer.esm.js.map +1 -0
- package/static/browser/ldap-tree-viewer.js +614 -0
- package/static/browser/ldap-tree-viewer.js.map +1 -0
- package/static/browser/ldap-tree-viewer.min.js +2 -0
- package/static/browser/ldap-tree-viewer.min.js.map +1 -0
- package/static/browser/ldap-unit-editor/LdapUnitEditor.js +119 -0
- package/static/browser/ldap-unit-editor/LdapUnitEditor.js.map +1 -0
- package/static/browser/ldap-unit-editor/api/UnitApiClient.js +95 -0
- package/static/browser/ldap-unit-editor/api/UnitApiClient.js.map +1 -0
- package/static/browser/ldap-unit-editor/components/MoveUnitModal.js +295 -0
- package/static/browser/ldap-unit-editor/components/MoveUnitModal.js.map +1 -0
- package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js +321 -0
- package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js.map +1 -0
- package/static/browser/ldap-unit-editor/components/UnitTree.js +197 -0
- package/static/browser/ldap-unit-editor/components/UnitTree.js.map +1 -0
- package/static/browser/ldap-unit-editor/index.js +2 -0
- package/static/browser/ldap-unit-editor/index.js.map +1 -0
- package/static/browser/ldap-unit-editor/types.js +2 -0
- package/static/browser/ldap-unit-editor/types.js.map +1 -0
- package/static/browser/ldap-unit-editor.esm.js +1013 -0
- package/static/browser/ldap-unit-editor.esm.js.map +1 -0
- package/static/browser/ldap-unit-editor.js +1021 -0
- package/static/browser/ldap-unit-editor.js.map +1 -0
- package/static/browser/ldap-unit-editor.min.js +2 -0
- package/static/browser/ldap-unit-editor.min.js.map +1 -0
- package/static/browser/ldap-user-editor/LdapUserEditor.js +184 -0
- package/static/browser/ldap-user-editor/LdapUserEditor.js.map +1 -0
- package/static/browser/ldap-user-editor/api/UserApiClient.js +209 -0
- package/static/browser/ldap-user-editor/api/UserApiClient.js.map +1 -0
- package/static/browser/ldap-user-editor/cache/CacheManager.js +123 -0
- package/static/browser/ldap-user-editor/cache/CacheManager.js.map +1 -0
- package/static/browser/ldap-user-editor/components/MoveUserModal.js +302 -0
- package/static/browser/ldap-user-editor/components/MoveUserModal.js.map +1 -0
- package/static/browser/ldap-user-editor/components/PointerField.js +152 -0
- package/static/browser/ldap-user-editor/components/PointerField.js.map +1 -0
- package/static/browser/ldap-user-editor/components/UserEditor.js +608 -0
- package/static/browser/ldap-user-editor/components/UserEditor.js.map +1 -0
- package/static/browser/ldap-user-editor/components/UserList.js +181 -0
- package/static/browser/ldap-user-editor/components/UserList.js.map +1 -0
- package/static/browser/ldap-user-editor/components/UserTree.js +164 -0
- package/static/browser/ldap-user-editor/components/UserTree.js.map +1 -0
- package/static/browser/ldap-user-editor/index.js +2 -0
- package/static/browser/ldap-user-editor/index.js.map +1 -0
- package/static/browser/ldap-user-editor/types.js +2 -0
- package/static/browser/ldap-user-editor/types.js.map +1 -0
- package/static/browser/ldap-user-editor.css +2 -0
- package/static/browser/ldap-user-editor.css.map +1 -0
- package/static/browser/ldap-user-editor.esm.js +1897 -0
- package/static/browser/ldap-user-editor.esm.js.map +1 -0
- package/static/browser/ldap-user-editor.js +1905 -0
- package/static/browser/ldap-user-editor.js.map +1 -0
- package/static/browser/ldap-user-editor.min.js +2 -0
- package/static/browser/ldap-user-editor.min.js.map +1 -0
- package/static/browser/shared/components/Modal.js +121 -0
- package/static/browser/shared/components/Modal.js.map +1 -0
- package/static/browser/shared/components/StatusMessage.js +119 -0
- package/static/browser/shared/components/StatusMessage.js.map +1 -0
- package/static/browser/shared/index.js +7 -0
- package/static/browser/shared/index.js.map +1 -0
- package/static/browser/shared/types/index.js +37 -0
- package/static/browser/shared/types/index.js.map +1 -0
- package/static/browser/shared/utils/dom.js +78 -0
- package/static/browser/shared/utils/dom.js.map +1 -0
- package/static/browser/shared/utils/form.js +234 -0
- package/static/browser/shared/utils/form.js.map +1 -0
- package/static/browser/shared/utils/schema.js +121 -0
- package/static/browser/shared/utils/schema.js.map +1 -0
- package/static/browser/shared.esm.js +694 -0
- package/static/browser/shared.esm.js.map +1 -0
- package/static/browser/shared.js +723 -0
- package/static/browser/shared.js.map +1 -0
- package/static/browser/shared.min.js +2 -0
- package/static/browser/shared.min.js.map +1 -0
- package/static/schemas/ad/computers.json +92 -0
- package/static/schemas/ad/groups.json +55 -0
- package/static/schemas/ad/organizations.json +66 -0
- package/static/schemas/ad/users.json +116 -0
- package/static/schemas/standard/devices.json +72 -0
- package/static/schemas/standard/groups.json +54 -0
- package/static/schemas/standard/organizations.json +49 -0
- package/static/schemas/standard/users.json +86 -0
- package/static/schemas/twake/groups.json +75 -0
- package/static/schemas/twake/nomenclature/twakeAccountStatus.json +31 -0
- package/static/schemas/twake/nomenclature/twakeDeliveryMode.json +31 -0
- package/static/schemas/twake/nomenclature/twakeListType.json +31 -0
- package/static/schemas/twake/nomenclature/twakeMailboxType.json +31 -0
- package/static/schemas/twake/nomenclature/twakeTitle.json +31 -0
- package/static/schemas/twake/organizations.json +52 -0
- package/static/schemas/twake/positions.json +32 -0
- package/static/schemas/twake/users.json +112 -0
|
@@ -0,0 +1,661 @@
|
|
|
1
|
+
# Twake James Mail Server Plugin
|
|
2
|
+
|
|
3
|
+
Synchronize LDAP user changes with Apache James mail server via WebAdmin API.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `twake/james` plugin automatically synchronizes email address and quota changes from LDAP to [Apache James](https://james.apache.org/) mail server. It listens to `onChange` hooks and updates James via its WebAdmin REST API.
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
1. **Apache James** mail server with WebAdmin API enabled
|
|
12
|
+
2. **onChange plugin** loaded to detect LDAP changes
|
|
13
|
+
3. **Mail and quota attributes** configured in LDAP schema
|
|
14
|
+
|
|
15
|
+
## Configuration
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
--plugin core/ldap/onChange \
|
|
19
|
+
--plugin core/ldap/flatGeneric \
|
|
20
|
+
--plugin twake/james \
|
|
21
|
+
--ldap-flat-schema ./static/schemas/twake/users.json \
|
|
22
|
+
--mail-attribute mail \
|
|
23
|
+
--quota-attribute mailQuota \
|
|
24
|
+
--james-webadmin-url http://james:8000 \
|
|
25
|
+
--james-webadmin-token "your-admin-token"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Environment Variables:**
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
DM_JAMES_WEBADMIN_URL="http://james:8000"
|
|
32
|
+
DM_JAMES_WEBADMIN_TOKEN="your-admin-token"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Parameters
|
|
36
|
+
|
|
37
|
+
- `--james-webadmin-url`: James WebAdmin API base URL (required)
|
|
38
|
+
- `--james-webadmin-token`: Bearer token for James WebAdmin authentication (optional)
|
|
39
|
+
- `--mail-attribute`: LDAP attribute for email (default: `mail`)
|
|
40
|
+
- `--quota-attribute`: LDAP attribute for quota (default: `mailQuota`)
|
|
41
|
+
- `--alias-attribute`: LDAP attribute for email aliases (default: `mailAlternateAddress`)
|
|
42
|
+
- `--james-mailbox-type-attribute`: LDAP attribute for mailbox type (default: `twakeMailboxType`)
|
|
43
|
+
|
|
44
|
+
## How It Works
|
|
45
|
+
|
|
46
|
+
### Mailing Lists
|
|
47
|
+
|
|
48
|
+
When a group with a `mail` attribute is created or modified:
|
|
49
|
+
|
|
50
|
+
1. **Create mailing list**
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
POST /api/v1/ldap/groups
|
|
54
|
+
{
|
|
55
|
+
"cn": "engineering",
|
|
56
|
+
"mail": "engineering@company.com",
|
|
57
|
+
"member": [
|
|
58
|
+
"uid=alice,ou=users,dc=example,dc=com",
|
|
59
|
+
"uid=bob,ou=users,dc=example,dc=com"
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
2. **James plugin** creates address group and adds all members:
|
|
65
|
+
|
|
66
|
+
```http
|
|
67
|
+
PUT /address/groups/engineering@company.com/alice@company.com
|
|
68
|
+
PUT /address/groups/engineering@company.com/bob@company.com
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
3. **Add/remove members** - when group members change:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
POST /api/v1/ldap/groups/engineering/members
|
|
75
|
+
{"member": "uid=charlie,ou=users,dc=example,dc=com"}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
James plugin automatically syncs:
|
|
79
|
+
|
|
80
|
+
```http
|
|
81
|
+
PUT /address/groups/engineering@company.com/charlie@company.com
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
4. **Delete mailing list** - when group is deleted:
|
|
85
|
+
|
|
86
|
+
```http
|
|
87
|
+
DELETE /address/groups/engineering@company.com
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Notes:**
|
|
91
|
+
|
|
92
|
+
- Only groups with a `mail` attribute are synchronized to James
|
|
93
|
+
- Groups without `mail` are ignored (regular LDAP groups)
|
|
94
|
+
- James Address Groups are simple distribution lists
|
|
95
|
+
- All group members receive emails sent to the group address
|
|
96
|
+
- List type attributes (open/restricted) are stored in LDAP but not enforced by James
|
|
97
|
+
|
|
98
|
+
### Mail Address Changes
|
|
99
|
+
|
|
100
|
+
When a user's mail attribute changes:
|
|
101
|
+
|
|
102
|
+
1. **LDAP modify operation**
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
PUT /api/v1/ldap/users/jdoe
|
|
106
|
+
{
|
|
107
|
+
"replace": {
|
|
108
|
+
"mail": "john.doe@company.com"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
2. **onChange plugin** detects mail change and triggers `onLdapMailChange` hook
|
|
114
|
+
|
|
115
|
+
3. **James plugin** receives hook and calls James WebAdmin API:
|
|
116
|
+
|
|
117
|
+
```http
|
|
118
|
+
POST /users/old@company.com/rename/john.doe@company.com?action=rename
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
4. **James** renames the mail account and all associated data
|
|
122
|
+
|
|
123
|
+
### Quota Changes
|
|
124
|
+
|
|
125
|
+
When a user's quota changes:
|
|
126
|
+
|
|
127
|
+
1. **LDAP modify operation**
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
PUT /api/v1/ldap/users/jdoe
|
|
131
|
+
{
|
|
132
|
+
"replace": {
|
|
133
|
+
"mailQuota": "5000000000"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
2. **onChange plugin** triggers `onLdapQuotaChange` hook
|
|
139
|
+
|
|
140
|
+
3. **James plugin** updates quota via WebAdmin API:
|
|
141
|
+
|
|
142
|
+
```http
|
|
143
|
+
PUT /quota/users/jdoe@company.com/size
|
|
144
|
+
Content-Type: text/plain
|
|
145
|
+
|
|
146
|
+
5000000000
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Email Aliases Management
|
|
150
|
+
|
|
151
|
+
The plugin automatically manages email aliases stored in LDAP and syncs them to James.
|
|
152
|
+
|
|
153
|
+
#### Creating a User with Aliases
|
|
154
|
+
|
|
155
|
+
When a user is created with aliases:
|
|
156
|
+
|
|
157
|
+
1. **LDAP add operation**
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
POST /api/v1/ldap/users
|
|
161
|
+
{
|
|
162
|
+
"uid": "jdoe",
|
|
163
|
+
"mail": "john.doe@company.com",
|
|
164
|
+
"mailAlternateAddress": [
|
|
165
|
+
"john@company.com",
|
|
166
|
+
"j.doe@company.com"
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
2. **James plugin** creates all aliases in James:
|
|
172
|
+
|
|
173
|
+
```http
|
|
174
|
+
PUT /address/aliases/john.doe@company.com/sources/john@company.com
|
|
175
|
+
PUT /address/aliases/john.doe@company.com/sources/j.doe@company.com
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Emails sent to any alias address will be delivered to `john.doe@company.com`.
|
|
179
|
+
|
|
180
|
+
#### Modifying Aliases
|
|
181
|
+
|
|
182
|
+
When aliases are added or removed:
|
|
183
|
+
|
|
184
|
+
1. **LDAP modify operation**
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
PUT /api/v1/ldap/users/jdoe
|
|
188
|
+
{
|
|
189
|
+
"replace": {
|
|
190
|
+
"mailAlternateAddress": [
|
|
191
|
+
"john@company.com",
|
|
192
|
+
"jdoe@company.com"
|
|
193
|
+
]
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
2. **onChange plugin** detects alias changes and triggers `onLdapAliasChange` hook
|
|
199
|
+
|
|
200
|
+
3. **James plugin** performs diff and updates only changed aliases:
|
|
201
|
+
|
|
202
|
+
```http
|
|
203
|
+
DELETE /address/aliases/john.doe@company.com/sources/j.doe@company.com
|
|
204
|
+
PUT /address/aliases/john.doe@company.com/sources/jdoe@company.com
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### Aliases and Mail Changes
|
|
208
|
+
|
|
209
|
+
When the primary email address changes, all aliases are automatically updated:
|
|
210
|
+
|
|
211
|
+
1. **LDAP modify operation**
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
PUT /api/v1/ldap/users/jdoe
|
|
215
|
+
{
|
|
216
|
+
"replace": {
|
|
217
|
+
"mail": "john.smith@company.com"
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
2. **James plugin** renames the account and updates alias destinations:
|
|
223
|
+
|
|
224
|
+
```http
|
|
225
|
+
POST /users/john.doe@company.com/rename/john.smith@company.com?action=rename
|
|
226
|
+
DELETE /address/aliases/john.doe@company.com/sources/john@company.com
|
|
227
|
+
PUT /address/aliases/john.smith@company.com/sources/john@company.com
|
|
228
|
+
DELETE /address/aliases/john.doe@company.com/sources/jdoe@company.com
|
|
229
|
+
PUT /address/aliases/john.smith@company.com/sources/jdoe@company.com
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Note:** James automatically creates an alias from the old address when renaming a user. The plugin attempts to create this alias explicitly, but handles the 409 Conflict response gracefully if it already exists.
|
|
233
|
+
|
|
234
|
+
#### Active Directory Format Support
|
|
235
|
+
|
|
236
|
+
The plugin supports Active Directory's `proxyAddresses` format:
|
|
237
|
+
|
|
238
|
+
```ldap
|
|
239
|
+
proxyAddresses: smtp:john@company.com
|
|
240
|
+
proxyAddresses: smtp:j.doe@company.com
|
|
241
|
+
proxyAddresses: SMTP:john.doe@company.com
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The `smtp:` prefix is automatically stripped. The capitalization (SMTP vs smtp) is ignored - only the email address after the colon is used.
|
|
245
|
+
|
|
246
|
+
## James WebAdmin API
|
|
247
|
+
|
|
248
|
+
### Endpoints Used
|
|
249
|
+
|
|
250
|
+
| Operation | Endpoint | Method |
|
|
251
|
+
| ------------------- | ------------------------------------------ | ------ |
|
|
252
|
+
| Rename account | `/users/{old}/rename/{new}?action=rename` | POST |
|
|
253
|
+
| Update quota | `/quota/users/{mail}/size` | PUT |
|
|
254
|
+
| Add delegation | `/users/{mail}/authorizedUsers/{delegate}` | PUT |
|
|
255
|
+
| Remove delegation | `/users/{mail}/authorizedUsers/{delegate}` | DELETE |
|
|
256
|
+
| Add alias | `/address/aliases/{mail}/sources/{alias}` | PUT |
|
|
257
|
+
| Remove alias | `/address/aliases/{mail}/sources/{alias}` | DELETE |
|
|
258
|
+
| Add group member | `/address/groups/{group}/{member}` | PUT |
|
|
259
|
+
| Remove group member | `/address/groups/{group}/{member}` | DELETE |
|
|
260
|
+
| Delete group | `/address/groups/{group}` | DELETE |
|
|
261
|
+
|
|
262
|
+
### Authentication
|
|
263
|
+
|
|
264
|
+
James WebAdmin API can be secured with bearer token authentication:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
--james-webadmin-token "your-admin-token"
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
The plugin automatically adds the `Authorization: Bearer {token}` header to all requests.
|
|
271
|
+
|
|
272
|
+
**Without token:**
|
|
273
|
+
|
|
274
|
+
```http
|
|
275
|
+
POST /users/old@company.com/rename/new@company.com?action=rename
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**With token:**
|
|
279
|
+
|
|
280
|
+
```http
|
|
281
|
+
POST /users/old@company.com/rename/new@company.com?action=rename
|
|
282
|
+
Authorization: Bearer your-admin-token
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**Note:** The `action=rename` query parameter is required by James WebAdmin API.
|
|
286
|
+
|
|
287
|
+
Alternative authentication methods (Basic Auth, JWT) can be configured via reverse proxy.
|
|
288
|
+
|
|
289
|
+
## Examples
|
|
290
|
+
|
|
291
|
+
### Example 1: Basic Setup (No Authentication)
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
--plugin core/ldap/onChange \
|
|
295
|
+
--plugin core/ldap/flatGeneric \
|
|
296
|
+
--plugin twake/james \
|
|
297
|
+
--ldap-flat-schema ./schemas/twake/users.json \
|
|
298
|
+
--mail-attribute mail \
|
|
299
|
+
--james-webadmin-url http://localhost:8000
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Example 1b: With Bearer Token
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
--plugin core/ldap/onChange \
|
|
306
|
+
--plugin core/ldap/flatGeneric \
|
|
307
|
+
--plugin twake/james \
|
|
308
|
+
--ldap-flat-schema ./schemas/twake/users.json \
|
|
309
|
+
--mail-attribute mail \
|
|
310
|
+
--james-webadmin-url http://james:8000 \
|
|
311
|
+
--james-webadmin-token "admin-secret-token"
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Example 2: With Quota Management
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
--plugin core/ldap/onChange \
|
|
318
|
+
--plugin core/ldap/flatGeneric \
|
|
319
|
+
--plugin twake/james \
|
|
320
|
+
--ldap-flat-schema ./schemas/twake/users.json \
|
|
321
|
+
--mail-attribute mail \
|
|
322
|
+
--quota-attribute mailQuota \
|
|
323
|
+
--james-webadmin-url http://james:8000
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Example 3: Complete Twake Setup
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
--plugin core/auth/token \
|
|
330
|
+
--plugin core/ldap/onChange \
|
|
331
|
+
--plugin core/ldap/flatGeneric \
|
|
332
|
+
--plugin core/ldap/groups \
|
|
333
|
+
--plugin core/ldap/organization \
|
|
334
|
+
--plugin twake/james \
|
|
335
|
+
--plugin core/static \
|
|
336
|
+
--ldap-flat-schema ./schemas/twake/users.json \
|
|
337
|
+
--ldap-flat-schema ./schemas/twake/positions.json \
|
|
338
|
+
--mail-attribute mail \
|
|
339
|
+
--quota-attribute mailQuota \
|
|
340
|
+
--james-webadmin-url http://james:8000 \
|
|
341
|
+
--james-webadmin-token "james-admin-token" \
|
|
342
|
+
--static-path ./static \
|
|
343
|
+
--auth-token "api-admin-token"
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Logging
|
|
347
|
+
|
|
348
|
+
The plugin logs all operations:
|
|
349
|
+
|
|
350
|
+
### Successful Operations
|
|
351
|
+
|
|
352
|
+
```json
|
|
353
|
+
{
|
|
354
|
+
"level": "info",
|
|
355
|
+
"message": "James operation succeeded",
|
|
356
|
+
"plugin": "james",
|
|
357
|
+
"event": "onLdapMailChange",
|
|
358
|
+
"url": "http://james:8000/users/old@company.com/rename/new@company.com",
|
|
359
|
+
"status": 204,
|
|
360
|
+
"oldmail": "old@company.com",
|
|
361
|
+
"newmail": "new@company.com"
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Failed Operations
|
|
366
|
+
|
|
367
|
+
```json
|
|
368
|
+
{
|
|
369
|
+
"level": "error",
|
|
370
|
+
"message": "James operation failed",
|
|
371
|
+
"plugin": "james",
|
|
372
|
+
"event": "onLdapMailChange",
|
|
373
|
+
"url": "http://james:8000/users/old@company.com/rename/new@company.com",
|
|
374
|
+
"status": 404,
|
|
375
|
+
"error": "User not found",
|
|
376
|
+
"oldmail": "old@company.com",
|
|
377
|
+
"newmail": "new@company.com"
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
## Error Handling
|
|
382
|
+
|
|
383
|
+
### Non-Existent User
|
|
384
|
+
|
|
385
|
+
If mail account doesn't exist in James:
|
|
386
|
+
|
|
387
|
+
```json
|
|
388
|
+
{
|
|
389
|
+
"level": "warn",
|
|
390
|
+
"message": "James user not found (expected for new users)",
|
|
391
|
+
"status": 404
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
This is normal for new users - create the account in James separately.
|
|
396
|
+
|
|
397
|
+
### James Server Down
|
|
398
|
+
|
|
399
|
+
If James WebAdmin is unreachable:
|
|
400
|
+
|
|
401
|
+
```json
|
|
402
|
+
{
|
|
403
|
+
"level": "error",
|
|
404
|
+
"message": "Failed to connect to James",
|
|
405
|
+
"error": "ECONNREFUSED"
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
The LDAP operation succeeds, but James is not updated. Manual sync may be required.
|
|
410
|
+
|
|
411
|
+
### Invalid Quota Value
|
|
412
|
+
|
|
413
|
+
If quota value is invalid:
|
|
414
|
+
|
|
415
|
+
```json
|
|
416
|
+
{
|
|
417
|
+
"level": "error",
|
|
418
|
+
"message": "Invalid quota value",
|
|
419
|
+
"status": 400,
|
|
420
|
+
"error": "Quota must be a positive integer"
|
|
421
|
+
}
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
## Integration Testing
|
|
425
|
+
|
|
426
|
+
### Test Mail Rename
|
|
427
|
+
|
|
428
|
+
```bash
|
|
429
|
+
# Update mail in LDAP
|
|
430
|
+
curl -X PUT http://localhost:8081/api/v1/ldap/users/jdoe \
|
|
431
|
+
-H "Authorization: Bearer admin-token" \
|
|
432
|
+
-H "Content-Type: application/json" \
|
|
433
|
+
-d '{"replace": {"mail": "john.doe@company.com"}}'
|
|
434
|
+
|
|
435
|
+
# Verify in James
|
|
436
|
+
curl http://james:8000/users/john.doe@company.com
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Test Quota Update
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
# Update quota in LDAP
|
|
443
|
+
curl -X PUT http://localhost:8081/api/v1/ldap/users/jdoe \
|
|
444
|
+
-H "Authorization: Bearer admin-token" \
|
|
445
|
+
-H "Content-Type: application/json" \
|
|
446
|
+
-d '{"replace": {"mailQuota": "5000000000"}}'
|
|
447
|
+
|
|
448
|
+
# Verify in James
|
|
449
|
+
curl http://james:8000/quota/users/jdoe@company.com/size
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
## Quota Format
|
|
453
|
+
|
|
454
|
+
Quota values are in **bytes**:
|
|
455
|
+
|
|
456
|
+
| Size | Bytes | Example |
|
|
457
|
+
| --------- | ----------- | ---------------------------- |
|
|
458
|
+
| 1 GB | 1000000000 | `"mailQuota": "1000000000"` |
|
|
459
|
+
| 5 GB | 5000000000 | `"mailQuota": "5000000000"` |
|
|
460
|
+
| 10 GB | 10000000000 | `"mailQuota": "10000000000"` |
|
|
461
|
+
| Unlimited | -1 | `"mailQuota": "-1"` |
|
|
462
|
+
|
|
463
|
+
## Synchronization Scenarios
|
|
464
|
+
|
|
465
|
+
### Scenario 1: User Creation
|
|
466
|
+
|
|
467
|
+
1. Create user in LDAP with mail attribute
|
|
468
|
+
2. James plugin does nothing (user doesn't exist in James yet)
|
|
469
|
+
3. Create mail account in James manually or via provisioning script
|
|
470
|
+
4. Future mail/quota changes are synced automatically
|
|
471
|
+
|
|
472
|
+
### Scenario 2: Mail Address Change
|
|
473
|
+
|
|
474
|
+
1. User changes email in LDAP: `old@company.com` → `new@company.com`
|
|
475
|
+
2. James plugin renames account in James
|
|
476
|
+
3. All mail data (inbox, sent, folders) is preserved
|
|
477
|
+
4. Old address is no longer valid
|
|
478
|
+
|
|
479
|
+
### Scenario 3: Quota Increase
|
|
480
|
+
|
|
481
|
+
1. Admin increases user quota in LDAP: `1GB` → `5GB`
|
|
482
|
+
2. James plugin updates quota in James
|
|
483
|
+
3. User can now receive more email
|
|
484
|
+
|
|
485
|
+
### Scenario 4: Quota Decrease
|
|
486
|
+
|
|
487
|
+
1. Admin decreases user quota in LDAP: `5GB` → `1GB`
|
|
488
|
+
2. James plugin updates quota in James
|
|
489
|
+
3. If user is over new quota, James may block incoming mail
|
|
490
|
+
4. User must delete mail to get under quota
|
|
491
|
+
|
|
492
|
+
## Mailing List Examples
|
|
493
|
+
|
|
494
|
+
### Creating a Mailing List
|
|
495
|
+
|
|
496
|
+
```bash
|
|
497
|
+
# Create a group with mail attribute
|
|
498
|
+
curl -X POST http://localhost:8081/api/v1/ldap/groups \
|
|
499
|
+
-H "Authorization: Bearer admin-token" \
|
|
500
|
+
-H "Content-Type: application/json" \
|
|
501
|
+
-d '{
|
|
502
|
+
"cn": "engineering",
|
|
503
|
+
"mail": "engineering@company.com",
|
|
504
|
+
"member": [
|
|
505
|
+
"uid=alice,ou=users,dc=example,dc=com",
|
|
506
|
+
"uid=bob,ou=users,dc=example,dc=com"
|
|
507
|
+
],
|
|
508
|
+
"twakeDepartmentLink": "ou=organization,dc=example,dc=com",
|
|
509
|
+
"twakeDepartmentPath": "Engineering"
|
|
510
|
+
}'
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
The James plugin automatically creates the mailing list and adds all members.
|
|
514
|
+
|
|
515
|
+
### Adding a Member
|
|
516
|
+
|
|
517
|
+
```bash
|
|
518
|
+
# Add member to existing group
|
|
519
|
+
curl -X POST http://localhost:8081/api/v1/ldap/groups/engineering/members \
|
|
520
|
+
-H "Authorization: Bearer admin-token" \
|
|
521
|
+
-H "Content-Type: application/json" \
|
|
522
|
+
-d '{"member": "uid=charlie,ou=users,dc=example,dc=com"}'
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
James is automatically updated to include charlie@company.com in the distribution list.
|
|
526
|
+
|
|
527
|
+
### Removing a Member
|
|
528
|
+
|
|
529
|
+
```bash
|
|
530
|
+
# Remove member from group
|
|
531
|
+
curl -X DELETE http://localhost:8081/api/v1/ldap/groups/engineering/members/uid=alice,ou=users,dc=example,dc=com \
|
|
532
|
+
-H "Authorization: Bearer admin-token"
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
James removes alice@company.com from the mailing list.
|
|
536
|
+
|
|
537
|
+
### Deleting a Mailing List
|
|
538
|
+
|
|
539
|
+
```bash
|
|
540
|
+
# Delete the entire group
|
|
541
|
+
curl -X DELETE http://localhost:8081/api/v1/ldap/groups/engineering \
|
|
542
|
+
-H "Authorization: Bearer admin-token"
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
James deletes the entire address group.
|
|
546
|
+
|
|
547
|
+
## Limitations
|
|
548
|
+
|
|
549
|
+
1. **One-way sync**: LDAP → James only. James changes don't sync back to LDAP.
|
|
550
|
+
2. **No account creation**: Plugin doesn't create James accounts, only updates existing ones.
|
|
551
|
+
3. **No user deletion**: Plugin doesn't delete James accounts when LDAP users are deleted.
|
|
552
|
+
4. **Synchronous**: James API calls block LDAP response. Slow James = slow LDAP.
|
|
553
|
+
5. **No send restrictions**: James doesn't enforce list type restrictions (open/member/owner-only). These are metadata in LDAP only.
|
|
554
|
+
|
|
555
|
+
## Advanced Configuration
|
|
556
|
+
|
|
557
|
+
### Custom James Attributes
|
|
558
|
+
|
|
559
|
+
Extend the plugin for custom James operations:
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
import James from './plugins/twake/james';
|
|
563
|
+
|
|
564
|
+
class CustomJames extends James {
|
|
565
|
+
hooks = {
|
|
566
|
+
...super.hooks,
|
|
567
|
+
onLdapDepartmentChange: async (dn, oldDept, newDept) => {
|
|
568
|
+
// Custom logic for department changes
|
|
569
|
+
await this._try(
|
|
570
|
+
'onLdapDepartmentChange',
|
|
571
|
+
`${this.config.james_webadmin_url}/users/${mail}/metadata/department`,
|
|
572
|
+
'PUT',
|
|
573
|
+
dn,
|
|
574
|
+
newDept,
|
|
575
|
+
{ oldDept, newDept }
|
|
576
|
+
);
|
|
577
|
+
},
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
### Async Operations
|
|
583
|
+
|
|
584
|
+
For high-latency James servers, consider async operations:
|
|
585
|
+
|
|
586
|
+
```typescript
|
|
587
|
+
hooks: {
|
|
588
|
+
onLdapMailChange: async (dn, oldMail, newMail) => {
|
|
589
|
+
// Fire and forget - don't block LDAP response
|
|
590
|
+
setImmediate(async () => {
|
|
591
|
+
try {
|
|
592
|
+
await jamesClient.renameUser(oldMail, newMail);
|
|
593
|
+
} catch (err) {
|
|
594
|
+
logger.error('Failed to sync mail change', err);
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
## Troubleshooting
|
|
602
|
+
|
|
603
|
+
### Problem: Changes Not Syncing
|
|
604
|
+
|
|
605
|
+
**Solutions:**
|
|
606
|
+
|
|
607
|
+
1. Verify onChange plugin is loaded:
|
|
608
|
+
|
|
609
|
+
```bash
|
|
610
|
+
--plugin core/ldap/onChange
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
2. Check mail/quota attributes configured:
|
|
614
|
+
|
|
615
|
+
```bash
|
|
616
|
+
--mail-attribute mail
|
|
617
|
+
--quota-attribute mailQuota
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
3. Enable debug logging:
|
|
621
|
+
|
|
622
|
+
```bash
|
|
623
|
+
--log-level debug
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
4. Verify James URL is correct:
|
|
627
|
+
```bash
|
|
628
|
+
curl http://james:8000/healthcheck
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
### Problem: 404 Errors
|
|
632
|
+
|
|
633
|
+
**Symptoms:**
|
|
634
|
+
|
|
635
|
+
```json
|
|
636
|
+
{ "level": "warn", "message": "James user not found", "status": 404 }
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
**Solutions:**
|
|
640
|
+
|
|
641
|
+
1. Create mail account in James first
|
|
642
|
+
2. Verify mail address matches between LDAP and James
|
|
643
|
+
3. Check James logs for account existence
|
|
644
|
+
|
|
645
|
+
### Problem: Slow LDAP Responses
|
|
646
|
+
|
|
647
|
+
**Symptoms:**
|
|
648
|
+
LDAP modify operations take several seconds.
|
|
649
|
+
|
|
650
|
+
**Solutions:**
|
|
651
|
+
|
|
652
|
+
1. Check James WebAdmin performance
|
|
653
|
+
2. Implement async operations (fire and forget)
|
|
654
|
+
3. Use local James instance (avoid network latency)
|
|
655
|
+
4. Add timeout to James API calls
|
|
656
|
+
|
|
657
|
+
## See Also
|
|
658
|
+
|
|
659
|
+
- [onChange.md](onChange.md) - LDAP change detection
|
|
660
|
+
- [ldapFlatGeneric.md](ldapFlatGeneric.md) - Schema-driven LDAP management
|
|
661
|
+
- [Apache James Documentation](https://james.apache.org/server/manage-webadmin.html) - WebAdmin API reference
|