ldap-rest 0.1.3 → 0.1.5

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 (78) hide show
  1. package/README.md +31 -21
  2. package/dist/abstract/ldapFlat.js +1 -1
  3. package/dist/lib/ldapActions.js +1 -1
  4. package/dist/plugins/ldap/groups.js +1 -1
  5. package/dist/src/abstract/ldapFlat.d.ts +9 -0
  6. package/dist/src/browser/ldap-user-editor/components/UserTree.d.ts +2 -1
  7. package/dist/src/browser/shared/components/DisposableComponent.d.ts +29 -0
  8. package/dist/src/browser/shared/components/Modal.d.ts +6 -1
  9. package/dist/src/lib/ldapActions.d.ts +9 -0
  10. package/dist/src/plugins/ldap/groups.d.ts +9 -0
  11. package/docs/README.md +23 -486
  12. package/docs/{DEVELOPER_GUIDE.md → client-development/README.md} +24 -24
  13. package/docs/client-development/api/README.md +75 -0
  14. package/docs/client-development/browser/README.md +65 -0
  15. package/docs/{plugins/DEVELOPMENT.md → plugin-development/README.md} +4 -9
  16. package/docs/plugin-development/hooks.md +18 -0
  17. package/docs/usage/README.md +89 -0
  18. package/docs/usage/configuration.md +375 -0
  19. package/docs/usage/plugins/README.md +87 -0
  20. package/docs/usage/plugins/auth/README.md +65 -0
  21. package/docs/usage/plugins/auth/crowdsec.md +95 -0
  22. package/docs/usage/plugins/auth/hmac.md +293 -0
  23. package/docs/usage/plugins/auth/llng.md +99 -0
  24. package/docs/usage/plugins/auth/oidc.md +167 -0
  25. package/docs/usage/plugins/auth/rate-limit.md +62 -0
  26. package/docs/usage/plugins/auth/token.md +136 -0
  27. package/docs/usage/plugins/auth/totp.md +213 -0
  28. package/docs/usage/plugins/auth/trusted-proxy.md +127 -0
  29. package/docs/usage/plugins/integrations/README.md +42 -0
  30. package/docs/usage/plugins/ldap/README.md +79 -0
  31. package/docs/usage/troubleshooting.md +105 -0
  32. package/package.json +9 -1
  33. package/static/browser/ldap-user-editor/components/UserTree.js +6 -3
  34. package/static/browser/ldap-user-editor/components/UserTree.js.map +1 -1
  35. package/static/browser/ldap-user-editor.esm.js +62 -3
  36. package/static/browser/ldap-user-editor.esm.js.map +1 -1
  37. package/static/browser/ldap-user-editor.js +62 -3
  38. package/static/browser/ldap-user-editor.js.map +1 -1
  39. package/static/browser/ldap-user-editor.min.js +1 -1
  40. package/static/browser/ldap-user-editor.min.js.map +1 -1
  41. package/static/browser/shared/components/DisposableComponent.js +59 -0
  42. package/static/browser/shared/components/DisposableComponent.js.map +1 -0
  43. package/static/browser/shared/components/Modal.js +16 -6
  44. package/static/browser/shared/components/Modal.js.map +1 -1
  45. package/static/browser/shared.esm.js +72 -6
  46. package/static/browser/shared.esm.js.map +1 -1
  47. package/static/browser/shared.js +72 -6
  48. package/static/browser/shared.js.map +1 -1
  49. package/static/browser/shared.min.js +1 -1
  50. package/static/browser/shared.min.js.map +1 -1
  51. package/docs/authentication.md +0 -1194
  52. /package/docs/{OPENAPI.md → client-development/api/openapi.md} +0 -0
  53. /package/docs/{api/REFERENCE.md → client-development/api/reference.md} +0 -0
  54. /package/docs/{api/REST_API.md → client-development/api/rest-api.md} +0 -0
  55. /package/docs/{browser/LIBRARIES.md → client-development/browser/libraries.md} +0 -0
  56. /package/docs/{examples/EXAMPLES.md → client-development/examples/README.md} +0 -0
  57. /package/docs/{examples → client-development/examples/ldif}/twake-mailbox-type-nomenclature.ldif +0 -0
  58. /package/docs/{examples → client-development/examples/ldif}/twake-mailbox-type-schema-amendment.ldif +0 -0
  59. /package/docs/{schemas/SCHEMAS.md → client-development/schemas/README.md} +0 -0
  60. /package/docs/{PLUGIN_DEPENDENCIES.md → plugin-development/dependencies.md} +0 -0
  61. /package/docs/{testing-with-embedded-ldap.md → plugin-development/testing.md} +0 -0
  62. /package/docs/{presenterm.md → presentations/en.md} +0 -0
  63. /package/docs/{presenterm-fr.md → presentations/fr.md} +0 -0
  64. /package/docs/{authzLinid1.md → usage/plugins/auth/authz-linid1.md} +0 -0
  65. /package/docs/{authzPerBranch.md → usage/plugins/auth/authz-per-branch.md} +0 -0
  66. /package/docs/{twakeAppAccountsApi.md → usage/plugins/integrations/app-accounts.md} +0 -0
  67. /package/docs/{twakeCalendarResources.md → usage/plugins/integrations/calendar-resources.md} +0 -0
  68. /package/docs/{twakeJames.md → usage/plugins/integrations/james-mail.md} +0 -0
  69. /package/docs/{jamesTeamMailboxes.md → usage/plugins/integrations/james-mailboxes.md} +0 -0
  70. /package/docs/{ldapBulkImport.md → usage/plugins/ldap/bulk-import.md} +0 -0
  71. /package/docs/{ldapExternalUsersInGroups.md → usage/plugins/ldap/external-users.md} +0 -0
  72. /package/docs/{ldapFlatGeneric.md → usage/plugins/ldap/flat-generic.md} +0 -0
  73. /package/docs/{ldapGroups.md → usage/plugins/ldap/groups.md} +0 -0
  74. /package/docs/{onChange.md → usage/plugins/ldap/on-change.md} +0 -0
  75. /package/docs/{ldapOrganizations.md → usage/plugins/ldap/organizations.md} +0 -0
  76. /package/docs/{ldapTrash.md → usage/plugins/ldap/trash.md} +0 -0
  77. /package/docs/{static.md → usage/plugins/utilities/static.md} +0 -0
  78. /package/docs/{weblogs.md → usage/plugins/utilities/weblogs.md} +0 -0
@@ -0,0 +1,167 @@
1
+ # OpenID Connect Authentication
2
+
3
+ OAuth 2.0 / OpenID Connect authentication for modern identity providers.
4
+
5
+ ## Configuration
6
+
7
+ ```bash
8
+ --plugin core/auth/openidconnect \
9
+ --oidc-server "https://auth.example.com" \
10
+ --oidc-client-id "ldap-rest-client" \
11
+ --oidc-client-secret "client-secret-here" \
12
+ --base-url "https://api.example.com"
13
+ ```
14
+
15
+ **Environment Variables:**
16
+
17
+ ```bash
18
+ DM_OIDC_SERVER="https://auth.example.com"
19
+ DM_OIDC_CLIENT_ID="ldap-rest-client"
20
+ DM_OIDC_CLIENT_SECRET="client-secret-here"
21
+ DM_BASE_URL="https://api.example.com"
22
+ ```
23
+
24
+ ## Prerequisites
25
+
26
+ 1. **OpenID Provider**: [Lemonldap-NG](https://lemonldap-ng.org), Keycloak, Auth0, Okta, Azure AD, etc.
27
+ 2. **Client Registration**: LDAP-Rest registered as OAuth2/OIDC client
28
+ 3. **Optional Dependency**: The `express-openid-connect` npm package
29
+
30
+ ## Installation
31
+
32
+ Install the optional dependency:
33
+
34
+ ```bash
35
+ npm install express-openid-connect
36
+ ```
37
+
38
+ ## How It Works
39
+
40
+ 1. Uses `express-openid-connect` for OAuth2/OIDC flow
41
+ 2. Handles authorization code flow automatically
42
+ 3. Extracts user identity from `sub` claim
43
+ 4. Sets `req.user` to user's subject identifier
44
+ 5. Provides `beforeAuth` and `afterAuth` hooks for customization
45
+
46
+ ## Provider Configuration
47
+
48
+ ### Keycloak
49
+
50
+ ```bash
51
+ --oidc-server "https://keycloak.example.com/realms/master" \
52
+ --oidc-client-id "ldap-rest" \
53
+ --oidc-client-secret "abc123..." \
54
+ --base-url "https://api.example.com"
55
+ ```
56
+
57
+ **Client Settings:**
58
+
59
+ - Access Type: `confidential`
60
+ - Valid Redirect URIs: `https://api.example.com/callback`
61
+ - Standard Flow Enabled: `ON`
62
+
63
+ ### Auth0
64
+
65
+ ```bash
66
+ --oidc-server "https://tenant.auth0.com" \
67
+ --oidc-client-id "your-client-id" \
68
+ --oidc-client-secret "your-client-secret" \
69
+ --base-url "https://api.example.com"
70
+ ```
71
+
72
+ ### Azure AD
73
+
74
+ ```bash
75
+ --oidc-server "https://login.microsoftonline.com/{tenant-id}/v2.0" \
76
+ --oidc-client-id "application-id" \
77
+ --oidc-client-secret "client-secret" \
78
+ --base-url "https://api.example.com"
79
+ ```
80
+
81
+ ## Scopes
82
+
83
+ Default scopes requested:
84
+
85
+ - `openid` - Basic OpenID Connect
86
+ - `profile` - User profile information
87
+ - `email` - User email address
88
+
89
+ ## Hooks
90
+
91
+ The OpenID Connect plugin supports custom hooks:
92
+
93
+ ### beforeAuth Hook
94
+
95
+ Called before authentication processing:
96
+
97
+ ```javascript
98
+ hooks: {
99
+ beforeAuth: async ([req, res]) => {
100
+ // Custom pre-authentication logic
101
+ console.log('Authentication attempt from:', req.ip);
102
+ return [req, res];
103
+ };
104
+ }
105
+ ```
106
+
107
+ ### afterAuth Hook
108
+
109
+ Called after successful authentication:
110
+
111
+ ```javascript
112
+ hooks: {
113
+ afterAuth: async ([req, res]) => {
114
+ // Access OIDC user data
115
+ const user = req.oidc.user;
116
+ console.log('User authenticated:', user.email);
117
+
118
+ // Add custom user properties
119
+ req.customData = {
120
+ email: user.email,
121
+ name: user.name,
122
+ };
123
+
124
+ return [req, res];
125
+ };
126
+ }
127
+ ```
128
+
129
+ ## Use Cases
130
+
131
+ - **Modern Identity Providers**: Integration with cloud identity services
132
+ - **Social Login**: Google, Microsoft, GitHub authentication
133
+ - **Multi-Tenant Applications**: Different OIDC providers per tenant
134
+ - **Standards-Based**: Portable across OIDC-compliant providers
135
+
136
+ ## Troubleshooting
137
+
138
+ **Problem:** express-openid-connect not found
139
+
140
+ **Solution:** Install optional dependency:
141
+
142
+ ```bash
143
+ npm install express-openid-connect
144
+ ```
145
+
146
+ **Problem:** Missing config parameter
147
+
148
+ **Solution:** Ensure all required parameters are set:
149
+
150
+ - `--oidc-server`
151
+ - `--oidc-client-id`
152
+ - `--oidc-client-secret`
153
+ - `--base-url`
154
+
155
+ **Problem:** Redirect loop
156
+
157
+ **Solutions:**
158
+
159
+ 1. Set a long secret, shorts are refused by `openid-client`
160
+ 2. Verify `--base-url` matches actual public URL
161
+ 3. Check redirect URI in provider matches `{base-url}/callback`
162
+ 4. Ensure HTTPS in production (many providers require it)
163
+
164
+ ## See Also
165
+
166
+ - [OpenID Connect Specification](https://openid.net/connect/)
167
+ - [express-openid-connect](https://github.com/auth0/express-openid-connect)
@@ -0,0 +1,62 @@
1
+ # Rate Limiting
2
+
3
+ Prevent brute force attacks by limiting the number of requests per IP address.
4
+
5
+ ## Configuration
6
+
7
+ ```bash
8
+ --plugin core/auth/rateLimit \
9
+ --rate-limit-window 60000 \
10
+ --rate-limit-max 100
11
+ ```
12
+
13
+ **Environment Variables:**
14
+
15
+ ```bash
16
+ DM_RATE_LIMIT_WINDOW=60000 # Time window in milliseconds (default: 60000 = 1 minute)
17
+ DM_RATE_LIMIT_MAX=100 # Maximum requests per window (default: 100)
18
+ ```
19
+
20
+ ## How It Works
21
+
22
+ 1. Tracks request count per IP address
23
+ 2. Uses sliding window algorithm
24
+ 3. Returns `429 Too Many Requests` when limit exceeded
25
+ 4. Automatically respects `X-Forwarded-For` when behind trusted proxy
26
+
27
+ ## Use Cases
28
+
29
+ - **Brute Force Prevention**: Limit authentication attempts
30
+ - **API Protection**: Prevent abuse of API endpoints
31
+ - **DDoS Mitigation**: Basic protection against flood attacks
32
+ - **Fair Usage**: Ensure equitable API access
33
+
34
+ ## Headers
35
+
36
+ When rate limiting is active, responses include:
37
+
38
+ ```
39
+ X-RateLimit-Limit: 100
40
+ X-RateLimit-Remaining: 95
41
+ X-RateLimit-Reset: 1698765492
42
+ ```
43
+
44
+ ## Combining with Trusted Proxy
45
+
46
+ For correct IP detection behind reverse proxies:
47
+
48
+ ```bash
49
+ --plugin core/auth/trustedProxy \
50
+ --trusted-proxy "127.0.0.1" \
51
+ --plugin core/auth/rateLimit \
52
+ --rate-limit-max 100
53
+ ```
54
+
55
+ The rate limiter will use the real client IP from `X-Forwarded-For` when the request comes from a trusted proxy.
56
+
57
+ ## Security Considerations
58
+
59
+ - Always use with `trustedProxy` plugin behind reverse proxies
60
+ - Consider different limits for different endpoints
61
+ - Monitor for legitimate users hitting limits
62
+ - Combine with CrowdSec for IP reputation
@@ -0,0 +1,136 @@
1
+ # Token Authentication
2
+
3
+ Simple stateless authentication using bearer tokens.
4
+
5
+ ## Configuration
6
+
7
+ ### Basic Configuration
8
+
9
+ ```bash
10
+ --plugin core/auth/token \
11
+ --auth-token "secret-token-1" \
12
+ --auth-token "secret-token-2" \
13
+ --auth-token "secret-token-3"
14
+ ```
15
+
16
+ **Environment Variable:**
17
+
18
+ ```bash
19
+ DM_AUTH_TOKENS="token1,token2,token3"
20
+ ```
21
+
22
+ ### Named Tokens (Recommended)
23
+
24
+ Associate a descriptive name with each token for better logging and audit trails:
25
+
26
+ ```bash
27
+ --plugin core/auth/token \
28
+ --auth-token "9f8e7d6c5b4a:web-application" \
29
+ --auth-token "1a2b3c4d5e6f:monitoring-service" \
30
+ --auth-token "f1e2d3c4b5a6:backup-scripts"
31
+ ```
32
+
33
+ **Environment Variable:**
34
+
35
+ ```bash
36
+ DM_AUTH_TOKENS="9f8e7d6c5b4a:web-application,1a2b3c4d5e6f:monitoring-service,f1e2d3c4b5a6:backup-scripts"
37
+ ```
38
+
39
+ **Syntax:** `token:name`
40
+
41
+ - Token value comes first (the secret)
42
+ - Colon `:` separator
43
+ - Name comes second (descriptive identifier)
44
+
45
+ ## Usage
46
+
47
+ Include the token in the `Authorization` header:
48
+
49
+ ```bash
50
+ curl -H "Authorization: Bearer 9f8e7d6c5b4a" \
51
+ http://localhost:8081/api/v1/ldap/users
52
+ ```
53
+
54
+ ## How It Works
55
+
56
+ 1. Extracts token from `Authorization: Bearer <token>` header
57
+ 2. Validates token against configured list
58
+ 3. Sets `req.user` to the token's name (e.g., `"web-application"`) or `"token {index}"` for unnamed tokens
59
+ 4. Returns 401 Unauthorized if token is missing or invalid
60
+
61
+ **Named tokens in logs:**
62
+
63
+ ```
64
+ INFO: Request from user: web-application
65
+ INFO: Request from user: monitoring-service
66
+ ```
67
+
68
+ **Unnamed tokens in logs (backward compatible):**
69
+
70
+ ```
71
+ INFO: Request from user: token 0
72
+ INFO: Request from user: token 1
73
+ ```
74
+
75
+ ## Use Cases
76
+
77
+ - **Development/Testing**: Quick authentication without complex setup
78
+ - **Service-to-Service**: API access for backend services
79
+ - **CI/CD Pipelines**: Automated scripts and deployments
80
+ - **Simple Deployments**: Small teams without SSO infrastructure
81
+
82
+ ## Security Considerations
83
+
84
+ - Tokens are static and shared (not user-specific)
85
+ - Use HTTPS in production to protect tokens in transit
86
+ - Rotate tokens regularly
87
+ - Limit token count to necessary services only
88
+ - Consider combining with IP whitelisting
89
+
90
+ ## Example: Multiple Services with Named Tokens
91
+
92
+ ```bash
93
+ # API server configuration with named tokens
94
+ npx ldap-rest \
95
+ --plugin core/auth/token \
96
+ --auth-token "a1b2c3d4e5f6:production-web-app" \
97
+ --auth-token "f6e5d4c3b2a1:prometheus-monitoring" \
98
+ --auth-token "1234567890ab:nightly-backup" \
99
+ --ldap-url ldap://localhost:389 \
100
+ ...
101
+ ```
102
+
103
+ ```bash
104
+ # Web application (logs will show: user: production-web-app)
105
+ curl -H "Authorization: Bearer a1b2c3d4e5f6" \
106
+ http://api/v1/ldap/users
107
+
108
+ # Monitoring system (logs will show: user: prometheus-monitoring)
109
+ curl -H "Authorization: Bearer f6e5d4c3b2a1" \
110
+ http://api/v1/ldap/groups
111
+
112
+ # Backup script (logs will show: user: nightly-backup)
113
+ curl -H "Authorization: Bearer 1234567890ab" \
114
+ http://api/v1/ldap/organizations/top
115
+ ```
116
+
117
+ ## Example: Mixed Named and Unnamed Tokens
118
+
119
+ You can mix named and unnamed tokens for backward compatibility:
120
+
121
+ ```bash
122
+ --auth-token "abc123:production-api" \
123
+ --auth-token "def456" # Unnamed, will be "token 1" in logs \
124
+ --auth-token "ghi789:staging-app"
125
+ ```
126
+
127
+ ## Troubleshooting
128
+
129
+ **Problem:** 401 Unauthorized despite correct token
130
+
131
+ **Solutions:**
132
+
133
+ 1. Ensure `Authorization: Bearer {token}` format (not just the token)
134
+ 2. Check token is in configured list
135
+ 3. Verify no whitespace in token
136
+ 4. Check server logs for token mismatch
@@ -0,0 +1,213 @@
1
+ # TOTP Authentication
2
+
3
+ Time-based One-Time Password (TOTP) authentication using dynamic codes compatible with authenticator apps.
4
+
5
+ ## Configuration
6
+
7
+ ### Basic Configuration
8
+
9
+ ```bash
10
+ --plugin core/auth/totp \
11
+ --auth-totp "JBSWY3DPEHPK3PXP:admin:6" \
12
+ --auth-totp "HXDMVJECJJWSRB3H:service:8"
13
+ ```
14
+
15
+ **Environment Variable:**
16
+
17
+ ```bash
18
+ DM_AUTH_TOTP="JBSWY3DPEHPK3PXP:admin:6,HXDMVJECJJWSRB3H:service:8"
19
+ ```
20
+
21
+ **Syntax:** `secret:name[:digits]`
22
+
23
+ - **secret**: Base32-encoded secret (e.g., generated by authenticator apps)
24
+ - **name**: Descriptive user/service name
25
+ - **digits**: Number of digits in TOTP code (optional, 6-10, default: 6)
26
+
27
+ ### Advanced Configuration
28
+
29
+ ```bash
30
+ --auth-totp-window 1 # Time window tolerance (±30s with step=30)
31
+ --auth-totp-step 30 # Time step in seconds (default: 30)
32
+ ```
33
+
34
+ **Environment Variables:**
35
+
36
+ ```bash
37
+ DM_AUTH_TOTP_WINDOW=1 # Default: 1
38
+ DM_AUTH_TOTP_STEP=30 # Default: 30
39
+ ```
40
+
41
+ - **window**: Number of time steps to check before/after current time (compensates for clock drift)
42
+ - **step**: Time interval in seconds for code generation (typically 30)
43
+
44
+ ## Generating Secrets
45
+
46
+ Use an authenticator app or generate Base32 secrets:
47
+
48
+ ```bash
49
+ # Using Node.js crypto (example)
50
+ node -e "console.log(require('crypto').randomBytes(20).toString('base32'))"
51
+ ```
52
+
53
+ ## Usage
54
+
55
+ ### HTTP Requests
56
+
57
+ Include the current TOTP code in the `Authorization` header:
58
+
59
+ ```bash
60
+ # Get current TOTP code from your authenticator app
61
+ curl -H "Authorization: Bearer 123456" \
62
+ http://localhost:8081/api/v1/ldap/users
63
+ ```
64
+
65
+ ### Browser Client
66
+
67
+ The TOTP client library is available as an npm module export:
68
+
69
+ ```bash
70
+ npm install ldap-rest
71
+ ```
72
+
73
+ ```typescript
74
+ import {
75
+ TotpAuthClient,
76
+ generateTotp,
77
+ getRemainingSeconds,
78
+ isValidBase32,
79
+ } from 'ldap-rest/browser-shared-utils-totp';
80
+
81
+ const client = new TotpAuthClient({
82
+ secret: 'JBSWY3DPEHPK3PXP',
83
+ digits: 6,
84
+ step: 30,
85
+ });
86
+
87
+ // Automatic authentication with current TOTP code
88
+ const response = await client.get('/api/v1/ldap/users');
89
+ const users = await response.json();
90
+
91
+ // Or get current code manually
92
+ const code = await client.getCode();
93
+ console.log(`Current TOTP code: ${code}`);
94
+ ```
95
+
96
+ **Live Demo:** See [examples/web/totp-client.html](../../../../examples/web/totp-client.html) for an interactive demonstration.
97
+
98
+ ## How It Works
99
+
100
+ 1. Extracts TOTP code from `Authorization: Bearer <code>` header
101
+ 2. Generates expected TOTP codes for current time window
102
+ 3. Validates code against all configured users' secrets
103
+ 4. Supports multiple time windows (±window × step seconds) for clock drift tolerance
104
+ 5. Sets `req.user` to the user's name on successful validation
105
+ 6. Returns 401 Unauthorized if code is missing, invalid, or expired
106
+
107
+ ## Multi-User Example
108
+
109
+ ```bash
110
+ # Configure multiple users with different code lengths
111
+ --plugin core/auth/totp \
112
+ --auth-totp "JBSWY3DPEHPK3PXP:admin:6" \
113
+ --auth-totp "HXDMVJECJJWSRB3H:api-service:8" \
114
+ --auth-totp "IXDMVJECJJWSRB2A:monitoring:10"
115
+ ```
116
+
117
+ **In logs:**
118
+
119
+ ```
120
+ INFO: TOTP authentication successful for user: admin
121
+ INFO: TOTP authentication successful for user: api-service
122
+ ```
123
+
124
+ ## Use Cases
125
+
126
+ - **Enhanced Security**: Dynamic codes that expire every 30 seconds
127
+ - **No Shared Secrets**: Each user/service has unique TOTP secret
128
+ - **Compatible**: Works with Google Authenticator, Authy, 1Password, etc.
129
+ - **API Access**: Suitable for automated scripts with TOTP generation
130
+ - **Multi-Factor**: Can be combined with other authentication methods
131
+
132
+ ## Security Considerations
133
+
134
+ - **Secret Storage**: Store Base32 secrets securely (encrypted configuration, environment variables)
135
+ - **HTTPS Required**: Always use HTTPS to protect TOTP codes in transit
136
+ - **Clock Synchronization**: Ensure server and client clocks are synchronized (NTP recommended)
137
+ - **Window Size**: Larger windows are more tolerant but slightly less secure
138
+ - **Secret Rotation**: Rotate TOTP secrets periodically for better security
139
+ - **Rate Limiting**: Consider adding rate limiting to prevent brute force attacks
140
+
141
+ ## Browser Client Features
142
+
143
+ The TOTP browser library provides these functions and classes:
144
+
145
+ ```typescript
146
+ import {
147
+ generateTotp,
148
+ getRemainingSeconds,
149
+ isValidBase32,
150
+ TotpAuthClient
151
+ } from 'ldap-rest/browser-shared-utils-totp';
152
+
153
+ // Generate TOTP code
154
+ const code = await generateTotp({
155
+ secret: 'JBSWY3DPEHPK3PXP',
156
+ digits: 6,
157
+ step: 30
158
+ });
159
+
160
+ // Check validity time
161
+ const remaining = getRemainingSeconds(30);
162
+ console.log(`Code expires in ${remaining} seconds`);
163
+
164
+ // Validate secret format
165
+ if (isValidBase32('JBSWY3DPEHPK3PXP')) {
166
+ console.log('Valid Base32 secret');
167
+ }
168
+
169
+ // HTTP client with automatic TOTP authentication
170
+ const client = new TotpAuthClient({
171
+ secret: 'JBSWY3DPEHPK3PXP',
172
+ digits: 6,
173
+ step: 30
174
+ });
175
+
176
+ // All HTTP methods automatically include TOTP in Authorization header
177
+ await client.post('/api/v1/ldap/users', { uid: 'user1', ... });
178
+ await client.put('/api/v1/ldap/users/user1', { mail: 'new@example.com' });
179
+ await client.delete('/api/v1/ldap/users/user1');
180
+ ```
181
+
182
+ **Module Export:** `ldap-rest/browser-shared-utils-totp`
183
+
184
+ **Live Demo:** Run the server and open [http://localhost:8081/static/examples/web/totp-client.html](http://localhost:8081/static/examples/web/totp-client.html)
185
+
186
+ ## Troubleshooting
187
+
188
+ **Problem:** 401 Unauthorized despite correct code
189
+
190
+ **Solutions:**
191
+
192
+ 1. Verify secret is correctly configured (Base32 format)
193
+ 2. Check system clock synchronization (use NTP)
194
+ 3. Increase `--auth-totp-window` if experiencing timing issues
195
+ 4. Ensure code is used immediately (codes expire every 30s)
196
+ 5. Verify `Authorization: Bearer {code}` format
197
+
198
+ **Problem:** Codes don't match authenticator app
199
+
200
+ **Solutions:**
201
+
202
+ 1. Verify secret matches exactly (case-sensitive Base32)
203
+ 2. Check `--auth-totp-step` matches app configuration (usually 30)
204
+ 3. Ensure both server and device clocks are synchronized
205
+ 4. Confirm correct number of digits configured
206
+
207
+ **Problem:** Invalid Base32 secret warning
208
+
209
+ **Solutions:**
210
+
211
+ 1. Secret must contain only A-Z and 2-7 characters
212
+ 2. Use proper Base32 encoding (not Base64)
213
+ 3. Remove padding `=` characters if present (optional)
@@ -0,0 +1,127 @@
1
+ # Trusted Proxy
2
+
3
+ When running behind a reverse proxy (nginx, Apache, HAProxy, etc.), client IP addresses are typically passed via `X-Forwarded-For` headers. The `trustedProxy` plugin validates these headers to prevent IP spoofing attacks.
4
+
5
+ ## Configuration
6
+
7
+ ```bash
8
+ --plugin core/auth/trustedProxy \
9
+ --trusted-proxy "127.0.0.1" \
10
+ --trusted-proxy "10.0.0.0/8" \
11
+ --trusted-proxy "192.168.0.0/16"
12
+ ```
13
+
14
+ **Environment Variables:**
15
+
16
+ ```bash
17
+ # Comma-separated list of trusted proxy IPs or CIDR ranges
18
+ DM_TRUSTED_PROXIES="127.0.0.1,10.0.0.0/8,192.168.0.0/16,::1"
19
+
20
+ # Optional: Header name for authenticated user from proxy (default: Auth-User)
21
+ DM_TRUSTED_PROXY_AUTH_HEADER="Auth-User"
22
+ ```
23
+
24
+ ## How It Works
25
+
26
+ 1. **Request arrives** from reverse proxy
27
+ 2. **Plugin checks** if `req.socket.remoteAddress` matches a trusted proxy
28
+ 3. **If trusted:**
29
+ - `X-Forwarded-For` header is preserved
30
+ - `Auth-User` header (or custom header) is extracted for logging
31
+ - Request is marked as `req.trustedProxy = true`
32
+ 4. **If untrusted:**
33
+ - `X-Forwarded-For` header is **removed** to prevent IP spoofing
34
+ - Request is marked as `req.trustedProxy = false`
35
+ 5. **Other plugins** (rate limiting, CrowdSec, weblogs) see sanitized headers
36
+
37
+ ## Supported Formats
38
+
39
+ - **IPv4 addresses:** `192.168.1.1`
40
+ - **IPv6 addresses:** `::1`, `fe80::1`
41
+ - **CIDR ranges:** `10.0.0.0/8`, `192.168.0.0/16`, `2001:db8::/32`
42
+ - **IPv4-mapped IPv6:** Automatically handled (e.g., `::ffff:127.0.0.1` matches `127.0.0.1`)
43
+
44
+ ## Auth-User Header
45
+
46
+ When requests come from a trusted proxy, the plugin can extract an authenticated username from a header set by the proxy. This is useful for:
47
+
48
+ - Logging who made the request (even if LDAP-Rest doesn't handle authentication)
49
+ - Passing identity from an upstream authentication system
50
+
51
+ ```bash
52
+ # Custom header name (default: Auth-User)
53
+ DM_TRUSTED_PROXY_AUTH_HEADER="X-Remote-User"
54
+ ```
55
+
56
+ The extracted username is:
57
+
58
+ - Available as `req.proxyAuthUser` for other plugins
59
+ - Used by the `weblogs` plugin to log the user field
60
+
61
+ ## Example: nginx Configuration
62
+
63
+ ```nginx
64
+ upstream ldap_rest {
65
+ server 127.0.0.1:8081;
66
+ }
67
+
68
+ server {
69
+ listen 443 ssl;
70
+ server_name api.example.com;
71
+
72
+ location / {
73
+ proxy_pass http://ldap_rest;
74
+ proxy_set_header Host $host;
75
+ proxy_set_header X-Real-IP $remote_addr;
76
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
77
+ proxy_set_header X-Forwarded-Proto $scheme;
78
+
79
+ # Optional: Pass authenticated user from nginx auth
80
+ proxy_set_header Auth-User $remote_user;
81
+ }
82
+ }
83
+ ```
84
+
85
+ LDAP-Rest configuration:
86
+
87
+ ```bash
88
+ DM_TRUSTED_PROXIES="127.0.0.1"
89
+ ```
90
+
91
+ ## Example: HAProxy Configuration
92
+
93
+ ```haproxy
94
+ frontend https
95
+ bind *:443 ssl crt /etc/ssl/cert.pem
96
+ default_backend ldap_rest
97
+
98
+ backend ldap_rest
99
+ option forwardfor
100
+ http-request set-header X-Forwarded-Proto https
101
+ server ldap_rest 127.0.0.1:8081
102
+ ```
103
+
104
+ ## Use Cases
105
+
106
+ - **Reverse Proxy Deployments:** Ensure correct client IP for rate limiting and logging
107
+ - **Load Balancers:** Trust headers from known load balancer IPs
108
+ - **CDN Integration:** Trust headers from CDN edge servers
109
+ - **Kubernetes:** Trust headers from ingress controllers
110
+ - **Security:** Prevent attackers from spoofing `X-Forwarded-For` to bypass rate limits
111
+
112
+ ## Security Considerations
113
+
114
+ - **Only trust known proxies:** Never use `0.0.0.0/0` or trust all IPs
115
+ - **Use specific IPs/ranges:** Limit to your actual proxy infrastructure
116
+ - **HTTPS between proxy and LDAP-Rest:** Prevent header injection attacks
117
+ - **Monitor logs:** Watch for warnings about removed X-Forwarded-For headers
118
+
119
+ ## Plugin Load Order
120
+
121
+ The `trustedProxy` plugin is automatically loaded **first** (via `priority.json`) to ensure all other plugins see sanitized headers:
122
+
123
+ 1. `core/auth/trustedProxy` - Sanitizes X-Forwarded-For headers
124
+ 2. `core/weblogs` - Logs requests with correct client IP
125
+ 3. `core/auth/crowdsec` - Checks IP reputation
126
+ 4. `core/auth/rateLimit` - Rate limits by IP
127
+ 5. Authentication plugins...