key-rotation-manager 1.0.11 → 1.1.1

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
@@ -615,7 +615,8 @@ Sets a single hook.
615
615
 
616
616
  See the full changelog for each version:
617
617
 
618
- - **[v1.0.10](./changelogs/1.0.10.md)** - Hooks system, enhanced gitIgnore configuration
618
+ - **[v1.1.1](https://github.com/DucAnh2611/key-rotation-manager/tree/master/changelogs/1.1.1.md)** - Native crypto, zero dependencies, bug fixes
619
+ - **[v1.0.10](https://github.com/DucAnh2611/key-rotation-manager/tree/master/changelogs/1.0.10.md)** - Hooks system, enhanced gitIgnore configuration
619
620
 
620
621
  ---
621
622
 
@@ -648,7 +649,7 @@ Contributions are welcome! Please feel free to submit a Pull Request.
648
649
 
649
650
  ## 📄 License
650
651
 
651
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
652
+ This project is licensed under the MIT License - see the [LICENSE](https://github.com/DucAnh2611/key-rotation-manager/blob/master/LICENSE) file for details.
652
653
 
653
654
  ---
654
655
 
package/dist/index.cjs CHANGED
@@ -2,12 +2,11 @@
2
2
 
3
3
  var promises = require('fs/promises');
4
4
  var path = require('path');
5
- var CryptoJS = require('crypto-js');
5
+ var crypto = require('crypto');
6
6
  var EventEmitter = require('events');
7
7
 
8
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
9
 
10
- var CryptoJS__default = /*#__PURE__*/_interopDefault(CryptoJS);
11
10
  var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter);
12
11
 
13
12
  // src/constants/default.constant.ts
@@ -185,7 +184,7 @@ var isType = (data) => {
185
184
  return {
186
185
  number: typeof data === "number" && !Number.isNaN(Number(data)),
187
186
  string: typeof data === "string",
188
- stringNumber: typeof data === "string" && !Number.isNaN(Number(data)) || typeof data === "number",
187
+ stringNumber: typeof data === "string" || typeof data === "number",
189
188
  boolean: typeof data === "boolean",
190
189
  null: data === null,
191
190
  undefined: data === void 0
@@ -196,97 +195,77 @@ var CryptoService = class {
196
195
  constructor(options = {}) {
197
196
  this.options = { ...DEFAULT_CRYPTO_OPTIONS, ...options };
198
197
  }
199
- generateRandomWordArray(length) {
200
- return CryptoJS__default.default.lib.WordArray.random(length);
201
- }
198
+ /**
199
+ * Generate random bytes and encode them
200
+ */
202
201
  generateRandom(length = 32) {
203
- const wordArray = this.generateRandomWordArray(length);
204
- return this.encode(wordArray);
202
+ const buffer = crypto.randomBytes(length);
203
+ return this.encodeBuffer(buffer);
205
204
  }
206
- /*
205
+ /**
207
206
  * Generate a random key
208
- * @param length Length of the key
207
+ * @param length Length of the key in bytes
209
208
  * @default cryptoOptions.keyLength
210
- * @returns { key: string, length: number }
211
209
  */
212
210
  generateKey(length = this.options.keyLength) {
213
211
  return { key: this.generateRandom(length), length };
214
212
  }
215
- /*
213
+ /**
216
214
  * Generate a random salt
217
- * @param length Length of the salt
215
+ * @param length Length of the salt in bytes
218
216
  * @default cryptoOptions.saltLength
219
- * @returns { salt: string, length: number }
220
217
  */
221
218
  generateSalt(length = this.options.saltLength) {
222
219
  return { salt: this.generateRandom(length), length };
223
220
  }
224
- /*
221
+ /**
225
222
  * Generate a random IV
226
- * @param length Length of the IV
223
+ * @param length Length of the IV in bytes
227
224
  * @default cryptoOptions.ivLength
228
- * @returns { iv: string, length: number }
229
225
  */
230
226
  generateIV(length = this.options.ivLength) {
231
227
  return { iv: this.generateRandom(length), length };
232
228
  }
233
- encode(wordArray) {
229
+ encodeBuffer(buffer) {
234
230
  switch (this.options.encoding) {
235
231
  case "hex":
236
- return wordArray.toString(CryptoJS__default.default.enc.Hex);
232
+ return buffer.toString("hex");
237
233
  case "base64url":
238
- return wordArray.toString(CryptoJS__default.default.enc.Base64).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
234
+ return buffer.toString("base64url");
239
235
  case "base64":
240
236
  default:
241
- return wordArray.toString(CryptoJS__default.default.enc.Base64);
237
+ return buffer.toString("base64");
242
238
  }
243
239
  }
244
- decode(encoded) {
240
+ decodeToBuffer(encoded) {
245
241
  switch (this.options.encoding) {
246
242
  case "hex":
247
- return CryptoJS__default.default.enc.Hex.parse(encoded);
243
+ return Buffer.from(encoded, "hex");
248
244
  case "base64url":
249
- const base64 = encoded.replace(/-/g, "+").replace(/_/g, "/");
250
- const padding = "=".repeat((4 - base64.length % 4) % 4);
251
- return CryptoJS__default.default.enc.Base64.parse(base64 + padding);
245
+ return Buffer.from(encoded, "base64url");
252
246
  case "base64":
253
247
  default:
254
- return CryptoJS__default.default.enc.Base64.parse(encoded);
248
+ return Buffer.from(encoded, "base64");
255
249
  }
256
250
  }
257
251
  deriveKey(password, salt, keyLength) {
258
252
  if (this.options.kdf === "none") {
259
- return CryptoJS__default.default.enc.Hex.parse(password);
253
+ return Buffer.from(password, "hex");
260
254
  }
261
255
  const actualKeyLength = keyLength ?? this.options.keyLength;
262
- const keySize = actualKeyLength / 4;
263
- return CryptoJS__default.default.PBKDF2(password, salt, {
264
- keySize,
265
- iterations: this.options.iterations,
266
- hasher: this.getHasher()
267
- });
268
- }
269
- getHasher() {
270
- switch (this.options.hashAlgorithm) {
271
- case "sha512":
272
- return CryptoJS__default.default.algo.SHA512;
273
- case "sha384":
274
- return CryptoJS__default.default.algo.SHA384;
275
- case "sha256":
276
- default:
277
- return CryptoJS__default.default.algo.SHA256;
278
- }
279
- }
280
- getAESMode() {
281
- return CryptoJS__default.default.mode.CBC;
282
- }
283
- getPadding() {
284
- return CryptoJS__default.default.pad.Pkcs7;
256
+ return crypto.pbkdf2Sync(
257
+ password,
258
+ salt,
259
+ this.options.iterations,
260
+ actualKeyLength,
261
+ this.options.hashAlgorithm
262
+ );
285
263
  }
286
264
  /**
287
- * Encrypt data
265
+ * Encrypt data using AES-CBC
288
266
  * @param plainText Text to encrypt
289
- * @param secret Secret key for encryption Key length, salt, and IV will be randomly generated within configured range
267
+ * @param secret Secret key for encryption
268
+ * @param options Optional lengths for key, salt, and IV
290
269
  */
291
270
  encrypt(plainText, secret, {
292
271
  keyLength,
@@ -296,61 +275,48 @@ var CryptoService = class {
296
275
  keyLength = keyLength ?? this.options.keyLength;
297
276
  saltLength = saltLength ?? this.options.saltLength;
298
277
  ivLength = ivLength ?? this.options.ivLength;
299
- const salt = this.options.kdf !== "none" ? this.generateRandomWordArray(saltLength) : CryptoJS__default.default.lib.WordArray.create();
300
- const iv = this.generateRandomWordArray(ivLength);
278
+ const salt = this.options.kdf !== "none" ? crypto.randomBytes(saltLength) : Buffer.alloc(0);
279
+ const iv = crypto.randomBytes(ivLength);
301
280
  const key = this.deriveKey(secret, salt, keyLength);
302
- const encrypted = CryptoJS__default.default.AES.encrypt(plainText, key, {
303
- iv,
304
- mode: this.getAESMode(),
305
- padding: this.getPadding()
306
- });
307
- const actualSaltLength = salt.sigBytes;
308
- const keyLengthHex = keyLength.toString(16).padStart(4, "0");
309
- const saltLengthHex = actualSaltLength.toString(16).padStart(4, "0");
310
- const ivLengthHex = ivLength.toString(16).padStart(4, "0");
311
- const saltHex = salt.toString(CryptoJS__default.default.enc.Hex);
312
- const ivHex = iv.toString(CryptoJS__default.default.enc.Hex);
313
- const encryptedHex = encrypted.ciphertext.toString(CryptoJS__default.default.enc.Hex);
314
- const combined = keyLengthHex + saltLengthHex + ivLengthHex + saltHex + ivHex + encryptedHex;
315
- return this.encode(CryptoJS__default.default.enc.Hex.parse(combined));
281
+ const cipher = crypto.createCipheriv(this.options.algorithm, key, iv);
282
+ const encrypted = Buffer.concat([cipher.update(plainText, "utf8"), cipher.final()]);
283
+ const keyLengthBuf = Buffer.alloc(2);
284
+ keyLengthBuf.writeUInt16BE(keyLength);
285
+ const saltLengthBuf = Buffer.alloc(2);
286
+ saltLengthBuf.writeUInt16BE(salt.length);
287
+ const ivLengthBuf = Buffer.alloc(2);
288
+ ivLengthBuf.writeUInt16BE(ivLength);
289
+ const combined = Buffer.concat([keyLengthBuf, saltLengthBuf, ivLengthBuf, salt, iv, encrypted]);
290
+ return this.encodeBuffer(combined);
316
291
  }
317
292
  /**
318
293
  * Decrypt data
319
294
  * @param encryptedData Encrypted data to decrypt
320
295
  * @param secret Secret key for decryption
296
+ * @returns Decrypted string, or empty string if decryption fails (wrong password/corrupted data)
321
297
  */
322
298
  decrypt(encryptedData, secret) {
323
- const combined = this.decode(encryptedData);
324
- const combinedHex = combined.toString(CryptoJS__default.default.enc.Hex);
325
- let offset = 0;
326
- const keyLengthHex = combinedHex.substring(offset, offset + 4);
327
- offset += 4;
328
- const saltLengthHex = combinedHex.substring(offset, offset + 4);
329
- offset += 4;
330
- const ivLengthHex = combinedHex.substring(offset, offset + 4);
331
- offset += 4;
332
- const keyLength = parseInt(keyLengthHex, 16);
333
- const saltLength = parseInt(saltLengthHex, 16);
334
- const ivLength = parseInt(ivLengthHex, 16);
335
- const saltHexLength = saltLength * 2;
336
- const ivHexLength = ivLength * 2;
337
- const saltHex = saltHexLength > 0 ? combinedHex.substring(offset, offset + saltHexLength) : "";
338
- offset += saltHexLength;
339
- const ivHex = combinedHex.substring(offset, offset + ivHexLength);
340
- offset += ivHexLength;
341
- const encryptedHex = combinedHex.substring(offset);
342
- const salt = saltHex ? CryptoJS__default.default.enc.Hex.parse(saltHex) : CryptoJS__default.default.lib.WordArray.create();
343
- const iv = CryptoJS__default.default.enc.Hex.parse(ivHex);
344
- const encrypted = CryptoJS__default.default.lib.CipherParams.create({
345
- ciphertext: CryptoJS__default.default.enc.Hex.parse(encryptedHex)
346
- });
347
- const key = this.deriveKey(secret, salt, keyLength);
348
- const decrypted = CryptoJS__default.default.AES.decrypt(encrypted, key, {
349
- iv,
350
- mode: this.getAESMode(),
351
- padding: this.getPadding()
352
- });
353
- return decrypted.toString(CryptoJS__default.default.enc.Utf8);
299
+ try {
300
+ const combined = this.decodeToBuffer(encryptedData);
301
+ let offset = 0;
302
+ const keyLength = combined.readUInt16BE(offset);
303
+ offset += 2;
304
+ const saltLength = combined.readUInt16BE(offset);
305
+ offset += 2;
306
+ const ivLength = combined.readUInt16BE(offset);
307
+ offset += 2;
308
+ const salt = combined.subarray(offset, offset + saltLength);
309
+ offset += saltLength;
310
+ const iv = combined.subarray(offset, offset + ivLength);
311
+ offset += ivLength;
312
+ const encrypted = combined.subarray(offset);
313
+ const key = this.deriveKey(secret, salt, keyLength);
314
+ const decipher = crypto.createDecipheriv(this.options.algorithm, key, iv);
315
+ const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
316
+ return decrypted.toString("utf8");
317
+ } catch {
318
+ return "";
319
+ }
354
320
  }
355
321
  /**
356
322
  * Hash data (one-way)
@@ -359,19 +325,17 @@ var CryptoService = class {
359
325
  * @param salt Optional encoded salt string for deterministic hashing
360
326
  */
361
327
  hash(data, secret, salt) {
362
- const secretWordArray = CryptoJS__default.default.enc.Utf8.parse(secret);
363
- const hasher = this.getHasher();
364
- let saltWordArray;
328
+ let saltBuffer;
365
329
  let saltStr;
366
330
  if (salt) {
367
- saltWordArray = this.decode(salt);
331
+ saltBuffer = this.decodeToBuffer(salt);
368
332
  saltStr = salt;
369
333
  } else {
370
- saltWordArray = this.generateRandomWordArray(this.options.saltLength);
371
- saltStr = this.encode(saltWordArray);
334
+ saltBuffer = crypto.randomBytes(this.options.saltLength);
335
+ saltStr = this.encodeBuffer(saltBuffer);
372
336
  }
373
- const hash = hasher.create().update(data).update(secretWordArray).update(saltWordArray).finalize();
374
- const hashStr = this.encode(hash);
337
+ const hash = crypto.createHash(this.options.hashAlgorithm).update(data).update(secret).update(saltBuffer).digest();
338
+ const hashStr = this.encodeBuffer(hash);
375
339
  return `${saltStr}:${hashStr}`;
376
340
  }
377
341
  /**
@@ -385,11 +349,9 @@ var CryptoService = class {
385
349
  if (!saltStr || !expectedHashStr) {
386
350
  return false;
387
351
  }
388
- const salt = this.decode(saltStr);
389
- const secretWordArray = CryptoJS__default.default.enc.Utf8.parse(secret);
390
- const hasher = this.getHasher();
391
- const hash = hasher.create().update(data).update(secretWordArray).update(salt).finalize();
392
- const hashStr = this.encode(hash);
352
+ const saltBuffer = this.decodeToBuffer(saltStr);
353
+ const hash = crypto.createHash(this.options.hashAlgorithm).update(data).update(secret).update(saltBuffer).digest();
354
+ const hashStr = this.encodeBuffer(hash);
393
355
  return hashStr === expectedHashStr;
394
356
  }
395
357
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants/default.constant.ts","../src/types/events.types.ts","../src/utils/promise.util.ts","../src/utils/file.util.ts","../src/utils/string.util.ts","../src/utils/crypto.util.ts","../src/core/base.core.ts","../src/core/events.core.ts","../src/core/store.core.ts","../src/core/key-manager.core.ts","../src/core/module.core.ts","../src/index.ts"],"names":["EEvent","access","mkdir","readFile","path","dirname","writeFile","unlink","CryptoJS","EventEmitter","join"],"mappings":"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","file":"index.cjs","sourcesContent":["import { TEventsOptions, TModuleOptions, TStoreOptions } from 'src/types';\nimport { TBaseOptions } from 'src/types/base.type';\nimport { TCryptoOptions } from 'src/types/crypto.type';\nimport { TKeyManagerOptions } from 'src/types/key-manager.types';\n\nexport const DEFAULT_CRYPTO_OPTIONS: Required<TCryptoOptions> = {\n algorithm: 'aes-256-cbc',\n kdf: 'pbkdf2',\n hashAlgorithm: 'sha256',\n keyLength: 32,\n ivLength: 16,\n saltLength: 32,\n tagLength: 16,\n iterations: 100000,\n encoding: 'base64',\n};\n\nexport const DEFAULT_BASE_OPTIONS: Required<TBaseOptions> = {\n quiet: false,\n};\n\nexport const DEFAULT_BASE_LOGGER = (...args: any[]) => console.log(...args);\n\nexport const DEFAULT_EVENTS_OPTIONS: Required<TEventsOptions> = {\n ...DEFAULT_BASE_OPTIONS,\n\n // Event\n useEvent: true,\n};\n\nexport const DEFAULT_STORE_OPTIONS: Required<TStoreOptions> = {\n path: ['keys', '{{type}}'],\n file: ['v', '{{version}}'],\n fileSplitor: '_',\n fileExt: 'json',\n gitIgnore: true,\n\n ...DEFAULT_EVENTS_OPTIONS,\n\n // Key manager\n crypto: DEFAULT_CRYPTO_OPTIONS,\n};\n\nexport const DEFAULT_KEY_MANAGER_OPTIONS: Required<TKeyManagerOptions> = {\n // Store\n ...DEFAULT_STORE_OPTIONS,\n\n versionGenerator: () => new Date().getTime(),\n};\n\nexport const DEFAULT_MODULE_OPTIONS: Required<TModuleOptions> = {\n ...DEFAULT_KEY_MANAGER_OPTIONS,\n\n // Module\n quiet: false,\n};\n","import { TBaseOptions } from './base.type';\nimport { TKeyGenerated } from './key-manager.types';\n\nexport enum EEvent {\n STORE_INIT_FOLDER = 'store-init-folder',\n STORE_FILE_SAVED = 'saved-key-file',\n}\n\nexport type TEvents = {\n [EEvent.STORE_INIT_FOLDER]: {\n gitIgnoreStorePath?: string;\n gitIgnorePath?: string;\n gitIgnoreAddStatus?: 'already' | 'added';\n storePath: string;\n };\n [EEvent.STORE_FILE_SAVED]: { path: string; data: Record<string, TKeyGenerated> };\n};\n\nexport type TEventsOptions = Partial<TBaseOptions> & {\n /**\n * Is use event emitter\n * @default true\n */\n useEvent?: boolean;\n};\n","export const executePromisably = <T>(\n promiseOrFn: T | Promise<T> | ((...args: unknown[]) => T | Promise<T>)\n): Promise<T> => {\n try {\n const value =\n typeof promiseOrFn === 'function' && !(promiseOrFn instanceof Promise)\n ? (promiseOrFn as (...args: unknown[]) => T | Promise<T>)()\n : promiseOrFn;\n return Promise.resolve(value);\n } catch (error) {\n return Promise.reject(error);\n }\n};\n\nexport const promiseAll = <T extends readonly unknown[]>(\n ...fns: T\n): Promise<{ [K in keyof T]: Awaited<T[K]> }> => {\n return Promise.all(fns);\n};\n","import { access, mkdir, readFile, unlink, writeFile } from 'fs/promises';\nimport { dirname } from 'path';\n\nexport class FileUtilError extends Error {\n constructor(\n message: string,\n public readonly path: string,\n public readonly operation: 'read' | 'write' | 'delete' | 'access' | 'mkdir',\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = 'FileUtilError';\n }\n}\n\nexport class FileUtil {\n async getFolder(path: string): Promise<string> {\n try {\n await access(path);\n return path;\n } catch {\n try {\n await mkdir(path, { recursive: true });\n return path;\n } catch (error) {\n throw new FileUtilError(`Failed to create folder: ${path}`, path, 'mkdir', error);\n }\n }\n }\n\n async read(path: string, fallback?: string): Promise<string> {\n try {\n const data = await readFile(path, { encoding: 'utf8' });\n return data;\n } catch (error) {\n if (fallback !== undefined) return fallback;\n throw new FileUtilError(`Failed to read file: ${path}`, path, 'read', error);\n }\n }\n\n async write(path: string, data: string, flag: 'w' | 'a' = 'w'): Promise<void> {\n const dir = dirname(path);\n await this.getFolder(dir);\n\n try {\n await writeFile(path, data, { encoding: 'utf8', flag });\n } catch (error) {\n throw new FileUtilError(`Failed to write file: ${path}`, path, 'write', error);\n }\n }\n\n async checkExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n }\n\n async delete(path: string): Promise<void> {\n try {\n await unlink(path);\n } catch (error) {\n throw new FileUtilError(`Failed to delete file: ${path}`, path, 'delete', error);\n }\n }\n}\n","import { TKeyDurationUnit } from 'src/types/key-manager.types';\n\nconst getNested = (obj: Record<string, any>, path: string): any =>\n path.split('.').reduce((curr, key) => curr?.[key], obj);\n\nconst flatten = (obj: Record<string, any>, prefix = ''): Record<string, any> =>\n Object.entries(obj).reduce((acc, [key, val]) => {\n const newKey = prefix ? `${prefix}.${key}` : key;\n return val && typeof val === 'object' && !Array.isArray(val)\n ? { ...acc, ...flatten(val, newKey) }\n : { ...acc, [newKey]: val };\n }, {});\n\nconst stringify = (val: any): string => {\n if (val === null || val === undefined) return '';\n if (typeof val === 'object') return JSON.stringify(val);\n return String(val);\n};\n\nexport const bindString = (format: string, bindValues: Record<string, any>): string => {\n return format\n .replace(/\\{\\{\\.\\.\\.([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n\n return val && typeof val === 'object' && !Array.isArray(val)\n ? JSON.stringify(flatten(val, trimmedPath))\n : match;\n })\n .replace(/\\{\\{([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n\n // Skip if it's a spread syntax (already handled)\n if (trimmedPath.startsWith('...')) {\n return match;\n }\n\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n return stringify(val);\n });\n};\nexport const isDate = (data: string): boolean => {\n try {\n const date = new Date(data);\n return !isNaN(date.getTime());\n } catch (error) {\n return false;\n }\n};\n\nexport const addDuration = (date: Date, duration: number, unit: TKeyDurationUnit): Date => {\n const result = new Date(date.getTime());\n\n switch (unit) {\n case 'seconds':\n result.setSeconds(result.getSeconds() + duration);\n break;\n\n case 'minutes':\n result.setMinutes(result.getMinutes() + duration);\n break;\n\n case 'hours':\n result.setHours(result.getHours() + duration);\n break;\n\n case 'days':\n result.setDate(result.getDate() + duration);\n break;\n\n default: {\n const _exhaustiveCheck: never = unit;\n throw new Error(`Unsupported duration unit: ${_exhaustiveCheck}`);\n }\n }\n\n return result;\n};\n\nexport const isType = (data?: unknown) => {\n return {\n number: typeof data === 'number' && !Number.isNaN(Number(data)),\n string: typeof data === 'string',\n stringNumber:\n (typeof data === 'string' && !Number.isNaN(Number(data))) || typeof data === 'number',\n boolean: typeof data === 'boolean',\n null: data === null,\n undefined: data === undefined,\n };\n};\n","import CryptoJS from 'crypto-js';\nimport { DEFAULT_CRYPTO_OPTIONS } from 'src/constants/default.constant';\nimport { TCryptoOptions } from 'src/types/crypto.type';\n\nexport class CryptoService {\n private options: TCryptoOptions;\n\n constructor(options: Partial<TCryptoOptions> = {}) {\n this.options = { ...DEFAULT_CRYPTO_OPTIONS, ...options };\n }\n\n private generateRandomWordArray(length: number): CryptoJS.lib.WordArray {\n return CryptoJS.lib.WordArray.random(length);\n }\n\n generateRandom(length: number = 32): string {\n const wordArray = this.generateRandomWordArray(length);\n return this.encode(wordArray);\n }\n\n /*\n * Generate a random key\n * @param length Length of the key\n * @default cryptoOptions.keyLength\n * @returns { key: string, length: number }\n */\n generateKey(length: number = this.options.keyLength) {\n return { key: this.generateRandom(length), length } as const;\n }\n\n /*\n * Generate a random salt\n * @param length Length of the salt\n * @default cryptoOptions.saltLength\n * @returns { salt: string, length: number }\n */\n generateSalt(length: number = this.options.saltLength) {\n return { salt: this.generateRandom(length), length } as const;\n }\n\n /*\n * Generate a random IV\n * @param length Length of the IV\n * @default cryptoOptions.ivLength\n * @returns { iv: string, length: number }\n */\n generateIV(length: number = this.options.ivLength) {\n return { iv: this.generateRandom(length), length } as const;\n }\n\n private encode(wordArray: CryptoJS.lib.WordArray): string {\n switch (this.options.encoding) {\n case 'hex':\n return wordArray.toString(CryptoJS.enc.Hex);\n case 'base64url':\n return wordArray\n .toString(CryptoJS.enc.Base64)\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n case 'base64':\n default:\n return wordArray.toString(CryptoJS.enc.Base64);\n }\n }\n\n private decode(encoded: string): CryptoJS.lib.WordArray {\n switch (this.options.encoding) {\n case 'hex':\n return CryptoJS.enc.Hex.parse(encoded);\n case 'base64url':\n // Convert base64url to base64\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padding = '='.repeat((4 - (base64.length % 4)) % 4);\n return CryptoJS.enc.Base64.parse(base64 + padding);\n case 'base64':\n default:\n return CryptoJS.enc.Base64.parse(encoded);\n }\n }\n\n private deriveKey(\n password: string,\n salt: CryptoJS.lib.WordArray,\n keyLength?: number\n ): CryptoJS.lib.WordArray {\n if (this.options.kdf === 'none') {\n return CryptoJS.enc.Hex.parse(password);\n }\n\n const actualKeyLength = keyLength ?? this.options.keyLength;\n const keySize = actualKeyLength / 4;\n return CryptoJS.PBKDF2(password, salt, {\n keySize,\n iterations: this.options.iterations,\n hasher: this.getHasher(),\n });\n }\n\n private getHasher(): typeof CryptoJS.algo.SHA256 {\n switch (this.options.hashAlgorithm) {\n case 'sha512':\n return CryptoJS.algo.SHA512;\n case 'sha384':\n return CryptoJS.algo.SHA384;\n case 'sha256':\n default:\n return CryptoJS.algo.SHA256;\n }\n }\n\n private getAESMode(): typeof CryptoJS.mode.CBC {\n return CryptoJS.mode.CBC;\n }\n\n private getPadding(): typeof CryptoJS.pad.Pkcs7 {\n return CryptoJS.pad.Pkcs7;\n }\n\n /**\n * Encrypt data\n * @param plainText Text to encrypt\n * @param secret Secret key for encryption Key length, salt, and IV will be randomly generated within configured range\n */\n encrypt(\n plainText: string,\n secret: string,\n {\n keyLength,\n saltLength,\n ivLength,\n }: { keyLength?: number; saltLength?: number; ivLength?: number } = {}\n ): string {\n keyLength = keyLength ?? this.options.keyLength;\n saltLength = saltLength ?? this.options.saltLength;\n ivLength = ivLength ?? this.options.ivLength;\n\n const salt =\n this.options.kdf !== 'none'\n ? this.generateRandomWordArray(saltLength)\n : CryptoJS.lib.WordArray.create();\n const iv = this.generateRandomWordArray(ivLength);\n const key = this.deriveKey(secret, salt, keyLength);\n\n const encrypted = CryptoJS.AES.encrypt(plainText, key, {\n iv,\n mode: this.getAESMode(),\n padding: this.getPadding(),\n });\n\n const actualSaltLength = salt.sigBytes;\n const keyLengthHex = keyLength.toString(16).padStart(4, '0');\n const saltLengthHex = actualSaltLength.toString(16).padStart(4, '0');\n const ivLengthHex = ivLength.toString(16).padStart(4, '0');\n const saltHex = salt.toString(CryptoJS.enc.Hex);\n const ivHex = iv.toString(CryptoJS.enc.Hex);\n const encryptedHex = encrypted.ciphertext.toString(CryptoJS.enc.Hex);\n\n const combined = keyLengthHex + saltLengthHex + ivLengthHex + saltHex + ivHex + encryptedHex;\n return this.encode(CryptoJS.enc.Hex.parse(combined));\n }\n\n /**\n * Decrypt data\n * @param encryptedData Encrypted data to decrypt\n * @param secret Secret key for decryption\n */\n decrypt(encryptedData: string, secret: string): string {\n const combined = this.decode(encryptedData);\n const combinedHex = combined.toString(CryptoJS.enc.Hex);\n\n let offset = 0;\n\n // Read key, salt and IV lengths (4 hex chars = 2 bytes each)\n const keyLengthHex = combinedHex.substring(offset, offset + 4);\n offset += 4;\n const saltLengthHex = combinedHex.substring(offset, offset + 4);\n offset += 4;\n const ivLengthHex = combinedHex.substring(offset, offset + 4);\n offset += 4;\n\n const keyLength = parseInt(keyLengthHex, 16);\n const saltLength = parseInt(saltLengthHex, 16);\n const ivLength = parseInt(ivLengthHex, 16);\n\n // Read salt and IV based on their lengths stored in the encrypted data\n const saltHexLength = saltLength * 2; // hex is 2 chars per byte\n const ivHexLength = ivLength * 2;\n\n const saltHex = saltHexLength > 0 ? combinedHex.substring(offset, offset + saltHexLength) : '';\n offset += saltHexLength;\n\n const ivHex = combinedHex.substring(offset, offset + ivHexLength);\n offset += ivHexLength;\n\n const encryptedHex = combinedHex.substring(offset);\n\n const salt = saltHex ? CryptoJS.enc.Hex.parse(saltHex) : CryptoJS.lib.WordArray.create();\n const iv = CryptoJS.enc.Hex.parse(ivHex);\n const encrypted = CryptoJS.lib.CipherParams.create({\n ciphertext: CryptoJS.enc.Hex.parse(encryptedHex),\n });\n\n const key = this.deriveKey(secret, salt, keyLength);\n\n const decrypted = CryptoJS.AES.decrypt(encrypted, key, {\n iv,\n mode: this.getAESMode(),\n padding: this.getPadding(),\n });\n\n return decrypted.toString(CryptoJS.enc.Utf8);\n }\n\n /**\n * Hash data (one-way)\n * @param data Data to hash\n * @param secret Secret key used in hashing\n * @param salt Optional encoded salt string for deterministic hashing\n */\n hash(data: string, secret: string, salt?: string): string {\n const secretWordArray = CryptoJS.enc.Utf8.parse(secret);\n const hasher = this.getHasher();\n\n let saltWordArray: CryptoJS.lib.WordArray;\n let saltStr: string;\n\n if (salt) {\n // Deterministic mode: use provided salt\n saltWordArray = this.decode(salt);\n saltStr = salt;\n } else {\n // Non-deterministic mode: generate random salt\n saltWordArray = this.generateRandomWordArray(this.options.saltLength);\n saltStr = this.encode(saltWordArray);\n }\n\n const hash = hasher\n .create()\n .update(data)\n .update(secretWordArray)\n .update(saltWordArray)\n .finalize();\n\n const hashStr = this.encode(hash);\n\n return `${saltStr}:${hashStr}`;\n }\n\n /**\n * Verify hashed data\n * @param data Data to verify\n * @param hashedData Previously hashed data (format: salt:hash)\n * @param secret Secret key used during hashing\n */\n verifyHash(data: string, hashedData: string, secret: string): boolean {\n const [saltStr, expectedHashStr] = hashedData.split(':');\n if (!saltStr || !expectedHashStr) {\n return false;\n }\n\n const salt = this.decode(saltStr);\n const secretWordArray = CryptoJS.enc.Utf8.parse(secret);\n const hasher = this.getHasher();\n\n const hash = hasher.create().update(data).update(secretWordArray).update(salt).finalize();\n\n const hashStr = this.encode(hash);\n\n return hashStr === expectedHashStr;\n }\n}\n","import { DEFAULT_BASE_LOGGER, DEFAULT_BASE_OPTIONS } from 'src/constants/default.constant';\nimport { TBaseLogger, TBaseOptions, THook } from 'src/types/base.type';\n\ntype DefaultLogger = typeof DEFAULT_BASE_LOGGER;\n\nexport class Base<TLogger extends (...args: any[]) => any = DefaultLogger> {\n private logger: TBaseLogger<TLogger>;\n private bOptions: Required<TBaseOptions>;\n private hooks: Map<string, THook> = new Map();\n\n constructor(options: Partial<TBaseOptions>) {\n this.bOptions = { ...DEFAULT_BASE_OPTIONS, ...options };\n this.logger = DEFAULT_BASE_LOGGER as TBaseLogger<TLogger>;\n }\n\n protected getLogger(): TBaseLogger<TLogger> {\n return this.logger;\n }\n\n public setLogger(logger: TBaseLogger<TLogger>): this {\n this.logger = logger;\n return this;\n }\n\n public sysLog(...args: Parameters<TLogger>): this {\n if (!this.bOptions.quiet) {\n const result = this.logger(...args);\n if (result && typeof result === 'object' && 'catch' in result) {\n (result as Promise<unknown>).catch(() => {});\n }\n }\n return this;\n }\n\n public async customLog<T extends (...args: any[]) => any>(\n logger: TBaseLogger<T>,\n ...args: Parameters<T>\n ) {\n await logger(...args);\n return this;\n }\n\n protected setHooks<T extends Record<string, THook> = {}>(hooks: T) {\n Object.entries(hooks).forEach(([name, handler]) => {\n if (this.hooks.has(name)) {\n this.hooks.get('onHookOverriding')?.call(this, name);\n }\n\n this.hooks.set(name, handler);\n });\n return this;\n }\n\n protected runHook<Hooks extends Record<string, THook>, K extends keyof Hooks>(\n name: K,\n ...args: Parameters<Hooks[K]>\n ): ReturnType<Hooks[K]> {\n if (!this.hooks.has(name as string)) {\n this.hooks.get('onHookNotFound')?.call(this, name as string);\n return undefined as any;\n }\n\n return this.hooks.get(name as string)!.call(this, ...args);\n }\n\n protected getHooks(): Record<string, THook> {\n return Object.fromEntries(this.hooks.entries()) as Record<string, THook>;\n }\n}\n","import EventEmitter from 'node:events';\nimport { Base } from './base.core';\nimport { TEvents, TEventsOptions } from 'src/types';\nimport { DEFAULT_EVENTS_OPTIONS } from 'src/constants/default.constant';\n\nexport class Events extends Base {\n private events?: EventEmitter;\n private eOptions: Required<TEventsOptions>;\n\n constructor(options: TEventsOptions) {\n super(options);\n\n this.eOptions = {\n ...DEFAULT_EVENTS_OPTIONS,\n ...options,\n };\n\n if (this.eOptions.useEvent) {\n this.events = new EventEmitter();\n }\n }\n\n protected emit<K extends keyof TEvents>(event: K, args: TEvents[K]) {\n if (!this.events) return this;\n\n this.events.emit(event, args);\n return this;\n }\n\n on<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.on(event, listener);\n return this;\n }\n\n once<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.once(event, listener);\n return this;\n }\n\n off<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.off(event, listener);\n return this;\n }\n}\n","import { EEvent, TEvents, TFormatUsable, TGetKeyFn, TSaveKeyFn, TStoreOptions } from 'src/types';\nimport { FileUtil } from 'src/utils';\nimport { DEFAULT_STORE_OPTIONS } from 'src/constants/default.constant';\nimport { join } from 'path';\nimport { TKeyGenerated } from 'src/types/key-manager.types';\nimport { Events } from './events.core';\n\nexport class Store extends Events {\n private sOptions: Required<Omit<TStoreOptions, 'useEvent' | 'crypto'>>;\n private fileUtil: FileUtil;\n protected storePath?: string;\n protected saveKeyFn?: TSaveKeyFn;\n protected getKeyFn?: TGetKeyFn;\n\n constructor(options: Partial<TStoreOptions>) {\n super(options);\n\n this.sOptions = { ...DEFAULT_STORE_OPTIONS, ...options };\n this.fileUtil = new FileUtil();\n\n this.initStore();\n }\n\n protected getPath(path: string | string[], splitor: string): string {\n if (typeof path === 'object' && Array.isArray(path)) {\n return path.join(splitor);\n }\n\n return path;\n }\n\n private async getKeyStoreFolder(): Promise<string> {\n if (this.storePath) return this.storePath;\n\n const { path } = this.sOptions;\n\n const first =\n typeof path === 'object' && Array.isArray(path)\n ? path[0]\n : typeof path === 'string'\n ? (path.split('/')[0] ?? '')\n : '';\n\n let folder = await this.fileUtil.getFolder(join(process.cwd(), first));\n\n return folder;\n }\n\n protected async getKeyFileData(filePath: string): Promise<Record<string, TKeyGenerated>> {\n const existingData = await this.fileUtil.read(filePath, '{}');\n const savedData = this.toSavedData(existingData);\n\n return savedData;\n }\n\n protected async saveKeyFile(\n path: string,\n data: TKeyGenerated,\n merge: boolean = false\n ): Promise<string> {\n let savedData = await this.getKeyFileData(path);\n\n let saveData: Record<string, TKeyGenerated> = {};\n\n if (merge) {\n saveData = { ...savedData };\n }\n\n saveData = { ...saveData, [data.version]: data };\n\n await this.fileUtil.write(path, JSON.stringify(saveData, null, 2));\n\n this.emit(EEvent.STORE_FILE_SAVED, { path, data: saveData });\n\n return path;\n }\n\n /**\n * @param storePath custom store path\n * root folder of store\n * @returns this\n */\n public useStorePath(storePath: string): this {\n this.storePath = storePath;\n return this;\n }\n\n /**\n * @param saveKeyFn custom save key function\n * @returns this\n */\n public useSaveKey(saveKeyFn: TSaveKeyFn): this {\n this.saveKeyFn = saveKeyFn;\n return this;\n }\n\n /**\n * @param saveKeyFn custom get key function\n * @returns this\n */\n public useGetKey(getKeyFn: TGetKeyFn): this {\n this.getKeyFn = getKeyFn;\n return this;\n }\n\n private async initStore(): Promise<void> {\n const storePath = await this.getKeyStoreFolder();\n\n let eventEmitPayload: TEvents[EEvent.STORE_INIT_FOLDER] = {\n storePath,\n };\n\n if (this.sOptions.gitIgnore) {\n const gitignore = await this.addStoreFolderGitignore();\n eventEmitPayload = { ...eventEmitPayload, ...gitignore };\n }\n\n this.emit(EEvent.STORE_INIT_FOLDER, eventEmitPayload);\n }\n\n private toSavedData(dataString: string): Record<string, TKeyGenerated> {\n try {\n if (!dataString) return {};\n const parsedData = JSON.parse(dataString) as Record<string, TKeyGenerated>;\n\n if (typeof parsedData !== 'object' || Array.isArray(parsedData)) {\n throw new Error('Invalid JSON data (must be Record<version, TKeyGenerated>)');\n }\n\n return parsedData;\n } catch (error) {\n throw new Error(`Invalid JSON data (must be Record<version, TKeyGenerated>) ${dataString}`);\n }\n }\n\n private async addStoreFolderGitignore(): Promise<\n Omit<TEvents[EEvent.STORE_INIT_FOLDER], 'storePath'>\n > {\n const gitignorePath = join(process.cwd(), '.gitignore');\n const gitignoreContent = await this.fileUtil.read(gitignorePath);\n\n const folder = this.getStoreFolderGitignore();\n const gitignoreLines = gitignoreContent.split(/\\r?\\n/).map((line) => line.trim());\n const hasExactLine = gitignoreLines.some((line) => line === folder);\n\n if (!hasExactLine) {\n await this.fileUtil.write(gitignorePath, `${gitignoreContent ? '\\r\\n' : ''}${folder}`, 'a');\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'added',\n };\n }\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'already',\n };\n }\n\n private getStoreFolderGitignore() {\n let folder = '';\n const storePath = this.getPath(this.sOptions.path, '/');\n\n if (typeof this.sOptions.gitIgnore === 'boolean') {\n folder = this.getStoreFolderGitignoreByDefault(storePath);\n } else {\n folder = this.addStoreFolderGitignoreByCustom(this.sOptions.gitIgnore);\n }\n\n return this.replaceVariableToStar(folder);\n }\n\n private getStoreFolderGitignoreByDefault(storePath: string) {\n const filePath = this.getPath(this.sOptions.file, this.sOptions.fileSplitor);\n\n const folder: string[] = [storePath];\n folder.push(`${filePath}.${this.sOptions.fileExt}`);\n\n return folder.join('/');\n }\n\n private addStoreFolderGitignoreByCustom(ignorePath: TFormatUsable) {\n return this.getPath(ignorePath, '/');\n }\n\n private replaceVariableToStar(path: string): string {\n return path.replace(/\\{\\{.*?\\}\\}/g, '*');\n }\n}\n","import {\n TGenerateKeyOptions,\n TGetKey,\n TGetKeyOptions,\n TKeyGenerated,\n TKeyManagerHooks,\n TKeyManagerOptions,\n TKeyVariables,\n} from 'src/types/key-manager.types';\nimport { Store } from './store.core';\nimport {\n CryptoService,\n executePromisably,\n addDuration,\n bindString,\n isDate,\n isType,\n} from 'src/utils';\nimport { DEFAULT_KEY_MANAGER_OPTIONS } from 'src/constants/default.constant';\n\nexport class KeyManager extends Store {\n private cryptoService: CryptoService;\n private kOptions: Required<TKeyManagerOptions>;\n\n constructor(options: Partial<TKeyManagerOptions>) {\n super(options);\n\n this.kOptions = { ...DEFAULT_KEY_MANAGER_OPTIONS, ...options };\n this.cryptoService = new CryptoService(this.kOptions.crypto);\n }\n\n /**\n * Retrieve and validate a stored key by path and version.\n *\n * This method:\n * - Loads a key from the configured store\n * - Validates structure, type safety, and time constraints\n * - Detects expiration and rotation eligibility\n * - Optionally auto-rotates an expired key if rotation options are provided\n *\n * If the key is expired and marked as rotatable, a new key will be generated\n * automatically using the provided `onRotate` options.\n *\n * @param options Configuration for key retrieval\n * @param options.path Storage path of the key\n * @param options.version Specific key version to retrieve\n * @param options.onRotate Optional rotation configuration used when the key\n * is expired and renewable\n *\n * @returns An object containing:\n * - `ready`: The valid (usable) key, or the newly generated key after rotation\n * - `expired`: The expired key if rotation occurred, otherwise `null`\n *\n * @throws Error if:\n * - The key does not exist\n * - The key structure or fields are invalid\n * - The key is expired but rotation options are missing\n * - The key is not yet valid or otherwise unusable\n *\n * @example\n * ```ts\n * const { ready, expired } = await keyManager.getKey({\n * path: '/keys/api',\n * version: 'v1',\n * // This define the new key attributes: is it rotate? Durations and unit?\n * onRotate: {\n * duration: 30,\n * unit: 'days',\n * rotate: true,\n * },\n * });\n *\n * if (expired) {\n * console.log('Key was rotated from version:', expired.version);\n * }\n *\n * // Use expired?.key ?? ready?.key safely\n * ```\n */\n public async getKey(options: TGetKeyOptions): Promise<TGetKey> {\n const { path, version } = options;\n\n const key = await this.getKeyByStore(path, String(version));\n\n if (!key) {\n this.runKeyHook('onKeyNotFound', path, version);\n this.sysLog(`Key not found!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);\n\n if (!ok && isExpired && isRenewable && key) {\n if (!options.onRotate) {\n this.runKeyHook('onKeyMissingRotateOption', key, options);\n this.sysLog(`Key missing rotate option!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const renew = await this.newKey({\n type: key.type,\n ...options.onRotate,\n });\n\n const resGetKey = { expired: key, ready: renew.key };\n\n this.runKeyHook('onKeyRenewed', resGetKey, options);\n this.sysLog(`Key renewed!`, { path, version });\n return resGetKey;\n }\n\n if (!ok && isExpired && !isRenewable && key) {\n this.runKeyHook('onKeyExpired', path, key);\n this.sysLog(`Key expired!`, { path, version });\n return { expired: key, ready: null };\n }\n\n if (!ok) {\n this.runKeyHook('onKeyInvalid', key, message, errorOn);\n this.sysLog(`Key invalid!`, { path, version });\n return { expired: null, ready: null };\n }\n\n return { expired: null, ready: key };\n }\n\n /**\n * Generate a new cryptographic key and persist it to the configured store.\n *\n * This method:\n * - Generates a random origin key\n * - Hashes the key using the configured crypto options\n * - Calculates an expiration time (if provided)\n * - Assigns versioning and rotation metadata\n * - Saves the generated key to storage\n * - The hashed key will follow this format: `salt-buffer:hashed`\n *\n * @param options Configuration for key generation\n * @param options.type Logical key type (e.g. api, session, encryption, etc.)\n * @param options.duration Optional lifetime value for the key\n * @param options.unit Time unit for the duration (seconds | minutes | hours | days)\n * @param options.rotate Whether this key should participate in key rotation\n * @param options.merge Whether to merge with an existing stored key (if supported)\n *\n * @param variables Optional variables used for dynamic path or filename resolution\n *\n * @returns An object containing:\n * - `key`: The generated key metadata and raw key value\n * - `path`: The storage path where the key was saved\n *\n * @example\n * ```ts\n * const { key, path } = await keyManager.newKey(\n * {\n * type: 'api',\n * duration: 30, <- Optional\n * unit: 'days', <- Optional\n * rotate: true, <- Optional\n * },\n * { env: 'production', ... }\n * );\n * ```\n */\n public async newKey(\n options: TGenerateKeyOptions,\n variables: TKeyVariables = {}\n ): Promise<{ key: TKeyGenerated; path: string }> {\n const { rotate, duration, type, unit, merge, keyLength } = options;\n\n const { key, length: kLength } = this.cryptoService.generateKey(keyLength);\n const { salt } = this.cryptoService.generateSalt();\n\n this.sysLog(`Key generated\\nOptions:`, options);\n\n const hashedKey = this.cryptoService.hash(key, salt);\n const now = new Date();\n\n const keyGenerated: TKeyGenerated = {\n from: now.toISOString(),\n to: duration && unit ? addDuration(now, duration, unit).toISOString() : 'NON_EXPIRED',\n key: key,\n hashed: hashedKey,\n hashedBytes: kLength,\n type,\n version: await executePromisably(this.kOptions.versionGenerator()),\n rotate: !!rotate,\n };\n\n const path = await this.saveKeyToStore(keyGenerated, !!merge, variables);\n this.sysLog(`Key saved!`, {\n path,\n version: keyGenerated.version,\n type: keyGenerated.type,\n });\n\n return { key: keyGenerated, path };\n }\n\n private async getKeyByStore(path: string, version: string): Promise<TKeyGenerated | null> {\n if (this.getKeyFn) {\n return this.getKeyFn(path, version);\n }\n\n const savedData = await this.getKeyFileData(path);\n return savedData[version] ?? null;\n }\n\n private async saveKeyToStore(\n key: TKeyGenerated,\n merge: boolean,\n variables: TKeyVariables\n ): Promise<string> {\n return (this.saveKeyFn?.bind(this) ?? this.saveKeyFile.bind(this))(\n this.getFilename({ ...variables, version: key.version, type: key.type }),\n key,\n merge\n );\n }\n\n private validateKey(keyGenerated: Partial<TKeyGenerated>): {\n ok: boolean;\n message: string;\n errorOn?: keyof TKeyGenerated;\n isExpired?: boolean;\n isRenewable?: boolean;\n } {\n const requiredKeyGenerated = keyGenerated as TKeyGenerated;\n\n const typeChecks: Record<keyof TKeyGenerated, keyof ReturnType<typeof isType>> = {\n from: 'string',\n to: 'string',\n key: 'string',\n hashed: 'string',\n rotate: 'boolean',\n type: 'string',\n version: 'stringNumber',\n hashedBytes: 'number',\n };\n\n for (const [field, type] of Object.entries(typeChecks) as Array<\n [field: keyof TKeyGenerated, type: keyof ReturnType<typeof isType>]\n >) {\n if (!isType(requiredKeyGenerated[field])[type])\n return { ok: false, message: `${field} is not valid`, errorOn: field };\n }\n\n if (!isDate(requiredKeyGenerated.from)) {\n return { ok: false, message: 'From date is not valid!', errorOn: 'from' };\n } else if (new Date(requiredKeyGenerated.from) > new Date()) {\n return { ok: false, message: 'Key is not started!' };\n }\n\n if (!isDate(requiredKeyGenerated.to)) {\n if (requiredKeyGenerated.to !== 'NON_EXPIRED') {\n return { ok: false, message: 'Expire date is not valid!', errorOn: 'to' };\n }\n } else if (new Date(requiredKeyGenerated.to) < new Date()) {\n return {\n ok: false,\n message: 'Key is expired',\n errorOn: 'to',\n isExpired: true,\n isRenewable: !!requiredKeyGenerated.rotate,\n };\n }\n\n if (requiredKeyGenerated.hashedBytes < 0)\n return {\n ok: false,\n message: 'Invalid hashedBytes range',\n errorOn: 'hashedBytes',\n };\n\n return { ok: true, message: '' };\n }\n\n private getFilename(variables: TKeyVariables) {\n return bindString(\n bindString(`{{root}}/{{filename}}.{{ext}}`, {\n root: this.getPath(this.kOptions.path, '/'),\n filename: this.getPath(this.kOptions.file, this.kOptions.fileSplitor),\n ext: this.kOptions.fileExt,\n }),\n variables\n );\n }\n\n private runKeyHook<K extends keyof TKeyManagerHooks>(\n name: K,\n ...args: Parameters<TKeyManagerHooks[K]>\n ): ReturnType<TKeyManagerHooks[K]> {\n return this.runHook<TKeyManagerHooks, K>(name, ...args);\n }\n}\n","import { TModuleHooks, TModuleOptions } from 'src/types';\nimport { DEFAULT_MODULE_OPTIONS } from 'src/constants/default.constant';\nimport { KeyManager } from './key-manager.core';\n\nexport class KM extends KeyManager {\n private options: Required<TModuleOptions>;\n\n constructor(options: Partial<TModuleOptions>) {\n super(options);\n\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n }\n\n public setOptions(options: TModuleOptions): this {\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n return this;\n }\n\n public getOptions(): TModuleOptions | undefined {\n return this.options;\n }\n\n /**\n *\n * @param instance: use instance options to create new instance\n * @param extend: overide options\n * @returns new instance\n */\n public clone(extend: Partial<TModuleOptions> = {}): KM {\n const module = new KM({ ...this.getOptions(), ...extend });\n\n if (this.saveKeyFn) module.useSaveKey(this.saveKeyFn);\n if (this.getKeyFn) module.useGetKey(this.getKeyFn);\n if (this.storePath) module.useStorePath(this.storePath);\n\n module.setHooks(this.getHooks());\n module.setLogger(this.getLogger());\n\n return module;\n }\n\n public useHooks(hooks: Partial<{ [x in keyof TModuleHooks]: TModuleHooks[x] }>) {\n this.setHooks(hooks);\n return this;\n }\n\n public setHook<HookName extends keyof TModuleHooks>(\n name: HookName,\n handler: TModuleHooks[HookName]\n ) {\n this.setHooks({ [name]: handler });\n return this;\n }\n}\n","import { KM } from './core/module.core';\nimport * as types from './types';\nexport * from './types';\n\nlet instance: KM | null = null;\n\n/**\n * Create a new KeyManager instance\n * @param options - Options to configure the instance\n * @param singleton - If true, returns a shared singleton instance; if false, creates a new instance\n * @returns KM instance\n */\nexport const create = (\n options: Partial<types.TModuleOptions> = {},\n singleton: boolean = false\n): KM => {\n if (!singleton) return new KM(options);\n\n if (!instance) {\n instance = new KM(options);\n }\n\n return instance;\n};\n\n/**\n * @alias create()\n */\nexport const km = create;\nexport type { KM };\n"]}
1
+ {"version":3,"sources":["../src/constants/default.constant.ts","../src/types/events.types.ts","../src/utils/promise.util.ts","../src/utils/file.util.ts","../src/utils/string.util.ts","../src/utils/crypto.util.ts","../src/core/base.core.ts","../src/core/events.core.ts","../src/core/store.core.ts","../src/core/key-manager.core.ts","../src/core/module.core.ts","../src/index.ts"],"names":["EEvent","access","mkdir","readFile","path","dirname","writeFile","unlink","randomBytes","pbkdf2Sync","createCipheriv","createDecipheriv","createHash","EventEmitter","join"],"mappings":"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","file":"index.cjs","sourcesContent":["import { TEventsOptions, TModuleOptions, TStoreOptions } from 'src/types';\nimport { TBaseOptions } from 'src/types/base.type';\nimport { TCryptoOptions } from 'src/types/crypto.type';\nimport { TKeyManagerOptions } from 'src/types/key-manager.types';\n\nexport const DEFAULT_CRYPTO_OPTIONS: Required<TCryptoOptions> = {\n algorithm: 'aes-256-cbc',\n kdf: 'pbkdf2',\n hashAlgorithm: 'sha256',\n keyLength: 32,\n ivLength: 16,\n saltLength: 32,\n tagLength: 16,\n iterations: 100000,\n encoding: 'base64',\n};\n\nexport const DEFAULT_BASE_OPTIONS: Required<TBaseOptions> = {\n quiet: false,\n};\n\nexport const DEFAULT_BASE_LOGGER = (...args: any[]) => console.log(...args);\n\nexport const DEFAULT_EVENTS_OPTIONS: Required<TEventsOptions> = {\n ...DEFAULT_BASE_OPTIONS,\n\n // Event\n useEvent: true,\n};\n\nexport const DEFAULT_STORE_OPTIONS: Required<TStoreOptions> = {\n path: ['keys', '{{type}}'],\n file: ['v', '{{version}}'],\n fileSplitor: '_',\n fileExt: 'json',\n gitIgnore: true,\n\n ...DEFAULT_EVENTS_OPTIONS,\n\n // Key manager\n crypto: DEFAULT_CRYPTO_OPTIONS,\n};\n\nexport const DEFAULT_KEY_MANAGER_OPTIONS: Required<TKeyManagerOptions> = {\n // Store\n ...DEFAULT_STORE_OPTIONS,\n\n versionGenerator: () => new Date().getTime(),\n};\n\nexport const DEFAULT_MODULE_OPTIONS: Required<TModuleOptions> = {\n ...DEFAULT_KEY_MANAGER_OPTIONS,\n\n // Module\n quiet: false,\n};\n","import { TBaseOptions } from './base.type';\nimport { TKeyGenerated } from './key-manager.types';\n\nexport enum EEvent {\n STORE_INIT_FOLDER = 'store-init-folder',\n STORE_FILE_SAVED = 'saved-key-file',\n}\n\nexport type TEvents = {\n [EEvent.STORE_INIT_FOLDER]: {\n gitIgnoreStorePath?: string;\n gitIgnorePath?: string;\n gitIgnoreAddStatus?: 'already' | 'added';\n storePath: string;\n };\n [EEvent.STORE_FILE_SAVED]: { path: string; data: Record<string, TKeyGenerated> };\n};\n\nexport type TEventsOptions = Partial<TBaseOptions> & {\n /**\n * Is use event emitter\n * @default true\n */\n useEvent?: boolean;\n};\n","export const executePromisably = <T>(\n promiseOrFn: T | Promise<T> | ((...args: unknown[]) => T | Promise<T>)\n): Promise<T> => {\n try {\n const value =\n typeof promiseOrFn === 'function' && !(promiseOrFn instanceof Promise)\n ? (promiseOrFn as (...args: unknown[]) => T | Promise<T>)()\n : promiseOrFn;\n return Promise.resolve(value);\n } catch (error) {\n return Promise.reject(error);\n }\n};\n\nexport const promiseAll = <T extends readonly unknown[]>(\n ...fns: T\n): Promise<{ [K in keyof T]: Awaited<T[K]> }> => {\n return Promise.all(fns);\n};\n","import { access, mkdir, readFile, unlink, writeFile } from 'fs/promises';\nimport { dirname } from 'path';\n\nexport class FileUtilError extends Error {\n constructor(\n message: string,\n public readonly path: string,\n public readonly operation: 'read' | 'write' | 'delete' | 'access' | 'mkdir',\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = 'FileUtilError';\n }\n}\n\nexport class FileUtil {\n async getFolder(path: string): Promise<string> {\n try {\n await access(path);\n return path;\n } catch {\n try {\n await mkdir(path, { recursive: true });\n return path;\n } catch (error) {\n throw new FileUtilError(`Failed to create folder: ${path}`, path, 'mkdir', error);\n }\n }\n }\n\n async read(path: string, fallback?: string): Promise<string> {\n try {\n const data = await readFile(path, { encoding: 'utf8' });\n return data;\n } catch (error) {\n if (fallback !== undefined) return fallback;\n throw new FileUtilError(`Failed to read file: ${path}`, path, 'read', error);\n }\n }\n\n async write(path: string, data: string, flag: 'w' | 'a' = 'w'): Promise<void> {\n const dir = dirname(path);\n await this.getFolder(dir);\n\n try {\n await writeFile(path, data, { encoding: 'utf8', flag });\n } catch (error) {\n throw new FileUtilError(`Failed to write file: ${path}`, path, 'write', error);\n }\n }\n\n async checkExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n }\n\n async delete(path: string): Promise<void> {\n try {\n await unlink(path);\n } catch (error) {\n throw new FileUtilError(`Failed to delete file: ${path}`, path, 'delete', error);\n }\n }\n}\n","import { TKeyDurationUnit } from 'src/types/key-manager.types';\n\nconst getNested = (obj: Record<string, any>, path: string): any =>\n path.split('.').reduce((curr, key) => curr?.[key], obj);\n\nconst flatten = (obj: Record<string, any>, prefix = ''): Record<string, any> =>\n Object.entries(obj).reduce((acc, [key, val]) => {\n const newKey = prefix ? `${prefix}.${key}` : key;\n return val && typeof val === 'object' && !Array.isArray(val)\n ? { ...acc, ...flatten(val, newKey) }\n : { ...acc, [newKey]: val };\n }, {});\n\nconst stringify = (val: any): string => {\n if (val === null || val === undefined) return '';\n if (typeof val === 'object') return JSON.stringify(val);\n return String(val);\n};\n\nexport const bindString = (format: string, bindValues: Record<string, any>): string => {\n return format\n .replace(/\\{\\{\\.\\.\\.([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n\n return val && typeof val === 'object' && !Array.isArray(val)\n ? JSON.stringify(flatten(val, trimmedPath))\n : match;\n })\n .replace(/\\{\\{([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n\n // Skip if it's a spread syntax (already handled)\n if (trimmedPath.startsWith('...')) {\n return match;\n }\n\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n return stringify(val);\n });\n};\nexport const isDate = (data: string): boolean => {\n try {\n const date = new Date(data);\n return !isNaN(date.getTime());\n } catch (error) {\n return false;\n }\n};\n\nexport const addDuration = (date: Date, duration: number, unit: TKeyDurationUnit): Date => {\n const result = new Date(date.getTime());\n\n switch (unit) {\n case 'seconds':\n result.setSeconds(result.getSeconds() + duration);\n break;\n\n case 'minutes':\n result.setMinutes(result.getMinutes() + duration);\n break;\n\n case 'hours':\n result.setHours(result.getHours() + duration);\n break;\n\n case 'days':\n result.setDate(result.getDate() + duration);\n break;\n\n default: {\n const _exhaustiveCheck: never = unit;\n throw new Error(`Unsupported duration unit: ${_exhaustiveCheck}`);\n }\n }\n\n return result;\n};\n\nexport const isType = (data?: unknown) => {\n return {\n number: typeof data === 'number' && !Number.isNaN(Number(data)),\n string: typeof data === 'string',\n stringNumber: typeof data === 'string' || typeof data === 'number',\n boolean: typeof data === 'boolean',\n null: data === null,\n undefined: data === undefined,\n };\n};\n","import { randomBytes, pbkdf2Sync, createCipheriv, createDecipheriv, createHash } from 'node:crypto';\nimport { DEFAULT_CRYPTO_OPTIONS } from 'src/constants/default.constant';\nimport { TCryptoOptions } from 'src/types/crypto.type';\n\nexport class CryptoService {\n private options: Required<TCryptoOptions>;\n\n constructor(options: Partial<TCryptoOptions> = {}) {\n this.options = { ...DEFAULT_CRYPTO_OPTIONS, ...options };\n }\n\n /**\n * Generate random bytes and encode them\n */\n generateRandom(length: number = 32): string {\n const buffer = randomBytes(length);\n return this.encodeBuffer(buffer);\n }\n\n /**\n * Generate a random key\n * @param length Length of the key in bytes\n * @default cryptoOptions.keyLength\n */\n generateKey(length: number = this.options.keyLength) {\n return { key: this.generateRandom(length), length } as const;\n }\n\n /**\n * Generate a random salt\n * @param length Length of the salt in bytes\n * @default cryptoOptions.saltLength\n */\n generateSalt(length: number = this.options.saltLength) {\n return { salt: this.generateRandom(length), length } as const;\n }\n\n /**\n * Generate a random IV\n * @param length Length of the IV in bytes\n * @default cryptoOptions.ivLength\n */\n generateIV(length: number = this.options.ivLength) {\n return { iv: this.generateRandom(length), length } as const;\n }\n\n private encodeBuffer(buffer: Buffer): string {\n switch (this.options.encoding) {\n case 'hex':\n return buffer.toString('hex');\n case 'base64url':\n return buffer.toString('base64url');\n case 'base64':\n default:\n return buffer.toString('base64');\n }\n }\n\n private decodeToBuffer(encoded: string): Buffer {\n switch (this.options.encoding) {\n case 'hex':\n return Buffer.from(encoded, 'hex');\n case 'base64url':\n return Buffer.from(encoded, 'base64url');\n case 'base64':\n default:\n return Buffer.from(encoded, 'base64');\n }\n }\n\n private deriveKey(password: string, salt: Buffer, keyLength?: number): Buffer {\n if (this.options.kdf === 'none') {\n return Buffer.from(password, 'hex');\n }\n\n const actualKeyLength = keyLength ?? this.options.keyLength;\n return pbkdf2Sync(\n password,\n salt,\n this.options.iterations,\n actualKeyLength,\n this.options.hashAlgorithm\n );\n }\n\n /**\n * Encrypt data using AES-CBC\n * @param plainText Text to encrypt\n * @param secret Secret key for encryption\n * @param options Optional lengths for key, salt, and IV\n */\n encrypt(\n plainText: string,\n secret: string,\n {\n keyLength,\n saltLength,\n ivLength,\n }: { keyLength?: number; saltLength?: number; ivLength?: number } = {}\n ): string {\n keyLength = keyLength ?? this.options.keyLength;\n saltLength = saltLength ?? this.options.saltLength;\n ivLength = ivLength ?? this.options.ivLength;\n\n const salt = this.options.kdf !== 'none' ? randomBytes(saltLength) : Buffer.alloc(0);\n const iv = randomBytes(ivLength);\n const key = this.deriveKey(secret, salt, keyLength);\n\n const cipher = createCipheriv(this.options.algorithm, key, iv);\n const encrypted = Buffer.concat([cipher.update(plainText, 'utf8'), cipher.final()]);\n\n // Pack: keyLength(2) + saltLength(2) + ivLength(2) + salt + iv + encrypted\n const keyLengthBuf = Buffer.alloc(2);\n keyLengthBuf.writeUInt16BE(keyLength);\n\n const saltLengthBuf = Buffer.alloc(2);\n saltLengthBuf.writeUInt16BE(salt.length);\n\n const ivLengthBuf = Buffer.alloc(2);\n ivLengthBuf.writeUInt16BE(ivLength);\n\n const combined = Buffer.concat([keyLengthBuf, saltLengthBuf, ivLengthBuf, salt, iv, encrypted]);\n\n return this.encodeBuffer(combined);\n }\n\n /**\n * Decrypt data\n * @param encryptedData Encrypted data to decrypt\n * @param secret Secret key for decryption\n * @returns Decrypted string, or empty string if decryption fails (wrong password/corrupted data)\n */\n decrypt(encryptedData: string, secret: string): string {\n try {\n const combined = this.decodeToBuffer(encryptedData);\n let offset = 0;\n\n // Read lengths (2 bytes each)\n const keyLength = combined.readUInt16BE(offset);\n offset += 2;\n const saltLength = combined.readUInt16BE(offset);\n offset += 2;\n const ivLength = combined.readUInt16BE(offset);\n offset += 2;\n\n // Read salt, iv, and encrypted data\n const salt = combined.subarray(offset, offset + saltLength);\n offset += saltLength;\n\n const iv = combined.subarray(offset, offset + ivLength);\n offset += ivLength;\n\n const encrypted = combined.subarray(offset);\n\n const key = this.deriveKey(secret, salt, keyLength);\n\n const decipher = createDecipheriv(this.options.algorithm, key, iv);\n const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);\n\n return decrypted.toString('utf8');\n } catch {\n // Return empty string on decryption failure (wrong password, corrupted data, etc.)\n // This matches the behavior of crypto-js\n return '';\n }\n }\n\n /**\n * Hash data (one-way)\n * @param data Data to hash\n * @param secret Secret key used in hashing\n * @param salt Optional encoded salt string for deterministic hashing\n */\n hash(data: string, secret: string, salt?: string): string {\n let saltBuffer: Buffer;\n let saltStr: string;\n\n if (salt) {\n // Deterministic mode: use provided salt\n saltBuffer = this.decodeToBuffer(salt);\n saltStr = salt;\n } else {\n // Non-deterministic mode: generate random salt\n saltBuffer = randomBytes(this.options.saltLength);\n saltStr = this.encodeBuffer(saltBuffer);\n }\n\n const hash = createHash(this.options.hashAlgorithm)\n .update(data)\n .update(secret)\n .update(saltBuffer)\n .digest();\n\n const hashStr = this.encodeBuffer(hash);\n\n return `${saltStr}:${hashStr}`;\n }\n\n /**\n * Verify hashed data\n * @param data Data to verify\n * @param hashedData Previously hashed data (format: salt:hash)\n * @param secret Secret key used during hashing\n */\n verifyHash(data: string, hashedData: string, secret: string): boolean {\n const [saltStr, expectedHashStr] = hashedData.split(':');\n if (!saltStr || !expectedHashStr) {\n return false;\n }\n\n const saltBuffer = this.decodeToBuffer(saltStr);\n\n const hash = createHash(this.options.hashAlgorithm)\n .update(data)\n .update(secret)\n .update(saltBuffer)\n .digest();\n\n const hashStr = this.encodeBuffer(hash);\n\n // Use timing-safe comparison\n return hashStr === expectedHashStr;\n }\n}\n","import { DEFAULT_BASE_LOGGER, DEFAULT_BASE_OPTIONS } from 'src/constants/default.constant';\nimport { TBaseLogger, TBaseOptions, THook } from 'src/types/base.type';\n\ntype DefaultLogger = typeof DEFAULT_BASE_LOGGER;\n\nexport class Base<TLogger extends (...args: any[]) => any = DefaultLogger> {\n private logger: TBaseLogger<TLogger>;\n private bOptions: Required<TBaseOptions>;\n private hooks: Map<string, THook> = new Map();\n\n constructor(options: Partial<TBaseOptions>) {\n this.bOptions = { ...DEFAULT_BASE_OPTIONS, ...options };\n this.logger = DEFAULT_BASE_LOGGER as TBaseLogger<TLogger>;\n }\n\n protected getLogger(): TBaseLogger<TLogger> {\n return this.logger;\n }\n\n public setLogger(logger: TBaseLogger<TLogger>): this {\n this.logger = logger;\n return this;\n }\n\n public sysLog(...args: Parameters<TLogger>): this {\n if (!this.bOptions.quiet) {\n const result = this.logger(...args);\n if (result && typeof result === 'object' && 'catch' in result) {\n (result as Promise<unknown>).catch(() => {});\n }\n }\n return this;\n }\n\n public async customLog<T extends (...args: any[]) => any>(\n logger: TBaseLogger<T>,\n ...args: Parameters<T>\n ) {\n await logger(...args);\n return this;\n }\n\n protected setHooks<T extends Record<string, THook> = {}>(hooks: T) {\n Object.entries(hooks).forEach(([name, handler]) => {\n if (this.hooks.has(name)) {\n this.hooks.get('onHookOverriding')?.call(this, name);\n }\n\n this.hooks.set(name, handler);\n });\n return this;\n }\n\n protected runHook<Hooks extends Record<string, THook>, K extends keyof Hooks>(\n name: K,\n ...args: Parameters<Hooks[K]>\n ): ReturnType<Hooks[K]> {\n if (!this.hooks.has(name as string)) {\n this.hooks.get('onHookNotFound')?.call(this, name as string);\n return undefined as any;\n }\n\n return this.hooks.get(name as string)!.call(this, ...args);\n }\n\n protected getHooks(): Record<string, THook> {\n return Object.fromEntries(this.hooks.entries()) as Record<string, THook>;\n }\n}\n","import EventEmitter from 'node:events';\nimport { Base } from './base.core';\nimport { TEvents, TEventsOptions } from 'src/types';\nimport { DEFAULT_EVENTS_OPTIONS } from 'src/constants/default.constant';\n\nexport class Events extends Base {\n private events?: EventEmitter;\n private eOptions: Required<TEventsOptions>;\n\n constructor(options: TEventsOptions) {\n super(options);\n\n this.eOptions = {\n ...DEFAULT_EVENTS_OPTIONS,\n ...options,\n };\n\n if (this.eOptions.useEvent) {\n this.events = new EventEmitter();\n }\n }\n\n protected emit<K extends keyof TEvents>(event: K, args: TEvents[K]) {\n if (!this.events) return this;\n\n this.events.emit(event, args);\n return this;\n }\n\n on<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.on(event, listener);\n return this;\n }\n\n once<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.once(event, listener);\n return this;\n }\n\n off<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.off(event, listener);\n return this;\n }\n}\n","import { EEvent, TEvents, TFormatUsable, TGetKeyFn, TSaveKeyFn, TStoreOptions } from 'src/types';\nimport { FileUtil } from 'src/utils';\nimport { DEFAULT_STORE_OPTIONS } from 'src/constants/default.constant';\nimport { join } from 'path';\nimport { TKeyGenerated } from 'src/types/key-manager.types';\nimport { Events } from './events.core';\n\nexport class Store extends Events {\n private sOptions: Required<Omit<TStoreOptions, 'useEvent' | 'crypto'>>;\n private fileUtil: FileUtil;\n protected storePath?: string;\n protected saveKeyFn?: TSaveKeyFn;\n protected getKeyFn?: TGetKeyFn;\n\n constructor(options: Partial<TStoreOptions>) {\n super(options);\n\n this.sOptions = { ...DEFAULT_STORE_OPTIONS, ...options };\n this.fileUtil = new FileUtil();\n\n this.initStore();\n }\n\n protected getPath(path: string | string[], splitor: string): string {\n if (typeof path === 'object' && Array.isArray(path)) {\n return path.join(splitor);\n }\n\n return path;\n }\n\n private async getKeyStoreFolder(): Promise<string> {\n if (this.storePath) return this.storePath;\n\n const { path } = this.sOptions;\n\n const first =\n typeof path === 'object' && Array.isArray(path)\n ? path[0]\n : typeof path === 'string'\n ? (path.split('/')[0] ?? '')\n : '';\n\n let folder = await this.fileUtil.getFolder(join(process.cwd(), first));\n\n return folder;\n }\n\n protected async getKeyFileData(filePath: string): Promise<Record<string, TKeyGenerated>> {\n const existingData = await this.fileUtil.read(filePath, '{}');\n const savedData = this.toSavedData(existingData);\n\n return savedData;\n }\n\n protected async saveKeyFile(\n path: string,\n data: TKeyGenerated,\n merge: boolean = false\n ): Promise<string> {\n let savedData = await this.getKeyFileData(path);\n\n let saveData: Record<string, TKeyGenerated> = {};\n\n if (merge) {\n saveData = { ...savedData };\n }\n\n saveData = { ...saveData, [data.version]: data };\n\n await this.fileUtil.write(path, JSON.stringify(saveData, null, 2));\n\n this.emit(EEvent.STORE_FILE_SAVED, { path, data: saveData });\n\n return path;\n }\n\n /**\n * @param storePath custom store path\n * root folder of store\n * @returns this\n */\n public useStorePath(storePath: string): this {\n this.storePath = storePath;\n return this;\n }\n\n /**\n * @param saveKeyFn custom save key function\n * @returns this\n */\n public useSaveKey(saveKeyFn: TSaveKeyFn): this {\n this.saveKeyFn = saveKeyFn;\n return this;\n }\n\n /**\n * @param saveKeyFn custom get key function\n * @returns this\n */\n public useGetKey(getKeyFn: TGetKeyFn): this {\n this.getKeyFn = getKeyFn;\n return this;\n }\n\n private async initStore(): Promise<void> {\n const storePath = await this.getKeyStoreFolder();\n\n let eventEmitPayload: TEvents[EEvent.STORE_INIT_FOLDER] = {\n storePath,\n };\n\n if (this.sOptions.gitIgnore) {\n const gitignore = await this.addStoreFolderGitignore();\n eventEmitPayload = { ...eventEmitPayload, ...gitignore };\n }\n\n this.emit(EEvent.STORE_INIT_FOLDER, eventEmitPayload);\n }\n\n private toSavedData(dataString: string): Record<string, TKeyGenerated> {\n try {\n if (!dataString) return {};\n const parsedData = JSON.parse(dataString) as Record<string, TKeyGenerated>;\n\n if (typeof parsedData !== 'object' || Array.isArray(parsedData)) {\n throw new Error('Invalid JSON data (must be Record<version, TKeyGenerated>)');\n }\n\n return parsedData;\n } catch (error) {\n throw new Error(`Invalid JSON data (must be Record<version, TKeyGenerated>) ${dataString}`);\n }\n }\n\n private async addStoreFolderGitignore(): Promise<\n Omit<TEvents[EEvent.STORE_INIT_FOLDER], 'storePath'>\n > {\n const gitignorePath = join(process.cwd(), '.gitignore');\n const gitignoreContent = await this.fileUtil.read(gitignorePath);\n\n const folder = this.getStoreFolderGitignore();\n const gitignoreLines = gitignoreContent.split(/\\r?\\n/).map((line) => line.trim());\n const hasExactLine = gitignoreLines.some((line) => line === folder);\n\n if (!hasExactLine) {\n await this.fileUtil.write(gitignorePath, `${gitignoreContent ? '\\r\\n' : ''}${folder}`, 'a');\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'added',\n };\n }\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'already',\n };\n }\n\n private getStoreFolderGitignore() {\n let folder = '';\n const storePath = this.getPath(this.sOptions.path, '/');\n\n if (typeof this.sOptions.gitIgnore === 'boolean') {\n folder = this.getStoreFolderGitignoreByDefault(storePath);\n } else {\n folder = this.addStoreFolderGitignoreByCustom(this.sOptions.gitIgnore);\n }\n\n return this.replaceVariableToStar(folder);\n }\n\n private getStoreFolderGitignoreByDefault(storePath: string) {\n const filePath = this.getPath(this.sOptions.file, this.sOptions.fileSplitor);\n\n const folder: string[] = [storePath];\n folder.push(`${filePath}.${this.sOptions.fileExt}`);\n\n return folder.join('/');\n }\n\n private addStoreFolderGitignoreByCustom(ignorePath: TFormatUsable) {\n return this.getPath(ignorePath, '/');\n }\n\n private replaceVariableToStar(path: string): string {\n return path.replace(/\\{\\{.*?\\}\\}/g, '*');\n }\n}\n","import {\n TGenerateKeyOptions,\n TGetKey,\n TGetKeyOptions,\n TKeyGenerated,\n TKeyManagerHooks,\n TKeyManagerOptions,\n TKeyVariables,\n} from 'src/types/key-manager.types';\nimport { Store } from './store.core';\nimport {\n CryptoService,\n executePromisably,\n addDuration,\n bindString,\n isDate,\n isType,\n} from 'src/utils';\nimport { DEFAULT_KEY_MANAGER_OPTIONS } from 'src/constants/default.constant';\n\nexport class KeyManager extends Store {\n private cryptoService: CryptoService;\n private kOptions: Required<TKeyManagerOptions>;\n\n constructor(options: Partial<TKeyManagerOptions>) {\n super(options);\n\n this.kOptions = { ...DEFAULT_KEY_MANAGER_OPTIONS, ...options };\n this.cryptoService = new CryptoService(this.kOptions.crypto);\n }\n\n /**\n * Retrieve and validate a stored key by path and version.\n *\n * This method:\n * - Loads a key from the configured store\n * - Validates structure, type safety, and time constraints\n * - Detects expiration and rotation eligibility\n * - Optionally auto-rotates an expired key if rotation options are provided\n *\n * If the key is expired and marked as rotatable, a new key will be generated\n * automatically using the provided `onRotate` options.\n *\n * @param options Configuration for key retrieval\n * @param options.path Storage path of the key\n * @param options.version Specific key version to retrieve\n * @param options.onRotate Optional rotation configuration used when the key\n * is expired and renewable\n *\n * @returns An object containing:\n * - `ready`: The valid (usable) key, or the newly generated key after rotation\n * - `expired`: The expired key if rotation occurred, otherwise `null`\n *\n * @throws Error if:\n * - The key does not exist\n * - The key structure or fields are invalid\n * - The key is expired but rotation options are missing\n * - The key is not yet valid or otherwise unusable\n *\n * @example\n * ```ts\n * const { ready, expired } = await keyManager.getKey({\n * path: '/keys/api',\n * version: 'v1',\n * // This define the new key attributes: is it rotate? Durations and unit?\n * onRotate: {\n * duration: 30,\n * unit: 'days',\n * rotate: true,\n * },\n * });\n *\n * if (expired) {\n * console.log('Key was rotated from version:', expired.version);\n * }\n *\n * // Use expired?.key ?? ready?.key safely\n * ```\n */\n public async getKey(options: TGetKeyOptions): Promise<TGetKey> {\n const { path, version } = options;\n\n const key = await this.getKeyByStore(path, String(version));\n\n if (!key) {\n this.runKeyHook('onKeyNotFound', path, version);\n this.sysLog(`Key not found!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);\n\n if (!ok && isExpired && isRenewable && key) {\n if (!options.onRotate) {\n this.runKeyHook('onKeyMissingRotateOption', key, options);\n this.sysLog(`Key missing rotate option!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const renew = await this.newKey({\n type: key.type,\n ...options.onRotate,\n });\n\n const resGetKey = { expired: key, ready: renew.key };\n\n this.runKeyHook('onKeyRenewed', resGetKey, options);\n this.sysLog(`Key renewed!`, { path, version });\n return resGetKey;\n }\n\n if (!ok && isExpired && !isRenewable && key) {\n this.runKeyHook('onKeyExpired', path, key);\n this.sysLog(`Key expired!`, { path, version });\n return { expired: key, ready: null };\n }\n\n if (!ok) {\n this.runKeyHook('onKeyInvalid', key, message, errorOn);\n this.sysLog(`Key invalid!`, { path, version });\n return { expired: null, ready: null };\n }\n\n return { expired: null, ready: key };\n }\n\n /**\n * Generate a new cryptographic key and persist it to the configured store.\n *\n * This method:\n * - Generates a random origin key\n * - Hashes the key using the configured crypto options\n * - Calculates an expiration time (if provided)\n * - Assigns versioning and rotation metadata\n * - Saves the generated key to storage\n * - The hashed key will follow this format: `salt-buffer:hashed`\n *\n * @param options Configuration for key generation\n * @param options.type Logical key type (e.g. api, session, encryption, etc.)\n * @param options.duration Optional lifetime value for the key\n * @param options.unit Time unit for the duration (seconds | minutes | hours | days)\n * @param options.rotate Whether this key should participate in key rotation\n * @param options.merge Whether to merge with an existing stored key (if supported)\n *\n * @param variables Optional variables used for dynamic path or filename resolution\n *\n * @returns An object containing:\n * - `key`: The generated key metadata and raw key value\n * - `path`: The storage path where the key was saved\n *\n * @example\n * ```ts\n * const { key, path } = await keyManager.newKey(\n * {\n * type: 'api',\n * duration: 30, <- Optional\n * unit: 'days', <- Optional\n * rotate: true, <- Optional\n * },\n * { env: 'production', ... }\n * );\n * ```\n */\n public async newKey(\n options: TGenerateKeyOptions,\n variables: TKeyVariables = {}\n ): Promise<{ key: TKeyGenerated; path: string }> {\n const { rotate, duration, type, unit, merge, keyLength } = options;\n\n const { key, length: kLength } = this.cryptoService.generateKey(keyLength);\n const { salt } = this.cryptoService.generateSalt();\n\n this.sysLog(`Key generated\\nOptions:`, options);\n\n const hashedKey = this.cryptoService.hash(key, salt);\n const now = new Date();\n\n const keyGenerated: TKeyGenerated = {\n from: now.toISOString(),\n to: duration && unit ? addDuration(now, duration, unit).toISOString() : 'NON_EXPIRED',\n key: key,\n hashed: hashedKey,\n hashedBytes: kLength,\n type,\n version: await executePromisably(this.kOptions.versionGenerator()),\n rotate: !!rotate,\n };\n\n const path = await this.saveKeyToStore(keyGenerated, !!merge, variables);\n this.sysLog(`Key saved!`, {\n path,\n version: keyGenerated.version,\n type: keyGenerated.type,\n });\n\n return { key: keyGenerated, path };\n }\n\n private async getKeyByStore(path: string, version: string): Promise<TKeyGenerated | null> {\n if (this.getKeyFn) {\n return this.getKeyFn(path, version);\n }\n\n const savedData = await this.getKeyFileData(path);\n return savedData[version] ?? null;\n }\n\n private async saveKeyToStore(\n key: TKeyGenerated,\n merge: boolean,\n variables: TKeyVariables\n ): Promise<string> {\n return (this.saveKeyFn?.bind(this) ?? this.saveKeyFile.bind(this))(\n this.getFilename({ ...variables, version: key.version, type: key.type }),\n key,\n merge\n );\n }\n\n private validateKey(keyGenerated: Partial<TKeyGenerated>): {\n ok: boolean;\n message: string;\n errorOn?: keyof TKeyGenerated;\n isExpired?: boolean;\n isRenewable?: boolean;\n } {\n const requiredKeyGenerated = keyGenerated as TKeyGenerated;\n\n const typeChecks: Record<keyof TKeyGenerated, keyof ReturnType<typeof isType>> = {\n from: 'string',\n to: 'string',\n key: 'string',\n hashed: 'string',\n rotate: 'boolean',\n type: 'string',\n version: 'stringNumber',\n hashedBytes: 'number',\n };\n\n for (const [field, type] of Object.entries(typeChecks) as Array<\n [field: keyof TKeyGenerated, type: keyof ReturnType<typeof isType>]\n >) {\n if (!isType(requiredKeyGenerated[field])[type])\n return { ok: false, message: `${field} is not valid`, errorOn: field };\n }\n\n if (!isDate(requiredKeyGenerated.from)) {\n return { ok: false, message: 'From date is not valid!', errorOn: 'from' };\n } else if (new Date(requiredKeyGenerated.from) > new Date()) {\n return { ok: false, message: 'Key is not started!' };\n }\n\n if (!isDate(requiredKeyGenerated.to)) {\n if (requiredKeyGenerated.to !== 'NON_EXPIRED') {\n return { ok: false, message: 'Expire date is not valid!', errorOn: 'to' };\n }\n } else if (new Date(requiredKeyGenerated.to) < new Date()) {\n return {\n ok: false,\n message: 'Key is expired',\n errorOn: 'to',\n isExpired: true,\n isRenewable: !!requiredKeyGenerated.rotate,\n };\n }\n\n if (requiredKeyGenerated.hashedBytes < 0)\n return {\n ok: false,\n message: 'Invalid hashedBytes range',\n errorOn: 'hashedBytes',\n };\n\n return { ok: true, message: '' };\n }\n\n private getFilename(variables: TKeyVariables) {\n return bindString(\n bindString(`{{root}}/{{filename}}.{{ext}}`, {\n root: this.getPath(this.kOptions.path, '/'),\n filename: this.getPath(this.kOptions.file, this.kOptions.fileSplitor),\n ext: this.kOptions.fileExt,\n }),\n variables\n );\n }\n\n private runKeyHook<K extends keyof TKeyManagerHooks>(\n name: K,\n ...args: Parameters<TKeyManagerHooks[K]>\n ): ReturnType<TKeyManagerHooks[K]> {\n return this.runHook<TKeyManagerHooks, K>(name, ...args);\n }\n}\n","import { TModuleHooks, TModuleOptions } from 'src/types';\nimport { DEFAULT_MODULE_OPTIONS } from 'src/constants/default.constant';\nimport { KeyManager } from './key-manager.core';\n\nexport class KM extends KeyManager {\n private options: Required<TModuleOptions>;\n\n constructor(options: Partial<TModuleOptions>) {\n super(options);\n\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n }\n\n public setOptions(options: TModuleOptions): this {\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n return this;\n }\n\n public getOptions(): TModuleOptions | undefined {\n return this.options;\n }\n\n /**\n *\n * @param instance: use instance options to create new instance\n * @param extend: overide options\n * @returns new instance\n */\n public clone(extend: Partial<TModuleOptions> = {}): KM {\n const module = new KM({ ...this.getOptions(), ...extend });\n\n if (this.saveKeyFn) module.useSaveKey(this.saveKeyFn);\n if (this.getKeyFn) module.useGetKey(this.getKeyFn);\n if (this.storePath) module.useStorePath(this.storePath);\n\n module.setHooks(this.getHooks());\n module.setLogger(this.getLogger());\n\n return module;\n }\n\n public useHooks(hooks: Partial<{ [x in keyof TModuleHooks]: TModuleHooks[x] }>) {\n this.setHooks(hooks);\n return this;\n }\n\n public setHook<HookName extends keyof TModuleHooks>(\n name: HookName,\n handler: TModuleHooks[HookName]\n ) {\n this.setHooks({ [name]: handler });\n return this;\n }\n}\n","import { KM } from './core/module.core';\nimport * as types from './types';\nexport * from './types';\n\nlet instance: KM | null = null;\n\n/**\n * Create a new KeyManager instance\n * @param options - Options to configure the instance\n * @param singleton - If true, returns a shared singleton instance; if false, creates a new instance\n * @returns KM instance\n */\nexport const create = (\n options: Partial<types.TModuleOptions> = {},\n singleton: boolean = false\n): KM => {\n if (!singleton) return new KM(options);\n\n if (!instance) {\n instance = new KM(options);\n }\n\n return instance;\n};\n\n/**\n * @alias create()\n */\nexport const km = create;\nexport type { KM };\n"]}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { access, mkdir, readFile, writeFile, unlink } from 'fs/promises';
2
2
  import { join, dirname } from 'path';
3
- import CryptoJS from 'crypto-js';
3
+ import { randomBytes, pbkdf2Sync, createCipheriv, createDecipheriv, createHash } from 'crypto';
4
4
  import EventEmitter from 'events';
5
5
 
6
6
  // src/constants/default.constant.ts
@@ -178,7 +178,7 @@ var isType = (data) => {
178
178
  return {
179
179
  number: typeof data === "number" && !Number.isNaN(Number(data)),
180
180
  string: typeof data === "string",
181
- stringNumber: typeof data === "string" && !Number.isNaN(Number(data)) || typeof data === "number",
181
+ stringNumber: typeof data === "string" || typeof data === "number",
182
182
  boolean: typeof data === "boolean",
183
183
  null: data === null,
184
184
  undefined: data === void 0
@@ -189,97 +189,77 @@ var CryptoService = class {
189
189
  constructor(options = {}) {
190
190
  this.options = { ...DEFAULT_CRYPTO_OPTIONS, ...options };
191
191
  }
192
- generateRandomWordArray(length) {
193
- return CryptoJS.lib.WordArray.random(length);
194
- }
192
+ /**
193
+ * Generate random bytes and encode them
194
+ */
195
195
  generateRandom(length = 32) {
196
- const wordArray = this.generateRandomWordArray(length);
197
- return this.encode(wordArray);
196
+ const buffer = randomBytes(length);
197
+ return this.encodeBuffer(buffer);
198
198
  }
199
- /*
199
+ /**
200
200
  * Generate a random key
201
- * @param length Length of the key
201
+ * @param length Length of the key in bytes
202
202
  * @default cryptoOptions.keyLength
203
- * @returns { key: string, length: number }
204
203
  */
205
204
  generateKey(length = this.options.keyLength) {
206
205
  return { key: this.generateRandom(length), length };
207
206
  }
208
- /*
207
+ /**
209
208
  * Generate a random salt
210
- * @param length Length of the salt
209
+ * @param length Length of the salt in bytes
211
210
  * @default cryptoOptions.saltLength
212
- * @returns { salt: string, length: number }
213
211
  */
214
212
  generateSalt(length = this.options.saltLength) {
215
213
  return { salt: this.generateRandom(length), length };
216
214
  }
217
- /*
215
+ /**
218
216
  * Generate a random IV
219
- * @param length Length of the IV
217
+ * @param length Length of the IV in bytes
220
218
  * @default cryptoOptions.ivLength
221
- * @returns { iv: string, length: number }
222
219
  */
223
220
  generateIV(length = this.options.ivLength) {
224
221
  return { iv: this.generateRandom(length), length };
225
222
  }
226
- encode(wordArray) {
223
+ encodeBuffer(buffer) {
227
224
  switch (this.options.encoding) {
228
225
  case "hex":
229
- return wordArray.toString(CryptoJS.enc.Hex);
226
+ return buffer.toString("hex");
230
227
  case "base64url":
231
- return wordArray.toString(CryptoJS.enc.Base64).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
228
+ return buffer.toString("base64url");
232
229
  case "base64":
233
230
  default:
234
- return wordArray.toString(CryptoJS.enc.Base64);
231
+ return buffer.toString("base64");
235
232
  }
236
233
  }
237
- decode(encoded) {
234
+ decodeToBuffer(encoded) {
238
235
  switch (this.options.encoding) {
239
236
  case "hex":
240
- return CryptoJS.enc.Hex.parse(encoded);
237
+ return Buffer.from(encoded, "hex");
241
238
  case "base64url":
242
- const base64 = encoded.replace(/-/g, "+").replace(/_/g, "/");
243
- const padding = "=".repeat((4 - base64.length % 4) % 4);
244
- return CryptoJS.enc.Base64.parse(base64 + padding);
239
+ return Buffer.from(encoded, "base64url");
245
240
  case "base64":
246
241
  default:
247
- return CryptoJS.enc.Base64.parse(encoded);
242
+ return Buffer.from(encoded, "base64");
248
243
  }
249
244
  }
250
245
  deriveKey(password, salt, keyLength) {
251
246
  if (this.options.kdf === "none") {
252
- return CryptoJS.enc.Hex.parse(password);
247
+ return Buffer.from(password, "hex");
253
248
  }
254
249
  const actualKeyLength = keyLength ?? this.options.keyLength;
255
- const keySize = actualKeyLength / 4;
256
- return CryptoJS.PBKDF2(password, salt, {
257
- keySize,
258
- iterations: this.options.iterations,
259
- hasher: this.getHasher()
260
- });
261
- }
262
- getHasher() {
263
- switch (this.options.hashAlgorithm) {
264
- case "sha512":
265
- return CryptoJS.algo.SHA512;
266
- case "sha384":
267
- return CryptoJS.algo.SHA384;
268
- case "sha256":
269
- default:
270
- return CryptoJS.algo.SHA256;
271
- }
272
- }
273
- getAESMode() {
274
- return CryptoJS.mode.CBC;
275
- }
276
- getPadding() {
277
- return CryptoJS.pad.Pkcs7;
250
+ return pbkdf2Sync(
251
+ password,
252
+ salt,
253
+ this.options.iterations,
254
+ actualKeyLength,
255
+ this.options.hashAlgorithm
256
+ );
278
257
  }
279
258
  /**
280
- * Encrypt data
259
+ * Encrypt data using AES-CBC
281
260
  * @param plainText Text to encrypt
282
- * @param secret Secret key for encryption Key length, salt, and IV will be randomly generated within configured range
261
+ * @param secret Secret key for encryption
262
+ * @param options Optional lengths for key, salt, and IV
283
263
  */
284
264
  encrypt(plainText, secret, {
285
265
  keyLength,
@@ -289,61 +269,48 @@ var CryptoService = class {
289
269
  keyLength = keyLength ?? this.options.keyLength;
290
270
  saltLength = saltLength ?? this.options.saltLength;
291
271
  ivLength = ivLength ?? this.options.ivLength;
292
- const salt = this.options.kdf !== "none" ? this.generateRandomWordArray(saltLength) : CryptoJS.lib.WordArray.create();
293
- const iv = this.generateRandomWordArray(ivLength);
272
+ const salt = this.options.kdf !== "none" ? randomBytes(saltLength) : Buffer.alloc(0);
273
+ const iv = randomBytes(ivLength);
294
274
  const key = this.deriveKey(secret, salt, keyLength);
295
- const encrypted = CryptoJS.AES.encrypt(plainText, key, {
296
- iv,
297
- mode: this.getAESMode(),
298
- padding: this.getPadding()
299
- });
300
- const actualSaltLength = salt.sigBytes;
301
- const keyLengthHex = keyLength.toString(16).padStart(4, "0");
302
- const saltLengthHex = actualSaltLength.toString(16).padStart(4, "0");
303
- const ivLengthHex = ivLength.toString(16).padStart(4, "0");
304
- const saltHex = salt.toString(CryptoJS.enc.Hex);
305
- const ivHex = iv.toString(CryptoJS.enc.Hex);
306
- const encryptedHex = encrypted.ciphertext.toString(CryptoJS.enc.Hex);
307
- const combined = keyLengthHex + saltLengthHex + ivLengthHex + saltHex + ivHex + encryptedHex;
308
- return this.encode(CryptoJS.enc.Hex.parse(combined));
275
+ const cipher = createCipheriv(this.options.algorithm, key, iv);
276
+ const encrypted = Buffer.concat([cipher.update(plainText, "utf8"), cipher.final()]);
277
+ const keyLengthBuf = Buffer.alloc(2);
278
+ keyLengthBuf.writeUInt16BE(keyLength);
279
+ const saltLengthBuf = Buffer.alloc(2);
280
+ saltLengthBuf.writeUInt16BE(salt.length);
281
+ const ivLengthBuf = Buffer.alloc(2);
282
+ ivLengthBuf.writeUInt16BE(ivLength);
283
+ const combined = Buffer.concat([keyLengthBuf, saltLengthBuf, ivLengthBuf, salt, iv, encrypted]);
284
+ return this.encodeBuffer(combined);
309
285
  }
310
286
  /**
311
287
  * Decrypt data
312
288
  * @param encryptedData Encrypted data to decrypt
313
289
  * @param secret Secret key for decryption
290
+ * @returns Decrypted string, or empty string if decryption fails (wrong password/corrupted data)
314
291
  */
315
292
  decrypt(encryptedData, secret) {
316
- const combined = this.decode(encryptedData);
317
- const combinedHex = combined.toString(CryptoJS.enc.Hex);
318
- let offset = 0;
319
- const keyLengthHex = combinedHex.substring(offset, offset + 4);
320
- offset += 4;
321
- const saltLengthHex = combinedHex.substring(offset, offset + 4);
322
- offset += 4;
323
- const ivLengthHex = combinedHex.substring(offset, offset + 4);
324
- offset += 4;
325
- const keyLength = parseInt(keyLengthHex, 16);
326
- const saltLength = parseInt(saltLengthHex, 16);
327
- const ivLength = parseInt(ivLengthHex, 16);
328
- const saltHexLength = saltLength * 2;
329
- const ivHexLength = ivLength * 2;
330
- const saltHex = saltHexLength > 0 ? combinedHex.substring(offset, offset + saltHexLength) : "";
331
- offset += saltHexLength;
332
- const ivHex = combinedHex.substring(offset, offset + ivHexLength);
333
- offset += ivHexLength;
334
- const encryptedHex = combinedHex.substring(offset);
335
- const salt = saltHex ? CryptoJS.enc.Hex.parse(saltHex) : CryptoJS.lib.WordArray.create();
336
- const iv = CryptoJS.enc.Hex.parse(ivHex);
337
- const encrypted = CryptoJS.lib.CipherParams.create({
338
- ciphertext: CryptoJS.enc.Hex.parse(encryptedHex)
339
- });
340
- const key = this.deriveKey(secret, salt, keyLength);
341
- const decrypted = CryptoJS.AES.decrypt(encrypted, key, {
342
- iv,
343
- mode: this.getAESMode(),
344
- padding: this.getPadding()
345
- });
346
- return decrypted.toString(CryptoJS.enc.Utf8);
293
+ try {
294
+ const combined = this.decodeToBuffer(encryptedData);
295
+ let offset = 0;
296
+ const keyLength = combined.readUInt16BE(offset);
297
+ offset += 2;
298
+ const saltLength = combined.readUInt16BE(offset);
299
+ offset += 2;
300
+ const ivLength = combined.readUInt16BE(offset);
301
+ offset += 2;
302
+ const salt = combined.subarray(offset, offset + saltLength);
303
+ offset += saltLength;
304
+ const iv = combined.subarray(offset, offset + ivLength);
305
+ offset += ivLength;
306
+ const encrypted = combined.subarray(offset);
307
+ const key = this.deriveKey(secret, salt, keyLength);
308
+ const decipher = createDecipheriv(this.options.algorithm, key, iv);
309
+ const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
310
+ return decrypted.toString("utf8");
311
+ } catch {
312
+ return "";
313
+ }
347
314
  }
348
315
  /**
349
316
  * Hash data (one-way)
@@ -352,19 +319,17 @@ var CryptoService = class {
352
319
  * @param salt Optional encoded salt string for deterministic hashing
353
320
  */
354
321
  hash(data, secret, salt) {
355
- const secretWordArray = CryptoJS.enc.Utf8.parse(secret);
356
- const hasher = this.getHasher();
357
- let saltWordArray;
322
+ let saltBuffer;
358
323
  let saltStr;
359
324
  if (salt) {
360
- saltWordArray = this.decode(salt);
325
+ saltBuffer = this.decodeToBuffer(salt);
361
326
  saltStr = salt;
362
327
  } else {
363
- saltWordArray = this.generateRandomWordArray(this.options.saltLength);
364
- saltStr = this.encode(saltWordArray);
328
+ saltBuffer = randomBytes(this.options.saltLength);
329
+ saltStr = this.encodeBuffer(saltBuffer);
365
330
  }
366
- const hash = hasher.create().update(data).update(secretWordArray).update(saltWordArray).finalize();
367
- const hashStr = this.encode(hash);
331
+ const hash = createHash(this.options.hashAlgorithm).update(data).update(secret).update(saltBuffer).digest();
332
+ const hashStr = this.encodeBuffer(hash);
368
333
  return `${saltStr}:${hashStr}`;
369
334
  }
370
335
  /**
@@ -378,11 +343,9 @@ var CryptoService = class {
378
343
  if (!saltStr || !expectedHashStr) {
379
344
  return false;
380
345
  }
381
- const salt = this.decode(saltStr);
382
- const secretWordArray = CryptoJS.enc.Utf8.parse(secret);
383
- const hasher = this.getHasher();
384
- const hash = hasher.create().update(data).update(secretWordArray).update(salt).finalize();
385
- const hashStr = this.encode(hash);
346
+ const saltBuffer = this.decodeToBuffer(saltStr);
347
+ const hash = createHash(this.options.hashAlgorithm).update(data).update(secret).update(saltBuffer).digest();
348
+ const hashStr = this.encodeBuffer(hash);
386
349
  return hashStr === expectedHashStr;
387
350
  }
388
351
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants/default.constant.ts","../src/types/events.types.ts","../src/utils/promise.util.ts","../src/utils/file.util.ts","../src/utils/string.util.ts","../src/utils/crypto.util.ts","../src/core/base.core.ts","../src/core/events.core.ts","../src/core/store.core.ts","../src/core/key-manager.core.ts","../src/core/module.core.ts","../src/index.ts"],"names":["EEvent"],"mappings":"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","file":"index.js","sourcesContent":["import { TEventsOptions, TModuleOptions, TStoreOptions } from 'src/types';\nimport { TBaseOptions } from 'src/types/base.type';\nimport { TCryptoOptions } from 'src/types/crypto.type';\nimport { TKeyManagerOptions } from 'src/types/key-manager.types';\n\nexport const DEFAULT_CRYPTO_OPTIONS: Required<TCryptoOptions> = {\n algorithm: 'aes-256-cbc',\n kdf: 'pbkdf2',\n hashAlgorithm: 'sha256',\n keyLength: 32,\n ivLength: 16,\n saltLength: 32,\n tagLength: 16,\n iterations: 100000,\n encoding: 'base64',\n};\n\nexport const DEFAULT_BASE_OPTIONS: Required<TBaseOptions> = {\n quiet: false,\n};\n\nexport const DEFAULT_BASE_LOGGER = (...args: any[]) => console.log(...args);\n\nexport const DEFAULT_EVENTS_OPTIONS: Required<TEventsOptions> = {\n ...DEFAULT_BASE_OPTIONS,\n\n // Event\n useEvent: true,\n};\n\nexport const DEFAULT_STORE_OPTIONS: Required<TStoreOptions> = {\n path: ['keys', '{{type}}'],\n file: ['v', '{{version}}'],\n fileSplitor: '_',\n fileExt: 'json',\n gitIgnore: true,\n\n ...DEFAULT_EVENTS_OPTIONS,\n\n // Key manager\n crypto: DEFAULT_CRYPTO_OPTIONS,\n};\n\nexport const DEFAULT_KEY_MANAGER_OPTIONS: Required<TKeyManagerOptions> = {\n // Store\n ...DEFAULT_STORE_OPTIONS,\n\n versionGenerator: () => new Date().getTime(),\n};\n\nexport const DEFAULT_MODULE_OPTIONS: Required<TModuleOptions> = {\n ...DEFAULT_KEY_MANAGER_OPTIONS,\n\n // Module\n quiet: false,\n};\n","import { TBaseOptions } from './base.type';\nimport { TKeyGenerated } from './key-manager.types';\n\nexport enum EEvent {\n STORE_INIT_FOLDER = 'store-init-folder',\n STORE_FILE_SAVED = 'saved-key-file',\n}\n\nexport type TEvents = {\n [EEvent.STORE_INIT_FOLDER]: {\n gitIgnoreStorePath?: string;\n gitIgnorePath?: string;\n gitIgnoreAddStatus?: 'already' | 'added';\n storePath: string;\n };\n [EEvent.STORE_FILE_SAVED]: { path: string; data: Record<string, TKeyGenerated> };\n};\n\nexport type TEventsOptions = Partial<TBaseOptions> & {\n /**\n * Is use event emitter\n * @default true\n */\n useEvent?: boolean;\n};\n","export const executePromisably = <T>(\n promiseOrFn: T | Promise<T> | ((...args: unknown[]) => T | Promise<T>)\n): Promise<T> => {\n try {\n const value =\n typeof promiseOrFn === 'function' && !(promiseOrFn instanceof Promise)\n ? (promiseOrFn as (...args: unknown[]) => T | Promise<T>)()\n : promiseOrFn;\n return Promise.resolve(value);\n } catch (error) {\n return Promise.reject(error);\n }\n};\n\nexport const promiseAll = <T extends readonly unknown[]>(\n ...fns: T\n): Promise<{ [K in keyof T]: Awaited<T[K]> }> => {\n return Promise.all(fns);\n};\n","import { access, mkdir, readFile, unlink, writeFile } from 'fs/promises';\nimport { dirname } from 'path';\n\nexport class FileUtilError extends Error {\n constructor(\n message: string,\n public readonly path: string,\n public readonly operation: 'read' | 'write' | 'delete' | 'access' | 'mkdir',\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = 'FileUtilError';\n }\n}\n\nexport class FileUtil {\n async getFolder(path: string): Promise<string> {\n try {\n await access(path);\n return path;\n } catch {\n try {\n await mkdir(path, { recursive: true });\n return path;\n } catch (error) {\n throw new FileUtilError(`Failed to create folder: ${path}`, path, 'mkdir', error);\n }\n }\n }\n\n async read(path: string, fallback?: string): Promise<string> {\n try {\n const data = await readFile(path, { encoding: 'utf8' });\n return data;\n } catch (error) {\n if (fallback !== undefined) return fallback;\n throw new FileUtilError(`Failed to read file: ${path}`, path, 'read', error);\n }\n }\n\n async write(path: string, data: string, flag: 'w' | 'a' = 'w'): Promise<void> {\n const dir = dirname(path);\n await this.getFolder(dir);\n\n try {\n await writeFile(path, data, { encoding: 'utf8', flag });\n } catch (error) {\n throw new FileUtilError(`Failed to write file: ${path}`, path, 'write', error);\n }\n }\n\n async checkExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n }\n\n async delete(path: string): Promise<void> {\n try {\n await unlink(path);\n } catch (error) {\n throw new FileUtilError(`Failed to delete file: ${path}`, path, 'delete', error);\n }\n }\n}\n","import { TKeyDurationUnit } from 'src/types/key-manager.types';\n\nconst getNested = (obj: Record<string, any>, path: string): any =>\n path.split('.').reduce((curr, key) => curr?.[key], obj);\n\nconst flatten = (obj: Record<string, any>, prefix = ''): Record<string, any> =>\n Object.entries(obj).reduce((acc, [key, val]) => {\n const newKey = prefix ? `${prefix}.${key}` : key;\n return val && typeof val === 'object' && !Array.isArray(val)\n ? { ...acc, ...flatten(val, newKey) }\n : { ...acc, [newKey]: val };\n }, {});\n\nconst stringify = (val: any): string => {\n if (val === null || val === undefined) return '';\n if (typeof val === 'object') return JSON.stringify(val);\n return String(val);\n};\n\nexport const bindString = (format: string, bindValues: Record<string, any>): string => {\n return format\n .replace(/\\{\\{\\.\\.\\.([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n\n return val && typeof val === 'object' && !Array.isArray(val)\n ? JSON.stringify(flatten(val, trimmedPath))\n : match;\n })\n .replace(/\\{\\{([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n\n // Skip if it's a spread syntax (already handled)\n if (trimmedPath.startsWith('...')) {\n return match;\n }\n\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n return stringify(val);\n });\n};\nexport const isDate = (data: string): boolean => {\n try {\n const date = new Date(data);\n return !isNaN(date.getTime());\n } catch (error) {\n return false;\n }\n};\n\nexport const addDuration = (date: Date, duration: number, unit: TKeyDurationUnit): Date => {\n const result = new Date(date.getTime());\n\n switch (unit) {\n case 'seconds':\n result.setSeconds(result.getSeconds() + duration);\n break;\n\n case 'minutes':\n result.setMinutes(result.getMinutes() + duration);\n break;\n\n case 'hours':\n result.setHours(result.getHours() + duration);\n break;\n\n case 'days':\n result.setDate(result.getDate() + duration);\n break;\n\n default: {\n const _exhaustiveCheck: never = unit;\n throw new Error(`Unsupported duration unit: ${_exhaustiveCheck}`);\n }\n }\n\n return result;\n};\n\nexport const isType = (data?: unknown) => {\n return {\n number: typeof data === 'number' && !Number.isNaN(Number(data)),\n string: typeof data === 'string',\n stringNumber:\n (typeof data === 'string' && !Number.isNaN(Number(data))) || typeof data === 'number',\n boolean: typeof data === 'boolean',\n null: data === null,\n undefined: data === undefined,\n };\n};\n","import CryptoJS from 'crypto-js';\nimport { DEFAULT_CRYPTO_OPTIONS } from 'src/constants/default.constant';\nimport { TCryptoOptions } from 'src/types/crypto.type';\n\nexport class CryptoService {\n private options: TCryptoOptions;\n\n constructor(options: Partial<TCryptoOptions> = {}) {\n this.options = { ...DEFAULT_CRYPTO_OPTIONS, ...options };\n }\n\n private generateRandomWordArray(length: number): CryptoJS.lib.WordArray {\n return CryptoJS.lib.WordArray.random(length);\n }\n\n generateRandom(length: number = 32): string {\n const wordArray = this.generateRandomWordArray(length);\n return this.encode(wordArray);\n }\n\n /*\n * Generate a random key\n * @param length Length of the key\n * @default cryptoOptions.keyLength\n * @returns { key: string, length: number }\n */\n generateKey(length: number = this.options.keyLength) {\n return { key: this.generateRandom(length), length } as const;\n }\n\n /*\n * Generate a random salt\n * @param length Length of the salt\n * @default cryptoOptions.saltLength\n * @returns { salt: string, length: number }\n */\n generateSalt(length: number = this.options.saltLength) {\n return { salt: this.generateRandom(length), length } as const;\n }\n\n /*\n * Generate a random IV\n * @param length Length of the IV\n * @default cryptoOptions.ivLength\n * @returns { iv: string, length: number }\n */\n generateIV(length: number = this.options.ivLength) {\n return { iv: this.generateRandom(length), length } as const;\n }\n\n private encode(wordArray: CryptoJS.lib.WordArray): string {\n switch (this.options.encoding) {\n case 'hex':\n return wordArray.toString(CryptoJS.enc.Hex);\n case 'base64url':\n return wordArray\n .toString(CryptoJS.enc.Base64)\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n case 'base64':\n default:\n return wordArray.toString(CryptoJS.enc.Base64);\n }\n }\n\n private decode(encoded: string): CryptoJS.lib.WordArray {\n switch (this.options.encoding) {\n case 'hex':\n return CryptoJS.enc.Hex.parse(encoded);\n case 'base64url':\n // Convert base64url to base64\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padding = '='.repeat((4 - (base64.length % 4)) % 4);\n return CryptoJS.enc.Base64.parse(base64 + padding);\n case 'base64':\n default:\n return CryptoJS.enc.Base64.parse(encoded);\n }\n }\n\n private deriveKey(\n password: string,\n salt: CryptoJS.lib.WordArray,\n keyLength?: number\n ): CryptoJS.lib.WordArray {\n if (this.options.kdf === 'none') {\n return CryptoJS.enc.Hex.parse(password);\n }\n\n const actualKeyLength = keyLength ?? this.options.keyLength;\n const keySize = actualKeyLength / 4;\n return CryptoJS.PBKDF2(password, salt, {\n keySize,\n iterations: this.options.iterations,\n hasher: this.getHasher(),\n });\n }\n\n private getHasher(): typeof CryptoJS.algo.SHA256 {\n switch (this.options.hashAlgorithm) {\n case 'sha512':\n return CryptoJS.algo.SHA512;\n case 'sha384':\n return CryptoJS.algo.SHA384;\n case 'sha256':\n default:\n return CryptoJS.algo.SHA256;\n }\n }\n\n private getAESMode(): typeof CryptoJS.mode.CBC {\n return CryptoJS.mode.CBC;\n }\n\n private getPadding(): typeof CryptoJS.pad.Pkcs7 {\n return CryptoJS.pad.Pkcs7;\n }\n\n /**\n * Encrypt data\n * @param plainText Text to encrypt\n * @param secret Secret key for encryption Key length, salt, and IV will be randomly generated within configured range\n */\n encrypt(\n plainText: string,\n secret: string,\n {\n keyLength,\n saltLength,\n ivLength,\n }: { keyLength?: number; saltLength?: number; ivLength?: number } = {}\n ): string {\n keyLength = keyLength ?? this.options.keyLength;\n saltLength = saltLength ?? this.options.saltLength;\n ivLength = ivLength ?? this.options.ivLength;\n\n const salt =\n this.options.kdf !== 'none'\n ? this.generateRandomWordArray(saltLength)\n : CryptoJS.lib.WordArray.create();\n const iv = this.generateRandomWordArray(ivLength);\n const key = this.deriveKey(secret, salt, keyLength);\n\n const encrypted = CryptoJS.AES.encrypt(plainText, key, {\n iv,\n mode: this.getAESMode(),\n padding: this.getPadding(),\n });\n\n const actualSaltLength = salt.sigBytes;\n const keyLengthHex = keyLength.toString(16).padStart(4, '0');\n const saltLengthHex = actualSaltLength.toString(16).padStart(4, '0');\n const ivLengthHex = ivLength.toString(16).padStart(4, '0');\n const saltHex = salt.toString(CryptoJS.enc.Hex);\n const ivHex = iv.toString(CryptoJS.enc.Hex);\n const encryptedHex = encrypted.ciphertext.toString(CryptoJS.enc.Hex);\n\n const combined = keyLengthHex + saltLengthHex + ivLengthHex + saltHex + ivHex + encryptedHex;\n return this.encode(CryptoJS.enc.Hex.parse(combined));\n }\n\n /**\n * Decrypt data\n * @param encryptedData Encrypted data to decrypt\n * @param secret Secret key for decryption\n */\n decrypt(encryptedData: string, secret: string): string {\n const combined = this.decode(encryptedData);\n const combinedHex = combined.toString(CryptoJS.enc.Hex);\n\n let offset = 0;\n\n // Read key, salt and IV lengths (4 hex chars = 2 bytes each)\n const keyLengthHex = combinedHex.substring(offset, offset + 4);\n offset += 4;\n const saltLengthHex = combinedHex.substring(offset, offset + 4);\n offset += 4;\n const ivLengthHex = combinedHex.substring(offset, offset + 4);\n offset += 4;\n\n const keyLength = parseInt(keyLengthHex, 16);\n const saltLength = parseInt(saltLengthHex, 16);\n const ivLength = parseInt(ivLengthHex, 16);\n\n // Read salt and IV based on their lengths stored in the encrypted data\n const saltHexLength = saltLength * 2; // hex is 2 chars per byte\n const ivHexLength = ivLength * 2;\n\n const saltHex = saltHexLength > 0 ? combinedHex.substring(offset, offset + saltHexLength) : '';\n offset += saltHexLength;\n\n const ivHex = combinedHex.substring(offset, offset + ivHexLength);\n offset += ivHexLength;\n\n const encryptedHex = combinedHex.substring(offset);\n\n const salt = saltHex ? CryptoJS.enc.Hex.parse(saltHex) : CryptoJS.lib.WordArray.create();\n const iv = CryptoJS.enc.Hex.parse(ivHex);\n const encrypted = CryptoJS.lib.CipherParams.create({\n ciphertext: CryptoJS.enc.Hex.parse(encryptedHex),\n });\n\n const key = this.deriveKey(secret, salt, keyLength);\n\n const decrypted = CryptoJS.AES.decrypt(encrypted, key, {\n iv,\n mode: this.getAESMode(),\n padding: this.getPadding(),\n });\n\n return decrypted.toString(CryptoJS.enc.Utf8);\n }\n\n /**\n * Hash data (one-way)\n * @param data Data to hash\n * @param secret Secret key used in hashing\n * @param salt Optional encoded salt string for deterministic hashing\n */\n hash(data: string, secret: string, salt?: string): string {\n const secretWordArray = CryptoJS.enc.Utf8.parse(secret);\n const hasher = this.getHasher();\n\n let saltWordArray: CryptoJS.lib.WordArray;\n let saltStr: string;\n\n if (salt) {\n // Deterministic mode: use provided salt\n saltWordArray = this.decode(salt);\n saltStr = salt;\n } else {\n // Non-deterministic mode: generate random salt\n saltWordArray = this.generateRandomWordArray(this.options.saltLength);\n saltStr = this.encode(saltWordArray);\n }\n\n const hash = hasher\n .create()\n .update(data)\n .update(secretWordArray)\n .update(saltWordArray)\n .finalize();\n\n const hashStr = this.encode(hash);\n\n return `${saltStr}:${hashStr}`;\n }\n\n /**\n * Verify hashed data\n * @param data Data to verify\n * @param hashedData Previously hashed data (format: salt:hash)\n * @param secret Secret key used during hashing\n */\n verifyHash(data: string, hashedData: string, secret: string): boolean {\n const [saltStr, expectedHashStr] = hashedData.split(':');\n if (!saltStr || !expectedHashStr) {\n return false;\n }\n\n const salt = this.decode(saltStr);\n const secretWordArray = CryptoJS.enc.Utf8.parse(secret);\n const hasher = this.getHasher();\n\n const hash = hasher.create().update(data).update(secretWordArray).update(salt).finalize();\n\n const hashStr = this.encode(hash);\n\n return hashStr === expectedHashStr;\n }\n}\n","import { DEFAULT_BASE_LOGGER, DEFAULT_BASE_OPTIONS } from 'src/constants/default.constant';\nimport { TBaseLogger, TBaseOptions, THook } from 'src/types/base.type';\n\ntype DefaultLogger = typeof DEFAULT_BASE_LOGGER;\n\nexport class Base<TLogger extends (...args: any[]) => any = DefaultLogger> {\n private logger: TBaseLogger<TLogger>;\n private bOptions: Required<TBaseOptions>;\n private hooks: Map<string, THook> = new Map();\n\n constructor(options: Partial<TBaseOptions>) {\n this.bOptions = { ...DEFAULT_BASE_OPTIONS, ...options };\n this.logger = DEFAULT_BASE_LOGGER as TBaseLogger<TLogger>;\n }\n\n protected getLogger(): TBaseLogger<TLogger> {\n return this.logger;\n }\n\n public setLogger(logger: TBaseLogger<TLogger>): this {\n this.logger = logger;\n return this;\n }\n\n public sysLog(...args: Parameters<TLogger>): this {\n if (!this.bOptions.quiet) {\n const result = this.logger(...args);\n if (result && typeof result === 'object' && 'catch' in result) {\n (result as Promise<unknown>).catch(() => {});\n }\n }\n return this;\n }\n\n public async customLog<T extends (...args: any[]) => any>(\n logger: TBaseLogger<T>,\n ...args: Parameters<T>\n ) {\n await logger(...args);\n return this;\n }\n\n protected setHooks<T extends Record<string, THook> = {}>(hooks: T) {\n Object.entries(hooks).forEach(([name, handler]) => {\n if (this.hooks.has(name)) {\n this.hooks.get('onHookOverriding')?.call(this, name);\n }\n\n this.hooks.set(name, handler);\n });\n return this;\n }\n\n protected runHook<Hooks extends Record<string, THook>, K extends keyof Hooks>(\n name: K,\n ...args: Parameters<Hooks[K]>\n ): ReturnType<Hooks[K]> {\n if (!this.hooks.has(name as string)) {\n this.hooks.get('onHookNotFound')?.call(this, name as string);\n return undefined as any;\n }\n\n return this.hooks.get(name as string)!.call(this, ...args);\n }\n\n protected getHooks(): Record<string, THook> {\n return Object.fromEntries(this.hooks.entries()) as Record<string, THook>;\n }\n}\n","import EventEmitter from 'node:events';\nimport { Base } from './base.core';\nimport { TEvents, TEventsOptions } from 'src/types';\nimport { DEFAULT_EVENTS_OPTIONS } from 'src/constants/default.constant';\n\nexport class Events extends Base {\n private events?: EventEmitter;\n private eOptions: Required<TEventsOptions>;\n\n constructor(options: TEventsOptions) {\n super(options);\n\n this.eOptions = {\n ...DEFAULT_EVENTS_OPTIONS,\n ...options,\n };\n\n if (this.eOptions.useEvent) {\n this.events = new EventEmitter();\n }\n }\n\n protected emit<K extends keyof TEvents>(event: K, args: TEvents[K]) {\n if (!this.events) return this;\n\n this.events.emit(event, args);\n return this;\n }\n\n on<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.on(event, listener);\n return this;\n }\n\n once<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.once(event, listener);\n return this;\n }\n\n off<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.off(event, listener);\n return this;\n }\n}\n","import { EEvent, TEvents, TFormatUsable, TGetKeyFn, TSaveKeyFn, TStoreOptions } from 'src/types';\nimport { FileUtil } from 'src/utils';\nimport { DEFAULT_STORE_OPTIONS } from 'src/constants/default.constant';\nimport { join } from 'path';\nimport { TKeyGenerated } from 'src/types/key-manager.types';\nimport { Events } from './events.core';\n\nexport class Store extends Events {\n private sOptions: Required<Omit<TStoreOptions, 'useEvent' | 'crypto'>>;\n private fileUtil: FileUtil;\n protected storePath?: string;\n protected saveKeyFn?: TSaveKeyFn;\n protected getKeyFn?: TGetKeyFn;\n\n constructor(options: Partial<TStoreOptions>) {\n super(options);\n\n this.sOptions = { ...DEFAULT_STORE_OPTIONS, ...options };\n this.fileUtil = new FileUtil();\n\n this.initStore();\n }\n\n protected getPath(path: string | string[], splitor: string): string {\n if (typeof path === 'object' && Array.isArray(path)) {\n return path.join(splitor);\n }\n\n return path;\n }\n\n private async getKeyStoreFolder(): Promise<string> {\n if (this.storePath) return this.storePath;\n\n const { path } = this.sOptions;\n\n const first =\n typeof path === 'object' && Array.isArray(path)\n ? path[0]\n : typeof path === 'string'\n ? (path.split('/')[0] ?? '')\n : '';\n\n let folder = await this.fileUtil.getFolder(join(process.cwd(), first));\n\n return folder;\n }\n\n protected async getKeyFileData(filePath: string): Promise<Record<string, TKeyGenerated>> {\n const existingData = await this.fileUtil.read(filePath, '{}');\n const savedData = this.toSavedData(existingData);\n\n return savedData;\n }\n\n protected async saveKeyFile(\n path: string,\n data: TKeyGenerated,\n merge: boolean = false\n ): Promise<string> {\n let savedData = await this.getKeyFileData(path);\n\n let saveData: Record<string, TKeyGenerated> = {};\n\n if (merge) {\n saveData = { ...savedData };\n }\n\n saveData = { ...saveData, [data.version]: data };\n\n await this.fileUtil.write(path, JSON.stringify(saveData, null, 2));\n\n this.emit(EEvent.STORE_FILE_SAVED, { path, data: saveData });\n\n return path;\n }\n\n /**\n * @param storePath custom store path\n * root folder of store\n * @returns this\n */\n public useStorePath(storePath: string): this {\n this.storePath = storePath;\n return this;\n }\n\n /**\n * @param saveKeyFn custom save key function\n * @returns this\n */\n public useSaveKey(saveKeyFn: TSaveKeyFn): this {\n this.saveKeyFn = saveKeyFn;\n return this;\n }\n\n /**\n * @param saveKeyFn custom get key function\n * @returns this\n */\n public useGetKey(getKeyFn: TGetKeyFn): this {\n this.getKeyFn = getKeyFn;\n return this;\n }\n\n private async initStore(): Promise<void> {\n const storePath = await this.getKeyStoreFolder();\n\n let eventEmitPayload: TEvents[EEvent.STORE_INIT_FOLDER] = {\n storePath,\n };\n\n if (this.sOptions.gitIgnore) {\n const gitignore = await this.addStoreFolderGitignore();\n eventEmitPayload = { ...eventEmitPayload, ...gitignore };\n }\n\n this.emit(EEvent.STORE_INIT_FOLDER, eventEmitPayload);\n }\n\n private toSavedData(dataString: string): Record<string, TKeyGenerated> {\n try {\n if (!dataString) return {};\n const parsedData = JSON.parse(dataString) as Record<string, TKeyGenerated>;\n\n if (typeof parsedData !== 'object' || Array.isArray(parsedData)) {\n throw new Error('Invalid JSON data (must be Record<version, TKeyGenerated>)');\n }\n\n return parsedData;\n } catch (error) {\n throw new Error(`Invalid JSON data (must be Record<version, TKeyGenerated>) ${dataString}`);\n }\n }\n\n private async addStoreFolderGitignore(): Promise<\n Omit<TEvents[EEvent.STORE_INIT_FOLDER], 'storePath'>\n > {\n const gitignorePath = join(process.cwd(), '.gitignore');\n const gitignoreContent = await this.fileUtil.read(gitignorePath);\n\n const folder = this.getStoreFolderGitignore();\n const gitignoreLines = gitignoreContent.split(/\\r?\\n/).map((line) => line.trim());\n const hasExactLine = gitignoreLines.some((line) => line === folder);\n\n if (!hasExactLine) {\n await this.fileUtil.write(gitignorePath, `${gitignoreContent ? '\\r\\n' : ''}${folder}`, 'a');\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'added',\n };\n }\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'already',\n };\n }\n\n private getStoreFolderGitignore() {\n let folder = '';\n const storePath = this.getPath(this.sOptions.path, '/');\n\n if (typeof this.sOptions.gitIgnore === 'boolean') {\n folder = this.getStoreFolderGitignoreByDefault(storePath);\n } else {\n folder = this.addStoreFolderGitignoreByCustom(this.sOptions.gitIgnore);\n }\n\n return this.replaceVariableToStar(folder);\n }\n\n private getStoreFolderGitignoreByDefault(storePath: string) {\n const filePath = this.getPath(this.sOptions.file, this.sOptions.fileSplitor);\n\n const folder: string[] = [storePath];\n folder.push(`${filePath}.${this.sOptions.fileExt}`);\n\n return folder.join('/');\n }\n\n private addStoreFolderGitignoreByCustom(ignorePath: TFormatUsable) {\n return this.getPath(ignorePath, '/');\n }\n\n private replaceVariableToStar(path: string): string {\n return path.replace(/\\{\\{.*?\\}\\}/g, '*');\n }\n}\n","import {\n TGenerateKeyOptions,\n TGetKey,\n TGetKeyOptions,\n TKeyGenerated,\n TKeyManagerHooks,\n TKeyManagerOptions,\n TKeyVariables,\n} from 'src/types/key-manager.types';\nimport { Store } from './store.core';\nimport {\n CryptoService,\n executePromisably,\n addDuration,\n bindString,\n isDate,\n isType,\n} from 'src/utils';\nimport { DEFAULT_KEY_MANAGER_OPTIONS } from 'src/constants/default.constant';\n\nexport class KeyManager extends Store {\n private cryptoService: CryptoService;\n private kOptions: Required<TKeyManagerOptions>;\n\n constructor(options: Partial<TKeyManagerOptions>) {\n super(options);\n\n this.kOptions = { ...DEFAULT_KEY_MANAGER_OPTIONS, ...options };\n this.cryptoService = new CryptoService(this.kOptions.crypto);\n }\n\n /**\n * Retrieve and validate a stored key by path and version.\n *\n * This method:\n * - Loads a key from the configured store\n * - Validates structure, type safety, and time constraints\n * - Detects expiration and rotation eligibility\n * - Optionally auto-rotates an expired key if rotation options are provided\n *\n * If the key is expired and marked as rotatable, a new key will be generated\n * automatically using the provided `onRotate` options.\n *\n * @param options Configuration for key retrieval\n * @param options.path Storage path of the key\n * @param options.version Specific key version to retrieve\n * @param options.onRotate Optional rotation configuration used when the key\n * is expired and renewable\n *\n * @returns An object containing:\n * - `ready`: The valid (usable) key, or the newly generated key after rotation\n * - `expired`: The expired key if rotation occurred, otherwise `null`\n *\n * @throws Error if:\n * - The key does not exist\n * - The key structure or fields are invalid\n * - The key is expired but rotation options are missing\n * - The key is not yet valid or otherwise unusable\n *\n * @example\n * ```ts\n * const { ready, expired } = await keyManager.getKey({\n * path: '/keys/api',\n * version: 'v1',\n * // This define the new key attributes: is it rotate? Durations and unit?\n * onRotate: {\n * duration: 30,\n * unit: 'days',\n * rotate: true,\n * },\n * });\n *\n * if (expired) {\n * console.log('Key was rotated from version:', expired.version);\n * }\n *\n * // Use expired?.key ?? ready?.key safely\n * ```\n */\n public async getKey(options: TGetKeyOptions): Promise<TGetKey> {\n const { path, version } = options;\n\n const key = await this.getKeyByStore(path, String(version));\n\n if (!key) {\n this.runKeyHook('onKeyNotFound', path, version);\n this.sysLog(`Key not found!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);\n\n if (!ok && isExpired && isRenewable && key) {\n if (!options.onRotate) {\n this.runKeyHook('onKeyMissingRotateOption', key, options);\n this.sysLog(`Key missing rotate option!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const renew = await this.newKey({\n type: key.type,\n ...options.onRotate,\n });\n\n const resGetKey = { expired: key, ready: renew.key };\n\n this.runKeyHook('onKeyRenewed', resGetKey, options);\n this.sysLog(`Key renewed!`, { path, version });\n return resGetKey;\n }\n\n if (!ok && isExpired && !isRenewable && key) {\n this.runKeyHook('onKeyExpired', path, key);\n this.sysLog(`Key expired!`, { path, version });\n return { expired: key, ready: null };\n }\n\n if (!ok) {\n this.runKeyHook('onKeyInvalid', key, message, errorOn);\n this.sysLog(`Key invalid!`, { path, version });\n return { expired: null, ready: null };\n }\n\n return { expired: null, ready: key };\n }\n\n /**\n * Generate a new cryptographic key and persist it to the configured store.\n *\n * This method:\n * - Generates a random origin key\n * - Hashes the key using the configured crypto options\n * - Calculates an expiration time (if provided)\n * - Assigns versioning and rotation metadata\n * - Saves the generated key to storage\n * - The hashed key will follow this format: `salt-buffer:hashed`\n *\n * @param options Configuration for key generation\n * @param options.type Logical key type (e.g. api, session, encryption, etc.)\n * @param options.duration Optional lifetime value for the key\n * @param options.unit Time unit for the duration (seconds | minutes | hours | days)\n * @param options.rotate Whether this key should participate in key rotation\n * @param options.merge Whether to merge with an existing stored key (if supported)\n *\n * @param variables Optional variables used for dynamic path or filename resolution\n *\n * @returns An object containing:\n * - `key`: The generated key metadata and raw key value\n * - `path`: The storage path where the key was saved\n *\n * @example\n * ```ts\n * const { key, path } = await keyManager.newKey(\n * {\n * type: 'api',\n * duration: 30, <- Optional\n * unit: 'days', <- Optional\n * rotate: true, <- Optional\n * },\n * { env: 'production', ... }\n * );\n * ```\n */\n public async newKey(\n options: TGenerateKeyOptions,\n variables: TKeyVariables = {}\n ): Promise<{ key: TKeyGenerated; path: string }> {\n const { rotate, duration, type, unit, merge, keyLength } = options;\n\n const { key, length: kLength } = this.cryptoService.generateKey(keyLength);\n const { salt } = this.cryptoService.generateSalt();\n\n this.sysLog(`Key generated\\nOptions:`, options);\n\n const hashedKey = this.cryptoService.hash(key, salt);\n const now = new Date();\n\n const keyGenerated: TKeyGenerated = {\n from: now.toISOString(),\n to: duration && unit ? addDuration(now, duration, unit).toISOString() : 'NON_EXPIRED',\n key: key,\n hashed: hashedKey,\n hashedBytes: kLength,\n type,\n version: await executePromisably(this.kOptions.versionGenerator()),\n rotate: !!rotate,\n };\n\n const path = await this.saveKeyToStore(keyGenerated, !!merge, variables);\n this.sysLog(`Key saved!`, {\n path,\n version: keyGenerated.version,\n type: keyGenerated.type,\n });\n\n return { key: keyGenerated, path };\n }\n\n private async getKeyByStore(path: string, version: string): Promise<TKeyGenerated | null> {\n if (this.getKeyFn) {\n return this.getKeyFn(path, version);\n }\n\n const savedData = await this.getKeyFileData(path);\n return savedData[version] ?? null;\n }\n\n private async saveKeyToStore(\n key: TKeyGenerated,\n merge: boolean,\n variables: TKeyVariables\n ): Promise<string> {\n return (this.saveKeyFn?.bind(this) ?? this.saveKeyFile.bind(this))(\n this.getFilename({ ...variables, version: key.version, type: key.type }),\n key,\n merge\n );\n }\n\n private validateKey(keyGenerated: Partial<TKeyGenerated>): {\n ok: boolean;\n message: string;\n errorOn?: keyof TKeyGenerated;\n isExpired?: boolean;\n isRenewable?: boolean;\n } {\n const requiredKeyGenerated = keyGenerated as TKeyGenerated;\n\n const typeChecks: Record<keyof TKeyGenerated, keyof ReturnType<typeof isType>> = {\n from: 'string',\n to: 'string',\n key: 'string',\n hashed: 'string',\n rotate: 'boolean',\n type: 'string',\n version: 'stringNumber',\n hashedBytes: 'number',\n };\n\n for (const [field, type] of Object.entries(typeChecks) as Array<\n [field: keyof TKeyGenerated, type: keyof ReturnType<typeof isType>]\n >) {\n if (!isType(requiredKeyGenerated[field])[type])\n return { ok: false, message: `${field} is not valid`, errorOn: field };\n }\n\n if (!isDate(requiredKeyGenerated.from)) {\n return { ok: false, message: 'From date is not valid!', errorOn: 'from' };\n } else if (new Date(requiredKeyGenerated.from) > new Date()) {\n return { ok: false, message: 'Key is not started!' };\n }\n\n if (!isDate(requiredKeyGenerated.to)) {\n if (requiredKeyGenerated.to !== 'NON_EXPIRED') {\n return { ok: false, message: 'Expire date is not valid!', errorOn: 'to' };\n }\n } else if (new Date(requiredKeyGenerated.to) < new Date()) {\n return {\n ok: false,\n message: 'Key is expired',\n errorOn: 'to',\n isExpired: true,\n isRenewable: !!requiredKeyGenerated.rotate,\n };\n }\n\n if (requiredKeyGenerated.hashedBytes < 0)\n return {\n ok: false,\n message: 'Invalid hashedBytes range',\n errorOn: 'hashedBytes',\n };\n\n return { ok: true, message: '' };\n }\n\n private getFilename(variables: TKeyVariables) {\n return bindString(\n bindString(`{{root}}/{{filename}}.{{ext}}`, {\n root: this.getPath(this.kOptions.path, '/'),\n filename: this.getPath(this.kOptions.file, this.kOptions.fileSplitor),\n ext: this.kOptions.fileExt,\n }),\n variables\n );\n }\n\n private runKeyHook<K extends keyof TKeyManagerHooks>(\n name: K,\n ...args: Parameters<TKeyManagerHooks[K]>\n ): ReturnType<TKeyManagerHooks[K]> {\n return this.runHook<TKeyManagerHooks, K>(name, ...args);\n }\n}\n","import { TModuleHooks, TModuleOptions } from 'src/types';\nimport { DEFAULT_MODULE_OPTIONS } from 'src/constants/default.constant';\nimport { KeyManager } from './key-manager.core';\n\nexport class KM extends KeyManager {\n private options: Required<TModuleOptions>;\n\n constructor(options: Partial<TModuleOptions>) {\n super(options);\n\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n }\n\n public setOptions(options: TModuleOptions): this {\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n return this;\n }\n\n public getOptions(): TModuleOptions | undefined {\n return this.options;\n }\n\n /**\n *\n * @param instance: use instance options to create new instance\n * @param extend: overide options\n * @returns new instance\n */\n public clone(extend: Partial<TModuleOptions> = {}): KM {\n const module = new KM({ ...this.getOptions(), ...extend });\n\n if (this.saveKeyFn) module.useSaveKey(this.saveKeyFn);\n if (this.getKeyFn) module.useGetKey(this.getKeyFn);\n if (this.storePath) module.useStorePath(this.storePath);\n\n module.setHooks(this.getHooks());\n module.setLogger(this.getLogger());\n\n return module;\n }\n\n public useHooks(hooks: Partial<{ [x in keyof TModuleHooks]: TModuleHooks[x] }>) {\n this.setHooks(hooks);\n return this;\n }\n\n public setHook<HookName extends keyof TModuleHooks>(\n name: HookName,\n handler: TModuleHooks[HookName]\n ) {\n this.setHooks({ [name]: handler });\n return this;\n }\n}\n","import { KM } from './core/module.core';\nimport * as types from './types';\nexport * from './types';\n\nlet instance: KM | null = null;\n\n/**\n * Create a new KeyManager instance\n * @param options - Options to configure the instance\n * @param singleton - If true, returns a shared singleton instance; if false, creates a new instance\n * @returns KM instance\n */\nexport const create = (\n options: Partial<types.TModuleOptions> = {},\n singleton: boolean = false\n): KM => {\n if (!singleton) return new KM(options);\n\n if (!instance) {\n instance = new KM(options);\n }\n\n return instance;\n};\n\n/**\n * @alias create()\n */\nexport const km = create;\nexport type { KM };\n"]}
1
+ {"version":3,"sources":["../src/constants/default.constant.ts","../src/types/events.types.ts","../src/utils/promise.util.ts","../src/utils/file.util.ts","../src/utils/string.util.ts","../src/utils/crypto.util.ts","../src/core/base.core.ts","../src/core/events.core.ts","../src/core/store.core.ts","../src/core/key-manager.core.ts","../src/core/module.core.ts","../src/index.ts"],"names":["EEvent"],"mappings":"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","file":"index.js","sourcesContent":["import { TEventsOptions, TModuleOptions, TStoreOptions } from 'src/types';\nimport { TBaseOptions } from 'src/types/base.type';\nimport { TCryptoOptions } from 'src/types/crypto.type';\nimport { TKeyManagerOptions } from 'src/types/key-manager.types';\n\nexport const DEFAULT_CRYPTO_OPTIONS: Required<TCryptoOptions> = {\n algorithm: 'aes-256-cbc',\n kdf: 'pbkdf2',\n hashAlgorithm: 'sha256',\n keyLength: 32,\n ivLength: 16,\n saltLength: 32,\n tagLength: 16,\n iterations: 100000,\n encoding: 'base64',\n};\n\nexport const DEFAULT_BASE_OPTIONS: Required<TBaseOptions> = {\n quiet: false,\n};\n\nexport const DEFAULT_BASE_LOGGER = (...args: any[]) => console.log(...args);\n\nexport const DEFAULT_EVENTS_OPTIONS: Required<TEventsOptions> = {\n ...DEFAULT_BASE_OPTIONS,\n\n // Event\n useEvent: true,\n};\n\nexport const DEFAULT_STORE_OPTIONS: Required<TStoreOptions> = {\n path: ['keys', '{{type}}'],\n file: ['v', '{{version}}'],\n fileSplitor: '_',\n fileExt: 'json',\n gitIgnore: true,\n\n ...DEFAULT_EVENTS_OPTIONS,\n\n // Key manager\n crypto: DEFAULT_CRYPTO_OPTIONS,\n};\n\nexport const DEFAULT_KEY_MANAGER_OPTIONS: Required<TKeyManagerOptions> = {\n // Store\n ...DEFAULT_STORE_OPTIONS,\n\n versionGenerator: () => new Date().getTime(),\n};\n\nexport const DEFAULT_MODULE_OPTIONS: Required<TModuleOptions> = {\n ...DEFAULT_KEY_MANAGER_OPTIONS,\n\n // Module\n quiet: false,\n};\n","import { TBaseOptions } from './base.type';\nimport { TKeyGenerated } from './key-manager.types';\n\nexport enum EEvent {\n STORE_INIT_FOLDER = 'store-init-folder',\n STORE_FILE_SAVED = 'saved-key-file',\n}\n\nexport type TEvents = {\n [EEvent.STORE_INIT_FOLDER]: {\n gitIgnoreStorePath?: string;\n gitIgnorePath?: string;\n gitIgnoreAddStatus?: 'already' | 'added';\n storePath: string;\n };\n [EEvent.STORE_FILE_SAVED]: { path: string; data: Record<string, TKeyGenerated> };\n};\n\nexport type TEventsOptions = Partial<TBaseOptions> & {\n /**\n * Is use event emitter\n * @default true\n */\n useEvent?: boolean;\n};\n","export const executePromisably = <T>(\n promiseOrFn: T | Promise<T> | ((...args: unknown[]) => T | Promise<T>)\n): Promise<T> => {\n try {\n const value =\n typeof promiseOrFn === 'function' && !(promiseOrFn instanceof Promise)\n ? (promiseOrFn as (...args: unknown[]) => T | Promise<T>)()\n : promiseOrFn;\n return Promise.resolve(value);\n } catch (error) {\n return Promise.reject(error);\n }\n};\n\nexport const promiseAll = <T extends readonly unknown[]>(\n ...fns: T\n): Promise<{ [K in keyof T]: Awaited<T[K]> }> => {\n return Promise.all(fns);\n};\n","import { access, mkdir, readFile, unlink, writeFile } from 'fs/promises';\nimport { dirname } from 'path';\n\nexport class FileUtilError extends Error {\n constructor(\n message: string,\n public readonly path: string,\n public readonly operation: 'read' | 'write' | 'delete' | 'access' | 'mkdir',\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = 'FileUtilError';\n }\n}\n\nexport class FileUtil {\n async getFolder(path: string): Promise<string> {\n try {\n await access(path);\n return path;\n } catch {\n try {\n await mkdir(path, { recursive: true });\n return path;\n } catch (error) {\n throw new FileUtilError(`Failed to create folder: ${path}`, path, 'mkdir', error);\n }\n }\n }\n\n async read(path: string, fallback?: string): Promise<string> {\n try {\n const data = await readFile(path, { encoding: 'utf8' });\n return data;\n } catch (error) {\n if (fallback !== undefined) return fallback;\n throw new FileUtilError(`Failed to read file: ${path}`, path, 'read', error);\n }\n }\n\n async write(path: string, data: string, flag: 'w' | 'a' = 'w'): Promise<void> {\n const dir = dirname(path);\n await this.getFolder(dir);\n\n try {\n await writeFile(path, data, { encoding: 'utf8', flag });\n } catch (error) {\n throw new FileUtilError(`Failed to write file: ${path}`, path, 'write', error);\n }\n }\n\n async checkExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n }\n\n async delete(path: string): Promise<void> {\n try {\n await unlink(path);\n } catch (error) {\n throw new FileUtilError(`Failed to delete file: ${path}`, path, 'delete', error);\n }\n }\n}\n","import { TKeyDurationUnit } from 'src/types/key-manager.types';\n\nconst getNested = (obj: Record<string, any>, path: string): any =>\n path.split('.').reduce((curr, key) => curr?.[key], obj);\n\nconst flatten = (obj: Record<string, any>, prefix = ''): Record<string, any> =>\n Object.entries(obj).reduce((acc, [key, val]) => {\n const newKey = prefix ? `${prefix}.${key}` : key;\n return val && typeof val === 'object' && !Array.isArray(val)\n ? { ...acc, ...flatten(val, newKey) }\n : { ...acc, [newKey]: val };\n }, {});\n\nconst stringify = (val: any): string => {\n if (val === null || val === undefined) return '';\n if (typeof val === 'object') return JSON.stringify(val);\n return String(val);\n};\n\nexport const bindString = (format: string, bindValues: Record<string, any>): string => {\n return format\n .replace(/\\{\\{\\.\\.\\.([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n\n return val && typeof val === 'object' && !Array.isArray(val)\n ? JSON.stringify(flatten(val, trimmedPath))\n : match;\n })\n .replace(/\\{\\{([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n\n // Skip if it's a spread syntax (already handled)\n if (trimmedPath.startsWith('...')) {\n return match;\n }\n\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n return stringify(val);\n });\n};\nexport const isDate = (data: string): boolean => {\n try {\n const date = new Date(data);\n return !isNaN(date.getTime());\n } catch (error) {\n return false;\n }\n};\n\nexport const addDuration = (date: Date, duration: number, unit: TKeyDurationUnit): Date => {\n const result = new Date(date.getTime());\n\n switch (unit) {\n case 'seconds':\n result.setSeconds(result.getSeconds() + duration);\n break;\n\n case 'minutes':\n result.setMinutes(result.getMinutes() + duration);\n break;\n\n case 'hours':\n result.setHours(result.getHours() + duration);\n break;\n\n case 'days':\n result.setDate(result.getDate() + duration);\n break;\n\n default: {\n const _exhaustiveCheck: never = unit;\n throw new Error(`Unsupported duration unit: ${_exhaustiveCheck}`);\n }\n }\n\n return result;\n};\n\nexport const isType = (data?: unknown) => {\n return {\n number: typeof data === 'number' && !Number.isNaN(Number(data)),\n string: typeof data === 'string',\n stringNumber: typeof data === 'string' || typeof data === 'number',\n boolean: typeof data === 'boolean',\n null: data === null,\n undefined: data === undefined,\n };\n};\n","import { randomBytes, pbkdf2Sync, createCipheriv, createDecipheriv, createHash } from 'node:crypto';\nimport { DEFAULT_CRYPTO_OPTIONS } from 'src/constants/default.constant';\nimport { TCryptoOptions } from 'src/types/crypto.type';\n\nexport class CryptoService {\n private options: Required<TCryptoOptions>;\n\n constructor(options: Partial<TCryptoOptions> = {}) {\n this.options = { ...DEFAULT_CRYPTO_OPTIONS, ...options };\n }\n\n /**\n * Generate random bytes and encode them\n */\n generateRandom(length: number = 32): string {\n const buffer = randomBytes(length);\n return this.encodeBuffer(buffer);\n }\n\n /**\n * Generate a random key\n * @param length Length of the key in bytes\n * @default cryptoOptions.keyLength\n */\n generateKey(length: number = this.options.keyLength) {\n return { key: this.generateRandom(length), length } as const;\n }\n\n /**\n * Generate a random salt\n * @param length Length of the salt in bytes\n * @default cryptoOptions.saltLength\n */\n generateSalt(length: number = this.options.saltLength) {\n return { salt: this.generateRandom(length), length } as const;\n }\n\n /**\n * Generate a random IV\n * @param length Length of the IV in bytes\n * @default cryptoOptions.ivLength\n */\n generateIV(length: number = this.options.ivLength) {\n return { iv: this.generateRandom(length), length } as const;\n }\n\n private encodeBuffer(buffer: Buffer): string {\n switch (this.options.encoding) {\n case 'hex':\n return buffer.toString('hex');\n case 'base64url':\n return buffer.toString('base64url');\n case 'base64':\n default:\n return buffer.toString('base64');\n }\n }\n\n private decodeToBuffer(encoded: string): Buffer {\n switch (this.options.encoding) {\n case 'hex':\n return Buffer.from(encoded, 'hex');\n case 'base64url':\n return Buffer.from(encoded, 'base64url');\n case 'base64':\n default:\n return Buffer.from(encoded, 'base64');\n }\n }\n\n private deriveKey(password: string, salt: Buffer, keyLength?: number): Buffer {\n if (this.options.kdf === 'none') {\n return Buffer.from(password, 'hex');\n }\n\n const actualKeyLength = keyLength ?? this.options.keyLength;\n return pbkdf2Sync(\n password,\n salt,\n this.options.iterations,\n actualKeyLength,\n this.options.hashAlgorithm\n );\n }\n\n /**\n * Encrypt data using AES-CBC\n * @param plainText Text to encrypt\n * @param secret Secret key for encryption\n * @param options Optional lengths for key, salt, and IV\n */\n encrypt(\n plainText: string,\n secret: string,\n {\n keyLength,\n saltLength,\n ivLength,\n }: { keyLength?: number; saltLength?: number; ivLength?: number } = {}\n ): string {\n keyLength = keyLength ?? this.options.keyLength;\n saltLength = saltLength ?? this.options.saltLength;\n ivLength = ivLength ?? this.options.ivLength;\n\n const salt = this.options.kdf !== 'none' ? randomBytes(saltLength) : Buffer.alloc(0);\n const iv = randomBytes(ivLength);\n const key = this.deriveKey(secret, salt, keyLength);\n\n const cipher = createCipheriv(this.options.algorithm, key, iv);\n const encrypted = Buffer.concat([cipher.update(plainText, 'utf8'), cipher.final()]);\n\n // Pack: keyLength(2) + saltLength(2) + ivLength(2) + salt + iv + encrypted\n const keyLengthBuf = Buffer.alloc(2);\n keyLengthBuf.writeUInt16BE(keyLength);\n\n const saltLengthBuf = Buffer.alloc(2);\n saltLengthBuf.writeUInt16BE(salt.length);\n\n const ivLengthBuf = Buffer.alloc(2);\n ivLengthBuf.writeUInt16BE(ivLength);\n\n const combined = Buffer.concat([keyLengthBuf, saltLengthBuf, ivLengthBuf, salt, iv, encrypted]);\n\n return this.encodeBuffer(combined);\n }\n\n /**\n * Decrypt data\n * @param encryptedData Encrypted data to decrypt\n * @param secret Secret key for decryption\n * @returns Decrypted string, or empty string if decryption fails (wrong password/corrupted data)\n */\n decrypt(encryptedData: string, secret: string): string {\n try {\n const combined = this.decodeToBuffer(encryptedData);\n let offset = 0;\n\n // Read lengths (2 bytes each)\n const keyLength = combined.readUInt16BE(offset);\n offset += 2;\n const saltLength = combined.readUInt16BE(offset);\n offset += 2;\n const ivLength = combined.readUInt16BE(offset);\n offset += 2;\n\n // Read salt, iv, and encrypted data\n const salt = combined.subarray(offset, offset + saltLength);\n offset += saltLength;\n\n const iv = combined.subarray(offset, offset + ivLength);\n offset += ivLength;\n\n const encrypted = combined.subarray(offset);\n\n const key = this.deriveKey(secret, salt, keyLength);\n\n const decipher = createDecipheriv(this.options.algorithm, key, iv);\n const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);\n\n return decrypted.toString('utf8');\n } catch {\n // Return empty string on decryption failure (wrong password, corrupted data, etc.)\n // This matches the behavior of crypto-js\n return '';\n }\n }\n\n /**\n * Hash data (one-way)\n * @param data Data to hash\n * @param secret Secret key used in hashing\n * @param salt Optional encoded salt string for deterministic hashing\n */\n hash(data: string, secret: string, salt?: string): string {\n let saltBuffer: Buffer;\n let saltStr: string;\n\n if (salt) {\n // Deterministic mode: use provided salt\n saltBuffer = this.decodeToBuffer(salt);\n saltStr = salt;\n } else {\n // Non-deterministic mode: generate random salt\n saltBuffer = randomBytes(this.options.saltLength);\n saltStr = this.encodeBuffer(saltBuffer);\n }\n\n const hash = createHash(this.options.hashAlgorithm)\n .update(data)\n .update(secret)\n .update(saltBuffer)\n .digest();\n\n const hashStr = this.encodeBuffer(hash);\n\n return `${saltStr}:${hashStr}`;\n }\n\n /**\n * Verify hashed data\n * @param data Data to verify\n * @param hashedData Previously hashed data (format: salt:hash)\n * @param secret Secret key used during hashing\n */\n verifyHash(data: string, hashedData: string, secret: string): boolean {\n const [saltStr, expectedHashStr] = hashedData.split(':');\n if (!saltStr || !expectedHashStr) {\n return false;\n }\n\n const saltBuffer = this.decodeToBuffer(saltStr);\n\n const hash = createHash(this.options.hashAlgorithm)\n .update(data)\n .update(secret)\n .update(saltBuffer)\n .digest();\n\n const hashStr = this.encodeBuffer(hash);\n\n // Use timing-safe comparison\n return hashStr === expectedHashStr;\n }\n}\n","import { DEFAULT_BASE_LOGGER, DEFAULT_BASE_OPTIONS } from 'src/constants/default.constant';\nimport { TBaseLogger, TBaseOptions, THook } from 'src/types/base.type';\n\ntype DefaultLogger = typeof DEFAULT_BASE_LOGGER;\n\nexport class Base<TLogger extends (...args: any[]) => any = DefaultLogger> {\n private logger: TBaseLogger<TLogger>;\n private bOptions: Required<TBaseOptions>;\n private hooks: Map<string, THook> = new Map();\n\n constructor(options: Partial<TBaseOptions>) {\n this.bOptions = { ...DEFAULT_BASE_OPTIONS, ...options };\n this.logger = DEFAULT_BASE_LOGGER as TBaseLogger<TLogger>;\n }\n\n protected getLogger(): TBaseLogger<TLogger> {\n return this.logger;\n }\n\n public setLogger(logger: TBaseLogger<TLogger>): this {\n this.logger = logger;\n return this;\n }\n\n public sysLog(...args: Parameters<TLogger>): this {\n if (!this.bOptions.quiet) {\n const result = this.logger(...args);\n if (result && typeof result === 'object' && 'catch' in result) {\n (result as Promise<unknown>).catch(() => {});\n }\n }\n return this;\n }\n\n public async customLog<T extends (...args: any[]) => any>(\n logger: TBaseLogger<T>,\n ...args: Parameters<T>\n ) {\n await logger(...args);\n return this;\n }\n\n protected setHooks<T extends Record<string, THook> = {}>(hooks: T) {\n Object.entries(hooks).forEach(([name, handler]) => {\n if (this.hooks.has(name)) {\n this.hooks.get('onHookOverriding')?.call(this, name);\n }\n\n this.hooks.set(name, handler);\n });\n return this;\n }\n\n protected runHook<Hooks extends Record<string, THook>, K extends keyof Hooks>(\n name: K,\n ...args: Parameters<Hooks[K]>\n ): ReturnType<Hooks[K]> {\n if (!this.hooks.has(name as string)) {\n this.hooks.get('onHookNotFound')?.call(this, name as string);\n return undefined as any;\n }\n\n return this.hooks.get(name as string)!.call(this, ...args);\n }\n\n protected getHooks(): Record<string, THook> {\n return Object.fromEntries(this.hooks.entries()) as Record<string, THook>;\n }\n}\n","import EventEmitter from 'node:events';\nimport { Base } from './base.core';\nimport { TEvents, TEventsOptions } from 'src/types';\nimport { DEFAULT_EVENTS_OPTIONS } from 'src/constants/default.constant';\n\nexport class Events extends Base {\n private events?: EventEmitter;\n private eOptions: Required<TEventsOptions>;\n\n constructor(options: TEventsOptions) {\n super(options);\n\n this.eOptions = {\n ...DEFAULT_EVENTS_OPTIONS,\n ...options,\n };\n\n if (this.eOptions.useEvent) {\n this.events = new EventEmitter();\n }\n }\n\n protected emit<K extends keyof TEvents>(event: K, args: TEvents[K]) {\n if (!this.events) return this;\n\n this.events.emit(event, args);\n return this;\n }\n\n on<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.on(event, listener);\n return this;\n }\n\n once<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.once(event, listener);\n return this;\n }\n\n off<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.off(event, listener);\n return this;\n }\n}\n","import { EEvent, TEvents, TFormatUsable, TGetKeyFn, TSaveKeyFn, TStoreOptions } from 'src/types';\nimport { FileUtil } from 'src/utils';\nimport { DEFAULT_STORE_OPTIONS } from 'src/constants/default.constant';\nimport { join } from 'path';\nimport { TKeyGenerated } from 'src/types/key-manager.types';\nimport { Events } from './events.core';\n\nexport class Store extends Events {\n private sOptions: Required<Omit<TStoreOptions, 'useEvent' | 'crypto'>>;\n private fileUtil: FileUtil;\n protected storePath?: string;\n protected saveKeyFn?: TSaveKeyFn;\n protected getKeyFn?: TGetKeyFn;\n\n constructor(options: Partial<TStoreOptions>) {\n super(options);\n\n this.sOptions = { ...DEFAULT_STORE_OPTIONS, ...options };\n this.fileUtil = new FileUtil();\n\n this.initStore();\n }\n\n protected getPath(path: string | string[], splitor: string): string {\n if (typeof path === 'object' && Array.isArray(path)) {\n return path.join(splitor);\n }\n\n return path;\n }\n\n private async getKeyStoreFolder(): Promise<string> {\n if (this.storePath) return this.storePath;\n\n const { path } = this.sOptions;\n\n const first =\n typeof path === 'object' && Array.isArray(path)\n ? path[0]\n : typeof path === 'string'\n ? (path.split('/')[0] ?? '')\n : '';\n\n let folder = await this.fileUtil.getFolder(join(process.cwd(), first));\n\n return folder;\n }\n\n protected async getKeyFileData(filePath: string): Promise<Record<string, TKeyGenerated>> {\n const existingData = await this.fileUtil.read(filePath, '{}');\n const savedData = this.toSavedData(existingData);\n\n return savedData;\n }\n\n protected async saveKeyFile(\n path: string,\n data: TKeyGenerated,\n merge: boolean = false\n ): Promise<string> {\n let savedData = await this.getKeyFileData(path);\n\n let saveData: Record<string, TKeyGenerated> = {};\n\n if (merge) {\n saveData = { ...savedData };\n }\n\n saveData = { ...saveData, [data.version]: data };\n\n await this.fileUtil.write(path, JSON.stringify(saveData, null, 2));\n\n this.emit(EEvent.STORE_FILE_SAVED, { path, data: saveData });\n\n return path;\n }\n\n /**\n * @param storePath custom store path\n * root folder of store\n * @returns this\n */\n public useStorePath(storePath: string): this {\n this.storePath = storePath;\n return this;\n }\n\n /**\n * @param saveKeyFn custom save key function\n * @returns this\n */\n public useSaveKey(saveKeyFn: TSaveKeyFn): this {\n this.saveKeyFn = saveKeyFn;\n return this;\n }\n\n /**\n * @param saveKeyFn custom get key function\n * @returns this\n */\n public useGetKey(getKeyFn: TGetKeyFn): this {\n this.getKeyFn = getKeyFn;\n return this;\n }\n\n private async initStore(): Promise<void> {\n const storePath = await this.getKeyStoreFolder();\n\n let eventEmitPayload: TEvents[EEvent.STORE_INIT_FOLDER] = {\n storePath,\n };\n\n if (this.sOptions.gitIgnore) {\n const gitignore = await this.addStoreFolderGitignore();\n eventEmitPayload = { ...eventEmitPayload, ...gitignore };\n }\n\n this.emit(EEvent.STORE_INIT_FOLDER, eventEmitPayload);\n }\n\n private toSavedData(dataString: string): Record<string, TKeyGenerated> {\n try {\n if (!dataString) return {};\n const parsedData = JSON.parse(dataString) as Record<string, TKeyGenerated>;\n\n if (typeof parsedData !== 'object' || Array.isArray(parsedData)) {\n throw new Error('Invalid JSON data (must be Record<version, TKeyGenerated>)');\n }\n\n return parsedData;\n } catch (error) {\n throw new Error(`Invalid JSON data (must be Record<version, TKeyGenerated>) ${dataString}`);\n }\n }\n\n private async addStoreFolderGitignore(): Promise<\n Omit<TEvents[EEvent.STORE_INIT_FOLDER], 'storePath'>\n > {\n const gitignorePath = join(process.cwd(), '.gitignore');\n const gitignoreContent = await this.fileUtil.read(gitignorePath);\n\n const folder = this.getStoreFolderGitignore();\n const gitignoreLines = gitignoreContent.split(/\\r?\\n/).map((line) => line.trim());\n const hasExactLine = gitignoreLines.some((line) => line === folder);\n\n if (!hasExactLine) {\n await this.fileUtil.write(gitignorePath, `${gitignoreContent ? '\\r\\n' : ''}${folder}`, 'a');\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'added',\n };\n }\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'already',\n };\n }\n\n private getStoreFolderGitignore() {\n let folder = '';\n const storePath = this.getPath(this.sOptions.path, '/');\n\n if (typeof this.sOptions.gitIgnore === 'boolean') {\n folder = this.getStoreFolderGitignoreByDefault(storePath);\n } else {\n folder = this.addStoreFolderGitignoreByCustom(this.sOptions.gitIgnore);\n }\n\n return this.replaceVariableToStar(folder);\n }\n\n private getStoreFolderGitignoreByDefault(storePath: string) {\n const filePath = this.getPath(this.sOptions.file, this.sOptions.fileSplitor);\n\n const folder: string[] = [storePath];\n folder.push(`${filePath}.${this.sOptions.fileExt}`);\n\n return folder.join('/');\n }\n\n private addStoreFolderGitignoreByCustom(ignorePath: TFormatUsable) {\n return this.getPath(ignorePath, '/');\n }\n\n private replaceVariableToStar(path: string): string {\n return path.replace(/\\{\\{.*?\\}\\}/g, '*');\n }\n}\n","import {\n TGenerateKeyOptions,\n TGetKey,\n TGetKeyOptions,\n TKeyGenerated,\n TKeyManagerHooks,\n TKeyManagerOptions,\n TKeyVariables,\n} from 'src/types/key-manager.types';\nimport { Store } from './store.core';\nimport {\n CryptoService,\n executePromisably,\n addDuration,\n bindString,\n isDate,\n isType,\n} from 'src/utils';\nimport { DEFAULT_KEY_MANAGER_OPTIONS } from 'src/constants/default.constant';\n\nexport class KeyManager extends Store {\n private cryptoService: CryptoService;\n private kOptions: Required<TKeyManagerOptions>;\n\n constructor(options: Partial<TKeyManagerOptions>) {\n super(options);\n\n this.kOptions = { ...DEFAULT_KEY_MANAGER_OPTIONS, ...options };\n this.cryptoService = new CryptoService(this.kOptions.crypto);\n }\n\n /**\n * Retrieve and validate a stored key by path and version.\n *\n * This method:\n * - Loads a key from the configured store\n * - Validates structure, type safety, and time constraints\n * - Detects expiration and rotation eligibility\n * - Optionally auto-rotates an expired key if rotation options are provided\n *\n * If the key is expired and marked as rotatable, a new key will be generated\n * automatically using the provided `onRotate` options.\n *\n * @param options Configuration for key retrieval\n * @param options.path Storage path of the key\n * @param options.version Specific key version to retrieve\n * @param options.onRotate Optional rotation configuration used when the key\n * is expired and renewable\n *\n * @returns An object containing:\n * - `ready`: The valid (usable) key, or the newly generated key after rotation\n * - `expired`: The expired key if rotation occurred, otherwise `null`\n *\n * @throws Error if:\n * - The key does not exist\n * - The key structure or fields are invalid\n * - The key is expired but rotation options are missing\n * - The key is not yet valid or otherwise unusable\n *\n * @example\n * ```ts\n * const { ready, expired } = await keyManager.getKey({\n * path: '/keys/api',\n * version: 'v1',\n * // This define the new key attributes: is it rotate? Durations and unit?\n * onRotate: {\n * duration: 30,\n * unit: 'days',\n * rotate: true,\n * },\n * });\n *\n * if (expired) {\n * console.log('Key was rotated from version:', expired.version);\n * }\n *\n * // Use expired?.key ?? ready?.key safely\n * ```\n */\n public async getKey(options: TGetKeyOptions): Promise<TGetKey> {\n const { path, version } = options;\n\n const key = await this.getKeyByStore(path, String(version));\n\n if (!key) {\n this.runKeyHook('onKeyNotFound', path, version);\n this.sysLog(`Key not found!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);\n\n if (!ok && isExpired && isRenewable && key) {\n if (!options.onRotate) {\n this.runKeyHook('onKeyMissingRotateOption', key, options);\n this.sysLog(`Key missing rotate option!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const renew = await this.newKey({\n type: key.type,\n ...options.onRotate,\n });\n\n const resGetKey = { expired: key, ready: renew.key };\n\n this.runKeyHook('onKeyRenewed', resGetKey, options);\n this.sysLog(`Key renewed!`, { path, version });\n return resGetKey;\n }\n\n if (!ok && isExpired && !isRenewable && key) {\n this.runKeyHook('onKeyExpired', path, key);\n this.sysLog(`Key expired!`, { path, version });\n return { expired: key, ready: null };\n }\n\n if (!ok) {\n this.runKeyHook('onKeyInvalid', key, message, errorOn);\n this.sysLog(`Key invalid!`, { path, version });\n return { expired: null, ready: null };\n }\n\n return { expired: null, ready: key };\n }\n\n /**\n * Generate a new cryptographic key and persist it to the configured store.\n *\n * This method:\n * - Generates a random origin key\n * - Hashes the key using the configured crypto options\n * - Calculates an expiration time (if provided)\n * - Assigns versioning and rotation metadata\n * - Saves the generated key to storage\n * - The hashed key will follow this format: `salt-buffer:hashed`\n *\n * @param options Configuration for key generation\n * @param options.type Logical key type (e.g. api, session, encryption, etc.)\n * @param options.duration Optional lifetime value for the key\n * @param options.unit Time unit for the duration (seconds | minutes | hours | days)\n * @param options.rotate Whether this key should participate in key rotation\n * @param options.merge Whether to merge with an existing stored key (if supported)\n *\n * @param variables Optional variables used for dynamic path or filename resolution\n *\n * @returns An object containing:\n * - `key`: The generated key metadata and raw key value\n * - `path`: The storage path where the key was saved\n *\n * @example\n * ```ts\n * const { key, path } = await keyManager.newKey(\n * {\n * type: 'api',\n * duration: 30, <- Optional\n * unit: 'days', <- Optional\n * rotate: true, <- Optional\n * },\n * { env: 'production', ... }\n * );\n * ```\n */\n public async newKey(\n options: TGenerateKeyOptions,\n variables: TKeyVariables = {}\n ): Promise<{ key: TKeyGenerated; path: string }> {\n const { rotate, duration, type, unit, merge, keyLength } = options;\n\n const { key, length: kLength } = this.cryptoService.generateKey(keyLength);\n const { salt } = this.cryptoService.generateSalt();\n\n this.sysLog(`Key generated\\nOptions:`, options);\n\n const hashedKey = this.cryptoService.hash(key, salt);\n const now = new Date();\n\n const keyGenerated: TKeyGenerated = {\n from: now.toISOString(),\n to: duration && unit ? addDuration(now, duration, unit).toISOString() : 'NON_EXPIRED',\n key: key,\n hashed: hashedKey,\n hashedBytes: kLength,\n type,\n version: await executePromisably(this.kOptions.versionGenerator()),\n rotate: !!rotate,\n };\n\n const path = await this.saveKeyToStore(keyGenerated, !!merge, variables);\n this.sysLog(`Key saved!`, {\n path,\n version: keyGenerated.version,\n type: keyGenerated.type,\n });\n\n return { key: keyGenerated, path };\n }\n\n private async getKeyByStore(path: string, version: string): Promise<TKeyGenerated | null> {\n if (this.getKeyFn) {\n return this.getKeyFn(path, version);\n }\n\n const savedData = await this.getKeyFileData(path);\n return savedData[version] ?? null;\n }\n\n private async saveKeyToStore(\n key: TKeyGenerated,\n merge: boolean,\n variables: TKeyVariables\n ): Promise<string> {\n return (this.saveKeyFn?.bind(this) ?? this.saveKeyFile.bind(this))(\n this.getFilename({ ...variables, version: key.version, type: key.type }),\n key,\n merge\n );\n }\n\n private validateKey(keyGenerated: Partial<TKeyGenerated>): {\n ok: boolean;\n message: string;\n errorOn?: keyof TKeyGenerated;\n isExpired?: boolean;\n isRenewable?: boolean;\n } {\n const requiredKeyGenerated = keyGenerated as TKeyGenerated;\n\n const typeChecks: Record<keyof TKeyGenerated, keyof ReturnType<typeof isType>> = {\n from: 'string',\n to: 'string',\n key: 'string',\n hashed: 'string',\n rotate: 'boolean',\n type: 'string',\n version: 'stringNumber',\n hashedBytes: 'number',\n };\n\n for (const [field, type] of Object.entries(typeChecks) as Array<\n [field: keyof TKeyGenerated, type: keyof ReturnType<typeof isType>]\n >) {\n if (!isType(requiredKeyGenerated[field])[type])\n return { ok: false, message: `${field} is not valid`, errorOn: field };\n }\n\n if (!isDate(requiredKeyGenerated.from)) {\n return { ok: false, message: 'From date is not valid!', errorOn: 'from' };\n } else if (new Date(requiredKeyGenerated.from) > new Date()) {\n return { ok: false, message: 'Key is not started!' };\n }\n\n if (!isDate(requiredKeyGenerated.to)) {\n if (requiredKeyGenerated.to !== 'NON_EXPIRED') {\n return { ok: false, message: 'Expire date is not valid!', errorOn: 'to' };\n }\n } else if (new Date(requiredKeyGenerated.to) < new Date()) {\n return {\n ok: false,\n message: 'Key is expired',\n errorOn: 'to',\n isExpired: true,\n isRenewable: !!requiredKeyGenerated.rotate,\n };\n }\n\n if (requiredKeyGenerated.hashedBytes < 0)\n return {\n ok: false,\n message: 'Invalid hashedBytes range',\n errorOn: 'hashedBytes',\n };\n\n return { ok: true, message: '' };\n }\n\n private getFilename(variables: TKeyVariables) {\n return bindString(\n bindString(`{{root}}/{{filename}}.{{ext}}`, {\n root: this.getPath(this.kOptions.path, '/'),\n filename: this.getPath(this.kOptions.file, this.kOptions.fileSplitor),\n ext: this.kOptions.fileExt,\n }),\n variables\n );\n }\n\n private runKeyHook<K extends keyof TKeyManagerHooks>(\n name: K,\n ...args: Parameters<TKeyManagerHooks[K]>\n ): ReturnType<TKeyManagerHooks[K]> {\n return this.runHook<TKeyManagerHooks, K>(name, ...args);\n }\n}\n","import { TModuleHooks, TModuleOptions } from 'src/types';\nimport { DEFAULT_MODULE_OPTIONS } from 'src/constants/default.constant';\nimport { KeyManager } from './key-manager.core';\n\nexport class KM extends KeyManager {\n private options: Required<TModuleOptions>;\n\n constructor(options: Partial<TModuleOptions>) {\n super(options);\n\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n }\n\n public setOptions(options: TModuleOptions): this {\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n return this;\n }\n\n public getOptions(): TModuleOptions | undefined {\n return this.options;\n }\n\n /**\n *\n * @param instance: use instance options to create new instance\n * @param extend: overide options\n * @returns new instance\n */\n public clone(extend: Partial<TModuleOptions> = {}): KM {\n const module = new KM({ ...this.getOptions(), ...extend });\n\n if (this.saveKeyFn) module.useSaveKey(this.saveKeyFn);\n if (this.getKeyFn) module.useGetKey(this.getKeyFn);\n if (this.storePath) module.useStorePath(this.storePath);\n\n module.setHooks(this.getHooks());\n module.setLogger(this.getLogger());\n\n return module;\n }\n\n public useHooks(hooks: Partial<{ [x in keyof TModuleHooks]: TModuleHooks[x] }>) {\n this.setHooks(hooks);\n return this;\n }\n\n public setHook<HookName extends keyof TModuleHooks>(\n name: HookName,\n handler: TModuleHooks[HookName]\n ) {\n this.setHooks({ [name]: handler });\n return this;\n }\n}\n","import { KM } from './core/module.core';\nimport * as types from './types';\nexport * from './types';\n\nlet instance: KM | null = null;\n\n/**\n * Create a new KeyManager instance\n * @param options - Options to configure the instance\n * @param singleton - If true, returns a shared singleton instance; if false, creates a new instance\n * @returns KM instance\n */\nexport const create = (\n options: Partial<types.TModuleOptions> = {},\n singleton: boolean = false\n): KM => {\n if (!singleton) return new KM(options);\n\n if (!instance) {\n instance = new KM(options);\n }\n\n return instance;\n};\n\n/**\n * @alias create()\n */\nexport const km = create;\nexport type { KM };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "key-rotation-manager",
3
- "version": "1.0.11",
3
+ "version": "1.1.1",
4
4
  "description": "Simple, secure key rotation for Node.js",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -36,7 +36,6 @@
36
36
  "node": ">=18.0.0"
37
37
  },
38
38
  "devDependencies": {
39
- "@types/crypto-js": "^4.2.2",
40
39
  "@types/node": "^18.19.74",
41
40
  "@typescript-eslint/eslint-plugin": "^8.28.0",
42
41
  "@typescript-eslint/parser": "^8.28.0",
@@ -45,8 +44,5 @@
45
44
  "tsup": "^8.5.1",
46
45
  "tsx": "^4.19.2",
47
46
  "typescript": "^5.4.5"
48
- },
49
- "dependencies": {
50
- "crypto-js": "^4.2.0"
51
47
  }
52
48
  }