key-rotation-manager 1.0.6 → 1.0.9
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 +104 -20
- package/dist/index.cjs +411 -129
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +181 -102
- package/dist/index.d.ts +181 -102
- package/dist/index.js +409 -121
- package/dist/index.js.map +1 -1
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -7,6 +7,21 @@ This library is designed for backend systems that need safe, extensible, and tra
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## Issues & Bug Reports
|
|
11
|
+
|
|
12
|
+
Found a bug or have a feature request?
|
|
13
|
+
|
|
14
|
+
**[🐛 Report an Issue](https://github.com/DucAnh2611/key-rotation-manager/issues/new)**
|
|
15
|
+
|
|
16
|
+
Please include:
|
|
17
|
+
- A clear description of the issue
|
|
18
|
+
- Steps to reproduce
|
|
19
|
+
- Expected vs actual behavior
|
|
20
|
+
- Your environment (Node.js version, OS, package version)
|
|
21
|
+
- Code samples if applicable
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
10
25
|
## Features
|
|
11
26
|
|
|
12
27
|
- 🔐 Secure key generation (AES-256-GCM by default)
|
|
@@ -43,7 +58,7 @@ const { key, path } = await keyManager.newKey({
|
|
|
43
58
|
```
|
|
44
59
|
|
|
45
60
|
This will:
|
|
46
|
-
- Create a `keys/` directory base on {{path}}/{{filename}}.{{fileExt}}
|
|
61
|
+
- Create a `keys/` directory base on `{{path}}/{{filename}}.{{fileExt}}`
|
|
47
62
|
- Generate a new key
|
|
48
63
|
- Save it using default storage rules
|
|
49
64
|
|
|
@@ -56,9 +71,9 @@ This will:
|
|
|
56
71
|
```typescript
|
|
57
72
|
import { create, km } from 'key-rotation-manager';
|
|
58
73
|
|
|
59
|
-
const keyManager = create(
|
|
74
|
+
const keyManager = create();
|
|
60
75
|
// or
|
|
61
|
-
const keyManager = km(
|
|
76
|
+
const keyManager = km();
|
|
62
77
|
```
|
|
63
78
|
|
|
64
79
|
On initialization:
|
|
@@ -70,15 +85,15 @@ On initialization:
|
|
|
70
85
|
|
|
71
86
|
```typescript
|
|
72
87
|
{
|
|
73
|
-
path: ['keys'],
|
|
74
|
-
file: ['
|
|
88
|
+
path: ['keys', '{{type}}'], // FROM 1.0.8 allow using variable: {{...}}
|
|
89
|
+
file: ['v', '{{version}}'],
|
|
75
90
|
fileSplitor: '_',
|
|
76
91
|
fileExt: 'json',
|
|
77
92
|
gitIgnore: true, // add resolved path to .gitignore
|
|
78
93
|
|
|
79
94
|
crypto: {
|
|
80
95
|
algorithm: 'aes-256-gcm',
|
|
81
|
-
kdf: '
|
|
96
|
+
kdf: 'pbkdf2',
|
|
82
97
|
hashAlgorithm: 'sha256',
|
|
83
98
|
keyLength: 32,
|
|
84
99
|
ivLength: 16,
|
|
@@ -98,7 +113,8 @@ With default settings, keys are stored as:
|
|
|
98
113
|
|
|
99
114
|
```
|
|
100
115
|
keys/
|
|
101
|
-
└──
|
|
116
|
+
└── {{type}}/
|
|
117
|
+
└── v_{{version}}.json
|
|
102
118
|
```
|
|
103
119
|
|
|
104
120
|
---
|
|
@@ -133,10 +149,8 @@ Merge mode stores multiple key versions in a single file.
|
|
|
133
149
|
```typescript
|
|
134
150
|
const { key } = await keyManager.newKey({
|
|
135
151
|
type: 'service',
|
|
136
|
-
duration: 30,
|
|
137
|
-
unit: 'seconds',
|
|
138
|
-
rotate: true,
|
|
139
152
|
merge: true, // Merge into 1 file {{path}}/{filename}
|
|
153
|
+
...options,
|
|
140
154
|
});
|
|
141
155
|
```
|
|
142
156
|
|
|
@@ -148,8 +162,8 @@ const { key } = await keyManager.newKey({
|
|
|
148
162
|
import { create } from 'key-rotation-manager';
|
|
149
163
|
|
|
150
164
|
const keyManager = create({
|
|
151
|
-
path: ['keys', '
|
|
152
|
-
file: '{{
|
|
165
|
+
path: ['keys', '{{type}}'],
|
|
166
|
+
file: ['{{version}}', '{{custom_variables}}'],
|
|
153
167
|
fileExt: 'txt',
|
|
154
168
|
...options,
|
|
155
169
|
});
|
|
@@ -158,10 +172,16 @@ const keyManager = create({
|
|
|
158
172
|
Resulting structure:
|
|
159
173
|
|
|
160
174
|
```
|
|
161
|
-
keys
|
|
175
|
+
path: ['keys', '{{type}}']
|
|
176
|
+
file: ['{{version}}', '{{custom_variables}}']
|
|
177
|
+
fileExt: "txt"
|
|
178
|
+
type: "service"
|
|
179
|
+
variables: { custom_variables: "example" }
|
|
180
|
+
|
|
181
|
+
getKey({ type }, variables) -> keys/service/17000000000_example.txt
|
|
162
182
|
|
|
163
183
|
>> .gitignore
|
|
164
|
-
keys
|
|
184
|
+
keys/*/*_*.txt
|
|
165
185
|
```
|
|
166
186
|
|
|
167
187
|
---
|
|
@@ -186,7 +206,7 @@ The returned value becomes `key.path`.
|
|
|
186
206
|
|
|
187
207
|
```typescript
|
|
188
208
|
const result = await keyManager.getKey({
|
|
189
|
-
path: '
|
|
209
|
+
path: 'path (full path return from km.newKey)',
|
|
190
210
|
version: 'rotate',
|
|
191
211
|
onRotate: {
|
|
192
212
|
duration: 30,
|
|
@@ -194,7 +214,42 @@ const result = await keyManager.getKey({
|
|
|
194
214
|
rotate: true,
|
|
195
215
|
merge: true,
|
|
196
216
|
},
|
|
197
|
-
});
|
|
217
|
+
}, eventHandlers);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
// from 1.0.8 getKey allow user use events
|
|
222
|
+
|
|
223
|
+
type TGetKeyEvents = {
|
|
224
|
+
/**
|
|
225
|
+
* This will fire when key is rotatable but expired and missing options to rotate
|
|
226
|
+
*/
|
|
227
|
+
onMissingRotateOption: (key: TKeyGenerated, options: TGetKeyOptions) => void | Promise<void>;
|
|
228
|
+
/**
|
|
229
|
+
* This will fire when key is invalid includes validate types, from date, to date, etc...
|
|
230
|
+
*/
|
|
231
|
+
onKeyInvalid: (
|
|
232
|
+
key: TKeyGenerated,
|
|
233
|
+
message: string,
|
|
234
|
+
errorOn?: keyof TKeyGenerated
|
|
235
|
+
) => void | Promise<void>;
|
|
236
|
+
/**
|
|
237
|
+
* This will fire when key is renewed
|
|
238
|
+
*/
|
|
239
|
+
onKeyRenewed: (getKey: TGetKey, options: TGetKeyOptions['onRotate']) => void | Promise<void>;
|
|
240
|
+
/**
|
|
241
|
+
* This will fire when key file is not found or version is not found in file
|
|
242
|
+
* @description
|
|
243
|
+
* IMPORTANT: every file invalid should return `{}` as key data and this will caused this event to be fired
|
|
244
|
+
* - Invalid file (file not found or not valid json)
|
|
245
|
+
* - Version not found in file
|
|
246
|
+
* - From date in future
|
|
247
|
+
* - Properties in key data is not valid types
|
|
248
|
+
* - hashedBytes is less than 0
|
|
249
|
+
*/
|
|
250
|
+
onKeyNotFound: (path: string, version: string | number) => void | Promise<void>;
|
|
251
|
+
onExpired: (path: string, key: TKeyGenerated) => void | Promise<void>;
|
|
252
|
+
};
|
|
198
253
|
```
|
|
199
254
|
|
|
200
255
|
Returned structure:
|
|
@@ -207,21 +262,21 @@ Returned structure:
|
|
|
207
262
|
```
|
|
208
263
|
|
|
209
264
|
- `ready` → usable key
|
|
210
|
-
- `expired` → expired key
|
|
265
|
+
- `expired` → expired key
|
|
211
266
|
|
|
212
267
|
### Rotate Key (Invalid – Missing Options)
|
|
213
268
|
|
|
214
269
|
```typescript
|
|
215
270
|
await keyManager.getKey({
|
|
216
|
-
path: '
|
|
271
|
+
path: 'path (full path return from km.newKey)',
|
|
217
272
|
version: 'rotate-invalid',
|
|
218
273
|
});
|
|
219
274
|
```
|
|
220
275
|
|
|
221
|
-
|
|
276
|
+
Return:
|
|
222
277
|
|
|
223
278
|
```
|
|
224
|
-
|
|
279
|
+
{ expired: null, ready: null }
|
|
225
280
|
```
|
|
226
281
|
|
|
227
282
|
### Non-Rotating Key
|
|
@@ -246,6 +301,7 @@ keyManager.useGetKey(async () => {
|
|
|
246
301
|
to: '2099-12-29T01:23:57.882Z',
|
|
247
302
|
key: '...',
|
|
248
303
|
hashed: '...',
|
|
304
|
+
hashedBytes: 16,
|
|
249
305
|
type: 'service',
|
|
250
306
|
version: 'version',
|
|
251
307
|
rotate: true,
|
|
@@ -255,6 +311,28 @@ keyManager.useGetKey(async () => {
|
|
|
255
311
|
|
|
256
312
|
Return `null` to indicate an invalid or missing key.
|
|
257
313
|
|
|
314
|
+
## Custom logger
|
|
315
|
+
|
|
316
|
+
Override how logger work
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
km.setLogger((...args: unknown[]) => console.log(...args))
|
|
320
|
+
// or Async
|
|
321
|
+
km.setLogger(async (...args: unknown[]) => console.log(...args))
|
|
322
|
+
|
|
323
|
+
km.sysLog(...args);
|
|
324
|
+
km.customLog(async (...args: unknown[]) => console.log(...args))
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Clone instance
|
|
328
|
+
|
|
329
|
+
Clone instance to new instance include custom saveKey, getKey and storePath
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
const k = km();
|
|
333
|
+
const k2 = k.clone(options);
|
|
334
|
+
```
|
|
335
|
+
|
|
258
336
|
---
|
|
259
337
|
|
|
260
338
|
## Events
|
|
@@ -286,6 +364,12 @@ keyManager.once(EEvent.STORE_INIT_FOLDER, ({ storePath }) => {
|
|
|
286
364
|
|
|
287
365
|
---
|
|
288
366
|
|
|
367
|
+
## Contributing
|
|
368
|
+
|
|
369
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
289
373
|
## License
|
|
290
374
|
|
|
291
375
|
MIT
|