@reldens/server-utils 0.36.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,388 +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
- - 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
- ## API Reference
285
-
286
- ### AppServerFactory Methods
287
-
288
- - `createAppServer(config)` - Creates and configures Express server
289
- - `addDomain(domainConfig)` - Adds domain configuration for virtual hosting
290
- - `addDevelopmentDomain(domain)` - Adds development domain pattern
291
- - `setDomainMapping(mapping)` - Sets domain to configuration mapping
292
- - `enableServeHome(app, callback)` - Enables homepage serving
293
- - `serveStatics(app, staticPath)` - Serves static files
294
- - `serveStaticsPath(app, route, staticPath)` - Serves static files on specific route
295
- - `enableCSP(cspOptions)` - Enables Content Security Policy
296
- - `listen(port)` - Starts server listening
297
- - `close()` - Gracefully closes server
298
-
299
- ### FileHandler Methods
300
-
301
- - `exists(path)` - Checks if file or folder exists
302
- - `createFolder(path)` - Creates folder with a recursive option
303
- - `remove(path)` - Removes file or folder recursively
304
- - `removeMultiple(filePaths)` - Removes multiple files from an array of paths
305
- - `copyFile(source, destination)` - Copies file to destination
306
- - `copyFolderSync(source, destination)` - Copies folder recursively
307
- - `readFile(path)` - Reads file contents as string
308
- - `writeFile(path, content)` - Writes content to file
309
- - `fetchFileJson(path)` - Reads and parses JSON file
310
- - `fetchFileContents(path)` - Reads file with validation
311
- - `updateFileContents(path, content)` - Updates existing file
312
- - `isFile(path)` - Checks if a path is a file
313
- - `isFolder(path)` - Checks if a path is folder
314
- - `getFilesInFolder(path, extensions)` - Lists files with optional filtering
315
- - `validateFileType(path, type, allowedTypes, maxSize)` - Validates file type and size
316
- - `detectFileType(path)` - Detects MIME type from file signature
317
- - `generateSecureFilename(originalName)` - Generates cryptographically secure filename
318
- - `quarantineFile(path, reason)` - Moves file to quarantine folder
319
- - `createTempFile(prefix, extension)` - Creates a temporary file path
320
- - `moveFile(from, to)` - Moves file to new location
321
- - `getFileSize(path)` - Gets file size in bytes
322
- - `compareFiles(file1, file2)` - Compares file contents
323
- - `getRelativePath(from, to)` - Calculates relative path
324
- - `walkDirectory(path, callback)` - Recursively processes directory tree
325
- - `getDirectorySize(path)` - Calculates total directory size
326
- - `emptyDirectory(path)` - Removes all contents from directory
327
-
328
- ### Encryptor Methods
329
-
330
- - `encryptPassword(password)` - Hashes password with salt
331
- - `validatePassword(password, hash)` - Validates password against hash
332
- - `generateSecretKey()` - Generates 256-bit secret key
333
- - `encryptData(data, key)` - Encrypts data with AES-256-GCM
334
- - `decryptData(encryptedData, key)` - Decrypts AES-256-GCM data
335
- - `generateSecureToken(length)` - Generates base64url token
336
- - `generateTOTP(secret, timeStep)` - Generates time-based OTP
337
- - `hashData(data, algorithm)` - Hashes data with specified algorithm
338
- - `generateHMAC(data, secret, algorithm)` - Generates HMAC signature
339
- - `verifyHMAC(data, secret, signature, algorithm)` - Verifies HMAC signature
340
- - `constantTimeCompare(a, b)` - Performs constant-time string comparison
341
-
342
- ### UploaderFactory Methods
343
-
344
- - `createUploader(fields, buckets, allowedTypes)` - Creates multer upload middleware
345
- - `validateFilenameSecurity(filename)` - Validates filename for security
346
- - `validateFile(file, allowedType, callback)` - Validates a file during upload
347
- - `validateFileContents(file, allowedType)` - Validates file content after upload
348
- - `convertToRegex(key)` - Converts MIME type patterns to regex
349
-
350
- ## Security Features
351
-
352
- ### Path Traversal Protection
353
- All file operations include comprehensive path validation to prevent directory traversal attacks and access to system files.
354
-
355
- ### Secure File Upload
356
- 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.
357
-
358
- ### Rate Limiting
359
- Configurable rate limiting with development mode detection for appropriate thresholds in different environments.
360
-
361
- ### HTTPS Support
362
- Full SSL/TLS support with SNI for multi-domain hosting and automatic certificate management.
363
-
364
- ### Input Validation
365
- Built-in validators for common input types including email, username, strong passwords, alphanumeric strings, and IP addresses.
366
-
367
- ### Cryptographic Security
368
- Industry-standard encryption using PBKDF2 for passwords, AES-256-GCM for data encryption, and secure random generation for tokens.
369
-
370
- ## Error Handling
371
-
372
- All methods include comprehensive error handling with detailed error objects containing context information. Errors are logged appropriately and never expose sensitive system information.
373
-
374
- ---
375
-
376
- ## Documentation
377
-
378
- [https://www.reldens.com/documentation/utils/](https://www.reldens.com/documentation/utils/)
379
-
380
- Need something specific?
381
-
382
- [Request a feature here: https://www.reldens.com/features-request](https://www.reldens.com/features-request)
383
-
384
- ---
385
-
386
- ### [Reldens](https://github.com/damian-pastorini/reldens/ "Reldens")
387
-
388
- ##### [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.36.0",
4
+ "version": "0.37.0",
5
5
  "description": "Reldens - Server Utils",
6
6
  "author": "Damian A. Pastorini",
7
7
  "license": "MIT",