ldap-rest 0.0.1 → 0.1.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.
Files changed (62) hide show
  1. package/README.md +38 -0
  2. package/bin/sync-app-accounts.mjs +276 -0
  3. package/dist/abstract/ldapFlat.js +1 -1
  4. package/dist/abstract/plugin.js +1 -1
  5. package/dist/bin/index.js +1 -1
  6. package/dist/config/args.js +1 -1
  7. package/dist/lib/ldapActions.js +1 -1
  8. package/dist/lib/utils.js +1 -1
  9. package/dist/logger/winston.js +1 -1
  10. package/dist/plugins/auth/hmac.js +1 -0
  11. package/dist/plugins/auth/totp.js +1 -0
  12. package/dist/plugins/demo/helloworld.js +1 -1
  13. package/dist/plugins/ldap/groups.js +1 -1
  14. package/dist/plugins/ldap/onChange.js +1 -1
  15. package/dist/plugins/static.js +1 -1
  16. package/dist/plugins/twake/appAccountsApi.js +1 -0
  17. package/dist/plugins/twake/appAccountsConsistency.js +1 -0
  18. package/dist/plugins/twake/james.js +1 -1
  19. package/dist/plugins/weblogs.js +1 -1
  20. package/dist/src/abstract/ldapFlat.d.ts +0 -5
  21. package/dist/src/abstract/plugin.d.ts +1 -0
  22. package/dist/src/bin/index.d.ts +1 -0
  23. package/dist/src/browser/shared/index.d.ts +1 -0
  24. package/dist/src/browser/shared/utils/hmac.d.ts +73 -0
  25. package/dist/src/browser/shared/utils/totp.d.ts +64 -0
  26. package/dist/src/config/args.d.ts +9 -1
  27. package/dist/src/hooks.d.ts +2 -2
  28. package/dist/src/lib/ldapActions.d.ts +3 -7
  29. package/dist/src/lib/utils.d.ts +17 -0
  30. package/dist/src/logger/winston.d.ts +5 -0
  31. package/dist/src/plugins/auth/hmac.d.ts +24 -0
  32. package/dist/src/plugins/auth/totp.d.ts +28 -0
  33. package/dist/src/plugins/ldap/onChange.d.ts +1 -0
  34. package/dist/src/plugins/static.d.ts +4 -0
  35. package/dist/src/plugins/twake/appAccountsApi.d.ts +52 -0
  36. package/dist/src/plugins/twake/appAccountsConsistency.d.ts +58 -0
  37. package/docs/DEVELOPER_GUIDE.md +1 -0
  38. package/docs/PLUGIN_DEPENDENCIES.md +19 -0
  39. package/docs/README.md +76 -30
  40. package/docs/authentication.md +604 -12
  41. package/docs/plugins/DEVELOPMENT.md +162 -76
  42. package/docs/testing-with-embedded-ldap.md +347 -0
  43. package/docs/twakeAppAccountsApi.md +485 -0
  44. package/docs/weblogs.md +37 -8
  45. package/examples/web/README.md +175 -0
  46. package/examples/web/ldap-tree-viewer.html +16 -2
  47. package/examples/web/totp-client.html +541 -0
  48. package/package.json +132 -87
  49. package/static/browser/shared/index.js +1 -0
  50. package/static/browser/shared/index.js.map +1 -1
  51. package/static/browser/shared/utils/hmac.js +202 -0
  52. package/static/browser/shared/utils/hmac.js.map +1 -0
  53. package/static/browser/shared/utils/totp.js +182 -0
  54. package/static/browser/shared/utils/totp.js.map +1 -0
  55. package/static/browser/shared.esm.js +181 -1
  56. package/static/browser/shared.esm.js.map +1 -1
  57. package/static/browser/shared.js +184 -0
  58. package/static/browser/shared.js.map +1 -1
  59. package/static/browser/shared.min.js +1 -1
  60. package/static/browser/shared.min.js.map +1 -1
  61. package/static/schemas/obm/organizations.json +24 -0
  62. package/static/schemas/obm/users.json +192 -0
@@ -0,0 +1,485 @@
1
+ # Twake Applicative Accounts API Plugin
2
+
3
+ RESTful API for managing applicative accounts (device/app-specific accounts) for users.
4
+
5
+ ## Overview
6
+
7
+ The `twake/appAccountsApi` plugin provides API endpoints for creating, listing, and deleting applicative accounts. These are secondary accounts that allow users to have multiple passwords for different devices or applications, each identified by a unique uid (e.g., `username_c12345678`).
8
+
9
+ Applicative accounts are stored in a separate LDAP branch (e.g., `ou=applicative`) and share the same mail address as the principal user account.
10
+
11
+ ## Why Applicative Accounts?
12
+
13
+ Instead of using a single primary password to access all services that authenticate via LDAP, the applicative accounts system provides separation of concerns:
14
+
15
+ ### Primary Authentication
16
+
17
+ - The primary authentication system may not use passwords at all (e.g., smart cards, biometrics, SSO)
18
+ - Users authenticate once with their primary credentials (which may be strong 2FA/MFA)
19
+ - Primary account remains secure and is not exposed to application protocols
20
+
21
+ ### Application-Specific Accounts
22
+
23
+ - Dedicated accounts for specific applications or devices
24
+ - Each device/app gets its own isolated password
25
+ - Essential for protocols that require password authentication: **IMAP**, **SMTP**, **CalDAV**, **CardDAV**, etc.
26
+ - Benefits:
27
+ - **Security**: Compromise of one device doesn't expose the primary account
28
+ - **Revocation**: Delete individual app accounts without affecting others
29
+ - **Auditing**: Track which device/app is accessing which service
30
+ - **Device identification**: Each account can be labeled (e.g., "My Phone", "My Laptop")
31
+
32
+ ### Use Cases
33
+
34
+ 1. **Email clients (IMAP/SMTP)**: Create an app account for each device accessing email
35
+ 2. **Calendar sync (CalDAV)**: Separate credentials for calendar applications
36
+ 3. **Contact sync (CardDAV)**: Dedicated account for contact synchronization
37
+ 4. **Legacy applications**: Apps that require password auth but can't use modern auth methods
38
+ 5. **API access**: Service accounts for automated tools that need LDAP authentication
39
+
40
+ ## Prerequisites
41
+
42
+ 1. **Authentication plugin** loaded (e.g., `core/auth/token`) - **Required**
43
+ 2. **App accounts consistency plugin** `core/twake/appAccountsConsistency` - **Required**
44
+ - Automatically creates principal accounts (uid=mail@domain.com)
45
+ - Ensures automatic cleanup when users are deleted
46
+ - Synchronizes mail changes across all app accounts
47
+ 3. **Applicative accounts base** configured in LDAP (e.g., `ou=applicative,dc=example,dc=com`)
48
+
49
+ ## Configuration
50
+
51
+ ```bash
52
+ --plugin core/auth/token \
53
+ --plugin core/ldap/onChange \
54
+ --plugin twake/appAccountsConsistency \
55
+ --plugin twake/appAccountsApi \
56
+ --auth-token "secret-token" \
57
+ --applicative-account-base "ou=applicative,dc=example,dc=com" \
58
+ --max-app-accounts 5 \
59
+ --mail-attribute mail
60
+ ```
61
+
62
+ **Environment Variables:**
63
+
64
+ ```bash
65
+ DM_AUTH_TOKEN="secret-token"
66
+ DM_APPLICATIVE_ACCOUNT_BASE="ou=applicative,dc=example,dc=com"
67
+ DM_MAX_APP_ACCOUNTS=5
68
+ DM_MAIL_ATTRIBUTE="mail"
69
+ ```
70
+
71
+ ### Parameters
72
+
73
+ - `--applicative-account-base`: LDAP base DN for applicative accounts (required)
74
+ - `--max-app-accounts`: Maximum number of app accounts per user (default: 5)
75
+ - `--mail-attribute`: LDAP attribute for email (default: `mail`)
76
+ - `--api-prefix`: API endpoint prefix (default: `/api`)
77
+
78
+ ## LDAP Structure
79
+
80
+ ### Principal Account
81
+
82
+ Created automatically by `twake/appAccountsConsistency` plugin when a user with a mail attribute is added:
83
+
84
+ ```
85
+ dn: uid=alice@example.com,ou=applicative,dc=example,dc=com
86
+ objectClass: inetOrgPerson
87
+ uid: alice@example.com
88
+ cn: Alice Smith
89
+ sn: Smith
90
+ mail: alice@example.com
91
+ userPassword: {SSHA}hash1...
92
+ userPassword: {SSHA}hash2...
93
+ userPassword: {SSHA}hash3...
94
+ ```
95
+
96
+ The principal account stores multiple passwords (one for each applicative account).
97
+
98
+ ### Applicative Accounts
99
+
100
+ Created via API:
101
+
102
+ ```
103
+ dn: uid=alice_c12345678,ou=applicative,dc=example,dc=com
104
+ objectClass: inetOrgPerson
105
+ uid: alice_c12345678
106
+ cn: Alice Smith
107
+ sn: Smith
108
+ mail: alice@example.com
109
+ userPassword: {SSHA}hash1...
110
+ description: My Phone
111
+ ```
112
+
113
+ Each applicative account:
114
+
115
+ - Has a unique uid with format: `{username}_c{8-digits}`
116
+ - Shares the same mail as the user
117
+ - Has its own password
118
+ - Optional description field for device name
119
+
120
+ ## API Endpoints
121
+
122
+ ### List Applicative Accounts
123
+
124
+ ```http
125
+ GET /api/v1/users/{username}/app-accounts
126
+ Authorization: Bearer {token}
127
+ ```
128
+
129
+ **Response:**
130
+
131
+ ```json
132
+ [
133
+ {
134
+ "uid": "alice_c12345678",
135
+ "name": "My Phone"
136
+ },
137
+ {
138
+ "uid": "alice_c87654321",
139
+ "name": "My Laptop"
140
+ }
141
+ ]
142
+ ```
143
+
144
+ **Status Codes:**
145
+
146
+ - `200 OK` - Success
147
+ - `401 Unauthorized` - Missing or invalid token
148
+ - `404 Not Found` - User not found
149
+
150
+ ### Create Applicative Account
151
+
152
+ ```http
153
+ POST /api/v1/users/{username}/app-accounts
154
+ Authorization: Bearer {token}
155
+ Content-Type: application/json
156
+
157
+ {
158
+ "name": "My Phone"
159
+ }
160
+ ```
161
+
162
+ **Request Body:**
163
+
164
+ - `name` (optional): Description/device name
165
+
166
+ **Response:**
167
+
168
+ ```json
169
+ {
170
+ "uid": "alice_c12345678",
171
+ "pwd": "AbC3@-2xYz!-9pQr@-St4v!-mN8#-pQ5$",
172
+ "mail": "alice@example.com"
173
+ }
174
+ ```
175
+
176
+ **Important**: The password is only returned once during creation. It cannot be retrieved later.
177
+
178
+ **Status Codes:**
179
+
180
+ - `200 OK` - Account created
181
+ - `400 Bad Request` - Max accounts limit reached or user has no mail
182
+ - `401 Unauthorized` - Missing or invalid token
183
+ - `404 Not Found` - User not found
184
+
185
+ ### Delete Applicative Account
186
+
187
+ ```http
188
+ DELETE /api/v1/users/{username}/app-accounts/{uid}
189
+ Authorization: Bearer {token}
190
+ ```
191
+
192
+ **Response:**
193
+
194
+ ```json
195
+ {
196
+ "uid": "alice_c12345678"
197
+ }
198
+ ```
199
+
200
+ **Status Codes:**
201
+
202
+ - `200 OK` - Account deleted (or already deleted - idempotent)
203
+ - `401 Unauthorized` - Missing or invalid token
204
+ - `403 Forbidden` - UID does not belong to user
205
+
206
+ ## Password Generation
207
+
208
+ Applicative account passwords are generated automatically with the following characteristics:
209
+
210
+ - **Format**: 6 blocks of 4 characters separated by `-`
211
+ - **Length**: 29 characters total
212
+ - **Example**: `AbC3@-2xYz!-9pQr@-St4v!-mN8#-pQ5$`
213
+ - **Character classes**: Each block contains:
214
+ - 1 uppercase letter (A-Z, excluding I, L, O)
215
+ - 1 lowercase letter (a-z, excluding i, l, o)
216
+ - 1 digit (2-9)
217
+ - 1 special character (@, !, #, $, %)
218
+
219
+ Passwords are passed to LDAP in cleartext. OpenLDAP's ppolicy overlay automatically hashes them using SSHA.
220
+
221
+ ## Command-Line Utility
222
+
223
+ The `sync-app-accounts` utility maintains consistency between user and applicative account branches:
224
+
225
+ ```bash
226
+ # Preview changes
227
+ sync-app-accounts --dry-run
228
+
229
+ # Execute synchronization
230
+ sync-app-accounts
231
+
232
+ # Quiet mode (for cron)
233
+ sync-app-accounts --quiet
234
+
235
+ # Show help
236
+ sync-app-accounts --help
237
+ ```
238
+
239
+ **Operations performed:**
240
+
241
+ 1. **Create missing principal accounts** - For users with mail but no `uid=mail` in applicative base
242
+ 2. **Delete orphaned applicative accounts** - `username_cXXXXXXXX` entries where username no longer exists
243
+ 3. **Delete orphaned principal accounts** - `uid=mail` entries where no user has that mail
244
+
245
+ **Recommended usage:**
246
+
247
+ ```bash
248
+ # Add to cron (run nightly)
249
+ 0 2 * * * /usr/local/bin/sync-app-accounts --quiet
250
+ ```
251
+
252
+ ## How It Works
253
+
254
+ ### Account Creation Flow
255
+
256
+ 1. Client requests new app account via `POST /api/v1/users/alice/app-accounts`
257
+ 2. Plugin validates:
258
+ - User exists in LDAP
259
+ - User has mail attribute
260
+ - Max accounts limit not reached
261
+ 3. Plugin generates:
262
+ - Unique account ID (`c12345678`)
263
+ - Secure random password
264
+ 4. Plugin creates applicative account in LDAP:
265
+ - `uid=alice_c12345678,ou=applicative,dc=example,dc=com`
266
+ - Copies attributes from user (cn, sn, mail, etc.)
267
+ - Sets generated password
268
+ 5. Plugin adds password to principal account:
269
+ - `uid=alice@example.com,ou=applicative,dc=example,dc=com`
270
+ - Adds password as additional `userPassword` value
271
+ 6. Returns credentials to client (only time password is visible)
272
+
273
+ ### Account Deletion Flow
274
+
275
+ 1. Client requests deletion via `DELETE /api/v1/users/alice/app-accounts/alice_c12345678`
276
+ 2. Plugin validates:
277
+ - UID belongs to user (starts with `alice_`)
278
+ 3. Plugin retrieves account from LDAP
279
+ 4. Plugin deletes password from principal account:
280
+ - Removes specific `userPassword` value
281
+ 5. Plugin deletes applicative account from LDAP
282
+ 6. Returns success (idempotent - no error if already deleted)
283
+
284
+ ### Authentication Flow
285
+
286
+ Users can authenticate with:
287
+
288
+ - **Principal account**: `uid=alice@example.com` + any app account password
289
+ - **Applicative account**: `uid=alice_c12345678` + its specific password
290
+
291
+ This allows revoking a single device's access by deleting its applicative account without affecting other devices.
292
+
293
+ ## Integration Example
294
+
295
+ ### JavaScript/TypeScript
296
+
297
+ ```typescript
298
+ import axios from 'axios';
299
+
300
+ const API_BASE = 'http://localhost:8081/api/v1';
301
+ const TOKEN = 'your-api-token';
302
+
303
+ // List accounts
304
+ const accounts = await axios.get(`${API_BASE}/users/alice/app-accounts`, {
305
+ headers: { Authorization: `Bearer ${TOKEN}` },
306
+ });
307
+ console.log(accounts.data);
308
+ // [{ uid: "alice_c12345678", name: "My Phone" }]
309
+
310
+ // Create account
311
+ const newAccount = await axios.post(
312
+ `${API_BASE}/users/alice/app-accounts`,
313
+ { name: 'My Laptop' },
314
+ { headers: { Authorization: `Bearer ${TOKEN}` } }
315
+ );
316
+ console.log(newAccount.data);
317
+ // { uid: "alice_c87654321", pwd: "...", mail: "alice@example.com" }
318
+
319
+ // Delete account
320
+ await axios.delete(`${API_BASE}/users/alice/app-accounts/alice_c87654321`, {
321
+ headers: { Authorization: `Bearer ${TOKEN}` },
322
+ });
323
+ ```
324
+
325
+ ### curl
326
+
327
+ ```bash
328
+ # List accounts
329
+ curl -H "Authorization: Bearer secret-token" \
330
+ http://localhost:8081/api/v1/users/alice/app-accounts
331
+
332
+ # Create account
333
+ curl -X POST \
334
+ -H "Authorization: Bearer secret-token" \
335
+ -H "Content-Type: application/json" \
336
+ -d '{"name":"My Phone"}' \
337
+ http://localhost:8081/api/v1/users/alice/app-accounts
338
+
339
+ # Delete account
340
+ curl -X DELETE \
341
+ -H "Authorization: Bearer secret-token" \
342
+ http://localhost:8081/api/v1/users/alice/app-accounts/alice_c12345678
343
+ ```
344
+
345
+ ## Use Cases
346
+
347
+ ### Mobile App Credentials
348
+
349
+ Users can create separate credentials for mobile devices:
350
+
351
+ ```bash
352
+ # User creates account for phone
353
+ POST /api/v1/users/alice/app-accounts
354
+ {"name": "iPhone"}
355
+
356
+ # Returns: { uid: "alice_c11111111", pwd: "..." }
357
+
358
+ # User enters credentials in phone app
359
+ # Phone uses alice@example.com + generated password
360
+ ```
361
+
362
+ If phone is lost:
363
+
364
+ ```bash
365
+ # Revoke phone access
366
+ DELETE /api/v1/users/alice/app-accounts/alice_c11111111
367
+
368
+ # Other devices continue working
369
+ ```
370
+
371
+ ### Application-Specific Passwords
372
+
373
+ Users can create passwords for different applications:
374
+
375
+ ```bash
376
+ POST /api/v1/users/alice/app-accounts {"name": "Email Client"}
377
+ POST /api/v1/users/alice/app-accounts {"name": "Calendar Sync"}
378
+ POST /api/v1/users/alice/app-accounts {"name": "Backup Tool"}
379
+ ```
380
+
381
+ Each application gets its own password that can be revoked independently.
382
+
383
+ ### Security Compliance
384
+
385
+ - Enforce maximum accounts per user
386
+ - Track which devices have access (via description)
387
+ - Revoke compromised credentials without resetting main password
388
+ - Audit trail via LDAP change logs
389
+
390
+ ## Security Considerations
391
+
392
+ 1. **Password Visibility**: Generated passwords are only returned once during creation. Store them securely on the client side.
393
+
394
+ 2. **Token Protection**: API requires bearer token authentication. Keep tokens secure and rotate regularly.
395
+
396
+ 3. **Account Limits**: Configure `max_app_accounts` based on your security policy to prevent abuse.
397
+
398
+ 4. **Password Policy**: Ensure OpenLDAP ppolicy overlay is configured to enforce password hashing and quality requirements.
399
+
400
+ 5. **Audit Logging**: Enable `weblogs` plugin to track account creation/deletion:
401
+
402
+ ```bash
403
+ --plugin core/weblogs
404
+ ```
405
+
406
+ 6. **HTTPS**: Always use HTTPS in production to protect passwords in transit.
407
+
408
+ ## Troubleshooting
409
+
410
+ ### "User not found" error
411
+
412
+ **Cause**: User doesn't exist in LDAP or username incorrect
413
+
414
+ **Solution**: Verify user exists:
415
+
416
+ ```bash
417
+ ldapsearch -x -b "dc=example,dc=com" "(uid=alice)"
418
+ ```
419
+
420
+ ### "User has no mail attribute" error
421
+
422
+ **Cause**: User entry missing mail attribute
423
+
424
+ **Solution**: Add mail to user:
425
+
426
+ ```bash
427
+ PUT /api/v1/ldap/users/alice
428
+ {"mail": "alice@example.com"}
429
+ ```
430
+
431
+ ### "Maximum number of accounts reached" error
432
+
433
+ **Cause**: User already has max_app_accounts applicative accounts
434
+
435
+ **Solution**: Delete unused accounts or increase limit:
436
+
437
+ ```bash
438
+ DELETE /api/v1/users/alice/app-accounts/alice_c11111111
439
+ ```
440
+
441
+ ### Principal account not created
442
+
443
+ **Cause**: `twake/appAccountsConsistency` plugin not loaded
444
+
445
+ **Solution**: Load plugin before `appAccountsApi`:
446
+
447
+ ```bash
448
+ --plugin twake/appAccountsConsistency \
449
+ --plugin twake/appAccountsApi
450
+ ```
451
+
452
+ ### Password rejected by LDAP
453
+
454
+ **Cause**: OpenLDAP ppolicy configuration issue
455
+
456
+ **Solution**: Check ppolicy configuration:
457
+
458
+ ```bash
459
+ ldapsearch -x -LLL -b "cn=config" "(objectClass=olcPPolicyConfig)"
460
+ ```
461
+
462
+ Ensure `olcPPolicyHashCleartext: TRUE` is set.
463
+
464
+ ## Dependencies
465
+
466
+ This plugin requires:
467
+
468
+ 1. **authToken plugin** (or another auth plugin) - For API authentication
469
+ 2. **twake/appAccountsConsistency plugin** - For automatic principal account creation
470
+
471
+ Optional:
472
+
473
+ - **core/ldap/onChange plugin** - Already required by appAccountsConsistency
474
+
475
+ ## Related Plugins
476
+
477
+ - **[twake/appAccountsConsistency](./appAccountsConsistency.md)** - Automatic principal account creation
478
+ - **[authentication](./authentication.md)** - API authentication
479
+ - **[onChange](./onChange.md)** - LDAP change detection
480
+
481
+ ## See Also
482
+
483
+ - [REST API Reference](./api/REST_API.md)
484
+ - [Developer Guide](./DEVELOPER_GUIDE.md)
485
+ - [Plugin Dependencies](./PLUGIN_DEPENDENCIES.md)
package/docs/weblogs.md CHANGED
@@ -26,11 +26,11 @@ Each request is logged when it arrives:
26
26
 
27
27
  ### Response Logging
28
28
 
29
- Each response is logged when completed:
29
+ Each response is logged when completed at **notice** level (between info and warn):
30
30
 
31
31
  ```json
32
32
  {
33
- "level": "info",
33
+ "level": "notice",
34
34
  "message": "GET /api/v1/ldap/users 200 45ms",
35
35
  "user": "admin",
36
36
  "method": "GET",
@@ -167,12 +167,21 @@ Track authorization failures:
167
167
  Configure log level to control verbosity:
168
168
 
169
169
  ```bash
170
- --log-level debug # All requests + debug info
171
- --log-level info # Completed requests only
172
- --log-level warn # Only warnings and errors
173
- --log-level error # Only errors
170
+ --log-level debug # All requests + debug info
171
+ --log-level info # Completed requests + info messages
172
+ --log-level notice # Completed requests (web logs) only
173
+ --log-level warn # Only warnings and errors (no web logs)
174
+ --log-level error # Only errors
174
175
  ```
175
176
 
177
+ The log level hierarchy (following syslog convention):
178
+
179
+ - **error** (0) - Error messages only
180
+ - **warn** (1) - Warnings and errors
181
+ - **notice** (2) - Web access logs, warnings and errors
182
+ - **info** (3) - General info messages, web logs, warnings and errors
183
+ - **debug** (4) - All messages including debug output
184
+
176
185
  ### Debug Level
177
186
 
178
187
  ```bash
@@ -188,6 +197,22 @@ Output:
188
197
  [info] POST /api/v1/ldap/users 201 123ms
189
198
  ```
190
199
 
200
+ ### Notice Level (Recommended)
201
+
202
+ ```bash
203
+ --plugin core/weblogs \
204
+ --log-level notice
205
+ ```
206
+
207
+ Output:
208
+
209
+ ```
210
+ [notice] POST /api/v1/ldap/users 201 123ms {"user":"admin"}
211
+ [notice] GET /api/v1/ldap/users 200 45ms {"user":"admin"}
212
+ ```
213
+
214
+ This level shows only web access logs without general info messages, ideal for production.
215
+
191
216
  ### Info Level
192
217
 
193
218
  ```bash
@@ -198,10 +223,14 @@ Output:
198
223
  Output:
199
224
 
200
225
  ```
201
- [info] POST /api/v1/ldap/users 201 123ms {"user":"admin"}
202
- [info] GET /api/v1/ldap/users 200 45ms {"user":"admin"}
226
+ [info] LDAP connection pool initialized: size=5, ttl=60s
227
+ [info] Plugin loaded: core/weblogs
228
+ [notice] POST /api/v1/ldap/users 201 123ms {"user":"admin"}
229
+ [notice] GET /api/v1/ldap/users 200 45ms {"user":"admin"}
203
230
  ```
204
231
 
232
+ This level includes general info messages along with web logs.
233
+
205
234
  ## Event Handling
206
235
 
207
236
  The plugin logs three types of events: