ldap-rest 0.4.5 → 0.4.7

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/README.md CHANGED
@@ -53,6 +53,28 @@ LDAP-Rest uses syslog-style log levels:
53
53
 
54
54
  Use `--log-level notice` for production to see web access logs without general info messages.
55
55
 
56
+ ## Deployment
57
+
58
+ ### Docker
59
+
60
+ Multi-arch (amd64/arm64) images are published on each release:
61
+
62
+ ```shell
63
+ docker run -p 8081:8081 ghcr.io/linagora/ldap-rest:latest
64
+ # also available on Docker Hub as yadd/ldap-rest
65
+ ```
66
+
67
+ ### Helm
68
+
69
+ A Helm chart is published as an OCI artifact on each release:
70
+
71
+ ```shell
72
+ helm install ldap-rest oci://ghcr.io/linagora/charts/ldap-rest
73
+ ```
74
+
75
+ See the **[Helm chart README](./helm/ldap-rest/README.md)** for configuration
76
+ (image, `env`/`secrets`, ingress, probes, …).
77
+
56
78
  ## Configuration
57
79
 
58
80
  See **[Configuration Guide](./docs/usage/configuration.md)** for all CLI options and environment variables.
@@ -67,6 +89,7 @@ Installation, configuration and plugin usage.
67
89
 
68
90
  - **[Getting Started](./docs/usage/README.md)** - Quick start guide
69
91
  - **[Configuration](./docs/usage/configuration.md)** - CLI options and environment variables
92
+ - **[Helm chart](./helm/ldap-rest/README.md)** - Kubernetes deployment
70
93
  - **[Plugins](./docs/usage/plugins/README.md)** - Plugin documentation
71
94
  - **[Authentication](./docs/usage/plugins/auth/README.md)** - Token, TOTP, HMAC, LemonLDAP::NG, OpenID Connect
72
95
 
@@ -1 +1 @@
1
- import e from"../abstract/plugin.js";class WebLogs extends e{constructor(){super(...arguments),this.name="weblogs",this.roles=["logging"]}api(e){e.use((e,r,o)=>{let s=!0;this.logger.debug(`Incoming request: ${e.method} ${e.originalUrl}`);const t=Date.now();r.on("finish",()=>{const o={};e.proxyAuthUser?o.user=e.proxyAuthUser:e.user&&(o.user=e.user),s&&this.log(e,r,t,o),s=!1}),r.on("error",o=>{s&&this.log(e,r,t,{error:o.message}),s=!1}),r.on("close",()=>{r.writableEnded||(s&&this.log(e,r,t,{error:`Connection closed before response was sent for ${e.method} ${e.originalUrl}`}),s=!1)}),o()})}log(e,r,o,s){const t=Date.now()-o,n={method:e.method,url:e.originalUrl,status:r.statusCode,duration:t,ip:this.getClientIp(e),...s};this.logger.notice(n)}getClientIp(e){const r=e.headers["x-forwarded-for"];if(r){return(Array.isArray(r)?r[0]:r).split(",")[0].trim()}return e.socket.remoteAddress||"unknown"}}export{WebLogs as default};
1
+ import e from"../abstract/plugin.js";class WebLogs extends e{constructor(){super(...arguments),this.name="weblogs",this.roles=["logging"]}api(e){e.use((e,r,o)=>{let s=!0;this.logger.debug(`Incoming request: ${e.method} ${e.originalUrl}`);const t=Date.now();r.on("finish",()=>{const o={};e.proxyAuthUser?o.user=e.proxyAuthUser:e.user&&(o.user=e.user),s&&this.log(e,r,t,o),s=!1}),r.on("error",o=>{s&&this.log(e,r,t,{error:o.message}),s=!1}),r.on("close",()=>{r.writableEnded||(s&&this.log(e,r,t,{error:`Connection closed before response was sent for ${e.method} ${e.originalUrl}`}),s=!1)}),o()})}log(e,r,o,s){const t=Date.now()-o,n={...e.logDetails||{},method:e.method,url:e.originalUrl,status:r.statusCode,duration:t,ip:this.getClientIp(e),...s};this.logger.notice(n)}getClientIp(e){const r=e.headers["x-forwarded-for"];if(r){return(Array.isArray(r)?r[0]:r).split(",")[0].trim()}return e.socket.remoteAddress||"unknown"}}export{WebLogs as default};
@@ -1,5 +1,12 @@
1
1
  import type { Express, Request, Response } from 'express';
2
2
  import DmPlugin, { type Role } from '../abstract/plugin';
3
+ declare global {
4
+ namespace Express {
5
+ interface Request {
6
+ logDetails?: Record<string, unknown>;
7
+ }
8
+ }
9
+ }
3
10
  export default class WebLogs extends DmPlugin {
4
11
  name: string;
5
12
  roles: Role[];
@@ -52,6 +52,53 @@ Each response is logged when completed at **notice** level (between info and war
52
52
  | `responseTime` | Request duration | `45ms`, `123ms` |
53
53
  | `error` | Error message (if applicable) | `Connection timeout` |
54
54
 
55
+ ## Enriching the Log Line From Another Plugin
56
+
57
+ The standard fields say _that_ a request happened, not _what_ was requested. For
58
+ `POST`/`DELETE` routes carrying their parameters in the body, the URL alone is
59
+ not enough for auditing.
60
+
61
+ Any plugin can attach extra context to the access log entry by setting
62
+ `req.logDetails` in its handler. Those fields are merged into the single
63
+ `notice` entry emitted when the response completes — no second log line, no
64
+ correlation by timestamp:
65
+
66
+ ```typescript
67
+ app.post('/api/_getldapentries', (req, res) => {
68
+ req.logDetails = { uids: req.body };
69
+ // ...
70
+ });
71
+ ```
72
+
73
+ Output:
74
+
75
+ ```json
76
+ {
77
+ "level": "notice",
78
+ "message": {
79
+ "uids": ["jdoe", "asmith"],
80
+ "method": "POST",
81
+ "url": "/api/_getldapentries",
82
+ "status": 200,
83
+ "duration": 9,
84
+ "ip": "10.0.9.12",
85
+ "user": "admin"
86
+ }
87
+ }
88
+ ```
89
+
90
+ Notes:
91
+
92
+ - Core fields (`method`, `url`, `status`, `duration`, `ip`, `user`, `error`)
93
+ always take precedence: a plugin cannot overwrite them.
94
+ - The value must be set **before** the response completes (i.e. before
95
+ `res.json()` / `res.end()`), since the entry is written on the `finish` event.
96
+ - Only log what identifies the request (uids, mail addresses, target user,
97
+ action). Do **not** put credentials or free-text personal data there — this
98
+ line is written at `notice` level, i.e. in production.
99
+ - Keep lists bounded: a request with thousands of uids produces an unreadable
100
+ log line. Truncate and log the real count alongside.
101
+
55
102
  ## Use Cases
56
103
 
57
104
  ### 1. Request Monitoring
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ldap-rest",
3
- "version": "0.4.5",
3
+ "version": "0.4.7",
4
4
  "description": "Light directory manager",
5
5
  "keywords": [
6
6
  "Identity-Manager"
@@ -549,7 +549,7 @@
549
549
  "require": "./static/schemas/twake/users.json"
550
550
  }
551
551
  },
552
- "main": "dist/bin/index.mjs",
552
+ "main": "dist/bin/index.js",
553
553
  "types": "./dist/src/bin/index.d.ts",
554
554
  "bin": {
555
555
  "cleanup-external-users": "bin/cleanup-external-users.mjs",