fuse-core-express 1.0.2 → 1.0.3

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,588 +1,334 @@
1
- # FuseCore - Express.js Development Toolkit
1
+ # FuseCore Express Encrypted Package
2
2
 
3
- > 🔐 **This package contains encrypted and obfuscated code**
4
- >
5
- > **Version:** 1.0.2
6
- > **Protection:** JavaScript Obfuscation + AES-256-CBC + RSA-2048
7
- > **MIT Compliant:** Private key included in package for open source compliance
3
+ FuseCore Express version - Provides the exact same API as the standard version, but with AES-256-GCM + RSA encryption for code protection.
8
4
 
9
- ## ⚠️ Security Notice
5
+ ## 🚀 Quick Start
10
6
 
11
- This package contains encrypted code that is protected by multiple layers of security. The private key is included in the package to comply with MIT open source license requirements. The code is protected by:
7
+ ### Installation
12
8
 
13
- - **JavaScript Obfuscation** - Code structure completely obfuscated
14
- - **AES-256-CBC Encryption** - All source code encrypted
15
- - **RSA-2048 Key Protection** - AES keys encrypted with RSA
16
- - **Digital Signature** - Code integrity verification
17
-
18
- ## Quick Start
19
-
20
- ```javascript
21
- import FuseCore from 'fuse-core-express';
22
-
23
- // Initialize decryption with included private key (MIT compliant)
24
- FuseCore.initDecryption('./private-1.0.2.pem');
25
-
26
- // Then use normally
27
- await FuseCore.init();
9
+ ```bash
10
+ npm install fuse-core-express
28
11
  ```
29
12
 
30
- ---
31
-
13
+ ### Basic Usage
32
14
 
33
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
15
+ The FuseCore uses a **two-stage initialization** pattern:
34
16
 
35
- **FuseCore** - A comprehensive Express.js toolkit that provides essential web development utilities including caching, logging, monitoring, AJAX handling, and more. Built with MIT open source license.
17
+ ```javascript
18
+ import FuseCore from 'fuse-core-express';
19
+ import path from 'path';
20
+ import { fileURLToPath } from 'url';
36
21
 
37
- ### init options
22
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
38
23
 
39
- ```
24
+ // Stage 1: Initialize decryption
25
+ const privateKeyPath = path.join(__dirname, 'keys/recipient-keys-1.0.3.json');
26
+ await FuseCore.initDecryption(privateKeyPath);
40
27
 
41
- {
42
- common: {
43
- expressApp: null,
44
- listenHostname: '',
45
- listenPort: 3000,
46
- },
47
- cache: {
48
- impl: 'memory', // 'memory' or 'redis'
49
- redis: {
50
- url: 'redis://localhost:6379',
51
- connectTimeout: 10000,
52
- commandTimeout: 5000,
53
- enableTls: false,
54
- clientOptions: {}
55
- }
56
- },
28
+ // Stage 2: Initialize FuseCore (same as standard version)
29
+ await FuseCore.init({
57
30
  log: {
58
- path: '',
59
- level: '',
60
- extraZipStreams: [],
61
- takeOverConsole: false,
62
- extraOutputStreams: {
63
- info: process.stdout,
64
- error: process.stderr,
65
- },
31
+ level: 'info',
32
+ format: 'json'
66
33
  },
67
- ajax: {
68
- timeout: 10000,
69
- slowThreshold: 3000,
70
- defaultHeaders: {
71
- "X-Requested-With": "FuseCore Web component V1.0"
72
- },
73
- agentOptions:{}
74
- },
75
- manifest: {
76
- path: '',
77
- name: '',
34
+ cache: {
35
+ type: 'memory',
36
+ maxSize: '100MB'
78
37
  },
79
-
80
38
  monitor: {
81
- prefix: '',
82
- suffix: '',
83
- mem: true,
84
- cpu: true,
85
- req404: true,
86
- req5xx: true,
87
- },
88
- isPrimaryProcess: cluster.isPrimary || cluster.isMaster
89
- }
39
+ enabled: true,
40
+ interval: 5000
41
+ }
42
+ });
43
+
44
+ // Use FuseCore API normally
45
+ // ... Your business logic ...
90
46
 
47
+ // Shutdown FuseCore
48
+ await FuseCore.shutdown();
91
49
  ```
92
50
 
93
- * common.expressApp (object) optional,Express.app object.
94
- * common.listenHostname (string) optional, hostname or ip http server listens on, used for config server callback.
95
- * common.listenPort (number) optional,port number http server listens on, used for config server callback.
96
- * cache.impl (string) optional, cache implementation, 'memory' or 'redis', default is memory.
97
- * cache.redis.url (string) optional, Redis connection URL, default is 'redis://localhost:6379'.
51
+ ## 📋 Detailed API Documentation
98
52
 
99
- * cache.redis.enableTls (boolean) optional, enable TLS/SSL for Redis connection, default is false.
100
- * cache.redis.clientOptions (object) optional, additional Redis client options.
101
- * log.path (string) optional, directory to save log files.
102
- * log.level (string) optional, minimal level written to log file,default is info.
103
- * log.extraZipStreams (array) optional, streams for access log.
104
- * log.takeOverConsole (bool) optional, default false, indicate log module take over system console, thus all console message will be pipe to log file.
105
- * log.extraOutputStreams (Object) optional, default null, extra log output stream, should be {info:[...Writable],error:[...Writable]}.
106
- * ajax.timeout (number) optional, default timeout in millisecond, default is 10000.
107
- * ajax.slowThreshold (number) optional, default slow log time limit in millisecond, all backend response time greater than limit will be logged to slow log file, default value is 50.
108
- * ajax.defaultHeaders (object) optional, default headers send to backend, default value is {'x-requested-with':'FuseCore Web Server 1.0'}.
109
- * ajax.agentOptions (object) optional, extra agent options will pass to http/https agent, also will applied to globalAgent.
110
- * manifest.path (string) optional, directory contain manifest file.
111
- * manifest.name (string) optional, manifest name to load.
53
+ ### `FuseCore.initDecryption(privateKeyPath)`
112
54
 
113
- * monitor.prefix (string) optional, prefix of all monitor keys.
114
- * monitor.suffix (string) optional, suffix of all monitor keys.
115
- * monitor.mem (bool) optional, auto monitor memory usage, default is false.
116
- * monitor.cpu (bool) optional, auto monitor cpu usage, default is false.
117
- * monitor.req404 (bool) optional, monitor 404 requests, default is false.
118
- * monitor.req5xx (bool) optional, monitor 5xx requests, default is false.
119
- * isPrimaryProcess (bool) optional, indicate current process is primary in cluster mode, monitor module will act differently when run as a worker process.
55
+ Initialize the decryption process, this is the necessary first step for using FuseCore.
120
56
 
57
+ #### Parameters
121
58
 
59
+ - **`privateKeyPath`** (string): Path to the recipient private key file
60
+ - Must be a JSON file containing the `privateKey` field
61
+ - Typically named `recipient-keys-{version}.json`
62
+ - Example path: `./keys/recipient-keys-1.0.3.json`
122
63
 
123
- ## Monitor
64
+ #### Return Value
124
65
 
125
- ### Usage:
66
+ - Returns FuseCore instance (for method chaining)
126
67
 
127
- #### Init:
128
- @deprecated
68
+ #### Examples
129
69
 
130
- var FuseCore = require('fuse-core-express');
131
- //this line must @ top ,before any routes or app filters.
132
- app.use(FuseCore.requestFilter());
70
+ ```javascript
71
+ // Use bundled key files (recommended for development/testing)
72
+ const privateKeyPath = path.join(__dirname, 'keys/recipient-keys-1.0.3.json');
73
+ await FuseCore.initDecryption(privateKeyPath);
133
74
 
134
- .....
75
+ // Use custom path key files
76
+ await FuseCore.initDecryption('/path/to/your/private-key.json');
77
+ ```
135
78
 
79
+ #### Key File Format
136
80
 
137
- var Monitor = FuseCore.monitor;
138
- Monitor.init(configObj);
81
+ The private key file should be in JSON format, containing the following fields:
139
82
 
140
- #### Monitor Config:
83
+ ```json
141
84
  {
142
- app: Express.app object (obj,required)
143
- prefix: monitor default prefix (string,optional)
144
- suffix: monitor default suffix (string,optional)
145
- mem: monitor memory usage (boolean,optional)
146
- cpu: monitor cpu usage (boolean,optional)
147
- mon404: monitor 404 response (boolean,optional)
148
- mon5xx: monitor 5xx response (boolean,optional)
149
- monitorPath: the path for express which remove graph drawer used to get monitor indicators and values
85
+ "privateKey": "-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----\n",
86
+ "publicKey": "-----BEGIN PUBLIC KEY-----\nMIIB...\n-----END PUBLIC KEY-----\n",
87
+ "owner": "recipient",
88
+ "timestamp": "2025-08-01T15:58:34.531Z"
150
89
  }
90
+ ```
151
91
 
92
+ ### `FuseCore.init(options)`
152
93
 
153
- #### Request filter
154
- 1. Used to adept nestia ip rule,when using request.ip property.
155
- 1. add req.realUrl property presents the url send to nginx.
94
+ Initialize FuseCore instance, exactly the same API as the standard version.
156
95
 
96
+ #### Prerequisites
157
97
 
158
- #### Request Utils
159
- Provides function to resolve request headers,such as accept-language or user-agent.
98
+ - ⚠️ **Must call `initDecryption()` first**
160
99
 
161
- ##### getUAInfo
100
+ #### Parameters
162
101
 
163
- param:
102
+ - **`options`** (object): FuseCore configuration options
103
+ - `log`: Logging configuration
104
+ - `cache`: Cache configuration
105
+ - `monitor`: Monitoring configuration
106
+ - etc... (same as standard version)
164
107
 
165
- * req: express request object
108
+ #### Examples
166
109
 
167
- return:
168
- ```
169
- {
170
- isBot: false,
171
- isWinPhone: false,
172
- isIPhone: false,
173
- isIPad: false,
174
- isAndroid: false,
175
- isAndroidTablet: false,
176
- isTablet: false,
177
- isOtherMobile: false,
178
- isMobile: false,
179
- isWechatMiniProg: false,
180
- platform: "windows" | "ios" | "android" | "linux" | "macos" | "whatsapp" | "compatible" | "unknown",
181
- platformVersion: "10.3.1",
182
- browser: "msie" | "opera" | "firefox" | "chrome" | "facebook" | "weixin" | "safari" | "unknown",
183
- browserVersion: "10.3.1"
184
- }
110
+ ```javascript
111
+ await FuseCore.init({
112
+ log: {
113
+ level: 'debug',
114
+ format: 'pretty',
115
+ output: './logs'
116
+ },
117
+ cache: {
118
+ type: 'redis',
119
+ host: 'localhost',
120
+ port: 6379
121
+ },
122
+ monitor: {
123
+ enabled: true,
124
+ interval: 3000,
125
+ metrics: ['cpu', 'memory', 'requests']
126
+ }
127
+ });
185
128
  ```
186
129
 
187
- ##### getLangInfo
188
-
189
- param:
190
-
191
- * req: express request object
192
- * is4PC: true means client is requesting a web page for PC not mobile device.
130
+ ### `FuseCore.shutdown()`
193
131
 
194
- return:
132
+ Shutdown FuseCore instance and clean up resources.
195
133
 
134
+ ```javascript
135
+ await FuseCore.shutdown();
196
136
  ```
197
- {
198
- languages: {
199
- "zh-CN": "0,8",
200
- "en": "0,6"
201
- },
202
- primaryLanguage: ["zh-CN"],
203
- isEnglish: false,
204
- lang: "zh-cn" | "en"
205
- }
206
- ```
207
-
208
137
 
209
- #### Log
138
+ ## 🔐 Key Management
210
139
 
211
- 1. provide an logger by using getLogger
212
- 1. automatically zip logs
213
- 1. automatically removes oldlogs
214
- 1. Requires init
215
- 1. FuseCore.logger's method can be called at any time, but it won't output any data until init finished.
140
+ ### Method 1: Use Bundled Keys (Development/Testing)
216
141
 
217
- init options:
142
+ The package includes ready-to-use key files:
218
143
 
219
- ```
220
- {
221
- dir:path.join(__dirname,'/../logs'),
222
- streams:FileStreamRotator.getStream({...}) | [FileStreamRotator.getStream({...})]
223
- }
144
+ ```javascript
145
+ const privateKeyPath = path.join(__dirname, 'keys/recipient-keys-1.0.3.json');
146
+ await FuseCore.initDecryption(privateKeyPath);
224
147
  ```
225
148
 
226
- Usage Example:
149
+ ### Method 2: Environment Variables (Production Recommended)
227
150
 
151
+ ```bash
152
+ export FUSECORE_RECIPIENT_PRIVATE_KEY="$(cat /secure/path/recipient-private-key.pem)"
153
+ export FUSECORE_SIGNER_PUBLIC_KEY="$(cat /secure/path/signer-public-key.pem)"
228
154
  ```
229
- FuseCore.logger.info('some text',someObject);
230
155
 
156
+ ```javascript
157
+ // When environment variables exist, no parameters need to be passed
158
+ await FuseCore.initDecryption();
231
159
  ```
232
160
 
233
- #### Manifest
234
- ```
235
- let FuseCore=require('fuse-core-express');
236
- let manifest=FuseCore.manifest;
161
+ ### Method 3: Custom Key Files
237
162
 
238
- let value=manifest.get('prop1.prop2.prop3');
239
- ......
163
+ ```javascript
164
+ await FuseCore.initDecryption('/custom/path/to/private-key.json');
240
165
  ```
241
166
 
242
- #### Ajax
243
-
244
- Ajax API
167
+ ## 📁 Package File Structure
245
168
 
246
- ###### Request Options
247
-
248
- demo:
249
169
  ```
250
-
251
- {
252
- server:'lottery',
253
- version:'v5.0'
254
- path:'/toto/broadcast'
255
- data:{
256
- key1:1234,
257
- key2:5678
258
- },
259
- method:'POST',
260
- timeout:800,
261
- reqContentType:'form',
262
- resContentType:'json',
263
- headers:{
264
- SomeUserDefinedHeader:'this will pass to server'
265
- },
266
- isWeb:true,
267
- anonymous:true,
268
- cname:'toto_broadcast',
269
- passClientIP:false,
270
- req:req,
271
- res:res
272
- }
273
-
170
+ node_modules/fuse-core-express/
171
+ ├── index.js # Main entry file
172
+ ├── secure-package.vxz # Encrypted code package
173
+ ├── decryptor.js # Standalone decryptor
174
+ ├── keys/ # Key files directory
175
+ │ ├── build-version.json
176
+ │ ├── recipient-keys-1.0.3.json # Recipient keys (contains private key)
177
+ │ ├── signer-keys-1.0.3.json # Signer public key
178
+ │ └── README.md
179
+ ├── example-usage.js # Usage examples
180
+ └── package.json
274
181
  ```
275
182
 
276
- * server: (string) (required) Server code defined in manifest.
277
- * version: (string) (optional) Version to replace '${version}' part in url.
278
- * path: (string) (required) Api path apart from url defined in manifest.
279
- * data: (object) (optional) Data will send to server.It should be a simple object.
280
- * method: (string) (optional) Http method,default is 'GET'.
281
- * timeout: (number) (optional) Timeout (microseconds) before server complete response,default is defined in config or init option DEFAULT_TIMEOUT.
282
- * reqContentType (deprecated alias dataType): (string) (optional) request data format,only support 'json' and 'form'(default).
283
- * resContentType (deprecated alias contentType): (string) (optional) Content format.If contentType set 'json' or server response with header 'content-type:application/json', response body will be decode automatically.
284
- * headers: (object) (optional) Headers passed to server.Note:if req object is set,most of req.headers' property will passed to backend,no need to redefine headers in this option.
285
- * isWeb: (bool) (optional) If true, and exists cookie named 'N1',then cookie N1's value will replace default Accept-Language value.Default is false.
286
- * anonymous: (bool) (optional) If false, and exists cookie named 'token',then a header named 'Authorization' will be set with value of cookie 'token'.
287
- * noCache: (bool) (optional) If true, headers named 'If-Modified-Since','If-None-Match' will be removed from header ,and 'Cache-Control' will be set 'no-cache'. Default is true.
288
- * passClientIP: (bool) (optional) If true, headers ('X-Forwarded-For','X-Real-IP') will be passed to server. Default is true.
289
- * req: (obj) (optional) (*required by proxy) By default,most of headers in req will pass to backend request.In proxy method,request's body stream will piped to backend request.
290
- * res: (obj) (unnecessary)(*required by proxy) Proxy will handle response,when reject happened.Only if ret.status === 0 ,proxy don't handle response,you should end response, such as res.status(500).end() .
291
-
292
- ###### Response Data (also as reject error)
183
+ ## 🔄 Complete Usage Workflow
293
184
 
294
- ```
185
+ ### 1. CommonJS Environment
295
186
 
296
- {
297
- ok: false,
298
- status: 0,
299
- message: '',
300
- error: null,
301
- data: {},
302
- raw: null,
303
- headers: null,
304
- totalCount: null,
305
- duration: [0, 123000]
187
+ ```javascript
188
+ const FuseCore = require('fuse-core-express');
189
+ const path = require('path');
190
+
191
+ async function initializeFuseCore() {
192
+ try {
193
+ // Decryption initialization
194
+ const privateKeyPath = path.join(__dirname, 'keys/recipient-keys-1.0.3.json');
195
+ await FuseCore.initDecryption(privateKeyPath);
196
+
197
+ // FuseCore initialization
198
+ await FuseCore.init({
199
+ log: { level: 'info' },
200
+ cache: { type: 'memory' }
201
+ });
202
+
203
+ // Use FuseCore...
204
+ console.log('FuseCore initialized successfully');
205
+
206
+ } catch (error) {
207
+ console.error('Failed to initialize FuseCore:', error.message);
208
+ process.exit(1);
209
+ }
306
210
  }
307
211
 
212
+ initializeFuseCore();
308
213
  ```
309
214
 
310
- * ok: (bool) indicates request is successful.
311
- * status: (number) http response code from backend server.
312
- * message: (string) error message when exception or error happened.
313
- * error: (Error) Error object,if exists.
314
- * data: (*) parsed server response content.Object if content-type option set "json",string if content-type set something else.
315
- * raw: (string) original server response text,null when calling proxy method.
316
- * headers: (object) response headers.
317
- * duration (array) \[seconds,nanoseconds\], time used from request start to finish.
318
- * totalCount: (number) same value of response's headers\["X-Total-Count"\],null if header not exists.
319
-
320
-
321
- ##### Ajax.request
322
-
323
- ```
324
- FuseCore.ajax.request({
325
- server: 'property',
326
- version: 'v4.6',
327
- timeout: 3000,
328
- path: path,
329
- method: 'POST',
330
- isWeb:true,
331
- req: req,
332
- performance: false,
333
- proxy: 'http://someuser:password@127.0.0.1:7666',
334
- headers: {
335
- 'origin': 'https://property-staging.nestia.com'
336
- }
337
- }).then((data) => {
338
- res.render('somepage',data.data);
339
- }, (err) => {
340
- req.app.locals.logger.error('error request backend API:' + err.message, err);
341
- if (err.status) {
342
- res.status(err.status).end();
343
- }else{
344
- res.status(500).end();
345
- }
346
- });
347
- ```
348
-
349
- ##### Ajax.proxy
350
-
351
- ```
352
- FuseCore.ajax.proxy({
353
- server: 'property',
354
- path: path,
355
- method: 'POST',
356
- isWeb:true,
357
- req: req,
358
- res: res,
359
- headers: {
360
- 'origin': 'https://property-staging.nestia.com'
361
- }
362
- }).then((data) => {
363
- }, (err) => {
364
- FuseCore.logger.error('error upload property image:' + err.message, err);
365
- if (!err.status) {
366
- res.status(500).end();
367
- }
368
- });
369
- ```
215
+ ### 2. ES Module Environment
370
216
 
371
- ##### Ajax.requestAll
217
+ ```javascript
218
+ import FuseCore from 'fuse-core-express';
219
+ import path from 'path';
220
+ import { fileURLToPath } from 'url';
372
221
 
373
- * This method is a little like Promise.all
374
- * When one of requests fails,you will always get a resolve callback, which is different from Promise.all.
375
- * You can use data\[n\].ok to check whether request fails, and also you can get status, and raw data if exists.
222
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
376
223
 
377
- ```
378
- FuseCore.ajax.request([
379
- {
380
- server: 'property',
381
- version: 'v4.6',
382
- timeout: 3000,
383
- path: '/nearby'
384
- },
385
- {
386
- server: 'news',
387
- version: 'v4.8',
388
- path: '/news'
389
- }
390
- ]).then((datas) => {
391
- let propertyData=datas[0];
392
- let newsData=datas[1];
224
+ async function initializeFuseCore() {
225
+ try {
226
+ // Decryption initialization
227
+ const privateKeyPath = path.join(__dirname, 'keys/recipient-keys-1.0.3.json');
228
+ await FuseCore.initDecryption(privateKeyPath);
393
229
 
394
- //assume property backend never fails.
395
- if(!newsData.ok){
396
- //news api fails
397
- res.render('onlyProperty',propertyData.data);
398
- }else{
399
- res.render('fullContent',{property:propertyData.data,news:newsData.data});
400
- }
401
- });
402
- ```
403
-
404
- #### Cache
405
-
406
- FuseCore supports two cache implementations: memory cache (memory) and Redis cache (redis).
407
-
408
- ##### Memory Cache (Default)
409
-
410
- ```javascript
411
- let FuseCore = require('fuse-core-express');
412
-
413
- // Initialize with memory cache
414
- await FuseCore.init({
415
- cache: {
416
- impl: 'memory'
230
+ // FuseCore initialization
231
+ await FuseCore.init({
232
+ log: { level: 'info' },
233
+ cache: { type: 'memory' }
234
+ });
235
+
236
+ // Use FuseCore...
237
+ console.log('FuseCore initialized successfully');
238
+
239
+ } catch (error) {
240
+ console.error('Failed to initialize FuseCore:', error.message);
241
+ process.exit(1);
417
242
  }
418
- });
243
+ }
419
244
 
420
- let cache = FuseCore.cache;
421
- // Set a cache
422
- // timeout is numeric represents seconds, default value is 300 seconds.
423
- // when timeout is negative number, the cache record will never expire.
424
- await cache.set('propName', 'propValue', 30);
245
+ initializeFuseCore();
246
+ ```
425
247
 
426
- // Get value
427
- let val = await cache.get('propName');
428
- console.log(val); // 'propValue'
248
+ ## ⚠️ Security Considerations
429
249
 
430
- // Memory cache cleanup has 60 seconds deviation
431
- setTimeout(async function(){
432
- let val = await cache.get('propName');
433
- console.log(val); // should be null
434
- }, 30 * 1000 + 60000);
250
+ ### Development Environment
435
251
 
436
- // Setting null value deletes the key
437
- await cache.set('anotherPropName', 'anotherPropValue', 30);
438
- await cache.set('anotherPropName', null, 30); // This deletes the key
252
+ - Can use bundled key files for rapid development
253
+ - Key files are already included in the npm package, ready to use
439
254
 
440
- let val = await cache.get('anotherPropName');
441
- console.log(val); // null
442
- ```
255
+ ### Production Environment
443
256
 
444
- ##### Redis Cache
257
+ - 🔐 **Do not expose private keys on the client side**
258
+ - 🔐 **Use environment variables or key management services**
259
+ - 🔐 **Rotate keys regularly**
260
+ - 🔐 **Monitor key usage**
261
+ - 🔐 **Restrict access permissions to key files**
445
262
 
446
- Use Redis as cache storage, supporting distributed caching and persistence.
447
-
448
- **Configure Redis Cache:**
263
+ ### Recommended Production Configuration
449
264
 
450
265
  ```javascript
451
- let FuseCore = require('fuse-core-express');
452
-
453
- // Initialize with Redis cache
454
- await FuseCore.init({
455
- cache: {
456
- impl: 'redis',
457
- redis: {
458
- url: 'redis://localhost:6379', // Redis connection URL
459
- enableTls: false, // Enable TLS/SSL connection
460
- clientOptions: { // Additional Redis client options
461
- // Optional configuration, such as password, database, etc.
462
- // password: 'your-password',
463
- // database: 0
464
- }
465
- }
466
- }
467
- });
468
-
469
- // Example with TLS enabled
470
- await FuseCore.init({
471
- cache: {
472
- impl: 'redis',
473
- redis: {
474
- url: 'redis://redis-server:6380', // Redis server URL
475
- enableTls: true, // Enable TLS/SSL connection
476
- clientOptions: {
477
- // Additional TLS options if needed
478
- // password: 'your-password',
479
- // database: 0
480
- }
481
- }
266
+ // Production environment recommended to use environment variables
267
+ if (process.env.NODE_ENV === 'production') {
268
+ // Ensure environment variables are set
269
+ if (!process.env.FUSECORE_RECIPIENT_PRIVATE_KEY) {
270
+ throw new Error('FUSECORE_RECIPIENT_PRIVATE_KEY environment variable is required in production');
482
271
  }
483
- });
272
+ await FuseCore.initDecryption(); // Automatically use environment variables
273
+ } else {
274
+ // Development environment use bundled keys
275
+ const privateKeyPath = path.join(__dirname, 'keys/recipient-keys-1.0.3.json');
276
+ await FuseCore.initDecryption(privateKeyPath);
277
+ }
484
278
  ```
485
279
 
486
- **Redis Connection URL Format:**
280
+ ## 🛠️ Troubleshooting
487
281
 
488
- ```
489
- redis://[:password@]host[:port][/database]
490
- redis://localhost:6379 // Local Redis, default port
491
- redis://:mypassword@localhost:6379/1 // With password, using database 1
492
- redis://redis-server:6379 // Remote Redis server
493
- rediss://ssl-redis-server:6380 // SSL encrypted connection
494
- redis://tls-redis-server:6380 // TLS enabled connection (with enableTls: true)
495
- ```
282
+ ### Common Errors
496
283
 
497
- **Basic Usage:**
284
+ #### 1. "FuseCore not decrypted. Call initDecryption(privateKeyPath) first."
498
285
 
499
- ```javascript
500
- let cache = FuseCore.cache;
286
+ **Cause**: Used FuseCore methods without calling `initDecryption()` first
501
287
 
502
- // Set cache (asynchronous operation)
503
- await cache.set('user:123', { name: 'John', age: 30 }, 3600); // Expires in 1 hour
504
- await cache.set('session:abc', 'session-data', 0); // Never expires
288
+ **Solution**: Ensure to call `await FuseCore.initDecryption(privateKeyPath)` first
505
289
 
506
- // Get cache
507
- let user = await cache.get('user:123');
508
- console.log(user); // { name: 'John', age: 30 }
290
+ #### 2. "Private key not found: /path/to/key.json"
509
291
 
510
- // Important: Type preservation (JSON strings are not automatically parsed into objects)
511
- await cache.set('json-string', '{"name":"John"}'); // Store JSON string
512
- let jsonStr = await cache.get('json-string'); // Retrieved is still a string
513
- console.log(typeof jsonStr); // "string"
292
+ **Cause**: Private key file path is incorrect or file doesn't exist
514
293
 
515
- // Delete cache
516
- await cache.set('user:123', null); // Delete key
294
+ **Solution**:
295
+ - Check if the file path is correct
296
+ - Ensure the file exists and is readable
297
+ - Use absolute path or correct relative path
517
298
 
518
- // Check if key exists (Redis-specific method)
519
- let exists = await cache.exists('user:123');
520
- console.log(exists); // false
299
+ #### 3. "Signature verification failed"
521
300
 
522
- // Set expiration time (Redis-specific method)
523
- await cache.set('temp:data', 'some-value');
524
- await cache.expire('temp:data', 600); // Expires in 10 minutes
301
+ **Cause**: Private key doesn't match the encrypted package, or package is corrupted
525
302
 
526
- // Get TTL (Redis-specific method)
527
- let ttl = await cache.ttl('temp:data');
528
- console.log(ttl); // Remaining seconds
303
+ **Solution**:
304
+ - Ensure using the correct version of key files
305
+ - Re-download the package or regenerate keys
529
306
 
530
- // Get matching keys (Redis-specific method)
531
- let keys = await cache.keys('user:*');
532
- console.log(keys); // ['user:123', 'user:456', ...]
307
+ #### 4. "Key files not found in either ./keys/ or ../keys/ directories"
533
308
 
534
- // Clear all cache (Redis-specific method)
535
- await cache.flushAll();
536
- ```
309
+ **Cause**: Cannot find the corresponding signer public key file
537
310
 
538
- **Error Handling:**
311
+ **Solution**: Ensure the `signer-keys-{version}.json` file exists in the keys directory
539
312
 
540
- ```javascript
541
- try {
542
- await cache.set('mykey', 'myvalue');
543
- let value = await cache.get('mykey');
544
- } catch (error) {
545
- console.error('Cache operation failed:', error);
546
- }
547
- ```
548
-
549
- **Close Connection:**
550
-
551
- ```javascript
552
- // FuseCore will automatically close Redis connection when the application shuts down
553
- await FuseCore.shutdown();
554
- ```
313
+ ## 📚 More Examples
555
314
 
556
- ---
315
+ Check the `example-usage.js` file for complete usage examples.
557
316
 
558
- ## 📄 License
559
-
560
- **FuseCore** follows the [MIT License](LICENSE) open source license.
561
-
562
- ### MIT License
563
-
564
- Copyright (c) 2024 Ds.3783
565
-
566
- Permission is hereby granted, free of charge, to any person obtaining a copy
567
- of this software and associated documentation files (the "Software"), to deal
568
- in the Software without restriction, including without limitation the rights
569
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
570
- copies of the Software, and to permit persons to whom the Software is
571
- furnished to do so, subject to the following conditions:
572
-
573
- The above copyright notice and this permission notice shall be included in all
574
- copies or substantial portions of the Software.
575
-
576
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
577
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
578
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
579
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
580
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
581
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
582
- SOFTWARE.
317
+ ## 🔗 Related Links
583
318
 
319
+ - [FuseCore Standard Version Documentation](https://github.com/ds3783/FuseCore)
320
+ - [Key Management Best Practices](./keys/README.md)
584
321
 
322
+ ## 📞 Support
585
323
 
324
+ If you encounter issues during use, please:
586
325
 
326
+ 1. Check the troubleshooting section of this documentation
327
+ 2. Review the `example-usage.js` examples
328
+ 3. Submit an Issue to the project repository
587
329
 
330
+ ---
588
331
 
332
+ **Version**: 1.0.3
333
+ **Last Updated**: 2025-08-02
334
+ **Encryption Algorithm**: AES-256-GCM + RSA-OAEP + RSA-PSS-SHA256