ldap-rest 0.4.6 → 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.
@@ -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.6",
3
+ "version": "0.4.7",
4
4
  "description": "Light directory manager",
5
5
  "keywords": [
6
6
  "Identity-Manager"