key-rotation-manager 1.0.10 → 1.0.11
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 +3 -3
- package/dist/index.cjs +127 -122
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -18
- package/dist/index.d.ts +15 -18
- package/dist/index.js +127 -121
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -521,13 +521,13 @@ const cloned = original.clone({
|
|
|
521
521
|
|
|
522
522
|
## 📖 API Reference
|
|
523
523
|
|
|
524
|
-
### `create(options?,
|
|
524
|
+
### `create(options?, singleton?)`
|
|
525
525
|
|
|
526
526
|
Creates a new KeyManager instance.
|
|
527
527
|
|
|
528
528
|
**Parameters:**
|
|
529
529
|
- `options` (optional): Partial `TModuleOptions`
|
|
530
|
-
- `
|
|
530
|
+
- `singleton` (optional): `boolean` - If `true`, returns a shared singleton instance (default: `false`)
|
|
531
531
|
|
|
532
532
|
**Returns:** `KM` instance
|
|
533
533
|
|
|
@@ -535,7 +535,7 @@ Creates a new KeyManager instance.
|
|
|
535
535
|
```typescript
|
|
536
536
|
const km = create({ versionGenerator: () => 'v1' });
|
|
537
537
|
// or
|
|
538
|
-
const km = create({},
|
|
538
|
+
const km = create({}, true); // Singleton instance
|
|
539
539
|
```
|
|
540
540
|
|
|
541
541
|
### `newKey(options, variables?)`
|
package/dist/index.cjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var EventEmitter = require('events');
|
|
4
3
|
var promises = require('fs/promises');
|
|
5
4
|
var path = require('path');
|
|
6
5
|
var CryptoJS = require('crypto-js');
|
|
6
|
+
var EventEmitter = require('events');
|
|
7
7
|
|
|
8
8
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
9
|
|
|
10
|
-
var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter);
|
|
11
10
|
var CryptoJS__default = /*#__PURE__*/_interopDefault(CryptoJS);
|
|
11
|
+
var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter);
|
|
12
12
|
|
|
13
13
|
// src/constants/default.constant.ts
|
|
14
14
|
var DEFAULT_CRYPTO_OPTIONS = {
|
|
@@ -59,99 +59,6 @@ var EEvent = /* @__PURE__ */ ((EEvent2) => {
|
|
|
59
59
|
return EEvent2;
|
|
60
60
|
})(EEvent || {});
|
|
61
61
|
|
|
62
|
-
// src/types/module.types.ts
|
|
63
|
-
var EError = /* @__PURE__ */ ((EError2) => {
|
|
64
|
-
return EError2;
|
|
65
|
-
})(EError || {});
|
|
66
|
-
|
|
67
|
-
// src/core/base.core.ts
|
|
68
|
-
var Base = class {
|
|
69
|
-
logger;
|
|
70
|
-
bOptions;
|
|
71
|
-
hooks = /* @__PURE__ */ new Map();
|
|
72
|
-
constructor(options) {
|
|
73
|
-
this.bOptions = { ...DEFAULT_BASE_OPTIONS, ...options };
|
|
74
|
-
this.logger = DEFAULT_BASE_LOGGER;
|
|
75
|
-
}
|
|
76
|
-
getLogger() {
|
|
77
|
-
return this.logger;
|
|
78
|
-
}
|
|
79
|
-
setLogger(logger) {
|
|
80
|
-
this.logger = logger;
|
|
81
|
-
return this;
|
|
82
|
-
}
|
|
83
|
-
async sysLog(...args) {
|
|
84
|
-
if (!this.bOptions.quiet) await this.logger(...args);
|
|
85
|
-
return this;
|
|
86
|
-
}
|
|
87
|
-
async customLog(logger, ...args) {
|
|
88
|
-
await logger(...args);
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
|
-
setHooks(hooks) {
|
|
92
|
-
Object.entries(hooks).forEach(([name, handler]) => {
|
|
93
|
-
if (this.hooks.has(name)) {
|
|
94
|
-
this.hooks.get("onHookOverriding")?.call(this, name);
|
|
95
|
-
}
|
|
96
|
-
this.hooks.set(name, handler);
|
|
97
|
-
});
|
|
98
|
-
return this;
|
|
99
|
-
}
|
|
100
|
-
runHook(name, ...args) {
|
|
101
|
-
if (!this.hooks.has(name)) {
|
|
102
|
-
this.hooks.get("onHookNotFound")?.call(this, name);
|
|
103
|
-
return void 0;
|
|
104
|
-
}
|
|
105
|
-
return this.hooks.get(name).call(this, ...args);
|
|
106
|
-
}
|
|
107
|
-
getHooks() {
|
|
108
|
-
return Object.fromEntries(this.hooks.entries());
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
// src/core/events.core.ts
|
|
113
|
-
var Events = class extends Base {
|
|
114
|
-
events;
|
|
115
|
-
eOptions;
|
|
116
|
-
constructor(options) {
|
|
117
|
-
super(options);
|
|
118
|
-
this.eOptions = {
|
|
119
|
-
...DEFAULT_EVENTS_OPTIONS,
|
|
120
|
-
...options
|
|
121
|
-
};
|
|
122
|
-
if (this.eOptions.useEvent) {
|
|
123
|
-
this.events = new EventEmitter__default.default();
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
emit(event, args) {
|
|
127
|
-
if (!this.events) return this;
|
|
128
|
-
this.events.emit(event, args);
|
|
129
|
-
return this;
|
|
130
|
-
}
|
|
131
|
-
on(event, listener) {
|
|
132
|
-
if (!this.events) return this;
|
|
133
|
-
this.events.on(event, listener);
|
|
134
|
-
return this;
|
|
135
|
-
}
|
|
136
|
-
once(event, listener) {
|
|
137
|
-
if (!this.events) return this;
|
|
138
|
-
this.events.once(event, listener);
|
|
139
|
-
return this;
|
|
140
|
-
}
|
|
141
|
-
off(event, listener) {
|
|
142
|
-
if (!this.events) return this;
|
|
143
|
-
this.events.off(event, listener);
|
|
144
|
-
return this;
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
// src/core/config-events.core.ts
|
|
149
|
-
var ConfigEvents = class extends Events {
|
|
150
|
-
constructor(options) {
|
|
151
|
-
super(options);
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
|
|
155
62
|
// src/utils/promise.util.ts
|
|
156
63
|
var executePromisably = (promiseOrFn) => {
|
|
157
64
|
try {
|
|
@@ -161,35 +68,45 @@ var executePromisably = (promiseOrFn) => {
|
|
|
161
68
|
return Promise.reject(error);
|
|
162
69
|
}
|
|
163
70
|
};
|
|
71
|
+
var FileUtilError = class extends Error {
|
|
72
|
+
constructor(message, path, operation, cause) {
|
|
73
|
+
super(message);
|
|
74
|
+
this.path = path;
|
|
75
|
+
this.operation = operation;
|
|
76
|
+
this.cause = cause;
|
|
77
|
+
this.name = "FileUtilError";
|
|
78
|
+
}
|
|
79
|
+
};
|
|
164
80
|
var FileUtil = class {
|
|
165
81
|
async getFolder(path) {
|
|
166
82
|
try {
|
|
83
|
+
await promises.access(path);
|
|
84
|
+
return path;
|
|
85
|
+
} catch {
|
|
167
86
|
try {
|
|
168
|
-
await promises.access(path);
|
|
169
|
-
} catch {
|
|
170
87
|
await promises.mkdir(path, { recursive: true });
|
|
88
|
+
return path;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
throw new FileUtilError(`Failed to create folder: ${path}`, path, "mkdir", error);
|
|
171
91
|
}
|
|
172
|
-
return path;
|
|
173
|
-
} catch {
|
|
174
|
-
throw new Error(`Failed to get folder: ${path}`);
|
|
175
92
|
}
|
|
176
93
|
}
|
|
177
|
-
async read(path, fallback
|
|
94
|
+
async read(path, fallback) {
|
|
178
95
|
try {
|
|
179
96
|
const data = await promises.readFile(path, { encoding: "utf8" });
|
|
180
97
|
return data;
|
|
181
98
|
} catch (error) {
|
|
182
|
-
if (fallback) return fallback;
|
|
183
|
-
throw error;
|
|
99
|
+
if (fallback !== void 0) return fallback;
|
|
100
|
+
throw new FileUtilError(`Failed to read file: ${path}`, path, "read", error);
|
|
184
101
|
}
|
|
185
102
|
}
|
|
186
103
|
async write(path$1, data, flag = "w") {
|
|
104
|
+
const dir = path.dirname(path$1);
|
|
105
|
+
await this.getFolder(dir);
|
|
187
106
|
try {
|
|
188
|
-
const dir = path.dirname(path$1);
|
|
189
|
-
await this.getFolder(dir);
|
|
190
107
|
await promises.writeFile(path$1, data, { encoding: "utf8", flag });
|
|
191
108
|
} catch (error) {
|
|
192
|
-
throw new
|
|
109
|
+
throw new FileUtilError(`Failed to write file: ${path$1}`, path$1, "write", error);
|
|
193
110
|
}
|
|
194
111
|
}
|
|
195
112
|
async checkExists(path) {
|
|
@@ -197,14 +114,14 @@ var FileUtil = class {
|
|
|
197
114
|
await promises.access(path);
|
|
198
115
|
return true;
|
|
199
116
|
} catch {
|
|
200
|
-
|
|
117
|
+
return false;
|
|
201
118
|
}
|
|
202
119
|
}
|
|
203
120
|
async delete(path) {
|
|
204
121
|
try {
|
|
205
122
|
await promises.unlink(path);
|
|
206
|
-
} catch {
|
|
207
|
-
throw new
|
|
123
|
+
} catch (error) {
|
|
124
|
+
throw new FileUtilError(`Failed to delete file: ${path}`, path, "delete", error);
|
|
208
125
|
}
|
|
209
126
|
}
|
|
210
127
|
};
|
|
@@ -476,7 +393,96 @@ var CryptoService = class {
|
|
|
476
393
|
return hashStr === expectedHashStr;
|
|
477
394
|
}
|
|
478
395
|
};
|
|
479
|
-
|
|
396
|
+
|
|
397
|
+
// src/core/base.core.ts
|
|
398
|
+
var Base = class {
|
|
399
|
+
logger;
|
|
400
|
+
bOptions;
|
|
401
|
+
hooks = /* @__PURE__ */ new Map();
|
|
402
|
+
constructor(options) {
|
|
403
|
+
this.bOptions = { ...DEFAULT_BASE_OPTIONS, ...options };
|
|
404
|
+
this.logger = DEFAULT_BASE_LOGGER;
|
|
405
|
+
}
|
|
406
|
+
getLogger() {
|
|
407
|
+
return this.logger;
|
|
408
|
+
}
|
|
409
|
+
setLogger(logger) {
|
|
410
|
+
this.logger = logger;
|
|
411
|
+
return this;
|
|
412
|
+
}
|
|
413
|
+
sysLog(...args) {
|
|
414
|
+
if (!this.bOptions.quiet) {
|
|
415
|
+
const result = this.logger(...args);
|
|
416
|
+
if (result && typeof result === "object" && "catch" in result) {
|
|
417
|
+
result.catch(() => {
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return this;
|
|
422
|
+
}
|
|
423
|
+
async customLog(logger, ...args) {
|
|
424
|
+
await logger(...args);
|
|
425
|
+
return this;
|
|
426
|
+
}
|
|
427
|
+
setHooks(hooks) {
|
|
428
|
+
Object.entries(hooks).forEach(([name, handler]) => {
|
|
429
|
+
if (this.hooks.has(name)) {
|
|
430
|
+
this.hooks.get("onHookOverriding")?.call(this, name);
|
|
431
|
+
}
|
|
432
|
+
this.hooks.set(name, handler);
|
|
433
|
+
});
|
|
434
|
+
return this;
|
|
435
|
+
}
|
|
436
|
+
runHook(name, ...args) {
|
|
437
|
+
if (!this.hooks.has(name)) {
|
|
438
|
+
this.hooks.get("onHookNotFound")?.call(this, name);
|
|
439
|
+
return void 0;
|
|
440
|
+
}
|
|
441
|
+
return this.hooks.get(name).call(this, ...args);
|
|
442
|
+
}
|
|
443
|
+
getHooks() {
|
|
444
|
+
return Object.fromEntries(this.hooks.entries());
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
// src/core/events.core.ts
|
|
449
|
+
var Events = class extends Base {
|
|
450
|
+
events;
|
|
451
|
+
eOptions;
|
|
452
|
+
constructor(options) {
|
|
453
|
+
super(options);
|
|
454
|
+
this.eOptions = {
|
|
455
|
+
...DEFAULT_EVENTS_OPTIONS,
|
|
456
|
+
...options
|
|
457
|
+
};
|
|
458
|
+
if (this.eOptions.useEvent) {
|
|
459
|
+
this.events = new EventEmitter__default.default();
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
emit(event, args) {
|
|
463
|
+
if (!this.events) return this;
|
|
464
|
+
this.events.emit(event, args);
|
|
465
|
+
return this;
|
|
466
|
+
}
|
|
467
|
+
on(event, listener) {
|
|
468
|
+
if (!this.events) return this;
|
|
469
|
+
this.events.on(event, listener);
|
|
470
|
+
return this;
|
|
471
|
+
}
|
|
472
|
+
once(event, listener) {
|
|
473
|
+
if (!this.events) return this;
|
|
474
|
+
this.events.once(event, listener);
|
|
475
|
+
return this;
|
|
476
|
+
}
|
|
477
|
+
off(event, listener) {
|
|
478
|
+
if (!this.events) return this;
|
|
479
|
+
this.events.off(event, listener);
|
|
480
|
+
return this;
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
// src/core/store.core.ts
|
|
485
|
+
var Store = class extends Events {
|
|
480
486
|
sOptions;
|
|
481
487
|
fileUtil;
|
|
482
488
|
storePath;
|
|
@@ -663,21 +669,21 @@ var KeyManager = class extends Store {
|
|
|
663
669
|
* console.log('Key was rotated from version:', expired.version);
|
|
664
670
|
* }
|
|
665
671
|
*
|
|
666
|
-
* // Use expired
|
|
672
|
+
* // Use expired?.key ?? ready?.key safely
|
|
667
673
|
* ```
|
|
668
674
|
*/
|
|
669
675
|
async getKey(options) {
|
|
670
676
|
const { path, version } = options;
|
|
671
677
|
const key = await this.getKeyByStore(path, String(version));
|
|
672
678
|
if (!key) {
|
|
673
|
-
|
|
679
|
+
this.runKeyHook("onKeyNotFound", path, version);
|
|
674
680
|
this.sysLog(`Key not found!`, { path, version });
|
|
675
681
|
return { expired: null, ready: null };
|
|
676
682
|
}
|
|
677
683
|
const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);
|
|
678
684
|
if (!ok && isExpired && isRenewable && key) {
|
|
679
685
|
if (!options.onRotate) {
|
|
680
|
-
|
|
686
|
+
this.runKeyHook("onKeyMissingRotateOption", key, options);
|
|
681
687
|
this.sysLog(`Key missing rotate option!`, { path, version });
|
|
682
688
|
return { expired: null, ready: null };
|
|
683
689
|
}
|
|
@@ -686,17 +692,17 @@ var KeyManager = class extends Store {
|
|
|
686
692
|
...options.onRotate
|
|
687
693
|
});
|
|
688
694
|
const resGetKey = { expired: key, ready: renew.key };
|
|
689
|
-
|
|
695
|
+
this.runKeyHook("onKeyRenewed", resGetKey, options);
|
|
690
696
|
this.sysLog(`Key renewed!`, { path, version });
|
|
691
697
|
return resGetKey;
|
|
692
698
|
}
|
|
693
699
|
if (!ok && isExpired && !isRenewable && key) {
|
|
694
|
-
|
|
700
|
+
this.runKeyHook("onKeyExpired", path, key);
|
|
695
701
|
this.sysLog(`Key expired!`, { path, version });
|
|
696
702
|
return { expired: key, ready: null };
|
|
697
703
|
}
|
|
698
704
|
if (!ok) {
|
|
699
|
-
|
|
705
|
+
this.runKeyHook("onKeyInvalid", key, message, errorOn);
|
|
700
706
|
this.sysLog(`Key invalid!`, { path, version });
|
|
701
707
|
return { expired: null, ready: null };
|
|
702
708
|
}
|
|
@@ -743,7 +749,7 @@ var KeyManager = class extends Store {
|
|
|
743
749
|
const { rotate, duration, type, unit, merge, keyLength } = options;
|
|
744
750
|
const { key, length: kLength } = this.cryptoService.generateKey(keyLength);
|
|
745
751
|
const { salt } = this.cryptoService.generateSalt();
|
|
746
|
-
|
|
752
|
+
this.sysLog(`Key generated
|
|
747
753
|
Options:`, options);
|
|
748
754
|
const hashedKey = this.cryptoService.hash(key, salt);
|
|
749
755
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -758,7 +764,7 @@ Options:`, options);
|
|
|
758
764
|
rotate: !!rotate
|
|
759
765
|
};
|
|
760
766
|
const path = await this.saveKeyToStore(keyGenerated, !!merge, variables);
|
|
761
|
-
|
|
767
|
+
this.sysLog(`Key saved!`, {
|
|
762
768
|
path,
|
|
763
769
|
version: keyGenerated.version,
|
|
764
770
|
type: keyGenerated.type
|
|
@@ -788,7 +794,7 @@ Options:`, options);
|
|
|
788
794
|
hashed: "string",
|
|
789
795
|
rotate: "boolean",
|
|
790
796
|
type: "string",
|
|
791
|
-
version: "
|
|
797
|
+
version: "stringNumber",
|
|
792
798
|
hashedBytes: "number"
|
|
793
799
|
};
|
|
794
800
|
for (const [field, type] of Object.entries(typeChecks)) {
|
|
@@ -883,8 +889,8 @@ var KM = class _KM extends KeyManager {
|
|
|
883
889
|
|
|
884
890
|
// src/index.ts
|
|
885
891
|
var instance = null;
|
|
886
|
-
var create = (options = {},
|
|
887
|
-
if (
|
|
892
|
+
var create = (options = {}, singleton = false) => {
|
|
893
|
+
if (!singleton) return new KM(options);
|
|
888
894
|
if (!instance) {
|
|
889
895
|
instance = new KM(options);
|
|
890
896
|
}
|
|
@@ -892,7 +898,6 @@ var create = (options = {}, only = true) => {
|
|
|
892
898
|
};
|
|
893
899
|
var km = create;
|
|
894
900
|
|
|
895
|
-
exports.EError = EError;
|
|
896
901
|
exports.EEvent = EEvent;
|
|
897
902
|
exports.create = create;
|
|
898
903
|
exports.km = km;
|