ldap-rest 1.1.0 → 1.2.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/index.mjs +8 -7
- 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/schema.js +1 -1
- package/dist/lib/changeContext.js +1 -1
- package/dist/lib/entitySchema/validator.js +1 -0
- package/dist/lib/expressFormatedResponses.js +1 -1
- package/dist/lib/health.js +1 -0
- package/dist/lib/instanceProviders.js +1 -1
- package/dist/lib/ldapActions.js +1 -1
- package/dist/lib/metrics.js +1 -0
- package/dist/lib/requestContext.js +1 -1
- package/dist/lib/shutdown.js +1 -0
- package/dist/lib/staticFiles.js +1 -0
- package/dist/lib/storage/store.js +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/logger/winston.js +1 -1
- package/dist/plugins/auth/crowdsec.js +1 -1
- package/dist/plugins/auth/openidconnect.js +1 -1
- package/dist/plugins/demo/helloworld.js +1 -1
- package/dist/plugins/ldap/bulkImport.js +1 -1
- package/dist/plugins/ldap/flatGeneric.js +1 -1
- package/dist/plugins/ldap/groups.js +1 -1
- package/dist/plugins/ldap/organizations.js +1 -1
- package/dist/plugins/metrics.js +1 -0
- package/dist/plugins/rabbitmq.js +1 -1
- package/dist/plugins/scim/scim.js +1 -1
- package/dist/plugins/static.js +1 -1
- package/dist/plugins/storage/file.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/twake/calendar.js +1 -1
- package/dist/plugins/twake/clouderyProvision.js +1 -1
- package/dist/plugins/twake/cozyProvision.js +1 -1
- package/dist/plugins/twake/drive.js +1 -1
- package/dist/plugins/twake/james.js +1 -1
- package/dist/plugins/twake/migrationProxy.js +1 -0
- package/dist/plugins/weblogs.js +1 -1
- package/dist/src/abstract/ldapFlat.d.ts +3 -13
- package/dist/src/abstract/plugin.d.ts +20 -0
- package/dist/src/abstract/twakePlugin.d.ts +23 -1
- package/dist/src/bin/index.d.ts +46 -1
- package/dist/src/config/args.d.ts +12 -1
- package/dist/src/lib/changeContext.d.ts +11 -0
- package/dist/src/lib/entitySchema/validator.d.ts +64 -0
- package/dist/src/lib/expressFormatedResponses.d.ts +19 -0
- package/dist/src/lib/health.d.ts +63 -0
- package/dist/src/lib/instanceProviders.d.ts +4 -0
- package/dist/src/lib/ldapActions.d.ts +28 -0
- package/dist/src/lib/metrics.d.ts +44 -0
- package/dist/src/lib/requestContext.d.ts +40 -0
- package/dist/src/lib/shutdown.d.ts +20 -0
- package/dist/src/lib/staticFiles.d.ts +33 -0
- package/dist/src/lib/storage/store.d.ts +8 -0
- package/dist/src/lib/utils.d.ts +9 -0
- package/dist/src/logger/winston.d.ts +4 -0
- package/dist/src/plugins/ldap/groups.d.ts +18 -3
- package/dist/src/plugins/ldap/organizations.d.ts +3 -5
- package/dist/src/plugins/metrics.d.ts +17 -0
- package/dist/src/plugins/rabbitmq.d.ts +37 -1
- package/dist/src/plugins/static.d.ts +12 -0
- package/dist/src/plugins/storage/file.d.ts +4 -0
- package/dist/src/plugins/storage/postgres.d.ts +7 -14
- package/dist/src/plugins/storage/valkey.d.ts +2 -15
- package/dist/src/plugins/storage.d.ts +8 -0
- package/dist/src/plugins/twake/drive.d.ts +8 -0
- package/dist/src/plugins/twake/james.d.ts +2 -0
- package/dist/src/plugins/twake/migrationProxy.d.ts +71 -0
- package/docs/client-development/api/reference.md +5 -9
- package/docs/client-development/api/rest-api.md +4 -10
- package/docs/client-development/schemas/README.md +60 -21
- package/docs/plugin-development/README.md +15 -13
- package/docs/plugin-development/dependencies.md +8 -0
- package/docs/plugin-development/hooks.md +1 -1
- package/docs/usage/README.md +1 -0
- package/docs/usage/configuration.md +49 -11
- package/docs/usage/operations.md +193 -0
- package/docs/usage/plugins/README.md +2 -0
- package/docs/usage/plugins/auth/authz-per-branch.md +2 -1
- package/docs/usage/plugins/integrations/README.md +8 -4
- package/docs/usage/plugins/integrations/mail-migration.md +102 -0
- package/docs/usage/plugins/integrations/scim.md +4 -2
- package/docs/usage/plugins/ldap/bulk-import.md +3 -1
- package/docs/usage/plugins/ldap/flat-generic.md +5 -2
- package/docs/usage/plugins/ldap/on-change.md +2 -1
- package/docs/usage/plugins/ldap/organizations.md +7 -7
- package/docs/usage/plugins/utilities/metrics.md +21 -0
- package/docs/usage/plugins/utilities/static.md +16 -8
- package/docs/usage/plugins/utilities/storage.md +7 -0
- package/docs/usage/plugins/utilities/weblogs.md +51 -30
- package/docs/usage/upgrading.md +71 -0
- package/package.json +11 -2
- package/static/schemas/example/README.md +1 -0
|
@@ -30,10 +30,18 @@
|
|
|
30
30
|
import DmPlugin from '../abstract/plugin';
|
|
31
31
|
import type { DM } from '../bin';
|
|
32
32
|
import type Store from '../lib/storage/store';
|
|
33
|
+
import type { HealthStatus } from '../lib/health';
|
|
33
34
|
export default class Storage extends DmPlugin {
|
|
34
35
|
name: string;
|
|
35
36
|
store: Store;
|
|
36
37
|
constructor(server: DM);
|
|
38
|
+
close(): Promise<void>;
|
|
39
|
+
/** Set while the backend fails the probe, so the reason is logged once */
|
|
40
|
+
private degraded;
|
|
41
|
+
/** Counts the probes: only the latest says what the log lines say */
|
|
42
|
+
private probes;
|
|
43
|
+
/** The backend's own answer; a backend that cannot answer is degraded */
|
|
44
|
+
health(): Promise<HealthStatus>;
|
|
37
45
|
/**
|
|
38
46
|
* Release the single-instance hold.
|
|
39
47
|
*
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Twake Drive Plugin
|
|
3
|
+
*
|
|
4
|
+
* Synchronizes LDAP user changes with Twake Drive via Admin API.
|
|
5
|
+
* Propagates email address, display name, and disk quota changes.
|
|
6
|
+
*
|
|
7
|
+
* @see https://docs.cozy.io/en/cozy-stack/admin/
|
|
8
|
+
*/
|
|
1
9
|
import TwakePlugin from '../../abstract/twakePlugin';
|
|
2
10
|
import { type Role } from '../../abstract/plugin';
|
|
3
11
|
import type { DM } from '../../bin';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Express } from 'express';
|
|
2
2
|
import TwakePlugin from '../../abstract/twakePlugin';
|
|
3
|
+
import type { HealthStatus } from '../../lib/health';
|
|
3
4
|
import { type Role } from '../../abstract/plugin';
|
|
4
5
|
import type { DM } from '../../bin';
|
|
5
6
|
import type { AttributeValue } from '../../lib/ldapActions';
|
|
@@ -22,6 +23,7 @@ export default class James extends TwakePlugin {
|
|
|
22
23
|
onLdapChange: string;
|
|
23
24
|
ldapGroups: string;
|
|
24
25
|
};
|
|
26
|
+
health(): Promise<HealthStatus>;
|
|
25
27
|
private quotaAttr;
|
|
26
28
|
private aliasAttr;
|
|
27
29
|
private mailboxTypeAttr;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module plugins/twake/migrationProxy
|
|
3
|
+
*
|
|
4
|
+
* Keeps the migrated-users list of the Twake Mail migration proxy in step
|
|
5
|
+
* with the accounts of the directory: an account created during the
|
|
6
|
+
* migration has no mailbox on the old system, so the proxy has to route it
|
|
7
|
+
* to the new one from its first login, and the addresses of a migrated
|
|
8
|
+
* account have to follow it.
|
|
9
|
+
*
|
|
10
|
+
* See `docs/usage/plugins/integrations/mail-migration.md`.
|
|
11
|
+
*/
|
|
12
|
+
import type { Express } from 'express';
|
|
13
|
+
import TwakePlugin from '../../abstract/twakePlugin';
|
|
14
|
+
import { type Role } from '../../abstract/plugin';
|
|
15
|
+
import type { DM } from '../../bin';
|
|
16
|
+
import type { Hooks } from '../../hooks';
|
|
17
|
+
import type { HealthStatus } from '../../lib/health';
|
|
18
|
+
/**
|
|
19
|
+
* @openapi
|
|
20
|
+
* components:
|
|
21
|
+
* schemas:
|
|
22
|
+
* MailMigrationStatus:
|
|
23
|
+
* type: object
|
|
24
|
+
* required: [migrated]
|
|
25
|
+
* properties:
|
|
26
|
+
* migrated:
|
|
27
|
+
* type: boolean
|
|
28
|
+
* description: Whether the proxy routes the user to the new backend
|
|
29
|
+
*/
|
|
30
|
+
export default class MigrationProxy extends TwakePlugin {
|
|
31
|
+
name: string;
|
|
32
|
+
roles: Role[];
|
|
33
|
+
dependencies: {
|
|
34
|
+
onLdapChange: string;
|
|
35
|
+
};
|
|
36
|
+
private readonly branches;
|
|
37
|
+
private readonly aliasAttr;
|
|
38
|
+
/** The work on one entry waits for the work before it */
|
|
39
|
+
private readonly queues;
|
|
40
|
+
constructor(server: DM);
|
|
41
|
+
health(): Promise<HealthStatus>;
|
|
42
|
+
api(app: Express): void;
|
|
43
|
+
hooks: Hooks;
|
|
44
|
+
/**
|
|
45
|
+
* One entry at a time: two writes close together would otherwise race to
|
|
46
|
+
* the proxy, the second reading a list the first has not written yet
|
|
47
|
+
*/
|
|
48
|
+
private inOrder;
|
|
49
|
+
/**
|
|
50
|
+
* The address the entry logs in with, and the ones that reach it, each
|
|
51
|
+
* once: an alias repeating the mail would otherwise be put and taken off
|
|
52
|
+
* in the same breath
|
|
53
|
+
*/
|
|
54
|
+
private addresses;
|
|
55
|
+
/**
|
|
56
|
+
* An entry gaining its address is put on the list with all of them, one
|
|
57
|
+
* losing it is taken off; one keeping it has its addresses follow it when
|
|
58
|
+
* the proxy says it is migrated, and is left to the migration otherwise.
|
|
59
|
+
* The proxy folds usernames to lower case, so a change of case is none.
|
|
60
|
+
*/
|
|
61
|
+
private follow;
|
|
62
|
+
private userUrl;
|
|
63
|
+
private call;
|
|
64
|
+
/**
|
|
65
|
+
* `HEAD /migratedUsers/{user}`: 204 when migrated, 404 otherwise. With
|
|
66
|
+
* `retry`, an answer of {@link PROXY_UNAVAILABLE} is asked again as a
|
|
67
|
+
* write would be; throws once the proxy has not said
|
|
68
|
+
*/
|
|
69
|
+
isMigrated(address: string, retry?: boolean): Promise<boolean>;
|
|
70
|
+
private getMigrationStatus;
|
|
71
|
+
}
|
|
@@ -93,11 +93,13 @@ Complete technical reference for the LDAP-Rest REST API including detailed speci
|
|
|
93
93
|
| 500 | Internal Server Error | Server-side failure | LDAP connection issues, database errors, plugin failures |
|
|
94
94
|
| 503 | Service Unavailable | Server temporarily unavailable | LDAP server down, maintenance mode |
|
|
95
95
|
|
|
96
|
-
**Example 500 Response
|
|
96
|
+
**Example 500 Response** (the failure is in the server's logs; `message`
|
|
97
|
+
names it only when the server runs with `--debug`):
|
|
97
98
|
|
|
98
99
|
```json
|
|
99
100
|
{
|
|
100
|
-
"error": "
|
|
101
|
+
"error": "Internal Server Error",
|
|
102
|
+
"message": "An error occurred"
|
|
101
103
|
}
|
|
102
104
|
```
|
|
103
105
|
|
|
@@ -805,13 +807,7 @@ Failed to fetch
|
|
|
805
807
|
|
|
806
808
|
#### Problem: LDAP Connection Failed
|
|
807
809
|
|
|
808
|
-
**Error:**
|
|
809
|
-
|
|
810
|
-
```json
|
|
811
|
-
{
|
|
812
|
-
"error": "LDAP bind error"
|
|
813
|
-
}
|
|
814
|
-
```
|
|
810
|
+
**Error:** a 500 answer, with `LDAP bind error` in the server's logs.
|
|
815
811
|
|
|
816
812
|
**Checklist:**
|
|
817
813
|
|
|
@@ -1335,19 +1335,13 @@ no `limit` was given —
|
|
|
1335
1335
|
|
|
1336
1336
|
#### 500 Internal Server Error
|
|
1337
1337
|
|
|
1338
|
-
|
|
1338
|
+
The failure is in the server's logs, not in the response; the message names
|
|
1339
|
+
it only when the server runs with `--debug`:
|
|
1339
1340
|
|
|
1340
1341
|
```json
|
|
1341
1342
|
{
|
|
1342
|
-
"error": "
|
|
1343
|
-
|
|
1344
|
-
```
|
|
1345
|
-
|
|
1346
|
-
**General Server Error:**
|
|
1347
|
-
|
|
1348
|
-
```json
|
|
1349
|
-
{
|
|
1350
|
-
"error": "Internal server error: <details>"
|
|
1343
|
+
"error": "Internal Server Error",
|
|
1344
|
+
"message": "An error occurred"
|
|
1351
1345
|
}
|
|
1352
1346
|
```
|
|
1353
1347
|
|
|
@@ -169,7 +169,10 @@ This will be replaced with the actual LDAP base at runtime (e.g., `ou=users,dc=e
|
|
|
169
169
|
|
|
170
170
|
## Attribute Types
|
|
171
171
|
|
|
172
|
-
LDAP-Rest supports three main attribute types: `string`, `array`, and `pointer
|
|
172
|
+
LDAP-Rest supports three main attribute types: `string`, `array`, and `pointer`,
|
|
173
|
+
plus `number`, `integer`, `boolean` and `date` for single values. What a
|
|
174
|
+
client sends has to have the shape of the type, see
|
|
175
|
+
[what a value must look like](#what-a-value-must-look-like).
|
|
173
176
|
|
|
174
177
|
### String Type
|
|
175
178
|
|
|
@@ -337,7 +340,7 @@ Complete reference for all attribute properties.
|
|
|
337
340
|
|
|
338
341
|
| Property | Type | Applies To | Description | Example |
|
|
339
342
|
| ---------- | --------------- | ------------------- | ------------------------------------------------------------------------------------- | ----------------------------------- |
|
|
340
|
-
| `type` | string | All |
|
|
343
|
+
| `type` | string | All | `"string"`, `"array"`, `"pointer"`, `"number"`, `"integer"`, `"boolean"`, `"date"` | `"string"` |
|
|
341
344
|
| `required` | boolean | All | Whether the attribute must be present | `true` |
|
|
342
345
|
| `fixed` | boolean | All | Whether the attribute value cannot be changed after creation | `true` |
|
|
343
346
|
| `role` | string/string[] | String | Semantic role, or roles, for special handling (see [Semantic Roles](#semantic-roles)) | `"identifier"` |
|
|
@@ -364,6 +367,32 @@ Defines the data type of the attribute. Supported values:
|
|
|
364
367
|
- `"pointer"`: Reference to another LDAP entry (DN)
|
|
365
368
|
- `"number"`: Numeric value (integer or float)
|
|
366
369
|
- `"integer"`: Integer value only
|
|
370
|
+
- `"boolean"`: `true` or `false`, stored as `TRUE` / `FALSE`
|
|
371
|
+
- `"date"`: LDAP generalized time, as text
|
|
372
|
+
|
|
373
|
+
#### What a value must look like
|
|
374
|
+
|
|
375
|
+
A single-valued attribute takes one value, an `array` a list. A list of one
|
|
376
|
+
value stands for that value and one value for a list of one, so what a read
|
|
377
|
+
answers, one value where the attribute holds one, can be sent back as is;
|
|
378
|
+
two values or more for a single-valued attribute are refused. Each element
|
|
379
|
+
of an `array` follows `items.type`, text without `items`. A `number` or
|
|
380
|
+
`integer` is a JSON number or its text (`42`, `"42"`), a `boolean` a JSON
|
|
381
|
+
boolean or the directory's `TRUE` / `FALSE`; anything else for them, and
|
|
382
|
+
anything but text for a `string`, `date` or `pointer`, is refused; an
|
|
383
|
+
attribute with `normalize` takes any text, read after validation. In a
|
|
384
|
+
`replace`, `null` or `[]` clears an attribute; in an `add` or on a creation
|
|
385
|
+
they are refused as no value. A `delete` naming the attribute, or naming it
|
|
386
|
+
with no value, removes it, unless it is `required`; naming values removes
|
|
387
|
+
those, every value it holds included, as the server does not read what
|
|
388
|
+
remains, and `''` names no value. An empty string sent as a value is
|
|
389
|
+
checked against `test`, refused for a pointer, and missing for a `required`
|
|
390
|
+
attribute. Every refusal answers 400 with the attribute's name.
|
|
391
|
+
|
|
392
|
+
Every entity route applies these rules; `test/lib/entitySchema.contract.test.ts`
|
|
393
|
+
asserts them on a flat entity, a group and an organization alike. In the
|
|
394
|
+
server they are enforced by `EntityValidator` (`src/lib/entitySchema/validator.ts`)
|
|
395
|
+
alone: ESLint refuses the import of the schema helpers anywhere else.
|
|
367
396
|
|
|
368
397
|
#### `required` (Optional, default: `false`)
|
|
369
398
|
|
|
@@ -674,13 +703,8 @@ Common validation patterns:
|
|
|
674
703
|
|
|
675
704
|
### Type Validation
|
|
676
705
|
|
|
677
|
-
Attribute values must
|
|
678
|
-
|
|
679
|
-
- **String**: Single text value
|
|
680
|
-
- **Array**: Multiple values (may be empty unless required)
|
|
681
|
-
- **Number**: Numeric value (integer or float)
|
|
682
|
-
- **Integer**: Integer value only
|
|
683
|
-
- **Pointer**: Valid DN string
|
|
706
|
+
Attribute values must have the shape of their declared type, see
|
|
707
|
+
[what a value must look like](#what-a-value-must-look-like).
|
|
684
708
|
|
|
685
709
|
### Fixed Attributes
|
|
686
710
|
|
|
@@ -780,6 +804,7 @@ twake/
|
|
|
780
804
|
```bash
|
|
781
805
|
npx ldap-rest \
|
|
782
806
|
--ldap-base 'dc=example,dc=com' \
|
|
807
|
+
--ldap-dn 'cn=admin,dc=example,dc=com' --ldap-pwd secret \
|
|
783
808
|
--plugin core/ldap/flatGeneric \
|
|
784
809
|
--ldap-flat-schema ./static/schemas/twake/users.json \
|
|
785
810
|
--plugin core/ldap/groups \
|
|
@@ -842,6 +867,7 @@ ad/
|
|
|
842
867
|
```bash
|
|
843
868
|
npx ldap-rest \
|
|
844
869
|
--ldap-base 'dc=example,dc=com' \
|
|
870
|
+
--ldap-dn 'cn=admin,dc=example,dc=com' --ldap-pwd secret \
|
|
845
871
|
--plugin core/ldap/flatGeneric \
|
|
846
872
|
--ldap-flat-schema ./static/schemas/ad/users.json \
|
|
847
873
|
--plugin core/ldap/groups \
|
|
@@ -910,6 +936,7 @@ standard/
|
|
|
910
936
|
```bash
|
|
911
937
|
npx ldap-rest \
|
|
912
938
|
--ldap-base 'dc=example,dc=com' \
|
|
939
|
+
--ldap-dn 'cn=admin,dc=example,dc=com' --ldap-pwd secret \
|
|
913
940
|
--plugin core/ldap/flatGeneric \
|
|
914
941
|
--ldap-flat-schema ./static/schemas/standard/users.json \
|
|
915
942
|
--plugin core/ldap/groups \
|
|
@@ -1055,6 +1082,7 @@ Save your schema and reference it when starting LDAP-Rest:
|
|
|
1055
1082
|
```bash
|
|
1056
1083
|
npx ldap-rest \
|
|
1057
1084
|
--ldap-base 'dc=example,dc=com' \
|
|
1085
|
+
--ldap-dn 'cn=admin,dc=example,dc=com' --ldap-pwd secret \
|
|
1058
1086
|
--plugin core/ldap/flatGeneric \
|
|
1059
1087
|
--ldap-flat-schema ./path/to/custom-users.json
|
|
1060
1088
|
```
|
|
@@ -1131,18 +1159,29 @@ it with a 500.
|
|
|
1131
1159
|
### Served Schemas
|
|
1132
1160
|
|
|
1133
1161
|
`core/static` serves the merged schema. The configuration API gives each
|
|
1134
|
-
entity its merged schema inline (`schema`) and,
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
`/etc/ldap-rest/schemas/
|
|
1140
|
-
`/static/schemas/
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1162
|
+
entity its merged schema inline (`schema`) and, where a static plugin's
|
|
1163
|
+
schema routes serve that very file, its `schemaUrl`, under the plugin's own
|
|
1164
|
+
`--static-name`:
|
|
1165
|
+
|
|
1166
|
+
- a schema file of the configuration gets the file path from its first
|
|
1167
|
+
`schemas` directory, `/etc/ldap-rest/schemas/users.json` getting
|
|
1168
|
+
`/static/schemas/users.json`. `core/static` serves it at that URL even
|
|
1169
|
+
when it is outside `--static-path`, and before a shipped schema of the
|
|
1170
|
+
same URL: `/etc/ldap-rest/schemas/twake/users.json` is what
|
|
1171
|
+
`/static/schemas/twake/users.json` returns. If two configured files get
|
|
1172
|
+
the same URL, the first one is served there and a warning names the
|
|
1173
|
+
other;
|
|
1174
|
+
- a file the `schemas/` directory of `--static-path` holds, that directory
|
|
1175
|
+
being a link or not, gets its path in it, if it is named `.json`.
|
|
1176
|
+
|
|
1177
|
+
An option left at its default does not count as configured: without
|
|
1178
|
+
`--group-schema`, a `--static-path` of your own still serves its
|
|
1179
|
+
`schemas/twake/groups.json`, and no `schemaUrl` is given unless that file is
|
|
1180
|
+
the package's, through a link. A static plugin loaded under another name, or with a
|
|
1181
|
+
`static_name` of its own, is asked as well, the one registered as `static`
|
|
1182
|
+
first. A file no static plugin serves merged has no `schemaUrl`, one
|
|
1183
|
+
express.static would send as it stands included (outside `schemas/`, or not
|
|
1184
|
+
named `.json`); its schema is still inline.
|
|
1146
1185
|
|
|
1147
1186
|
---
|
|
1148
1187
|
|
|
@@ -61,20 +61,22 @@ export default class MyPlugin extends DmPlugin {
|
|
|
61
61
|
- **this.config**: Complete configuration object
|
|
62
62
|
- **this.logger**: Winston logger instance
|
|
63
63
|
- **this.registeredHooks**: Access to global hook registry
|
|
64
|
+
- **this.fetch**: `fetch` timed into the
|
|
65
|
+
[outbound metrics](../usage/operations.md#metrics) under the plugin's
|
|
66
|
+
name; the lint refuses a bare `fetch` or `node-fetch` under `src`, and a
|
|
67
|
+
plugin with a `fetch` member of its own has to rename it
|
|
64
68
|
|
|
65
69
|
### Error Handling and Server Resilience
|
|
66
70
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
All errors are logged with full stack traces without crashing the server.
|
|
71
|
+
An error a route handler or a hook throws is logged with its stack; the
|
|
72
|
+
request is answered with a 5xx when the hook ran before the operation, and
|
|
73
|
+
the server keeps serving. An exception nothing catches, in a timer or an
|
|
74
|
+
event handler, is not: the binary shuts down and exits with 1, and a
|
|
75
|
+
promise rejection nothing handles is logged and counted, see
|
|
76
|
+
[shutdown](../usage/operations.md#shutdown); a host assembling the server
|
|
77
|
+
chooses with `exitOnCrash()`. A plugin holding a connection, a timer or a
|
|
78
|
+
queue implements `close()`, see
|
|
79
|
+
[for plugin authors](../usage/operations.md#for-plugin-authors).
|
|
78
80
|
|
|
79
81
|
#### Using asyncHandler
|
|
80
82
|
|
|
@@ -175,7 +177,7 @@ export default class WebhookNotifier extends DmPlugin {
|
|
|
175
177
|
// Private methods
|
|
176
178
|
private async sendWebhook(event: string, data: unknown): Promise<void> {
|
|
177
179
|
try {
|
|
178
|
-
await fetch(this.config.webhook_url as string, {
|
|
180
|
+
await this.fetch(this.config.webhook_url as string, {
|
|
179
181
|
method: 'POST',
|
|
180
182
|
headers: { 'Content-Type': 'application/json' },
|
|
181
183
|
body: JSON.stringify({ event, data }),
|
|
@@ -1153,7 +1155,7 @@ export default class NotificationPlugin extends DmPlugin {
|
|
|
1153
1155
|
const timeoutId = setTimeout(() => controller.abort(), this.webhookTimeout);
|
|
1154
1156
|
|
|
1155
1157
|
try {
|
|
1156
|
-
const response = await fetch(this.webhookUrl, {
|
|
1158
|
+
const response = await this.fetch(this.webhookUrl, {
|
|
1157
1159
|
method: 'POST',
|
|
1158
1160
|
headers: {
|
|
1159
1161
|
'Content-Type': 'application/json',
|
|
@@ -204,6 +204,14 @@ overrides builds a second instance, and it needs a name of its own.
|
|
|
204
204
|
- **Consumes Hooks**: (Hooks provided by `onLdapChange`)
|
|
205
205
|
- **Notes**: Synchronizes LDAP users/groups with Apache James mail server
|
|
206
206
|
|
|
207
|
+
#### `migrationProxy` (twake/migrationProxy)
|
|
208
|
+
|
|
209
|
+
- **Dependencies**:
|
|
210
|
+
- `onLdapChange: 'core/ldap/onChange'` ⚠️ **Required**
|
|
211
|
+
- **Provides Hooks**: None
|
|
212
|
+
- **Consumes Hooks**: `onLdapEntryChange` (provided by `onLdapChange`)
|
|
213
|
+
- **Notes**: Keeps the migrated-users list of the Twake Mail migration proxy, see [mail-migration](../usage/plugins/integrations/mail-migration.md)
|
|
214
|
+
|
|
207
215
|
#### `calendar` (twake/calendar)
|
|
208
216
|
|
|
209
217
|
- **Dependencies**:
|
|
@@ -9,7 +9,7 @@ those typed in [hooks.ts](../../src/hooks.ts), which is the reference.
|
|
|
9
9
|
|
|
10
10
|
## [LDAP](../../src/lib/ldapActions.ts) hooks
|
|
11
11
|
|
|
12
|
-
- **
|
|
12
|
+
- **ldapsearchopts**: called before any ldapsearch to modify search options
|
|
13
13
|
- **ldapsearchresult**: called after any ldapsearch to modify search result
|
|
14
14
|
- **ldapaddrequest**: called before any ldapadd
|
|
15
15
|
- **ldapadddone**: launched once an ldapadd has written the entry, not awaited
|
package/docs/usage/README.md
CHANGED
|
@@ -88,4 +88,5 @@ The system will:
|
|
|
88
88
|
- **[Plugins](plugins/README.md)** - Choose and configure plugins
|
|
89
89
|
- **[Upgrading](upgrading.md)** - What to check before deploying a new version
|
|
90
90
|
- **[Directory audit](directory-audit.md)** - What a schema would refuse in an existing directory
|
|
91
|
+
- **[Operations](operations.md)** - Health and readiness probes
|
|
91
92
|
- **[Troubleshooting](troubleshooting.md)** - Problem resolution
|
|
@@ -39,17 +39,20 @@ All LDAP-Rest configuration options.
|
|
|
39
39
|
- [core/auth/trustedProxy](#coreauthtrustedproxy)
|
|
40
40
|
- [Twake Integration Plugins](#twake-integration-plugins)
|
|
41
41
|
- [core/twake/james](#coretwakejames)
|
|
42
|
+
- [core/twake/migrationProxy](#coretwakemigrationproxy)
|
|
42
43
|
- [core/twake/calendar](#coretwakecalendar)
|
|
43
44
|
- [core/twake/applicativeAccounts](#coretwakeapplicativeaccounts)
|
|
44
45
|
- [core/twake/appAccountsConsistency](#coretwakeappaccountsconsistency)
|
|
45
46
|
- [Utility Plugins](#utility-plugins)
|
|
46
47
|
- [core/static](#corestatic)
|
|
47
48
|
- [core/weblogs](#coreweblogs)
|
|
49
|
+
- [core/metrics](#coremetrics)
|
|
48
50
|
- [core/storage](#corestorage)
|
|
49
51
|
- [core/configApi](#coreconfigapi)
|
|
50
52
|
- [Configuration File](#configuration-file)
|
|
51
53
|
- [LDAP Failover](#ldap-failover)
|
|
52
54
|
- [Log Levels (`--log-level`)](#log-levels---log-level)
|
|
55
|
+
- [Logger (`--logger`)](#logger---logger)
|
|
53
56
|
|
|
54
57
|
## Environment Variables
|
|
55
58
|
|
|
@@ -148,15 +151,18 @@ to keep the default.
|
|
|
148
151
|
|
|
149
152
|
## General Options
|
|
150
153
|
|
|
151
|
-
| CLI
|
|
152
|
-
|
|
|
153
|
-
| `--port`
|
|
154
|
-
| `--
|
|
155
|
-
| `--
|
|
156
|
-
| `--
|
|
157
|
-
| `--
|
|
158
|
-
| `--
|
|
159
|
-
| `--
|
|
154
|
+
| CLI | Plural | Env | Default | Description |
|
|
155
|
+
| -------------------- | ---------------- | --------------------- | ---------------- | ------------------------------------------------------------------------------------------------- |
|
|
156
|
+
| `--port` | | `DM_PORT` | `8081` | Listen port |
|
|
157
|
+
| `--shutdown-timeout` | | `DM_SHUTDOWN_TIMEOUT` | `20000` | How long a stop may take, in ms, see [shutdown](operations.md#shutdown) |
|
|
158
|
+
| `--plugin` | `--plugins` | `DM_PLUGINS` | `[]` | Plugins to load |
|
|
159
|
+
| `--log-level` | | `DM_LOG_LEVEL` | `notice` | Log level: error, warn, notice, info, debug |
|
|
160
|
+
| `--logger` | | `DM_LOGGER` | `console` | `console` or `file`, see [Logger](#logger---logger) |
|
|
161
|
+
| `--log-file` | | `DM_LOG_FILE` | `error.log` | File `--logger file` writes to |
|
|
162
|
+
| `--debug` | | `DM_DEBUG` | `false` | Name the failure in the 5xx answers of the error middleware and `serverError`; not for production |
|
|
163
|
+
| `--api-prefix` | | `DM_API_PREFIX` | `/api` | API URL prefix |
|
|
164
|
+
| `--mail-domain` | `--mail-domains` | `DM_MAIL_DOMAIN` | `[]` | Mail domains |
|
|
165
|
+
| `--schemas-path` | | `DM_SCHEMAS_PATH` | `static/schemas` | Path to JSON schemas |
|
|
160
166
|
|
|
161
167
|
A schema file named by an option may extend another one, shipped or not, and
|
|
162
168
|
hold only the differences:
|
|
@@ -167,8 +173,8 @@ hold only the differences:
|
|
|
167
173
|
| CLI | Plural | Env | Default | Description |
|
|
168
174
|
| ---------------------------- | ---------------- | ------------------------ | ---------------------------------- | ------------------------------------------- |
|
|
169
175
|
| `--ldap-url` | `--ldap-urls` | `DM_LDAP_URL` | `ldap://localhost` | LDAP server URL(s) |
|
|
170
|
-
| `--ldap-dn` | | `DM_LDAP_DN` |
|
|
171
|
-
| `--ldap-pwd` | | `DM_LDAP_PWD` |
|
|
176
|
+
| `--ldap-dn` | | `DM_LDAP_DN` | | Bind DN (required) |
|
|
177
|
+
| `--ldap-pwd` | | `DM_LDAP_PWD` | | Password (required) |
|
|
172
178
|
| `--ldap-base` | | `DM_LDAP_BASE` | | Base DN for searches (required) |
|
|
173
179
|
| `--ldap-user-main-attribute` | | `DM_LDAP_USER_ATTRIBUTE` | `uid` | User identifier attribute |
|
|
174
180
|
| `--ldap-cache-max` | | `DM_LDAP_CACHE_MAX` | `1000` | Max cache entries |
|
|
@@ -493,6 +499,19 @@ whichever of the two names it selects. A value other than `req.user` or
|
|
|
493
499
|
|
|
494
500
|
The wait before each retry grows with the attempt, so the total wait is `--james-retry-delay` × n(n−1)/2 for n attempts: 10 s with the defaults, 190 s with 20 attempts.
|
|
495
501
|
|
|
502
|
+
#### `core/twake/migrationProxy`
|
|
503
|
+
|
|
504
|
+
Keeps the migrated-users list of the Twake Mail migration proxy in step with the accounts, [details](plugins/integrations/mail-migration.md).
|
|
505
|
+
|
|
506
|
+
| CLI | Plural | Env | Default | Description |
|
|
507
|
+
| ---------------------------------- | ---------------------------- | ----------------------------------- | ------- | ---------------------------------------------------------------- |
|
|
508
|
+
| `--migration-proxy-url` | | `DM_MIGRATION_PROXY_URL` | | Webadmin URL of the proxy (required) |
|
|
509
|
+
| `--migration-proxy-token` | | `DM_MIGRATION_PROXY_TOKEN` | | Bearer token |
|
|
510
|
+
| `--migration-proxy-branch` | `--migration-proxy-branches` | `DM_MIGRATION_PROXY_BRANCHES` | `[]` | Branches whose entries are followed, `;`-separated (required) |
|
|
511
|
+
| `--migration-proxy-concurrency` | | `DM_MIGRATION_PROXY_CONCURRENCY` | `10` | Calls to the proxy at once |
|
|
512
|
+
| `--migration-proxy-retry-attempts` | | `DM_MIGRATION_PROXY_RETRY_ATTEMPTS` | `5` | Attempts in all of a call the proxy answers 500, 502, 503 or 504 |
|
|
513
|
+
| `--migration-proxy-retry-delay` | | `DM_MIGRATION_PROXY_RETRY_DELAY` | `1000` | Base retry delay (ms), growing with the attempt |
|
|
514
|
+
|
|
496
515
|
#### `core/twake/calendar`
|
|
497
516
|
|
|
498
517
|
Formerly `core/twake/calendarResources`, still accepted as a deprecated alias.
|
|
@@ -675,6 +694,15 @@ See [security headers](plugins/utilities/static.md#security-headers).
|
|
|
675
694
|
|
|
676
695
|
Web access logging plugin. No configuration options - just add the plugin to enable access logs.
|
|
677
696
|
|
|
697
|
+
#### `core/metrics`
|
|
698
|
+
|
|
699
|
+
Prometheus metrics on a port of their own, see
|
|
700
|
+
[metrics](operations.md#metrics).
|
|
701
|
+
|
|
702
|
+
| CLI | Env | Default | Description |
|
|
703
|
+
| ---------------- | ----------------- | ------- | ---------------------------------------------------------- |
|
|
704
|
+
| `--metrics-port` | `DM_METRICS_PORT` | `9464` | Port `GET /metrics` is served on; keep it off the internet |
|
|
705
|
+
|
|
678
706
|
#### `core/storage`
|
|
679
707
|
|
|
680
708
|
Keyed storage with a deadline, for the plugins that need to keep something —
|
|
@@ -743,3 +771,13 @@ The system will:
|
|
|
743
771
|
| `debug` | Everything, including debug output |
|
|
744
772
|
|
|
745
773
|
The `notice` level is ideal for production as it shows web access logs without flooding with general info messages.
|
|
774
|
+
|
|
775
|
+
## Logger _(`--logger`)_
|
|
776
|
+
|
|
777
|
+
| Logger | Output |
|
|
778
|
+
| --------- | ---------------------------------------------------------------------------------------------------- |
|
|
779
|
+
| `console` | One JSON object per line on standard output (errors and warnings on standard error) |
|
|
780
|
+
| `file` | Text lines appended to `--log-file` (`DM_LOG_FILE`), `error.log` in the working directory by default |
|
|
781
|
+
|
|
782
|
+
An empty value is `console`. Any other value, or `file` with an empty
|
|
783
|
+
`--log-file`, stops the server at startup.
|