yinzerflow 0.4.4 → 0.5.0

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,346 +0,0 @@
1
- # Quick Reference
2
-
3
- This quick reference contains the most common patterns and examples for YinzerFlow. For detailed documentation, see the full documentation sections.
4
-
5
- ## Installation & Setup
6
-
7
- ```bash
8
- # Install
9
- npm install yinzerflow
10
-
11
- # Basic setup
12
- import { YinzerFlow } from 'yinzerflow';
13
- const app = new YinzerFlow({ port: 3000 });
14
- await app.listen();
15
- ```
16
-
17
- ## Basic Routes
18
-
19
- ```typescript
20
- // GET route
21
- app.get('/api/users', (ctx) => {
22
- return { users: ['John', 'Jane'] };
23
- });
24
-
25
- // POST route with body
26
- app.post('/api/users', (ctx) => {
27
- const userData = ctx.request.body;
28
- return { message: 'User created', data: userData };
29
- });
30
-
31
- // Route with parameters
32
- app.get('/api/users/:id', (ctx) => {
33
- const userId = ctx.request.params.id;
34
- return { userId, name: 'John Doe' };
35
- });
36
-
37
- // Route with query parameters
38
- app.get('/api/search', (ctx) => {
39
- const { q, limit } = ctx.request.query;
40
- return { search: q, limit: parseInt(limit || '10') };
41
- });
42
- ```
43
-
44
- ## HTTP Methods
45
-
46
- ```typescript
47
- app.get('/api/users', handler); // GET
48
- app.post('/api/users', handler); // POST
49
- app.put('/api/users/:id', handler); // PUT
50
- app.patch('/api/users/:id', handler); // PATCH
51
- app.delete('/api/users/:id', handler); // DELETE
52
- app.options('/api/users', handler); // OPTIONS
53
- app.head('/api/users', handler); // HEAD (or auto-registered with GET)
54
- ```
55
-
56
- ## Route Groups
57
-
58
- ```typescript
59
- app.group('/api/v1', (group) => {
60
- group.get('/users', handler);
61
- group.post('/users', handler);
62
- group.get('/users/:id', handler);
63
- }, {
64
- beforeHooks: [authHook]
65
- });
66
- ```
67
-
68
- ## Hooks
69
-
70
- ```typescript
71
- // Route-specific hooks
72
- app.post('/api/users', handler, {
73
- beforeHooks: [authHook, logHook],
74
- afterHooks: [responseHook]
75
- });
76
-
77
- // Global hooks
78
- app.beforeAll([globalAuthHook]);
79
- app.afterAll([globalLogHook]);
80
- app.onError(errorHandler);
81
- app.onNotFound(notFoundHandler);
82
- ```
83
-
84
- ## Request Data
85
-
86
- ```typescript
87
- app.post('/api/users', ({ request }) => {
88
- // Body data
89
- const userData = request.body;
90
-
91
- // URL parameters
92
- const userId = request.params.id;
93
-
94
- // Query parameters
95
- const { page, limit } = request.query;
96
-
97
- // Headers
98
- const token = request.headers['authorization'];
99
-
100
- // Client IP
101
- const clientIp = request.ipAddress;
102
-
103
- // Request info
104
- const { method, path, url } = request;
105
- });
106
- ```
107
-
108
- ## Response Control
109
-
110
- ```typescript
111
- app.post('/api/users', ({ response }) => {
112
- // Set status code
113
- response.setStatusCode(201);
114
-
115
- // Add headers
116
- response.addHeaders({
117
- 'X-User-ID': '123',
118
- 'Content-Type': 'application/json'
119
- });
120
-
121
- // Return data
122
- return { message: 'User created' };
123
- });
124
- ```
125
-
126
- ## Error Handling
127
-
128
- ```typescript
129
- // Global error handler
130
- app.onError(({ response }, error) => {
131
- response.setStatusCode(500);
132
- return { error: 'Internal server error' };
133
- });
134
-
135
- // Route error handling
136
- app.get('/api/users/:id', ({ request }) => {
137
- const userId = request.params.id;
138
- if (!userId) {
139
- throw new Error('User ID required');
140
- }
141
- return { userId };
142
- });
143
- ```
144
-
145
- ## Common Configurations
146
-
147
- ### Basic API
148
- ```typescript
149
- const app = new YinzerFlow({
150
- port: 3000,
151
- cors: {
152
- enabled: true,
153
- origin: ['https://yourdomain.com']
154
- }
155
- });
156
- ```
157
-
158
- ### Production API
159
- ```typescript
160
- const app = new YinzerFlow({
161
- port: 443,
162
- cors: {
163
- enabled: true,
164
- origin: ['https://yourdomain.com'],
165
- credentials: true
166
- },
167
- bodyParser: {
168
- json: {
169
- maxSize: 262144, // 256KB
170
- allowPrototypeProperties: false
171
- }
172
- },
173
- ipSecurity: {
174
- trustedProxies: ['127.0.0.1'],
175
- detectSpoofing: true
176
- }
177
- });
178
- ```
179
-
180
- ### File Upload Service
181
- ```typescript
182
- const app = new YinzerFlow({
183
- port: 3000,
184
- bodyParser: {
185
- fileUploads: {
186
- maxFileSize: 10485760, // 10MB
187
- maxFiles: 10,
188
- allowedExtensions: ['.jpg', '.png', '.pdf']
189
- }
190
- }
191
- });
192
- ```
193
-
194
- ## TypeScript Support
195
-
196
- ```typescript
197
- interface UserBody {
198
- name: string;
199
- email: string;
200
- }
201
-
202
- interface UserResponse {
203
- id: string;
204
- name: string;
205
- email: string;
206
- }
207
-
208
- const createUser: HandlerCallback<{
209
- body: UserBody;
210
- response: UserResponse;
211
- }> = ({ request }) => {
212
- const userData = request.body; // Typed as UserBody
213
- return {
214
- id: 'user-123',
215
- name: userData.name,
216
- email: userData.email
217
- }; // Typed as UserResponse
218
- };
219
-
220
- app.post('/api/users', createUser);
221
- ```
222
-
223
- ## Common Patterns
224
-
225
- ### Authentication Hook
226
- ```typescript
227
- const authHook = ({ request, response }) => {
228
- const token = request.headers['authorization'];
229
- if (!token) {
230
- response.setStatusCode(401);
231
- return { error: 'Unauthorized' };
232
- }
233
- };
234
- ```
235
-
236
- ### Logging Hook
237
- ```typescript
238
- const logHook = ({ request }) => {
239
- console.log(`${request.method} ${request.path} - ${request.ipAddress}`);
240
- };
241
- ```
242
-
243
- ### Rate Limiting Hook
244
- ```typescript
245
- const rateLimitHook = ({ request, response }) => {
246
- const clientIp = request.ipAddress;
247
- const requests = getRequestCount(clientIp);
248
-
249
- if (requests > 100) {
250
- response.setStatusCode(429);
251
- return { error: 'Too many requests' };
252
- }
253
- };
254
- ```
255
-
256
- ### Validation Hook
257
- ```typescript
258
- const validateUserData = ({ request, response }) => {
259
- const userData = request.body;
260
-
261
- if (!userData.name || !userData.email) {
262
- response.setStatusCode(400);
263
- return { error: 'Name and email required' };
264
- }
265
- };
266
- ```
267
-
268
- ## File Organization
269
-
270
- ### routes/users.ts
271
- ```typescript
272
- import type { YinzerFlow } from 'yinzerflow';
273
-
274
- export const registerUserRoutes = (app: YinzerFlow) => {
275
- app.get('/api/users', getAllUsers);
276
- app.post('/api/users', createUser);
277
- app.get('/api/users/:id', getUserById);
278
- app.put('/api/users/:id', updateUser);
279
- app.delete('/api/users/:id', deleteUser);
280
- };
281
- ```
282
-
283
- ### Main app
284
- ```typescript
285
- import { YinzerFlow } from 'yinzerflow';
286
- import { registerUserRoutes } from './routes/users';
287
-
288
- const app = new YinzerFlow({ port: 3000 });
289
- registerUserRoutes(app);
290
- await app.listen();
291
- ```
292
-
293
- ## Security Checklist
294
-
295
- - [ ] CORS configured with specific origins
296
- - [ ] Body parsing limits set appropriately
297
- - [ ] File upload restrictions in place
298
- - [ ] IP security configured for infrastructure
299
- - [ ] Error handling prevents information leakage
300
- - [ ] Authentication hooks implemented
301
- - [ ] Rate limiting configured
302
- - [ ] HTTPS enabled (production)
303
- - [ ] Security headers configured
304
- - [ ] Logging configured to avoid sensitive data
305
-
306
- ## Common Issues
307
-
308
- ### CORS Errors
309
- ```typescript
310
- cors: {
311
- enabled: true,
312
- origin: ['https://yourdomain.com'], // Specific origin
313
- credentials: true // If using cookies
314
- }
315
- ```
316
-
317
- ### File Upload Issues
318
- ```typescript
319
- bodyParser: {
320
- fileUploads: {
321
- maxFileSize: 10485760, // 10MB
322
- allowedExtensions: ['.jpg', '.png', '.pdf']
323
- }
324
- }
325
- ```
326
-
327
- ### IP Address Issues
328
- ```typescript
329
- ipSecurity: {
330
- trustedProxies: ['127.0.0.1', '192.168.1.10'],
331
- headerPreference: ['x-forwarded-for', 'x-real-ip']
332
- }
333
- ```
334
-
335
- ## Documentation Sections
336
-
337
- - **[Getting Started](./start-here.md)** - Installation and basic setup
338
- - **[Routes](./core/routes.md)** - Complete routing system
339
- - **[Context Object](./core/context.md)** - Request/response interface
340
- - **[Request Object](./core/request.md)** - Request data access
341
- - **[Response Object](./core/response.md)** - Response control
342
- - **[Error Handling](./core/error-handling.md)** - Error management
343
- - **[Examples](./core/examples.md)** - Common patterns and examples
344
- - **[Security Overview](./security/security-overview.md)** - Security features
345
- - **[Configuration Patterns](./configuration/configuration-patterns.md)** - Configuration examples
346
- - **[Advanced Configuration](./configuration/advanced-configuration-options.md)** - Complete configuration reference
@@ -1,296 +0,0 @@
1
- # Body Parsing Security
2
-
3
- YinzerFlow provides comprehensive body parsing with built-in security protections against DoS attacks, prototype pollution, and memory exhaustion vulnerabilities. The body parser automatically handles JSON, file uploads, and URL-encoded form data with configurable security limits.
4
-
5
- For an overview of all security features, see [Security Overview](./security-overview.md).
6
-
7
- ## Configuration
8
-
9
- Body parsing is automatically enabled with secure defaults that protect against common attack vectors:
10
-
11
- ```typescript
12
- import { YinzerFlow } from 'yinzerflow';
13
-
14
- const app = new YinzerFlow({
15
- port: 3000,
16
- bodyParser: {
17
- json: {
18
- maxSize: 262144, // 256KB (reasonable for JSON APIs)
19
- maxDepth: 10,
20
- allowPrototypeProperties: false, // Blocks prototype pollution
21
- maxKeys: 1000,
22
- maxStringLength: 1048576, // 1MB per string
23
- maxArrayLength: 10000
24
- },
25
- fileUploads: {
26
- maxFileSize: 10485760, // 10MB per file
27
- maxTotalSize: 52428800, // 50MB total
28
- maxFiles: 10,
29
- allowedExtensions: [], // Empty = allow all
30
- blockedExtensions: ['.exe', '.bat', '.cmd', '.scr', '.pif', '.com'],
31
- maxFilenameLength: 255
32
- },
33
- urlEncoded: {
34
- maxSize: 1048576, // 1MB
35
- maxFields: 1000,
36
- maxFieldNameLength: 100,
37
- maxFieldLength: 1048576 // 1MB per field
38
- }
39
- }
40
- });
41
- ```
42
-
43
- ### Configuration Options
44
-
45
- #### JSON Parser Configuration
46
-
47
- Controls how JSON request bodies are parsed and validated:
48
-
49
- | Option | Type | Default | Description |
50
- |-----|---|---|---|
51
- | `maxSize` | `number` | `262144` (256KB) | Maximum JSON body size in bytes |
52
- | `maxDepth` | `number` | `10` | Maximum nesting depth to prevent stack overflow |
53
- | `allowPrototypeProperties` | `boolean` | `false` | Allow dangerous prototype properties (⚠️ Security Risk) |
54
- | `maxKeys` | `number` | `1000` | Maximum object keys to prevent memory exhaustion |
55
- | `maxStringLength` | `number` | `1048576` (1MB) | Maximum string length per property |
56
- | `maxArrayLength` | `number` | `10000` | Maximum array elements per property |
57
-
58
- #### File Upload Configuration
59
-
60
- Controls file upload processing and security:
61
-
62
- | Option | Type | Default | Description |
63
- |-----|---|---|---|
64
- | `maxFileSize` | `number` | `10485760` (10MB) | Maximum size per individual file |
65
- | `maxTotalSize` | `number` | `52428800` (50MB) | Maximum total upload size per request |
66
- | `maxFiles` | `number` | `10` | Maximum number of files per request |
67
- | `allowedExtensions` | `string[]` | `[]` | Allowed file extensions (empty = allow all) |
68
- | `blockedExtensions` | `string[]` | `['.exe', '.bat', ...]` | Blocked file extensions for security |
69
- | `maxFilenameLength` | `number` | `255` | Maximum filename length |
70
-
71
- #### URL-Encoded Form Configuration
72
-
73
- Controls form data parsing and validation:
74
-
75
- | Option | Type | Default | Description |
76
- |-----|---|---|---|
77
- | `maxSize` | `number` | `1048576` (1MB) | Maximum form data size |
78
- | `maxFields` | `number` | `1000` | Maximum form fields to prevent DoS |
79
- | `maxFieldNameLength` | `number` | `100` | Maximum field name length |
80
- | `maxFieldLength` | `number` | `1048576` (1MB) | Maximum field value length |
81
-
82
- ## Examples
83
-
84
- #### Strict API Configuration
85
- ```typescript
86
- const strictApiApp = new YinzerFlow({
87
- port: 3000,
88
- bodyParser: {
89
- json: {
90
- maxSize: 131072, // 128KB - smaller for strict APIs
91
- maxDepth: 5, // Shallow nesting only
92
- allowPrototypeProperties: false, // Always keep false!
93
- maxKeys: 100, // Fewer keys allowed
94
- maxStringLength: 10240, // 10KB strings max
95
- maxArrayLength: 100 // Small arrays only
96
- },
97
- fileUploads: {
98
- maxFileSize: 1048576, // 1MB files only
99
- maxFiles: 3, // Very few files
100
- allowedExtensions: ['.jpg', '.png', '.pdf'], // Specific types only
101
- maxFilenameLength: 50 // Short filenames
102
- }
103
- }
104
- });
105
- ```
106
-
107
- #### Media Upload Configuration
108
- ```typescript
109
- const mediaApp = new YinzerFlow({
110
- port: 3000,
111
- bodyParser: {
112
- json: {
113
- maxSize: 512000, // 500KB for metadata
114
- maxDepth: 3, // Simple metadata only
115
- allowPrototypeProperties: false
116
- },
117
- fileUploads: {
118
- maxFileSize: 104857600, // 100MB per file for media
119
- maxTotalSize: 524288000, // 500MB total
120
- maxFiles: 20,
121
- allowedExtensions: ['.jpg', '.jpeg', '.png', '.gif', '.mp4', '.webm', '.pdf'],
122
- blockedExtensions: [], // Using allowlist instead
123
- maxFilenameLength: 200
124
- }
125
- }
126
- });
127
- ```
128
-
129
- #### High-Security Configuration
130
- ```typescript
131
- const secureApp = new YinzerFlow({
132
- port: 443,
133
- bodyParser: {
134
- json: {
135
- maxSize: 32768, // 32KB only
136
- maxDepth: 3,
137
- maxKeys: 50
138
- },
139
- fileUploads: {
140
- maxFileSize: 0, // No file uploads
141
- maxFiles: 0
142
- },
143
- urlEncoded: {
144
- maxSize: 8192, // 8KB forms only
145
- maxFields: 20
146
- }
147
- }
148
- });
149
- ```
150
-
151
- ## Common Use Cases
152
-
153
- - **API Data Processing**: Parse JSON payloads with automatic security validation and DoS protection
154
- - **File Upload Handling**: Secure file upload processing with size, type, and count restrictions
155
- - **Form Data Processing**: Handle HTML form submissions with field validation and memory protection
156
- - **Content Type Detection**: Automatic parsing based on Content-Type headers with fallback handling
157
- - **Security Compliance**: Built-in protection against common web vulnerabilities and attack vectors
158
- - **Memory Protection**: Prevent DoS attacks through configurable size and complexity limits
159
-
160
- ## API Reference
161
-
162
- ### Request Body Properties
163
-
164
- When body parsing is successful, the parsed data is available on `request.body`:
165
-
166
- #### JSON Requests
167
- ```typescript
168
- // Content-Type: application/json
169
- request.body: unknown // Parsed JSON object or array
170
- ```
171
-
172
- #### File Upload Requests
173
- ```typescript
174
- // Content-Type: multipart/form-data
175
- request.body: {
176
- fields: Record<string, string | string[]>; // Form fields
177
- files: Array<{
178
- fieldname: string;
179
- filename: string;
180
- mimetype: string;
181
- size: number;
182
- buffer: Buffer;
183
- }>;
184
- }
185
- ```
186
-
187
- #### URL-Encoded Form Requests
188
- ```typescript
189
- // Content-Type: application/x-www-form-urlencoded
190
- request.body: Record<string, string | string[]> // Parsed form data
191
- ```
192
-
193
- ### Configuration Methods
194
-
195
- Body parser configuration is set during YinzerFlow initialization:
196
-
197
- ```typescript
198
- const app = new YinzerFlow({
199
- bodyParser: {
200
- json: JsonParserOptions,
201
- fileUploads: FileUploadOptions,
202
- urlEncoded: UrlEncodedOptions
203
- }
204
- });
205
- ```
206
-
207
- ## Configuration Validation and Warnings
208
-
209
- YinzerFlow validates all body parser configuration options and provides security warnings for potentially risky settings:
210
-
211
- ### Automatic Validation
212
- - **Minimum limits**: Prevents broken configurations (e.g., maxSize: 0)
213
- - **Type checking**: Ensures proper data types for all options
214
- - **Logical validation**: Checks for contradictory settings
215
-
216
- ### Security Warnings
217
- YinzerFlow will log warnings (but not block) potentially risky configurations:
218
-
219
- ```typescript
220
- // This will trigger security warnings
221
- const riskyApp = new YinzerFlow({
222
- bodyParser: {
223
- json: {
224
- maxSize: 52428800, // 50MB JSON - warning about memory risk
225
- allowPrototypeProperties: true, // Warning about prototype pollution
226
- maxDepth: 100 // Warning about stack overflow risk
227
- },
228
- fileUploads: {
229
- maxFileSize: 1073741824, // 1GB files - warning about resources
230
- allowedExtensions: ['.exe'] // Warning about dangerous file types
231
- }
232
- }
233
- });
234
- ```
235
-
236
- ## Error Handling
237
-
238
- YinzerFlow automatically handles body parsing errors and provides clear error messages:
239
-
240
- **JSON parsing errors:**
241
- - `Invalid JSON in request body: Unexpected token at position X`
242
- - `JSON body too large: maximum 256KB allowed`
243
- - `JSON nesting too deep: maximum 10 levels allowed`
244
- - `JSON object has too many keys: maximum 1000 allowed`
245
-
246
- **File upload errors:**
247
- - `File too large: maximum 10MB per file allowed`
248
- - `Too many files: maximum 10 files per request`
249
- - `File type not allowed: .exe files are blocked`
250
- - `Total upload size exceeded: maximum 50MB total allowed`
251
-
252
- **URL-encoded form errors:**
253
- - `Form data too large: maximum 1MB allowed`
254
- - `Too many form fields: maximum 1000 fields allowed`
255
- - `Form field name too long: maximum 100 characters`
256
- - `Form field value too large: maximum 1MB per field`
257
-
258
- These errors automatically result in appropriate HTTP status codes (400 Bad Request) and prevent malformed or malicious requests from reaching your application handlers.
259
-
260
- ## Security Considerations
261
-
262
- YinzerFlow implements comprehensive security measures to prevent body parsing vulnerabilities:
263
-
264
- ### 🛡️ JSON DoS Attack Prevention
265
- - **Problem**: Large or deeply nested JSON can cause memory exhaustion and stack overflow attacks
266
- - **YinzerFlow Solution**: Configurable size limits, nesting depth limits, key count restrictions, and string/array length limits prevent resource exhaustion
267
-
268
- ### 🛡️ Prototype Pollution Protection
269
- - **Problem**: Malicious JSON can pollute JavaScript prototypes using `__proto__`, `constructor`, and `prototype` properties
270
- - **YinzerFlow Solution**: Blocks dangerous properties by default with `allowPrototypeProperties: false` and validates all object keys
271
-
272
- ### 🛡️ File Upload Security
273
- - **Problem**: Malicious file uploads can execute code, consume server resources, or bypass security controls
274
- - **YinzerFlow Solution**: File type filtering, size limits, filename validation, and extension-based security controls
275
-
276
- ### 🛡️ Memory Exhaustion Protection
277
- - **Problem**: Large form data, arrays, or objects can exhaust server memory and cause crashes
278
- - **YinzerFlow Solution**: Configurable limits on strings, arrays, fields, object keys, and total request sizes
279
-
280
- ### 🛡️ Request Size Validation
281
- - **Problem**: Extremely large requests can cause DoS through resource exhaustion
282
- - **YinzerFlow Solution**: Content-type specific size limits with early validation before full parsing
283
-
284
- ### 🛡️ Malformed Data Handling
285
- - **Problem**: Invalid or malformed data can crash parsers, cause security issues, or bypass validation
286
- - **YinzerFlow Solution**: Graceful error handling with detailed security context and safe fallback parsing
287
-
288
- ### 🛡️ Filename Injection Prevention
289
- - **Problem**: Malicious filenames can contain path traversal attacks or dangerous characters
290
- - **YinzerFlow Solution**: Filename length validation, character sanitization, and path traversal prevention
291
-
292
- ### 🛡️ MIME Type Validation
293
- - **Problem**: Spoofed or incorrect MIME types can bypass security filters
294
- - **YinzerFlow Solution**: Content-Type header validation and file extension cross-checking for uploaded files
295
-
296
- These security measures ensure YinzerFlow's body parsing implementation follows security best practices and prevents common attack vectors while maintaining spec compliance.