ldap-rest 0.13.4 → 0.15.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/dist/bin/index.js +1 -1
- package/dist/config/args.js +1 -1
- package/dist/lib/errors.js +1 -1
- package/dist/lib/expressFormatedResponses.js +1 -1
- package/dist/lib/ldapActions.js +1 -1
- package/dist/lib/operation.js +1 -0
- package/dist/lib/parseConfig.js +1 -1
- package/dist/lib/rawBody.js +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/plugins/auth/hmac.js +1 -1
- package/dist/plugins/auth/totp.js +1 -1
- package/dist/plugins/ldap/onChange.js +1 -1
- package/dist/plugins/scim/errors.js +1 -1
- package/dist/plugins/scim/scim.js +1 -1
- package/dist/plugins/twake/groups.js +1 -1
- package/dist/plugins/twake/instances.js +1 -1
- package/dist/plugins/twake/lifecycleEvents.js +1 -1
- package/dist/plugins/twake/spaces.js +1 -0
- package/dist/plugins/twake/tombstone.js +1 -1
- package/dist/src/bin/index.d.ts +16 -0
- package/dist/src/config/args.d.ts +8 -1
- package/dist/src/hooks.d.ts +17 -0
- package/dist/src/lib/errors.d.ts +5 -0
- package/dist/src/lib/ldapActions.d.ts +12 -1
- package/dist/src/lib/operation.d.ts +29 -0
- package/dist/src/lib/parseConfig.d.ts +4 -1
- package/dist/src/lib/rawBody.d.ts +27 -8
- package/dist/src/lib/utils.d.ts +6 -0
- package/dist/src/plugins/auth/hmac.d.ts +1 -1
- package/dist/src/plugins/ldap/onChange.d.ts +5 -2
- package/dist/src/plugins/scim/scim.d.ts +11 -1
- package/dist/src/plugins/twake/groups.d.ts +72 -12
- package/dist/src/plugins/twake/instances.d.ts +0 -8
- package/dist/src/plugins/twake/spaces.d.ts +186 -0
- package/dist/src/plugins/twake/tombstone.d.ts +5 -0
- package/docs/plugin-development/README.md +21 -0
- package/docs/plugin-development/hooks.md +25 -0
- package/docs/usage/configuration.md +83 -4
- package/docs/usage/plugins/auth/hmac.md +6 -1
- package/docs/usage/plugins/integrations/README.md +6 -0
- package/docs/usage/plugins/integrations/groups.md +12 -5
- package/docs/usage/plugins/integrations/instances.md +0 -10
- package/docs/usage/plugins/integrations/lifecycle-events.md +3 -1
- package/docs/usage/plugins/integrations/spaces.md +221 -0
- package/docs/usage/plugins/ldap/raw.md +1 -1
- package/docs/usage/upgrading.md +131 -0
- package/package.json +6 -1
- package/static/browser/shared/utils/hmac.js +5 -0
- package/static/browser/shared/utils/hmac.js.map +1 -1
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Organization Spaces
|
|
2
|
+
|
|
3
|
+
`core/twake/spaces` serves the spaces of an organization under
|
|
4
|
+
`/api/v1/organizations/:id/spaces`. A space gathers users and groups of the
|
|
5
|
+
organization, each with a role in it: `viewer`, `editor` or `admin`.
|
|
6
|
+
|
|
7
|
+
## Behaviour
|
|
8
|
+
|
|
9
|
+
- A space lives in the organization's space branch, given by a DN pattern
|
|
10
|
+
where `{org}` stands for the organization id. Its `cn` is a generated UUID,
|
|
11
|
+
its name is in the display name attribute.
|
|
12
|
+
- A space holds DNs in three attributes, one per role. Each holds users of
|
|
13
|
+
the organization's user branch and groups of its group branch, the
|
|
14
|
+
branches [groups](groups.md) serves.
|
|
15
|
+
- A user or a group holds one role in a space. A user's role in a space is
|
|
16
|
+
the strongest of their own role and the roles of the linked groups they
|
|
17
|
+
belong to.
|
|
18
|
+
- The routes keep at least one admin among a space's users: a request that
|
|
19
|
+
would demote or remove the last one is refused with 409 `LAST_ADMIN`. A
|
|
20
|
+
linked group does not count as an admin. A tombstoned or erased admin is
|
|
21
|
+
not a request, and can leave a space with none.
|
|
22
|
+
- A space holds users and groups of its organization only: any other value is
|
|
23
|
+
refused with a 400, whichever API writes the space, or moves it straight
|
|
24
|
+
into another organization's space branch; a move refused names none of
|
|
25
|
+
them. Not checked: moving a space out of the organizations' branches (to
|
|
26
|
+
`ou=archive,…`, for instance) or deeper than one level under another
|
|
27
|
+
organization, which takes its holders along, and moving a user or group
|
|
28
|
+
to another organization, whose spaces in the one it left keep it. The
|
|
29
|
+
one role and the admin are kept by the routes below only; a user or group
|
|
30
|
+
a direct write, or two requests at once, left under two roles reads with
|
|
31
|
+
the strongest, and a role change or removal takes it out of all of them.
|
|
32
|
+
- A tombstone (see [tombstone](tombstone.md)) keeps its roles until it is
|
|
33
|
+
erased, and is hidden from the spaces read through these routes, whatever
|
|
34
|
+
the caller may read of the user branch: it never counts as an admin. It
|
|
35
|
+
cannot be added.
|
|
36
|
+
- An erased user or group leaves its spaces through the directory: enable the
|
|
37
|
+
`refint` overlay on the three role attributes.
|
|
38
|
+
- When a user who is erased or becomes a tombstone was the last admin among
|
|
39
|
+
a space's users, its editors become admins, or its viewers when it has no
|
|
40
|
+
editor. A space left with no user of its own is deleted, whatever groups
|
|
41
|
+
it links. Both happen shortly after the deletion, and publish their
|
|
42
|
+
events. Erasing a tombstone checks its spaces again, for a hand-over that
|
|
43
|
+
failed or was never made. The hand-over relies on refint: without it an erased admin's DN
|
|
44
|
+
stays in the space and still counts as an admin, so erasing two admins
|
|
45
|
+
one after the other hands nothing over. A write of the space made at the
|
|
46
|
+
same moment is retried twice; past that the hand-over is logged and left
|
|
47
|
+
undone.
|
|
48
|
+
- With `--twake-space-user-role-attribute`, each user entry holds one
|
|
49
|
+
`<space id>:<role>` value per space they are in, their resolved role. It
|
|
50
|
+
follows every write of a space, every change of a linked group's members,
|
|
51
|
+
and the deletion of a linked group, whichever API makes them, shortly after
|
|
52
|
+
the write. A change only tells which users to look at: each one's values
|
|
53
|
+
are then rewritten from the directory as it is, so changes made close
|
|
54
|
+
together end the same whatever order they are followed in. Values not
|
|
55
|
+
ending in `:viewer`, `:editor` or `:admin` are left alone. A tombstone keeps
|
|
56
|
+
the values it held when it was deleted.
|
|
57
|
+
- With `--rabbitmq-url`, every write of a space and every change of a
|
|
58
|
+
member's role is published as an event, see below.
|
|
59
|
+
- With either of the two, the plugin refuses to start when core/ldap/trash
|
|
60
|
+
watches the group or space branches: a group or space it moves away is
|
|
61
|
+
never followed.
|
|
62
|
+
|
|
63
|
+
## Events
|
|
64
|
+
|
|
65
|
+
Each event goes to the `--twake-space-exchange` topic exchange with the
|
|
66
|
+
routing key `twake.space.<event>`. Like the user role attribute, events follow
|
|
67
|
+
every write, whichever API makes it, shortly after it.
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"organizationId": "acme",
|
|
72
|
+
"id": "3b9e2c71-5d4a-4f0e-9c8b-1a2d6e7f8091",
|
|
73
|
+
"members": [
|
|
74
|
+
{
|
|
75
|
+
"uuid": "6f1c0a52-8e3b-4d7f-a9c2-5b0e1d4f7a83",
|
|
76
|
+
"username": "jdoe",
|
|
77
|
+
"email": "jdoe@acme.example.org",
|
|
78
|
+
"firstName": "John",
|
|
79
|
+
"lastName": "Doe",
|
|
80
|
+
"role": "editor"
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"actor": "jsmith",
|
|
84
|
+
"timestamp": "2026-10-06T09:12:44.512Z"
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Every event carries `organizationId`, `id` (the space), `actor` (who made
|
|
89
|
+
the write, when known) and `timestamp`. A member is described as above, its
|
|
90
|
+
`uuid` the user's `entryUUID`; a group is `{ id, name, role }`.
|
|
91
|
+
|
|
92
|
+
Writes made close together blur the actor: the member events of two writes
|
|
93
|
+
of one space or group followed together may go out under the first one's.
|
|
94
|
+
With `--twake-space-user-role-attribute`, the follow of a write may find a
|
|
95
|
+
role another write moved in another space, not followed yet: it publishes
|
|
96
|
+
that event with no actor, as the later follow finds nothing left to
|
|
97
|
+
announce.
|
|
98
|
+
|
|
99
|
+
- `created`: `name`, `members` (every user in the space with their resolved
|
|
100
|
+
role, linked groups' members included) and `groups`.
|
|
101
|
+
- `updated`: the changed `name`.
|
|
102
|
+
- `deleted`.
|
|
103
|
+
- `member.added`, `member.role.changed`, `member.removed`: `members`, the one
|
|
104
|
+
user whose resolved role changed, whatever the cause: a member write, a
|
|
105
|
+
group linked, unlinked or given another role, a user joining or leaving a
|
|
106
|
+
linked group. `member.removed` gives the role the user held.
|
|
107
|
+
- `group.linked`, `group.role.changed`, `group.unlinked`: `groups`, the one
|
|
108
|
+
group, with its name when the event is published. A deleted group is
|
|
109
|
+
unlinked from each of its spaces once, whether refint or a later write
|
|
110
|
+
takes its DN out of them; one unlinked, then deleted before the unlink is
|
|
111
|
+
followed, is unlinked too, under its id for a name. Renaming a linked group
|
|
112
|
+
publishes nothing.
|
|
113
|
+
|
|
114
|
+
A user who is deleted or becomes a tombstone publishes no member event.
|
|
115
|
+
|
|
116
|
+
The server does not start when the broker cannot be reached. An event the
|
|
117
|
+
broker cannot take once the server runs is logged with `result: "error"` and
|
|
118
|
+
not sent again.
|
|
119
|
+
|
|
120
|
+
Member events compare each moved user's roles before and after a change:
|
|
121
|
+
|
|
122
|
+
- With `--twake-space-user-role-attribute`, the roles before are the values
|
|
123
|
+
on the user's entry, so changes made close together announce each role
|
|
124
|
+
once, in whatever order they are followed.
|
|
125
|
+
- Without it, the roles before are worked out from the directory with the
|
|
126
|
+
change undone. Two changes followed late may announce a role twice, or
|
|
127
|
+
not at all. Consumers that need an exact copy resync from the routes.
|
|
128
|
+
|
|
129
|
+
## Routes
|
|
130
|
+
|
|
131
|
+
Every route answers 404 `ORGANIZATION_NOT_FOUND` when the organization entry
|
|
132
|
+
is missing, and 410 `ORGANIZATION_DELETED` when it is deleted. Errors are
|
|
133
|
+
`{ "error": "...", "code": "..." }`. A request an authorization plugin refuses
|
|
134
|
+
answers 403 `REFUSED`. A write answers `{ "success": true }` unless stated
|
|
135
|
+
otherwise.
|
|
136
|
+
|
|
137
|
+
A space reads, strongest role first:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"id": "3b9e2c71-5d4a-4f0e-9c8b-1a2d6e7f8091",
|
|
142
|
+
"name": "Design Sprint",
|
|
143
|
+
"organizationId": "acme",
|
|
144
|
+
"members": [
|
|
145
|
+
{ "username": "jsmith", "role": "admin" },
|
|
146
|
+
{ "username": "jdoe", "role": "editor" }
|
|
147
|
+
],
|
|
148
|
+
"groups": [{ "id": "c2a8e1f0-7b3d-4e9a-8f61-2d5b9c0e4a17", "role": "viewer" }]
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`username` is the RDN value of a user, `id` the `cn` of a group.
|
|
153
|
+
|
|
154
|
+
- `GET /spaces?page&limit&search&sortBy&sortOrder&user`: `search` (2
|
|
155
|
+
characters or more) matches the name; `sortBy` is `name`. With `user`, the
|
|
156
|
+
spaces that user is in, directly or through a linked group, each with the
|
|
157
|
+
user's `role` (404 `USER_NOT_FOUND` for an unknown user). Answers
|
|
158
|
+
`{ organizationId, spaces, pagination: { page, limit, total, totalPages } }`.
|
|
159
|
+
- `POST /spaces` with `{ name, members: [{ username, role }], groups?: [{ id, role }] }`:
|
|
160
|
+
`name` follows the [groups](groups.md) rule, `members` holds at least one
|
|
161
|
+
admin (400 `ADMIN_REQUIRED`), every user and group must exist in the
|
|
162
|
+
organization (404 `USER_NOT_FOUND`, `GROUP_NOT_FOUND`). Answers 201 with the
|
|
163
|
+
space.
|
|
164
|
+
- `GET /spaces/:spaceId`: the space, or 404 `SPACE_NOT_FOUND`.
|
|
165
|
+
- `PATCH /spaces/:spaceId` with `{ name }`: renames the space; any other
|
|
166
|
+
field is a 400.
|
|
167
|
+
- `DELETE /spaces/:spaceId`.
|
|
168
|
+
- `GET /spaces/:spaceId/members?page&limit&search&sortBy&sortOrder`: the
|
|
169
|
+
members' public profiles, as [groups](groups.md) answers them, each with
|
|
170
|
+
its `role`; `sortBy` is `uid` (default), `displayName`, `mail`, `jobTitle`
|
|
171
|
+
or `role`.
|
|
172
|
+
- `POST /spaces/:spaceId/members` with `{ usernames: [...], role }`: every
|
|
173
|
+
user must exist in the organization (404 `USER_NOT_FOUND`, nothing added),
|
|
174
|
+
at most `--twake-group-max-page-limit` per request, as for every list of
|
|
175
|
+
users or groups below.
|
|
176
|
+
A member already holding that role is left as is; one holding another role
|
|
177
|
+
answers 409 `MEMBER_EXISTS`, nothing added.
|
|
178
|
+
- `PATCH /spaces/:spaceId/members/:userId` with `{ role }`, and
|
|
179
|
+
`DELETE /spaces/:spaceId/members/:userId`: 404 `MEMBER_NOT_FOUND` for a
|
|
180
|
+
user who is not a member.
|
|
181
|
+
- `GET /spaces/:spaceId/groups`: `{ organizationId, id, groups }`, each group
|
|
182
|
+
`{ id, name, role }`, by name.
|
|
183
|
+
- `POST /spaces/:spaceId/groups` with `{ groupIds: [...], role }`: every group
|
|
184
|
+
must exist in the organization (404 `GROUP_NOT_FOUND`, nothing linked). A
|
|
185
|
+
group already linked with another role answers 409 `GROUP_ALREADY_LINKED`.
|
|
186
|
+
- `PATCH /spaces/:spaceId/groups/:groupId` with `{ role }`, and
|
|
187
|
+
`DELETE /spaces/:spaceId/groups/:groupId`: 404 `GROUP_NOT_FOUND` for a group
|
|
188
|
+
that is not linked.
|
|
189
|
+
|
|
190
|
+
## Configuration
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
--plugin core/twake/spaces \
|
|
194
|
+
--twake-space-base 'ou=spaces,ou={org},dc=example,dc=com'
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The plugin loads [groups](groups.md), and reads its options for the
|
|
198
|
+
organization's users, groups and organization entry.
|
|
199
|
+
|
|
200
|
+
- `--twake-space-base`: required, with `{org}`.
|
|
201
|
+
- `--twake-space-class` (default `top,twakeSpace`): the classes of a space
|
|
202
|
+
created.
|
|
203
|
+
- `--twake-space-display-name-attribute` (default `twakeDisplayName`).
|
|
204
|
+
- `--twake-space-admin-attribute` (default `twakeSpaceAdmin`),
|
|
205
|
+
`--twake-space-editor-attribute` (default `twakeSpaceEditor`),
|
|
206
|
+
`--twake-space-viewer-attribute` (default `twakeSpaceViewer`): the role
|
|
207
|
+
attributes, holding DNs.
|
|
208
|
+
- `--twake-space-user-role-attribute` (no default): the multi-valued user
|
|
209
|
+
attribute holding the user's role in each space, such as `twakeSpaceRole`.
|
|
210
|
+
Unset, no user entry is written.
|
|
211
|
+
- `--twake-space-exchange` (default `space`): the topic exchange of the
|
|
212
|
+
events, published only when `--rabbitmq-url` is set.
|
|
213
|
+
|
|
214
|
+
## Dependencies
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
core/twake/spaces
|
|
218
|
+
├─ requires: core/twake/groups
|
|
219
|
+
├─ requires: core/ldap/onChange
|
|
220
|
+
└─ requires: core/rabbitmq (with RabbitMQ)
|
|
221
|
+
```
|
|
@@ -17,7 +17,7 @@ The companion browser library is [`ldap-browser`](../../../client-development/br
|
|
|
17
17
|
|
|
18
18
|
### Environment Variables
|
|
19
19
|
|
|
20
|
-
- `DM_LDAP_RAW_BASE`:
|
|
20
|
+
- `DM_LDAP_RAW_BASE`: subtrees to expose, separated by `;` (default: `--ldap-base`)
|
|
21
21
|
- `DM_LDAP_RAW_HIDDEN_ATTRIBUTES`: comma-separated attributes never returned, on top of the credential ones (default: none)
|
|
22
22
|
- `DM_LDAP_RAW_SHOW_SECRETS`: serve credential attributes instead of hiding them (default: `false`)
|
|
23
23
|
- `DM_LDAP_RAW_MAX_RESULTS`: maximum entries returned by a search or a children listing (default: `200`)
|
package/docs/usage/upgrading.md
CHANGED
|
@@ -4,6 +4,130 @@ What to check before deploying, newest first. Only releases that need a
|
|
|
4
4
|
decision or a configuration change appear here; see the
|
|
5
5
|
[CHANGELOG](../../CHANGELOG.md) for everything else.
|
|
6
6
|
|
|
7
|
+
## To 0.15.0
|
|
8
|
+
|
|
9
|
+
### A DN option read from the environment splits on `;` only
|
|
10
|
+
|
|
11
|
+
**Who is affected:** a deployment that sets `DM_LDAP_RAW_BASE`,
|
|
12
|
+
`DM_JAMES_MAILING_LIST_BRANCHES`, `DM_TWAKE_TOMBSTONE_DN`,
|
|
13
|
+
`DM_TWAKE_TOMBSTONE_GROUP_BASES` or `DM_TWAKE_INSTANCE_DN`, or gives
|
|
14
|
+
`--ldap-raw-bases` or `--james-mailing-list-branches`.
|
|
15
|
+
|
|
16
|
+
Their values are no longer cut on spaces or commas: a DN such as
|
|
17
|
+
`DM_LDAP_RAW_BASE="ou=My Unit,dc=example,dc=com"` stays whole. Separate
|
|
18
|
+
several DNs with `;`, as already documented.
|
|
19
|
+
|
|
20
|
+
### HMAC and TOTP entries are no longer split on spaces
|
|
21
|
+
|
|
22
|
+
**Who is affected:** a deployment that sets `DM_AUTH_HMAC` or `DM_AUTH_TOTP`,
|
|
23
|
+
or gives `--auth-hmacs` or `--auth-totps`.
|
|
24
|
+
|
|
25
|
+
Separate entries with `,`, `;` or newlines. A name may now hold spaces, as in
|
|
26
|
+
`id:secret:Registration Service`. A list separated by spaces is read as one
|
|
27
|
+
entry: an HMAC list gives one service, the others cannot authenticate (their
|
|
28
|
+
requests get 401, and a warning is logged), and a TOTP list stops the server.
|
|
29
|
+
|
|
30
|
+
`core/auth/hmac` and `core/auth/totp` also stop the server on an entry that
|
|
31
|
+
cannot work, instead of skipping it with a warning: an HMAC entry with an
|
|
32
|
+
empty id, secret or name or fewer than 3 fields, a TOTP entry with an empty
|
|
33
|
+
secret or name, more than 3 fields, a secret that is not Base32 or digits that
|
|
34
|
+
are not an integer from 6 to 10. A TOTP entry such as `secret:name:abc` used
|
|
35
|
+
to register a user whose code was the string `NaN`.
|
|
36
|
+
|
|
37
|
+
### The plural command-line form of an array option splits on `;` first
|
|
38
|
+
|
|
39
|
+
**Who is affected:** a deployment that gives a plural form such as
|
|
40
|
+
`--auth-tokens`, `--ldap-urls` or `--plugins`.
|
|
41
|
+
|
|
42
|
+
A value containing `;` is now split on `;` and not on `,`, as the environment
|
|
43
|
+
variable does: `--auth-tokens 'a;b;c'` was one token and is now three, and
|
|
44
|
+
`--auth-tokens 'a;b,c'` was `a;b` and `c` and is now `a` and `b,c`. A value
|
|
45
|
+
without `;` is split as before.
|
|
46
|
+
|
|
47
|
+
`--authz-dynamic-bypass` and `--twake-space-class` now split on commas in their
|
|
48
|
+
singular form, as the other options holding identifiers do.
|
|
49
|
+
|
|
50
|
+
### An empty environment variable or a number that is not one
|
|
51
|
+
|
|
52
|
+
**Who is affected:** a deployment that sets an array option, a number or a JSON
|
|
53
|
+
option to an empty value, or a number option to something else than an integer.
|
|
54
|
+
|
|
55
|
+
- An array variable that is empty, only holds whitespace or only holds
|
|
56
|
+
separators (`DM_GROUP_CLASSES=`, `DM_GROUP_CLASSES=,`) keeps the default
|
|
57
|
+
instead of giving an empty list, which was a silent misconfiguration (a
|
|
58
|
+
server without object class, for instance). `DM_LDAP_OPERATIONAL_ATTRIBUTES=`
|
|
59
|
+
used to give `[]` and now gives the default; an option with a non-empty
|
|
60
|
+
default cannot be given an empty list from the environment.
|
|
61
|
+
- `DM_LDAP_URL=` is the exception: its default, `ldap://localhost`, is a guess,
|
|
62
|
+
not a fallback, so an empty value still stops the server. Set the variable
|
|
63
|
+
or leave it out.
|
|
64
|
+
- An empty number or JSON value (`DM_PORT=`) keeps its default instead of
|
|
65
|
+
giving `NaN` or stopping the server.
|
|
66
|
+
- A number option takes an integer only: `DM_PORT=abc`, `DM_PORT=1e3`,
|
|
67
|
+
`DM_PORT=8080abc`, `--port ''` or `--port --log-level debug` stop the server
|
|
68
|
+
instead of giving `NaN` or a truncated value.
|
|
69
|
+
|
|
70
|
+
Booleans and strings are unchanged.
|
|
71
|
+
|
|
72
|
+
### An array option on the command line replaces its default
|
|
73
|
+
|
|
74
|
+
**Who is affected:** a deployment that gives, on the command line, an array
|
|
75
|
+
option that has a default: `--user-class`, `--group-class`,
|
|
76
|
+
`--ldap-organization-class`, `--external-branch-class`,
|
|
77
|
+
`--scim-user-object-class`, `--scim-group-object-class`,
|
|
78
|
+
`--applicative-account-attribute`, `--ldap-operational-attribute` or
|
|
79
|
+
`--ldap-url`, in their singular or plural form.
|
|
80
|
+
|
|
81
|
+
Their values used to be added to the default, and now replace it. Repeat the
|
|
82
|
+
default values you want to keep:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Until now: top, twakeAccount, twakeWhitePages, twakeExtra
|
|
86
|
+
ldap-rest --user-class twakeExtra
|
|
87
|
+
|
|
88
|
+
# Now
|
|
89
|
+
ldap-rest --user-class top,twakeAccount,twakeWhitePages,twakeExtra
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Without its default classes, an entry is created without its structural
|
|
93
|
+
class. Without the default operational attributes, `appAccountsConsistency`
|
|
94
|
+
recreates an applicative account with `userPassword` and the attributes the
|
|
95
|
+
directory generates. The defaults are listed in
|
|
96
|
+
[the configuration reference](configuration.md).
|
|
97
|
+
|
|
98
|
+
`--ldap-url ldap://ldap.example.com` no longer keeps `ldap://localhost` next
|
|
99
|
+
to it.
|
|
100
|
+
|
|
101
|
+
An environment variable already replaced the default, and values given on the
|
|
102
|
+
command line are still added to it.
|
|
103
|
+
|
|
104
|
+
## To 0.14.0
|
|
105
|
+
|
|
106
|
+
### `--twake-instance-organization-account` is removed
|
|
107
|
+
|
|
108
|
+
**Who is affected:** a deployment that sets
|
|
109
|
+
`--twake-instance-organization-account` or
|
|
110
|
+
`DM_TWAKE_INSTANCE_ORGANIZATION_ACCOUNT`.
|
|
111
|
+
|
|
112
|
+
The option is ignored, and no account gets the organization's address any
|
|
113
|
+
more. An account that already got it keeps it. To copy the address to
|
|
114
|
+
accounts yourself, set `--twake-instance-organization-fqdn-attribute`. The
|
|
115
|
+
organization entry then keeps the address, but only for organizations
|
|
116
|
+
announced from then on. An organization already announced does not get it:
|
|
117
|
+
take its address from its account or from the Cloudery.
|
|
118
|
+
|
|
119
|
+
### HMAC refuses a body it does not sign
|
|
120
|
+
|
|
121
|
+
**Who is affected:** a client of `core/auth/hmac` that sends a body with a
|
|
122
|
+
GET, DELETE or HEAD, or a signed body under a `charset` other than UTF-8.
|
|
123
|
+
|
|
124
|
+
These methods are signed without a body, so one they carried reached the
|
|
125
|
+
route unsigned; and the signature covers the bytes, not the charset that says
|
|
126
|
+
how to read them. Both are now answered `401`: send GET, DELETE and HEAD
|
|
127
|
+
without a body (and without `Transfer-Encoding`, which announces one), and
|
|
128
|
+
bodies in UTF-8
|
|
129
|
+
([#257](https://github.com/linagora/ldap-rest/issues/257)).
|
|
130
|
+
|
|
7
131
|
## To 0.13.3
|
|
8
132
|
|
|
9
133
|
### HMAC hashes the body bytes received
|
|
@@ -20,6 +144,13 @@ bundled browser client does, sees no change. One that hashed a
|
|
|
20
144
|
hash the bytes sent instead, before compressing them if the request carries
|
|
21
145
|
a `Content-Encoding`.
|
|
22
146
|
|
|
147
|
+
A request without a body is signed with an empty `body-hash`, as documented.
|
|
148
|
+
0.13.2 hashed the `{}` the parser left for a request that carries
|
|
149
|
+
`Content-Type: application/json` without a body, and required
|
|
150
|
+
`sha256("{}")`. A client that signs this way is now refused with `401`. The
|
|
151
|
+
bundled browser client sends no `Content-Type` without a body and is not
|
|
152
|
+
affected.
|
|
153
|
+
|
|
23
154
|
## To 0.13.2
|
|
24
155
|
|
|
25
156
|
### HMAC refuses a body it cannot check
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ldap-rest",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Light directory manager",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Identity-Manager"
|
|
@@ -288,6 +288,10 @@
|
|
|
288
288
|
"types": "./dist/src/plugins/twake/lifecycleEvents.d.ts",
|
|
289
289
|
"import": "./dist/plugins/twake/lifecycleEvents.js"
|
|
290
290
|
},
|
|
291
|
+
"./plugin-twake-spaces": {
|
|
292
|
+
"types": "./dist/src/plugins/twake/spaces.d.ts",
|
|
293
|
+
"import": "./dist/plugins/twake/spaces.js"
|
|
294
|
+
},
|
|
291
295
|
"./plugin-twake-tombstone": {
|
|
292
296
|
"types": "./dist/src/plugins/twake/tombstone.d.ts",
|
|
293
297
|
"import": "./dist/plugins/twake/tombstone.js"
|
|
@@ -733,6 +737,7 @@
|
|
|
733
737
|
"fast-xml-parser": ">=5.3.6",
|
|
734
738
|
"glob": ">=11.0.4",
|
|
735
739
|
"minimatch": "^10.2.1",
|
|
740
|
+
"postcss-selector-parser": "^7.1.6",
|
|
736
741
|
"serialize-javascript": ">=7.0.3"
|
|
737
742
|
},
|
|
738
743
|
"dependencies": {
|
|
@@ -120,6 +120,11 @@ class HmacAuthClient {
|
|
|
120
120
|
return undefined;
|
|
121
121
|
}
|
|
122
122
|
if (typeof body === 'string') {
|
|
123
|
+
// fetch would send it as text/plain, which the server does not read:
|
|
124
|
+
// a string here is JSON already serialized, unless the caller says
|
|
125
|
+
// otherwise
|
|
126
|
+
if (!headers.has('Content-Type'))
|
|
127
|
+
headers.set('Content-Type', 'application/json');
|
|
123
128
|
return body;
|
|
124
129
|
}
|
|
125
130
|
if (body instanceof FormData) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmac.js","sources":["../../../../../src/browser/shared/utils/hmac.ts"],"sourcesContent":[null],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"hmac.js","sources":["../../../../../src/browser/shared/utils/hmac.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|