@reldens/server-utils 0.35.0 → 0.37.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.
package/README.md CHANGED
@@ -1,395 +1,457 @@
1
- # Reldens - Server Utils
2
-
3
- A Node.js server toolkit providing secure application server creation, file handling, encryption, and file upload capabilities for production-ready applications with modular security configurations.
4
-
5
- [![Reldens - GitHub - Release](https://www.dwdeveloper.com/media/reldens/reldens-mmorpg-platform.png)](https://github.com/damian-pastorini/reldens)
6
-
7
- ## Features
8
-
9
- ### AppServerFactory
10
- - Complete Express.js server configuration with modular security
11
- - HTTPS/HTTP server creation with SSL certificate management
12
- - HTTP/2 support via spdy with automatic HTTP/1.1 fallback
13
- - Optimized static asset caching for CSS, JS, fonts, and images
14
- - SNI (Server Name Indication) support for multi-domain hosting
15
- - Virtual host management with domain mapping
16
- - Development mode detection with appropriate configurations
17
- - CORS configuration with flexible origin management
18
- - Rate limiting with customizable thresholds
19
- - Security headers and XSS protection
20
- - Helmet integration for enhanced security
21
- - Protocol enforcement (HTTP to HTTPS redirection)
22
- - Trusted proxy configuration
23
- - Request parsing with size limits and validation
24
- - Static file serving with security headers
25
- - Compression middleware with smart filtering
26
- - Input validation utilities
27
-
28
- #### Modular Security Components
29
- The AppServerFactory now uses specialized security configurers:
30
-
31
- - **CorsConfigurer** - Dynamic CORS origin validation with development domain support
32
- - **DevelopmentModeDetector** - Automatic development environment detection
33
- - **ProtocolEnforcer** - Protocol redirection with development mode awareness
34
- - **RateLimitConfigurer** - Global and endpoint-specific rate limiting
35
- - **SecurityConfigurer** - Helmet integration with CSP management and XSS protection
36
-
37
- ### FileHandler
38
- - Secure file system operations with path validation
39
- - File and folder creation, copying, and removal
40
- - JSON file parsing and validation
41
- - File type detection based on magic numbers
42
- - Secure filename generation
43
- - Path sanitization and traversal protection
44
- - File permissions checking
45
- - Folder content listing and filtering
46
- - Temporary file creation
47
- - File quarantine functionality for security threats
48
- - Binary file head reading for type detection
49
- - Directory walking with callback processing
50
- - File comparison and relative path calculations
51
- - Comprehensive error handling with detailed context
52
-
53
- ### Encryptor
54
- - Password hashing using PBKDF2 with configurable iterations
55
- - Password validation against stored hashes
56
- - AES-256-GCM data encryption and decryption
57
- - Secure token generation with a customizable length
58
- - TOTP (Time-based One-Time Password) generation
59
- - Data hashing with multiple algorithms (SHA-256, SHA-512, MD5)
60
- - HMAC generation and verification
61
- - Constant-time string comparison for security
62
- - Cryptographically secure random value generation
63
-
64
- ### UploaderFactory
65
- - Multer-based file upload handling with security validation
66
- - Multiple file upload support with field mapping
67
- - File type validation using MIME types and extensions
68
- - Filename security validation and sanitization
69
- - File size limits and upload count restrictions
70
- - Secure filename generation option
71
- - File content validation based on magic numbers
72
- - Dangerous file extension filtering
73
- - Automatic file cleanup on validation failure
74
- - Custom error response handling
75
- - Upload destination mapping per field
76
-
77
- ## Installation
78
-
79
- ```bash
80
- npm install @reldens/server-utils
81
- ```
82
-
83
- ## Quick Start
84
-
85
- ### Basic Server Setup
86
-
87
- ```javascript
88
- const { AppServerFactory } = require('@reldens/server-utils');
89
-
90
- let appServerFactory = new AppServerFactory();
91
- let serverResult = appServerFactory.createAppServer({
92
- port: 3000,
93
- useHttps: false,
94
- autoListen: true,
95
- useCompression: true
96
- });
97
-
98
- if(serverResult){
99
- let { app, appServer } = serverResult;
100
- console.log('Server running on port 3000');
101
- }
102
- ```
103
-
104
- ### HTTP/2 Server with Optimized Caching
105
-
106
- ```javascript
107
- let appServerFactory = new AppServerFactory();
108
- let serverResult = appServerFactory.createAppServer({
109
- port: 443,
110
- useHttps: true,
111
- useHttp2: true,
112
- keyPath: '/ssl/server.key',
113
- certPath: '/ssl/server.crt',
114
- autoListen: true
115
- });
116
- ```
117
-
118
- Cache configuration is automatic with defaults:
119
- - CSS/JS: 1 year
120
- - Fonts: 1 year
121
- - Images: 30 days
122
-
123
- Override cache settings if needed:
124
-
125
- ```javascript
126
- let appServerFactory = new AppServerFactory();
127
- appServerFactory.cacheConfig = {
128
- '.css': 86400,
129
- '.js': 86400,
130
- '.png': 604800
131
- };
132
- let serverResult = appServerFactory.createAppServer({
133
- useHttps: true,
134
- useHttp2: true
135
- });
136
- ```
137
-
138
- ### File Operations
139
-
140
- ```javascript
141
- const { FileHandler } = require('@reldens/server-utils');
142
-
143
- // Read a JSON configuration file
144
- let config = FileHandler.fetchFileJson('/path/to/config.json');
145
- if(config){
146
- console.log('Configuration loaded:', config);
147
- }
148
-
149
- // Create a folder securely
150
- if(FileHandler.createFolder('/path/to/new/folder')){
151
- console.log('Folder created successfully');
152
- }
153
-
154
- // Generate a secure filename
155
- let secureFilename = FileHandler.generateSecureFilename('user-upload.jpg');
156
- console.log('Secure filename:', secureFilename);
157
- ```
158
-
159
- ### Password Encryption
160
-
161
- ```javascript
162
- const { Encryptor } = require('@reldens/server-utils');
163
-
164
- // Hash a password
165
- let hashedPassword = Encryptor.encryptPassword('userPassword123');
166
- if(hashedPassword){
167
- console.log('Password hashed:', hashedPassword);
168
- }
169
-
170
- // Validate password
171
- let isValid = Encryptor.validatePassword('userPassword123', hashedPassword);
172
- console.log('Password valid:', isValid);
173
-
174
- // Generate secure token
175
- let secureToken = Encryptor.generateSecureToken(32);
176
- console.log('Secure token:', secureToken);
177
- ```
178
-
179
- ### File Upload Configuration
180
-
181
- ```javascript
182
- const { UploaderFactory } = require('@reldens/server-utils');
183
-
184
- let uploaderFactory = new UploaderFactory({
185
- maxFileSize: 10 * 1024 * 1024, // 10MB
186
- mimeTypes: {
187
- image: ['image/jpeg', 'image/png', 'image/gif'],
188
- document: ['application/pdf', 'text/plain']
189
- },
190
- allowedExtensions: {
191
- image: ['.jpg', '.jpeg', '.png', '.gif'],
192
- document: ['.pdf', '.txt']
193
- },
194
- applySecureFileNames: true
195
- });
196
-
197
- let uploader = uploaderFactory.createUploader(
198
- [{ name: 'avatar' }, { name: 'document' }],
199
- { avatar: '/uploads/avatars', document: '/uploads/docs' },
200
- { avatar: 'image', document: 'document' }
201
- );
202
-
203
- // Use with Express
204
- app.post('/upload', uploader, (req, res) => {
205
- console.log('Files uploaded:', req.files);
206
- res.json({ success: true });
207
- });
208
- ```
209
-
210
- ## Advanced Configuration
211
-
212
- ### HTTPS Server with Multiple Domains
213
-
214
- ```javascript
215
- let appServerFactory = new AppServerFactory();
216
-
217
- appServerFactory.addDomain({
218
- hostname: 'example.com',
219
- keyPath: '/ssl/example.com.key',
220
- certPath: '/ssl/example.com.crt',
221
- aliases: ['www.example.com']
222
- });
223
-
224
- appServerFactory.addDomain({
225
- hostname: 'api.example.com',
226
- keyPath: '/ssl/api.example.com.key',
227
- certPath: '/ssl/api.example.com.crt'
228
- });
229
-
230
- let serverResult = appServerFactory.createAppServer({
231
- useHttps: true,
232
- useHttp2: true,
233
- useVirtualHosts: true,
234
- keyPath: '/ssl/default.key',
235
- certPath: '/ssl/default.crt',
236
- port: 443,
237
- enforceProtocol: true,
238
- developmentMultiplier: 10
239
- });
240
- ```
241
-
242
- ### Development Mode Configuration
243
-
244
- ```javascript
245
- let appServerFactory = new AppServerFactory();
246
-
247
- // Add development domains (automatically detected)
248
- appServerFactory.addDevelopmentDomain('localhost');
249
- appServerFactory.addDevelopmentDomain('dev.myapp.local');
250
-
251
- let serverResult = appServerFactory.createAppServer({
252
- port: 3000,
253
- corsOrigin: ['http://localhost:3000', 'http://dev.myapp.local:3000'],
254
- developmentMultiplier: 5, // More lenient rate limiting in dev
255
- developmentPorts: [3000, 3001, 8080],
256
- developmentExternalDomains: {
257
- 'script-src': ['https://cdn.example.com'],
258
- 'style-src': ['https://fonts.googleapis.com']
259
- }
260
- });
261
- ```
262
-
263
- ### Custom Security Configuration
264
-
265
- ```javascript
266
- let appServerFactory = new AppServerFactory();
267
-
268
- let serverResult = appServerFactory.createAppServer({
269
- useHelmet: true,
270
- helmetConfig: {
271
- contentSecurityPolicy: {
272
- directives: {
273
- defaultSrc: ["'self'"],
274
- styleSrc: ["'self'", "'unsafe-inline'"],
275
- scriptSrc: ["'self'"]
276
- }
277
- }
278
- },
279
- globalRateLimit: 100, // requests per window
280
- windowMs: 60000, // 1 minute
281
- maxRequests: 30,
282
- trustedProxy: '127.0.0.1',
283
- useXssProtection: true,
284
- sanitizeOptions: {allowedTags: [], allowedAttributes: {}}
285
- });
286
- ```
287
-
288
- ## API Reference
289
-
290
- ### AppServerFactory Methods
291
-
292
- - `createAppServer(config)` - Creates and configures Express server
293
- - `addDomain(domainConfig)` - Adds domain configuration for virtual hosting
294
- - `addDevelopmentDomain(domain)` - Adds development domain pattern
295
- - `setDomainMapping(mapping)` - Sets domain to configuration mapping
296
- - `enableServeHome(app, callback)` - Enables homepage serving
297
- - `serveStatics(app, staticPath)` - Serves static files
298
- - `serveStaticsPath(app, route, staticPath)` - Serves static files on specific route
299
- - `enableCSP(cspOptions)` - Enables Content Security Policy
300
- - `listen(port)` - Starts server listening
301
- - `close()` - Gracefully closes server
302
-
303
- ### FileHandler Methods
304
-
305
- - `exists(path)` - Checks if file or folder exists
306
- - `createFolder(path)` - Creates folder with a recursive option
307
- - `remove(path)` - Removes file or folder recursively
308
- - `removeMultiple(filePaths)` - Removes multiple files from an array of paths
309
- - `copyFile(source, destination)` - Copies file to destination
310
- - `copyFolderSync(source, destination)` - Copies folder recursively
311
- - `readFile(path)` - Reads file contents as string
312
- - `writeFile(path, content)` - Writes content to file
313
- - `fetchFileJson(path)` - Reads and parses JSON file
314
- - `fetchFileContents(path)` - Reads file with validation
315
- - `updateFileContents(path, content)` - Updates existing file
316
- - `isFile(path)` - Checks if a path is a file
317
- - `isFolder(path)` - Checks if a path is folder
318
- - `getFilesInFolder(path, extensions)` - Lists files with optional filtering
319
- - `validateFileType(path, type, allowedTypes, maxSize)` - Validates file type and size
320
- - `detectFileType(path)` - Detects MIME type from file signature
321
- - `generateSecureFilename(originalName)` - Generates cryptographically secure filename
322
- - `quarantineFile(path, reason)` - Moves file to quarantine folder
323
- - `createTempFile(prefix, extension)` - Creates a temporary file path
324
- - `moveFile(from, to)` - Moves file to new location
325
- - `getFileSize(path)` - Gets file size in bytes
326
- - `compareFiles(file1, file2)` - Compares file contents
327
- - `getRelativePath(from, to)` - Calculates relative path
328
- - `walkDirectory(path, callback)` - Recursively processes directory tree
329
- - `getDirectorySize(path)` - Calculates total directory size
330
- - `emptyDirectory(path)` - Removes all contents from directory
331
-
332
- ### Encryptor Methods
333
-
334
- - `encryptPassword(password)` - Hashes password with salt
335
- - `validatePassword(password, hash)` - Validates password against hash
336
- - `generateSecretKey()` - Generates 256-bit secret key
337
- - `encryptData(data, key)` - Encrypts data with AES-256-GCM
338
- - `decryptData(encryptedData, key)` - Decrypts AES-256-GCM data
339
- - `generateSecureToken(length)` - Generates base64url token
340
- - `generateTOTP(secret, timeStep)` - Generates time-based OTP
341
- - `hashData(data, algorithm)` - Hashes data with specified algorithm
342
- - `generateHMAC(data, secret, algorithm)` - Generates HMAC signature
343
- - `verifyHMAC(data, secret, signature, algorithm)` - Verifies HMAC signature
344
- - `constantTimeCompare(a, b)` - Performs constant-time string comparison
345
-
346
- ### UploaderFactory Methods
347
-
348
- - `createUploader(fields, buckets, allowedTypes)` - Creates multer upload middleware
349
- - `validateFilenameSecurity(filename)` - Validates filename for security
350
- - `validateFile(file, allowedType, callback)` - Validates a file during upload
351
- - `validateFileContents(file, allowedType)` - Validates file content after upload
352
- - `convertToRegex(key)` - Converts MIME type patterns to regex
353
-
354
- ## Security Features
355
-
356
- ### Path Traversal Protection
357
- All file operations include comprehensive path validation to prevent directory traversal attacks and access to system files.
358
-
359
- ### Secure File Upload
360
- File uploads are validated at multiple levels including filename, MIME type, file extension, file size, and content validation using magic number detection. Failed uploads are automatically cleaned up using efficient file removal.
361
-
362
- ### Rate Limiting
363
- Configurable rate limiting with development mode detection for appropriate thresholds in different environments.
364
-
365
- ### HTTPS Support
366
- Full SSL/TLS support with SNI for multi-domain hosting and automatic certificate management.
367
-
368
- ### HTTP/2 Support
369
- HTTP/2 support via spdy with multiplexing for improved performance and automatic HTTP/1.1 fallback for older clients.
370
-
371
- ### Input Validation
372
- Built-in validators for common input types including email, username, strong passwords, alphanumeric strings, and IP addresses.
373
-
374
- ### Cryptographic Security
375
- Industry-standard encryption using PBKDF2 for passwords, AES-256-GCM for data encryption, and secure random generation for tokens.
376
-
377
- ## Error Handling
378
-
379
- All methods include comprehensive error handling with detailed error objects containing context information. Errors are logged appropriately and never expose sensitive system information.
380
-
381
- ---
382
-
383
- ## Documentation
384
-
385
- [https://www.reldens.com/documentation/utils/](https://www.reldens.com/documentation/utils/)
386
-
387
- Need something specific?
388
-
389
- [Request a feature here: https://www.reldens.com/features-request](https://www.reldens.com/features-request)
390
-
391
- ---
392
-
393
- ### [Reldens](https://github.com/damian-pastorini/reldens/ "Reldens")
394
-
395
- ##### [By DwDeveloper](https://www.dwdeveloper.com/ "DwDeveloper")
1
+ # Reldens - Server Utils
2
+
3
+ A Node.js server toolkit providing secure application server creation, file handling, encryption, and file upload capabilities for production-ready applications with modular security configurations.
4
+
5
+ [![Reldens - GitHub - Release](https://www.dwdeveloper.com/media/reldens/reldens-mmorpg-platform.png)](https://github.com/damian-pastorini/reldens)
6
+
7
+ ## Features
8
+
9
+ ### AppServerFactory
10
+ - Complete Express.js server configuration with modular security
11
+ - HTTPS/HTTP server creation with SSL certificate management
12
+ - Optimized static asset caching for CSS, JS, fonts, and images
13
+ - SNI (Server Name Indication) support for multi-domain hosting
14
+ - Virtual host management with domain mapping
15
+ - Development mode detection with appropriate configurations
16
+ - CORS configuration with flexible origin management
17
+ - Rate limiting with customizable thresholds
18
+ - Security headers and XSS protection
19
+ - Helmet integration for enhanced security
20
+ - Protocol enforcement (HTTP to HTTPS redirection)
21
+ - Trusted proxy configuration
22
+ - Request parsing with size limits and validation
23
+ - Static file serving with security headers
24
+ - Compression middleware with smart filtering
25
+ - Input validation utilities
26
+
27
+ #### Modular Security Components
28
+ The AppServerFactory now uses specialized security configurers:
29
+
30
+ - **CorsConfigurer** - Dynamic CORS origin validation with development domain support
31
+ - **DevelopmentModeDetector** - Automatic development environment detection
32
+ - **ProtocolEnforcer** - Protocol redirection with development mode awareness
33
+ - **RateLimitConfigurer** - Global and endpoint-specific rate limiting
34
+ - **SecurityConfigurer** - Helmet integration with CSP management and XSS protection
35
+
36
+ ### FileHandler
37
+ - Secure file system operations with path validation
38
+ - File and folder creation, copying, and removal
39
+ - JSON file parsing and validation
40
+ - File type detection based on magic numbers
41
+ - Secure filename generation
42
+ - Path sanitization and traversal protection
43
+ - File permissions checking
44
+ - Folder content listing and filtering
45
+ - Temporary file creation
46
+ - File quarantine functionality for security threats
47
+ - Binary file head reading for type detection
48
+ - Directory walking with callback processing
49
+ - File comparison and relative path calculations
50
+ - Comprehensive error handling with detailed context
51
+
52
+ ### Encryptor
53
+ - Password hashing using PBKDF2 with configurable iterations
54
+ - Password validation against stored hashes
55
+ - AES-256-GCM data encryption and decryption
56
+ - Secure token generation with a customizable length
57
+ - TOTP (Time-based One-Time Password) generation
58
+ - Data hashing with multiple algorithms (SHA-256, SHA-512, MD5)
59
+ - HMAC generation and verification
60
+ - Constant-time string comparison for security
61
+ - Cryptographically secure random value generation
62
+
63
+ ### UploaderFactory
64
+ - Multer-based file upload handling with security validation
65
+ - Multiple file upload support with field mapping
66
+ - File type validation using MIME types and extensions
67
+ - Filename security validation and sanitization
68
+ - File size limits and upload count restrictions
69
+ - Secure filename generation option
70
+ - File content validation based on magic numbers
71
+ - Dangerous file extension filtering
72
+ - Automatic file cleanup on validation failure
73
+ - Custom error response handling
74
+ - Upload destination mapping per field
75
+
76
+ ## Installation
77
+
78
+ ```bash
79
+ npm install @reldens/server-utils
80
+ ```
81
+
82
+ ## Quick Start
83
+
84
+ ### Basic Server Setup
85
+
86
+ ```javascript
87
+ const { AppServerFactory } = require('@reldens/server-utils');
88
+
89
+ let appServerFactory = new AppServerFactory();
90
+ let serverResult = appServerFactory.createAppServer({
91
+ port: 3000,
92
+ useHttps: false,
93
+ autoListen: true,
94
+ useCompression: true
95
+ });
96
+
97
+ if(serverResult){
98
+ let { app, appServer } = serverResult;
99
+ console.log('Server running on port 3000');
100
+ }
101
+ ```
102
+
103
+ ### HTTPS Server with Optimized Caching
104
+
105
+ ```javascript
106
+ let appServerFactory = new AppServerFactory();
107
+ let serverResult = appServerFactory.createAppServer({
108
+ port: 443,
109
+ useHttps: true,
110
+ keyPath: '/ssl/server.key',
111
+ certPath: '/ssl/server.crt',
112
+ autoListen: true
113
+ });
114
+ ```
115
+
116
+ Cache configuration is automatic with defaults:
117
+ - CSS/JS: 1 year
118
+ - Fonts: 1 year
119
+ - Images: 30 days
120
+
121
+ Override cache settings if needed:
122
+
123
+ ```javascript
124
+ let appServerFactory = new AppServerFactory();
125
+ appServerFactory.cacheConfig = {
126
+ '.css': 86400,
127
+ '.js': 86400,
128
+ '.png': 604800
129
+ };
130
+ let serverResult = appServerFactory.createAppServer({
131
+ useHttps: true,
132
+ });
133
+ ```
134
+
135
+ ### File Operations
136
+
137
+ ```javascript
138
+ const { FileHandler } = require('@reldens/server-utils');
139
+
140
+ // Read a JSON configuration file
141
+ let config = FileHandler.fetchFileJson('/path/to/config.json');
142
+ if(config){
143
+ console.log('Configuration loaded:', config);
144
+ }
145
+
146
+ // Create a folder securely
147
+ if(FileHandler.createFolder('/path/to/new/folder')){
148
+ console.log('Folder created successfully');
149
+ }
150
+
151
+ // Generate a secure filename
152
+ let secureFilename = FileHandler.generateSecureFilename('user-upload.jpg');
153
+ console.log('Secure filename:', secureFilename);
154
+ ```
155
+
156
+ ### Password Encryption
157
+
158
+ ```javascript
159
+ const { Encryptor } = require('@reldens/server-utils');
160
+
161
+ // Hash a password
162
+ let hashedPassword = Encryptor.encryptPassword('userPassword123');
163
+ if(hashedPassword){
164
+ console.log('Password hashed:', hashedPassword);
165
+ }
166
+
167
+ // Validate password
168
+ let isValid = Encryptor.validatePassword('userPassword123', hashedPassword);
169
+ console.log('Password valid:', isValid);
170
+
171
+ // Generate secure token
172
+ let secureToken = Encryptor.generateSecureToken(32);
173
+ console.log('Secure token:', secureToken);
174
+ ```
175
+
176
+ ### File Upload Configuration
177
+
178
+ ```javascript
179
+ const { UploaderFactory } = require('@reldens/server-utils');
180
+
181
+ let uploaderFactory = new UploaderFactory({
182
+ maxFileSize: 10 * 1024 * 1024, // 10MB
183
+ mimeTypes: {
184
+ image: ['image/jpeg', 'image/png', 'image/gif'],
185
+ document: ['application/pdf', 'text/plain']
186
+ },
187
+ allowedExtensions: {
188
+ image: ['.jpg', '.jpeg', '.png', '.gif'],
189
+ document: ['.pdf', '.txt']
190
+ },
191
+ applySecureFileNames: true
192
+ });
193
+
194
+ let uploader = uploaderFactory.createUploader(
195
+ [{ name: 'avatar' }, { name: 'document' }],
196
+ { avatar: '/uploads/avatars', document: '/uploads/docs' },
197
+ { avatar: 'image', document: 'document' }
198
+ );
199
+
200
+ // Use with Express
201
+ app.post('/upload', uploader, (req, res) => {
202
+ console.log('Files uploaded:', req.files);
203
+ res.json({ success: true });
204
+ });
205
+ ```
206
+
207
+ ## Advanced Configuration
208
+
209
+ ### HTTPS Server with Multiple Domains
210
+
211
+ ```javascript
212
+ let appServerFactory = new AppServerFactory();
213
+
214
+ appServerFactory.addDomain({
215
+ hostname: 'example.com',
216
+ keyPath: '/ssl/example.com.key',
217
+ certPath: '/ssl/example.com.crt',
218
+ aliases: ['www.example.com']
219
+ });
220
+
221
+ appServerFactory.addDomain({
222
+ hostname: 'api.example.com',
223
+ keyPath: '/ssl/api.example.com.key',
224
+ certPath: '/ssl/api.example.com.crt'
225
+ });
226
+
227
+ let serverResult = appServerFactory.createAppServer({
228
+ useHttps: true,
229
+ useVirtualHosts: true,
230
+ keyPath: '/ssl/default.key',
231
+ certPath: '/ssl/default.crt',
232
+ port: 443,
233
+ enforceProtocol: true,
234
+ developmentMultiplier: 10
235
+ });
236
+ ```
237
+
238
+ ### Development Mode Configuration
239
+
240
+ ```javascript
241
+ let appServerFactory = new AppServerFactory();
242
+
243
+ // Add development domains (automatically detected)
244
+ appServerFactory.addDevelopmentDomain('localhost');
245
+ appServerFactory.addDevelopmentDomain('dev.myapp.local');
246
+
247
+ let serverResult = appServerFactory.createAppServer({
248
+ port: 3000,
249
+ corsOrigin: ['http://localhost:3000', 'http://dev.myapp.local:3000'],
250
+ developmentMultiplier: 5, // More lenient rate limiting in dev
251
+ developmentPorts: [3000, 3001, 8080],
252
+ developmentExternalDomains: {
253
+ 'script-src': ['https://cdn.example.com'],
254
+ 'style-src': ['https://fonts.googleapis.com']
255
+ }
256
+ });
257
+ ```
258
+
259
+ ### Custom Security Configuration
260
+
261
+ ```javascript
262
+ let appServerFactory = new AppServerFactory();
263
+
264
+ let serverResult = appServerFactory.createAppServer({
265
+ useHelmet: true,
266
+ helmetConfig: {
267
+ contentSecurityPolicy: {
268
+ directives: {
269
+ defaultSrc: ["'self'"],
270
+ styleSrc: ["'self'", "'unsafe-inline'"],
271
+ scriptSrc: ["'self'"]
272
+ }
273
+ }
274
+ },
275
+ globalRateLimit: 100, // requests per window
276
+ windowMs: 60000, // 1 minute
277
+ maxRequests: 30,
278
+ trustedProxy: '127.0.0.1',
279
+ useXssProtection: true,
280
+ sanitizeOptions: {allowedTags: [], allowedAttributes: {}}
281
+ });
282
+ ```
283
+
284
+ ### External Domains Configuration
285
+
286
+ When using `developmentExternalDomains` to configure CSP policies, keys can be specified in either kebab-case or camelCase format. The system automatically converts kebab-case keys to the appropriate camelCase format:
287
+
288
+ ```javascript
289
+ let serverResult = appServerFactory.createAppServer({
290
+ developmentExternalDomains: {
291
+ // Both formats work - choose whichever you prefer
292
+ 'scriptSrc': ['https://cdn.example.com'], // camelCase
293
+ 'script-src': ['https://platform-api.example.com'], // kebab-case (auto-converted)
294
+ 'styleSrc': ['https://fonts.googleapis.com'], // camelCase
295
+ 'font-src': ['https://fonts.gstatic.com'] // kebab-case (auto-converted)
296
+ }
297
+ });
298
+ ```
299
+
300
+ The system automatically adds these domains to both the base directive and the corresponding `-elem` variant (e.g., `scriptSrc` and `scriptSrcElem`).
301
+
302
+ ### Helmet CSP Configuration Options
303
+
304
+ The security configurer provides flexible CSP directive handling with merge or override behavior:
305
+
306
+ #### Merging Directives (Default)
307
+
308
+ By default, custom CSP directives are merged with the security defaults, allowing you to add additional sources without redefining all directives:
309
+
310
+ ```javascript
311
+ let serverResult = appServerFactory.createAppServer({
312
+ useHelmet: true,
313
+ helmetConfig: {
314
+ contentSecurityPolicy: {
315
+ directives: {
316
+ // These will be ADDED to the default directives
317
+ scriptSrc: ['https://analytics.example.com'],
318
+ styleSrc: ['https://cdn.example.com']
319
+ }
320
+ }
321
+ }
322
+ });
323
+
324
+ // Result: default directives + your additional sources
325
+ ```
326
+
327
+ #### Overriding Directives
328
+
329
+ Set `overrideDirectives: true` to completely replace the default directives with your custom configuration:
330
+
331
+ ```javascript
332
+ let serverResult = appServerFactory.createAppServer({
333
+ useHelmet: true,
334
+ helmetConfig: {
335
+ contentSecurityPolicy: {
336
+ overrideDirectives: true, // Replace defaults entirely
337
+ directives: {
338
+ defaultSrc: ["'self'"],
339
+ scriptSrc: ["'self'", "https://trusted-cdn.com"],
340
+ styleSrc: ["'self'", "'unsafe-inline'"],
341
+ imgSrc: ["'self'", "data:", "https:"],
342
+ fontSrc: ["'self'"],
343
+ connectSrc: ["'self'"],
344
+ frameAncestors: ["'none'"],
345
+ baseUri: ["'self'"],
346
+ formAction: ["'self'"]
347
+ }
348
+ }
349
+ }
350
+ });
351
+ ```
352
+
353
+ ## API Reference
354
+
355
+ ### AppServerFactory Methods
356
+
357
+ - `createAppServer(config)` - Creates and configures Express server
358
+ - `addDomain(domainConfig)` - Adds domain configuration for virtual hosting
359
+ - `addDevelopmentDomain(domain)` - Adds development domain pattern
360
+ - `setDomainMapping(mapping)` - Sets domain to configuration mapping
361
+ - `enableServeHome(app, callback)` - Enables homepage serving
362
+ - `serveStatics(app, staticPath)` - Serves static files
363
+ - `serveStaticsPath(app, route, staticPath)` - Serves static files on specific route
364
+ - `enableCSP(cspOptions)` - Enables Content Security Policy
365
+ - `listen(port)` - Starts server listening
366
+ - `close()` - Gracefully closes server
367
+
368
+ ### FileHandler Methods
369
+
370
+ - `exists(path)` - Checks if file or folder exists
371
+ - `createFolder(path)` - Creates folder with a recursive option
372
+ - `remove(path)` - Removes file or folder recursively
373
+ - `removeMultiple(filePaths)` - Removes multiple files from an array of paths
374
+ - `copyFile(source, destination)` - Copies file to destination
375
+ - `copyFolderSync(source, destination)` - Copies folder recursively
376
+ - `readFile(path)` - Reads file contents as string
377
+ - `writeFile(path, content)` - Writes content to file
378
+ - `fetchFileJson(path)` - Reads and parses JSON file
379
+ - `fetchFileContents(path)` - Reads file with validation
380
+ - `updateFileContents(path, content)` - Updates existing file
381
+ - `isFile(path)` - Checks if a path is a file
382
+ - `isFolder(path)` - Checks if a path is folder
383
+ - `getFilesInFolder(path, extensions)` - Lists files with optional filtering
384
+ - `validateFileType(path, type, allowedTypes, maxSize)` - Validates file type and size
385
+ - `detectFileType(path)` - Detects MIME type from file signature
386
+ - `generateSecureFilename(originalName)` - Generates cryptographically secure filename
387
+ - `quarantineFile(path, reason)` - Moves file to quarantine folder
388
+ - `createTempFile(prefix, extension)` - Creates a temporary file path
389
+ - `moveFile(from, to)` - Moves file to new location
390
+ - `getFileSize(path)` - Gets file size in bytes
391
+ - `compareFiles(file1, file2)` - Compares file contents
392
+ - `getRelativePath(from, to)` - Calculates relative path
393
+ - `walkDirectory(path, callback)` - Recursively processes directory tree
394
+ - `getDirectorySize(path)` - Calculates total directory size
395
+ - `emptyDirectory(path)` - Removes all contents from directory
396
+
397
+ ### Encryptor Methods
398
+
399
+ - `encryptPassword(password)` - Hashes password with salt
400
+ - `validatePassword(password, hash)` - Validates password against hash
401
+ - `generateSecretKey()` - Generates 256-bit secret key
402
+ - `encryptData(data, key)` - Encrypts data with AES-256-GCM
403
+ - `decryptData(encryptedData, key)` - Decrypts AES-256-GCM data
404
+ - `generateSecureToken(length)` - Generates base64url token
405
+ - `generateTOTP(secret, timeStep)` - Generates time-based OTP
406
+ - `hashData(data, algorithm)` - Hashes data with specified algorithm
407
+ - `generateHMAC(data, secret, algorithm)` - Generates HMAC signature
408
+ - `verifyHMAC(data, secret, signature, algorithm)` - Verifies HMAC signature
409
+ - `constantTimeCompare(a, b)` - Performs constant-time string comparison
410
+
411
+ ### UploaderFactory Methods
412
+
413
+ - `createUploader(fields, buckets, allowedTypes)` - Creates multer upload middleware
414
+ - `validateFilenameSecurity(filename)` - Validates filename for security
415
+ - `validateFile(file, allowedType, callback)` - Validates a file during upload
416
+ - `validateFileContents(file, allowedType)` - Validates file content after upload
417
+ - `convertToRegex(key)` - Converts MIME type patterns to regex
418
+
419
+ ## Security Features
420
+
421
+ ### Path Traversal Protection
422
+ All file operations include comprehensive path validation to prevent directory traversal attacks and access to system files.
423
+
424
+ ### Secure File Upload
425
+ File uploads are validated at multiple levels including filename, MIME type, file extension, file size, and content validation using magic number detection. Failed uploads are automatically cleaned up using efficient file removal.
426
+
427
+ ### Rate Limiting
428
+ Configurable rate limiting with development mode detection for appropriate thresholds in different environments.
429
+
430
+ ### HTTPS Support
431
+ Full SSL/TLS support with SNI for multi-domain hosting and automatic certificate management.
432
+
433
+ ### Input Validation
434
+ Built-in validators for common input types including email, username, strong passwords, alphanumeric strings, and IP addresses.
435
+
436
+ ### Cryptographic Security
437
+ Industry-standard encryption using PBKDF2 for passwords, AES-256-GCM for data encryption, and secure random generation for tokens.
438
+
439
+ ## Error Handling
440
+
441
+ All methods include comprehensive error handling with detailed error objects containing context information. Errors are logged appropriately and never expose sensitive system information.
442
+
443
+ ---
444
+
445
+ ## Documentation
446
+
447
+ [https://www.reldens.com/documentation/utils/](https://www.reldens.com/documentation/utils/)
448
+
449
+ Need something specific?
450
+
451
+ [Request a feature here: https://www.reldens.com/features-request](https://www.reldens.com/features-request)
452
+
453
+ ---
454
+
455
+ ### [Reldens](https://github.com/damian-pastorini/reldens/ "Reldens")
456
+
457
+ ##### [By DwDeveloper](https://www.dwdeveloper.com/ "DwDeveloper")
@@ -16,38 +16,36 @@ class SecurityConfigurer
16
16
  this.useHelmet = true;
17
17
  this.useXssProtection = true;
18
18
  this.helmetConfig = false;
19
+ this.helmetOptions = {};
19
20
  this.sanitizeOptions = {allowedTags: [], allowedAttributes: {}};
20
21
  }
21
22
 
22
23
  setupHelmet(app, config)
23
24
  {
24
- this.isDevelopmentMode = config.isDevelopmentMode || false;
25
25
  this.useHelmet = config.useHelmet !== false;
26
- this.helmetConfig = config.helmetConfig || false;
27
26
  if(!this.useHelmet){
28
27
  return;
29
28
  }
30
- let helmetOptions = this.setModeOptions({
29
+ app.use(helmet(this.mapHelmetOptions(config)));
30
+ }
31
+
32
+ mapHelmetOptions(config)
33
+ {
34
+ this.isDevelopmentMode = config.isDevelopmentMode || false;
35
+ this.helmetConfig = config.helmetConfig || {};
36
+ this.helmetOptions = {
31
37
  crossOriginEmbedderPolicy: false,
32
38
  crossOriginOpenerPolicy: false,
33
39
  crossOriginResourcePolicy: false,
34
40
  originAgentCluster: false
35
- }, config);
36
- if(this.helmetConfig){
37
- Object.assign(helmetOptions, this.helmetConfig);
38
- }
39
- app.use(helmet(helmetOptions));
40
- }
41
-
42
- setModeOptions(helmetOptions, config)
43
- {
41
+ };
44
42
  if(this.isDevelopmentMode){
45
- helmetOptions.contentSecurityPolicy = false;
46
- helmetOptions.hsts = false;
47
- helmetOptions.noSniff = false;
48
- return helmetOptions;
43
+ this.helmetOptions.contentSecurityPolicy = false;
44
+ this.helmetOptions.hsts = false;
45
+ this.helmetOptions.noSniff = false;
46
+ return this.helmetOptions;
49
47
  }
50
- helmetOptions.contentSecurityPolicy = {
48
+ this.helmetOptions.contentSecurityPolicy = {
51
49
  directives: {
52
50
  defaultSrc: ["'self'"],
53
51
  scriptSrc: ["'self'"],
@@ -62,13 +60,50 @@ class SecurityConfigurer
62
60
  formAction: ["'self'"]
63
61
  }
64
62
  };
63
+ if(this.helmetConfig.contentSecurityPolicy){
64
+ if(this.helmetConfig.contentSecurityPolicy.overrideDirectives){
65
+ this.helmetOptions.contentSecurityPolicy.directives = this.helmetConfig.contentSecurityPolicy.directives;
66
+ }
67
+ if(
68
+ !this.helmetConfig.contentSecurityPolicy.overrideDirectives
69
+ && this.helmetConfig.contentSecurityPolicy.directives
70
+ ){
71
+ let configDirectivesKeys = Object.keys(this.helmetConfig.contentSecurityPolicy.directives);
72
+ for(let directiveKey of configDirectivesKeys){
73
+ let directiveValues = this.helmetConfig.contentSecurityPolicy.directives[directiveKey];
74
+ if(!Array.isArray(directiveValues)){
75
+ continue;
76
+ }
77
+ if(!this.helmetOptions.contentSecurityPolicy.directives[directiveKey]){
78
+ this.helmetOptions.contentSecurityPolicy.directives[directiveKey] = [];
79
+ }
80
+ for(let value of directiveValues){
81
+ this.helmetOptions.contentSecurityPolicy.directives[directiveKey].push(value);
82
+ }
83
+ }
84
+ }
85
+ let cspKeys = Object.keys(this.helmetConfig.contentSecurityPolicy);
86
+ for(let cspKey of cspKeys){
87
+ if('directives' === cspKey || 'overrideDirectives' === cspKey){
88
+ continue;
89
+ }
90
+ this.helmetOptions.contentSecurityPolicy[cspKey] = this.helmetConfig.contentSecurityPolicy[cspKey];
91
+ }
92
+ }
93
+ let helmetConfigKeys = Object.keys(this.helmetConfig);
94
+ for(let configKey of helmetConfigKeys){
95
+ if('contentSecurityPolicy' === configKey){
96
+ continue;
97
+ }
98
+ this.helmetOptions[configKey] = this.helmetConfig[configKey];
99
+ }
65
100
  if(config.developmentExternalDomains){
66
101
  this.addExternalDomainsToCsp(
67
- helmetOptions.contentSecurityPolicy.directives,
102
+ this.helmetOptions.contentSecurityPolicy.directives,
68
103
  config.developmentExternalDomains
69
104
  );
70
105
  }
71
- return helmetOptions;
106
+ return this.helmetOptions;
72
107
  }
73
108
 
74
109
  addExternalDomainsToCsp(directives, externalDomains)
@@ -79,11 +114,12 @@ class SecurityConfigurer
79
114
  if(!Array.isArray(domains)){
80
115
  continue;
81
116
  }
117
+ let camelCaseKey = directiveKey.replace(/-([a-z])/g, (match, letter) => letter.toUpperCase());
82
118
  for(let domain of domains){
83
- if(directives[directiveKey]){
84
- directives[directiveKey].push(domain);
119
+ if(directives[camelCaseKey]){
120
+ directives[camelCaseKey].push(domain);
85
121
  }
86
- let elemKey = directiveKey.replace('-src', '-src-elem');
122
+ let elemKey = camelCaseKey+'Elem';
87
123
  if(directives[elemKey]){
88
124
  directives[elemKey].push(domain);
89
125
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@reldens/server-utils",
3
3
  "scope": "@reldens",
4
- "version": "0.35.0",
4
+ "version": "0.37.0",
5
5
  "description": "Reldens - Server Utils",
6
6
  "author": "Damian A. Pastorini",
7
7
  "license": "MIT",