securenow 7.6.7 → 7.6.8
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/NPM_README.md +13 -13
- package/README.md +21 -37
- package/app-config.js +5 -3
- package/cli/config.js +4 -3
- package/cli/diagnostics.js +54 -15
- package/cli/run.js +40 -11
- package/firewall-only.js +1 -1
- package/mcp/catalog.js +1 -1
- package/nextjs-webpack-config.js +3 -15
- package/nextjs.js +21 -23
- package/nuxt-server-plugin.mjs +20 -10
- package/package.json +33 -34
- package/register.js +1 -1
- package/tracing.js +17 -7
- package/web-vite.mjs +23 -13
- package/CONSUMING-APPS-GUIDE.md +0 -463
- package/docs/ALL-FRAMEWORKS-QUICKSTART.md +0 -1388
- package/docs/API-KEYS-GUIDE.md +0 -278
- package/docs/ARCHITECTURE.md +0 -408
- package/docs/AUTO-BODY-CAPTURE.md +0 -412
- package/docs/AUTO-SETUP-SUMMARY.md +0 -331
- package/docs/AUTO-SETUP.md +0 -419
- package/docs/AUTOMATIC-IP-CAPTURE.md +0 -359
- package/docs/BODY-CAPTURE-FIX.md +0 -261
- package/docs/BODY-CAPTURE-QUICKSTART.md +0 -147
- package/docs/CHANGELOG-NEXTJS.md +0 -235
- package/docs/COMPLETION-REPORT.md +0 -408
- package/docs/CUSTOMER-GUIDE.md +0 -364
- package/docs/EASIEST-SETUP.md +0 -342
- package/docs/ENVIRONMENT-VARIABLES.md +0 -166
- package/docs/ENVIRONMENTS.md +0 -60
- package/docs/EXPRESS-BODY-CAPTURE.md +0 -1028
- package/docs/EXPRESS-SETUP-GUIDE.md +0 -722
- package/docs/FINAL-SOLUTION.md +0 -335
- package/docs/FIREWALL-GUIDE.md +0 -440
- package/docs/IMPLEMENTATION-SUMMARY.md +0 -410
- package/docs/INDEX.md +0 -222
- package/docs/LOGGING-GUIDE.md +0 -704
- package/docs/LOGGING-QUICKSTART.md +0 -221
- package/docs/MCP-GUIDE.md +0 -58
- package/docs/NEXTJS-BODY-CAPTURE-COMPARISON.md +0 -323
- package/docs/NEXTJS-BODY-CAPTURE.md +0 -368
- package/docs/NEXTJS-GUIDE.md +0 -392
- package/docs/NEXTJS-QUICKSTART.md +0 -83
- package/docs/NEXTJS-SETUP-COMPLETE.md +0 -795
- package/docs/NEXTJS-WEBPACK-WARNINGS.md +0 -267
- package/docs/NEXTJS-WRAPPER-APPROACH.md +0 -414
- package/docs/NUXT-GUIDE.md +0 -173
- package/docs/QUICKSTART-BODY-CAPTURE.md +0 -293
- package/docs/REDACTION-EXAMPLES.md +0 -484
- package/docs/REQUEST-BODY-CAPTURE.md +0 -587
- package/docs/SOLUTION-SUMMARY.md +0 -312
- package/docs/VERCEL-OTEL-MIGRATION.md +0 -255
- package/examples/README.md +0 -265
- package/examples/express-with-logging.js +0 -137
- package/examples/instrumentation-with-auto-capture.ts +0 -41
- package/examples/next.config.js +0 -37
- package/examples/nextjs-api-route-with-body-capture.ts +0 -54
- package/examples/nextjs-env-example.txt +0 -32
- package/examples/nextjs-instrumentation.js +0 -36
- package/examples/nextjs-instrumentation.ts +0 -36
- package/examples/nextjs-middleware.js +0 -37
- package/examples/nextjs-middleware.ts +0 -37
- package/examples/nextjs-with-logging-example.md +0 -301
- package/examples/nextjs-with-options.ts +0 -36
- package/examples/test-nextjs-setup.js +0 -70
- package/postinstall.js +0 -296
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
# 📊 Automatic IP and Request Metadata Capture
|
|
2
|
-
|
|
3
|
-
SecureNow automatically captures user IP addresses and detailed request metadata in your Next.js traces!
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## ✅ What Gets Captured Automatically
|
|
8
|
-
|
|
9
|
-
### 🌐 Client Information
|
|
10
|
-
- **IP Address** (`http.client_ip`)
|
|
11
|
-
- From `x-forwarded-for` (Vercel, most proxies)
|
|
12
|
-
- From `x-real-ip`
|
|
13
|
-
- From `cf-connecting-ip` (Cloudflare)
|
|
14
|
-
- From `x-client-ip`
|
|
15
|
-
- From socket `remoteAddress`
|
|
16
|
-
|
|
17
|
-
### 📱 Request Details
|
|
18
|
-
- **User Agent** (`http.user_agent`) - Browser/device info
|
|
19
|
-
- **Referer** (`http.referer`) - Where the user came from
|
|
20
|
-
- **Host** (`http.host`) - Your domain
|
|
21
|
-
- **Scheme** (`http.scheme`) - http or https
|
|
22
|
-
- **Request ID** (`http.request_id`) - Correlation ID if present
|
|
23
|
-
|
|
24
|
-
### 🌍 Geographic Data (when available)
|
|
25
|
-
- **Country** (`http.geo.country`)
|
|
26
|
-
- From Vercel: `x-vercel-ip-country`
|
|
27
|
-
- From Cloudflare: `cf-ipcountry`
|
|
28
|
-
- **Region** (`http.geo.region`) - From `x-vercel-ip-country-region`
|
|
29
|
-
- **City** (`http.geo.city`) - From `x-vercel-ip-city`
|
|
30
|
-
|
|
31
|
-
### 📊 Response Data
|
|
32
|
-
- **Status Code** (`http.status_code`) - 200, 404, 500, etc.
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## 🚀 Usage
|
|
37
|
-
|
|
38
|
-
**No configuration needed!** Just use SecureNow:
|
|
39
|
-
|
|
40
|
-
```typescript
|
|
41
|
-
// instrumentation.ts
|
|
42
|
-
import { registerSecureNow } from 'securenow/nextjs';
|
|
43
|
-
|
|
44
|
-
export function register() {
|
|
45
|
-
registerSecureNow();
|
|
46
|
-
}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
That's it! All request metadata is automatically captured.
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## 📈 View in SecureNow
|
|
54
|
-
|
|
55
|
-
In your SecureNow dashboard, you'll see these attributes on every span:
|
|
56
|
-
|
|
57
|
-
```json
|
|
58
|
-
{
|
|
59
|
-
"http.client_ip": "203.0.113.45",
|
|
60
|
-
"http.user_agent": "Mozilla/5.0...",
|
|
61
|
-
"http.referer": "https://google.com",
|
|
62
|
-
"http.host": "your-app.vercel.app",
|
|
63
|
-
"http.scheme": "https",
|
|
64
|
-
"http.status_code": 200,
|
|
65
|
-
"http.geo.country": "US",
|
|
66
|
-
"http.geo.region": "CA",
|
|
67
|
-
"http.geo.city": "San Francisco"
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## 🔍 Use Cases
|
|
74
|
-
|
|
75
|
-
### 1. Debug Location-Specific Issues
|
|
76
|
-
Filter traces by country/region to debug geographic problems:
|
|
77
|
-
```
|
|
78
|
-
http.geo.country = "JP" AND http.status_code >= 500
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### 2. Track User Journey
|
|
82
|
-
Follow a specific user through your app using IP:
|
|
83
|
-
```
|
|
84
|
-
http.client_ip = "203.0.113.45"
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### 3. Monitor Bot Traffic
|
|
88
|
-
Identify and filter bot requests:
|
|
89
|
-
```
|
|
90
|
-
http.user_agent CONTAINS "bot" OR http.user_agent CONTAINS "crawler"
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### 4. Analyze Referer Sources
|
|
94
|
-
See where your traffic comes from:
|
|
95
|
-
```
|
|
96
|
-
GROUP BY http.referer
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### 5. Performance by Region
|
|
100
|
-
Compare response times across regions:
|
|
101
|
-
```
|
|
102
|
-
AVG(duration) GROUP BY http.geo.country
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
## 🛠️ Customization
|
|
108
|
-
|
|
109
|
-
### Option 1: Add More Attributes
|
|
110
|
-
|
|
111
|
-
You can add custom attributes in your Next.js code:
|
|
112
|
-
|
|
113
|
-
```typescript
|
|
114
|
-
// In your API route or server component
|
|
115
|
-
import { trace } from '@opentelemetry/api';
|
|
116
|
-
|
|
117
|
-
export async function GET(request: Request) {
|
|
118
|
-
const span = trace.getActiveSpan();
|
|
119
|
-
|
|
120
|
-
if (span) {
|
|
121
|
-
// Add custom attributes
|
|
122
|
-
span.setAttributes({
|
|
123
|
-
'user.id': getUserId(request),
|
|
124
|
-
'user.subscription': 'premium',
|
|
125
|
-
'request.path': new URL(request.url).pathname,
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Your code...
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### Option 2: Disable Auto-Capture
|
|
134
|
-
|
|
135
|
-
If you don't want automatic IP capture, you can use a simpler configuration:
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
// instrumentation.ts
|
|
139
|
-
import { registerSecureNow } from 'securenow/nextjs';
|
|
140
|
-
|
|
141
|
-
export function register() {
|
|
142
|
-
// This will use the simple @vercel/otel default
|
|
143
|
-
// (no automatic IP capture)
|
|
144
|
-
process.env.SECURENOW_SIMPLE_MODE = '1';
|
|
145
|
-
registerSecureNow();
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## 🔒 Privacy Considerations
|
|
152
|
-
|
|
153
|
-
### IP Address Handling
|
|
154
|
-
|
|
155
|
-
**By default, SecureNow captures IP addresses.** Consider these privacy aspects:
|
|
156
|
-
|
|
157
|
-
1. **GDPR Compliance**
|
|
158
|
-
- IP addresses are considered personal data under GDPR
|
|
159
|
-
- Ensure you have legal basis for processing
|
|
160
|
-
- Consider anonymizing IPs in some regions
|
|
161
|
-
|
|
162
|
-
2. **Data Retention**
|
|
163
|
-
- Configure SecureNow retention policies
|
|
164
|
-
- Consider shorter retention for IP data
|
|
165
|
-
|
|
166
|
-
3. **Anonymization Option**
|
|
167
|
-
|
|
168
|
-
```typescript
|
|
169
|
-
// Custom middleware to anonymize IPs
|
|
170
|
-
import { trace } from '@opentelemetry/api';
|
|
171
|
-
|
|
172
|
-
export function middleware(request: NextRequest) {
|
|
173
|
-
const span = trace.getActiveSpan();
|
|
174
|
-
|
|
175
|
-
if (span) {
|
|
176
|
-
const ip = request.ip || 'unknown';
|
|
177
|
-
// Anonymize last octet: 203.0.113.45 → 203.0.113.0
|
|
178
|
-
const anonymized = ip.replace(/\.\d+$/, '.0');
|
|
179
|
-
span.setAttribute('http.client_ip', anonymized);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return NextResponse.next();
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
---
|
|
187
|
-
|
|
188
|
-
## 🎯 Examples
|
|
189
|
-
|
|
190
|
-
### Example 1: Geographic Load Balancing Debugging
|
|
191
|
-
|
|
192
|
-
**Problem:** Users in Asia report slow performance
|
|
193
|
-
|
|
194
|
-
**Solution:** Query traces by region
|
|
195
|
-
```
|
|
196
|
-
http.geo.country IN ["JP", "CN", "KR"]
|
|
197
|
-
AND duration > 1000ms
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### Example 2: Bot Detection
|
|
201
|
-
|
|
202
|
-
**Problem:** Suspicious traffic patterns
|
|
203
|
-
|
|
204
|
-
**Solution:** Filter by user agent
|
|
205
|
-
```
|
|
206
|
-
http.user_agent CONTAINS "bot"
|
|
207
|
-
OR http.user_agent CONTAINS "crawler"
|
|
208
|
-
OR http.user_agent CONTAINS "spider"
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### Example 3: Referer Analysis
|
|
212
|
-
|
|
213
|
-
**Problem:** Want to track marketing campaigns
|
|
214
|
-
|
|
215
|
-
**Solution:** Group by referer
|
|
216
|
-
```
|
|
217
|
-
http.referer CONTAINS "utm_source"
|
|
218
|
-
GROUP BY http.referer
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### Example 4: Rate Limiting Analysis
|
|
222
|
-
|
|
223
|
-
**Problem:** Need to identify IPs hitting rate limits
|
|
224
|
-
|
|
225
|
-
**Solution:** Track by IP and status
|
|
226
|
-
```
|
|
227
|
-
http.status_code = 429
|
|
228
|
-
GROUP BY http.client_ip
|
|
229
|
-
ORDER BY COUNT DESC
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
---
|
|
233
|
-
|
|
234
|
-
## 📊 Dashboard Queries
|
|
235
|
-
|
|
236
|
-
### Top Countries by Traffic
|
|
237
|
-
```sql
|
|
238
|
-
SELECT
|
|
239
|
-
http.geo.country,
|
|
240
|
-
COUNT(*) as requests,
|
|
241
|
-
AVG(duration) as avg_duration
|
|
242
|
-
FROM spans
|
|
243
|
-
WHERE http.geo.country IS NOT NULL
|
|
244
|
-
GROUP BY http.geo.country
|
|
245
|
-
ORDER BY requests DESC
|
|
246
|
-
LIMIT 10
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
### Slowest Requests by Region
|
|
250
|
-
```sql
|
|
251
|
-
SELECT
|
|
252
|
-
http.geo.country,
|
|
253
|
-
http.target,
|
|
254
|
-
MAX(duration) as max_duration
|
|
255
|
-
FROM spans
|
|
256
|
-
WHERE http.geo.country IS NOT NULL
|
|
257
|
-
GROUP BY http.geo.country, http.target
|
|
258
|
-
ORDER BY max_duration DESC
|
|
259
|
-
LIMIT 20
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
### Error Rate by User Agent
|
|
263
|
-
```sql
|
|
264
|
-
SELECT
|
|
265
|
-
http.user_agent,
|
|
266
|
-
COUNT(*) as total,
|
|
267
|
-
SUM(CASE WHEN http.status_code >= 400 THEN 1 ELSE 0 END) as errors,
|
|
268
|
-
(errors / total * 100) as error_rate
|
|
269
|
-
FROM spans
|
|
270
|
-
GROUP BY http.user_agent
|
|
271
|
-
ORDER BY error_rate DESC
|
|
272
|
-
LIMIT 10
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
---
|
|
276
|
-
|
|
277
|
-
## 🔧 Technical Details
|
|
278
|
-
|
|
279
|
-
### How It Works
|
|
280
|
-
|
|
281
|
-
1. **HttpInstrumentation** intercepts incoming HTTP requests
|
|
282
|
-
2. **requestHook** extracts headers and metadata
|
|
283
|
-
3. **Attributes** are added to the active span
|
|
284
|
-
4. **Data flows** to SecureNow with the trace
|
|
285
|
-
|
|
286
|
-
### Headers Priority
|
|
287
|
-
|
|
288
|
-
IP address is extracted in this order:
|
|
289
|
-
1. `x-forwarded-for` (first IP in list)
|
|
290
|
-
2. `x-real-ip`
|
|
291
|
-
3. `cf-connecting-ip` (Cloudflare)
|
|
292
|
-
4. `x-client-ip`
|
|
293
|
-
5. `socket.remoteAddress`
|
|
294
|
-
|
|
295
|
-
### Performance Impact
|
|
296
|
-
|
|
297
|
-
- **Minimal overhead:** < 1ms per request
|
|
298
|
-
- **No blocking:** Runs async with request processing
|
|
299
|
-
- **Fail-safe:** Errors don't break requests
|
|
300
|
-
|
|
301
|
-
---
|
|
302
|
-
|
|
303
|
-
## ❓ FAQ
|
|
304
|
-
|
|
305
|
-
### Q: Is this GDPR compliant?
|
|
306
|
-
|
|
307
|
-
**A:** IP addresses are personal data. Ensure you:
|
|
308
|
-
- Have legal basis (legitimate interest, consent, etc.)
|
|
309
|
-
- Document in privacy policy
|
|
310
|
-
- Configure appropriate retention
|
|
311
|
-
- Consider anonymization for EU users
|
|
312
|
-
|
|
313
|
-
### Q: Can I disable IP capture?
|
|
314
|
-
|
|
315
|
-
**A:** Yes, use simple mode:
|
|
316
|
-
```typescript
|
|
317
|
-
process.env.SECURENOW_SIMPLE_MODE = '1';
|
|
318
|
-
registerSecureNow();
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
### Q: Does this work on Edge Runtime?
|
|
322
|
-
|
|
323
|
-
**A:** Currently only Node.js runtime is supported. Edge runtime support coming soon.
|
|
324
|
-
|
|
325
|
-
### Q: What about bot traffic?
|
|
326
|
-
|
|
327
|
-
**A:** Bot traffic is captured automatically. Filter using:
|
|
328
|
-
```
|
|
329
|
-
http.user_agent NOT CONTAINS "bot"
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
### Q: Can I capture custom headers?
|
|
333
|
-
|
|
334
|
-
**A:** Yes! Use OpenTelemetry API:
|
|
335
|
-
```typescript
|
|
336
|
-
import { trace } from '@opentelemetry/api';
|
|
337
|
-
|
|
338
|
-
const span = trace.getActiveSpan();
|
|
339
|
-
span.setAttribute('custom.header', request.headers.get('x-custom'));
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
---
|
|
343
|
-
|
|
344
|
-
## 🎉 Summary
|
|
345
|
-
|
|
346
|
-
SecureNow automatically captures:
|
|
347
|
-
- ✅ IP addresses (multiple sources)
|
|
348
|
-
- ✅ User agents
|
|
349
|
-
- ✅ Referers
|
|
350
|
-
- ✅ Geographic data (Vercel/Cloudflare)
|
|
351
|
-
- ✅ Request/response metadata
|
|
352
|
-
|
|
353
|
-
**Zero configuration required** - it just works!
|
|
354
|
-
|
|
355
|
-
View everything in SecureNow for powerful analytics and debugging.
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
package/docs/BODY-CAPTURE-FIX.md
DELETED
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
# ✅ Body Capture Fix - Self-Sufficient Solution Complete!
|
|
2
|
-
|
|
3
|
-
## 🐛 The Bug (FIXED!)
|
|
4
|
-
|
|
5
|
-
**Error:** `TypeError: Response body object should not be disturbed or locked`
|
|
6
|
-
|
|
7
|
-
**Cause:** Reading the HTTP request stream directly locks it, preventing Next.js from parsing the body.
|
|
8
|
-
|
|
9
|
-
**Fix:** Use Next.js middleware with `request.clone()` instead of HTTP instrumentation hooks.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## ✅ The Solution (100% Self-Sufficient!)
|
|
14
|
-
|
|
15
|
-
### For Your Customers - Zero Code to Write!
|
|
16
|
-
|
|
17
|
-
**Installation automatically creates everything:**
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
$ npm install securenow
|
|
21
|
-
|
|
22
|
-
┌─────────────────────────────────────────────────┐
|
|
23
|
-
│ 🎉 SecureNow installed successfully! │
|
|
24
|
-
└─────────────────────────────────────────────────┘
|
|
25
|
-
|
|
26
|
-
Would you like to automatically create instrumentation file? (Y/n) Y
|
|
27
|
-
✅ Created instrumentation.ts
|
|
28
|
-
|
|
29
|
-
Would you like to enable request body capture? (y/N) y
|
|
30
|
-
✅ Created middleware.ts
|
|
31
|
-
→ Captures JSON, GraphQL, Form bodies with auto-redaction
|
|
32
|
-
✅ Created .env.local template
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
**Files created (all by installer):**
|
|
36
|
-
|
|
37
|
-
1. **instrumentation.ts**
|
|
38
|
-
```typescript
|
|
39
|
-
import { registerSecureNow } from 'securenow/nextjs';
|
|
40
|
-
export function register() { registerSecureNow(); }
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
2. **middleware.ts** (if they choose body capture)
|
|
44
|
-
```typescript
|
|
45
|
-
export { middleware } from 'securenow/nextjs-middleware';
|
|
46
|
-
export const config = { matcher: '/api/:path*' };
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
3. **.env.local**
|
|
50
|
-
```bash
|
|
51
|
-
SECURENOW_APPID=my-app
|
|
52
|
-
SECURENOW_INSTANCE=http://otel-collector:4318
|
|
53
|
-
SECURENOW_CAPTURE_BODY=1
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
**Customer code written: 0 lines!** ✨
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## 🎯 Technical Fix
|
|
61
|
-
|
|
62
|
-
### What Changed
|
|
63
|
-
|
|
64
|
-
**Before (Broken):**
|
|
65
|
-
```javascript
|
|
66
|
-
// In nextjs.js - requestHook
|
|
67
|
-
request.on('data', (chunk) => {
|
|
68
|
-
chunks.push(chunk); // ❌ Locks stream
|
|
69
|
-
});
|
|
70
|
-
// → Next.js can't read → ERROR
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**After (Fixed):**
|
|
74
|
-
```javascript
|
|
75
|
-
// In nextjs-middleware.js
|
|
76
|
-
const cloned = request.clone(); // ✅ Clone first
|
|
77
|
-
const body = await cloned.text(); // ✅ Read clone
|
|
78
|
-
// → Original untouched → No error!
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### New Files Created
|
|
82
|
-
|
|
83
|
-
1. **nextjs-middleware.js** (part of package)
|
|
84
|
-
- Exports ready-to-use middleware
|
|
85
|
-
- All parsing/redaction logic included
|
|
86
|
-
- Uses `request.clone()` - safe!
|
|
87
|
-
- 150+ lines of logic customers don't write
|
|
88
|
-
|
|
89
|
-
2. **examples/nextjs-middleware.ts** (.js)
|
|
90
|
-
- Show how to import
|
|
91
|
-
- Matcher configurations
|
|
92
|
-
- Best practices
|
|
93
|
-
|
|
94
|
-
3. **NEXTJS-BODY-CAPTURE.md**
|
|
95
|
-
- Complete guide
|
|
96
|
-
- Examples
|
|
97
|
-
- Troubleshooting
|
|
98
|
-
|
|
99
|
-
4. **Updated postinstall.js**
|
|
100
|
-
- Now offers to create middleware.ts
|
|
101
|
-
- Auto-creates with correct import
|
|
102
|
-
- Updates .env.local template
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
## 🚀 Package Exports
|
|
107
|
-
|
|
108
|
-
```json
|
|
109
|
-
{
|
|
110
|
-
"exports": {
|
|
111
|
-
"./nextjs-middleware": "./nextjs-middleware.js"
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
**Customers import:**
|
|
117
|
-
```typescript
|
|
118
|
-
export { middleware } from 'securenow/nextjs-middleware';
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
**Package provides:**
|
|
122
|
-
- Middleware function
|
|
123
|
-
- Redaction logic
|
|
124
|
-
- Parsing logic
|
|
125
|
-
- Size limits
|
|
126
|
-
- Error handling
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## ✨ Self-Sufficient Design
|
|
131
|
-
|
|
132
|
-
### What's in the Package
|
|
133
|
-
|
|
134
|
-
✅ **nextjs-middleware.js** - Complete middleware implementation
|
|
135
|
-
✅ **Redaction logic** - 20+ sensitive fields
|
|
136
|
-
✅ **Parser** - JSON, GraphQL, Form
|
|
137
|
-
✅ **Size limits** - Configurable
|
|
138
|
-
✅ **Error handling** - Fail-safe
|
|
139
|
-
✅ **Type detection** - Auto-detect content type
|
|
140
|
-
|
|
141
|
-
### What Customer Does
|
|
142
|
-
|
|
143
|
-
✅ **Re-export** - `export { middleware } from 'securenow/nextjs-middleware'`
|
|
144
|
-
✅ **Configure** - Add matcher config (which routes to apply to)
|
|
145
|
-
✅ **Enable** - Set `SECURENOW_CAPTURE_BODY=1`
|
|
146
|
-
|
|
147
|
-
**No logic to write!** Just configuration.
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## 🎓 Customer Experience
|
|
152
|
-
|
|
153
|
-
### Automatic (Recommended)
|
|
154
|
-
|
|
155
|
-
```bash
|
|
156
|
-
npm install securenow
|
|
157
|
-
# Press Y → Creates instrumentation.ts
|
|
158
|
-
# Press Y → Creates middleware.ts
|
|
159
|
-
# Edit .env.local → Set SECURENOW_CAPTURE_BODY=1
|
|
160
|
-
# Run app → Bodies captured!
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
**Total time: 2 minutes**
|
|
164
|
-
**Lines of code: 0**
|
|
165
|
-
|
|
166
|
-
### Manual (If they skip auto-setup)
|
|
167
|
-
|
|
168
|
-
```bash
|
|
169
|
-
npm install securenow
|
|
170
|
-
npx securenow init # Creates both files
|
|
171
|
-
# Edit .env.local
|
|
172
|
-
# Run app
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
**Total time: 3 minutes**
|
|
176
|
-
**Lines of code: 0**
|
|
177
|
-
|
|
178
|
-
### Super Manual (If they want control)
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
npm install securenow
|
|
182
|
-
|
|
183
|
-
# Create middleware.ts manually:
|
|
184
|
-
echo 'export { middleware } from "securenow/nextjs-middleware";' > middleware.ts
|
|
185
|
-
|
|
186
|
-
# Enable in .env.local
|
|
187
|
-
# Run app
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
**Total time: 5 minutes**
|
|
191
|
-
**Lines of code: 1** (the export line)
|
|
192
|
-
|
|
193
|
-
---
|
|
194
|
-
|
|
195
|
-
## 🎉 Result
|
|
196
|
-
|
|
197
|
-
**The error is fixed AND the solution is self-sufficient!**
|
|
198
|
-
|
|
199
|
-
✅ **No stream locking errors**
|
|
200
|
-
✅ **No code for customers to write**
|
|
201
|
-
✅ **All logic in package**
|
|
202
|
-
✅ **Installer creates files automatically**
|
|
203
|
-
✅ **Just configuration needed**
|
|
204
|
-
✅ **Works perfectly with Next.js**
|
|
205
|
-
|
|
206
|
-
### Before Fix
|
|
207
|
-
```
|
|
208
|
-
Customer enables SECURENOW_CAPTURE_BODY=1
|
|
209
|
-
→ Stream locked
|
|
210
|
-
→ TypeError
|
|
211
|
-
→ App broken ❌
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
### After Fix
|
|
215
|
-
```
|
|
216
|
-
Customer enables SECURENOW_CAPTURE_BODY=1
|
|
217
|
-
Customer adds middleware (auto-created by installer)
|
|
218
|
-
→ Request cloned
|
|
219
|
-
→ Body captured
|
|
220
|
-
→ Sensitive data redacted
|
|
221
|
-
→ App works perfectly ✅
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
---
|
|
225
|
-
|
|
226
|
-
## 📦 Files Modified
|
|
227
|
-
|
|
228
|
-
1. **nextjs.js** - Removed stream-consuming code
|
|
229
|
-
2. **nextjs-middleware.js** - NEW! Complete middleware
|
|
230
|
-
3. **postinstall.js** - Now offers middleware creation
|
|
231
|
-
4. **package.json** - Added middleware export
|
|
232
|
-
5. **examples/** - Added middleware examples
|
|
233
|
-
6. **Documentation** - Added guides
|
|
234
|
-
|
|
235
|
-
---
|
|
236
|
-
|
|
237
|
-
## ✅ Testing Checklist
|
|
238
|
-
|
|
239
|
-
- [x] No linter errors
|
|
240
|
-
- [x] Middleware uses request.clone()
|
|
241
|
-
- [x] All logic in package
|
|
242
|
-
- [x] Installer creates files
|
|
243
|
-
- [x] Documentation complete
|
|
244
|
-
- [x] Examples provided
|
|
245
|
-
|
|
246
|
-
---
|
|
247
|
-
|
|
248
|
-
## 🚀 Status: READY TO SHIP!
|
|
249
|
-
|
|
250
|
-
**The package is now:**
|
|
251
|
-
- ✅ Self-sufficient (customers write 0 lines)
|
|
252
|
-
- ✅ Bug-free (no stream locking)
|
|
253
|
-
- ✅ Secure (auto-redaction)
|
|
254
|
-
- ✅ Easy (installer creates files)
|
|
255
|
-
- ✅ Flexible (env var configuration)
|
|
256
|
-
|
|
257
|
-
**No more `Response body object should not be disturbed or locked` error!** 🎯
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|