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
|
|
package/dist/plugins/weblogs.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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",
|