key-rotation-manager 1.1.1 → 1.1.2
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 +75 -6
- package/dist/index.cjs +58 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +58 -10
- package/dist/index.js.map +1 -1
- package/package.json +18 -3
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
A production-ready library for generating, storing, rotating, and retrieving cryptographic keys with support for expiration, versioning, merge strategies, custom storage logic, and lifecycle hooks.
|
|
6
6
|
|
|
7
|
+
**Key Rotation Manager** is a comprehensive Node.js library for secure cryptographic key management. It provides automatic key rotation, expiration handling, versioning, and flexible storage options. Perfect for API key management, token rotation, secret management, and credential handling in production applications.
|
|
8
|
+
|
|
7
9
|
[](https://www.npmjs.com/package/key-rotation-manager)
|
|
8
10
|
[](https://nodejs.org/)
|
|
9
11
|
[](LICENSE)
|
|
@@ -44,6 +46,8 @@ A production-ready library for generating, storing, rotating, and retrieving cry
|
|
|
44
46
|
- 📡 **Event-Driven** - Lifecycle hooks for key events
|
|
45
47
|
- 📁 **Git Integration** - Automatic `.gitignore` management
|
|
46
48
|
- 🎯 **TypeScript** - Full TypeScript support with comprehensive types
|
|
49
|
+
- ⚡ **Zero Dependencies** - Uses native Node.js crypto module
|
|
50
|
+
- 🚀 **Production Ready** - Battle-tested for enterprise applications
|
|
47
51
|
|
|
48
52
|
---
|
|
49
53
|
|
|
@@ -55,6 +59,8 @@ npm install key-rotation-manager
|
|
|
55
59
|
|
|
56
60
|
**Requirements:** Node.js >= 18.0.0
|
|
57
61
|
|
|
62
|
+
**Package:** [npmjs.com/package/key-rotation-manager](https://www.npmjs.com/package/key-rotation-manager)
|
|
63
|
+
|
|
58
64
|
---
|
|
59
65
|
|
|
60
66
|
## 🚀 Quick Start
|
|
@@ -562,6 +568,7 @@ Retrieves a key by path and version.
|
|
|
562
568
|
- `options`: `TGetKeyOptions`
|
|
563
569
|
- `path`: `string` - Storage path
|
|
564
570
|
- `version`: `string` - Key version
|
|
571
|
+
- `disableHooks?`: `boolean` - Skip hook execution (default: `false`)
|
|
565
572
|
- `onRotate?`: Rotation options (if key is expired and rotatable)
|
|
566
573
|
|
|
567
574
|
**Returns:** `Promise<TGetKey>`
|
|
@@ -577,8 +584,45 @@ const result = await keyManager.getKey({
|
|
|
577
584
|
rotate: true,
|
|
578
585
|
},
|
|
579
586
|
});
|
|
587
|
+
|
|
588
|
+
// With disabled hooks for performance
|
|
589
|
+
const result = await keyManager.getKey({
|
|
590
|
+
path: '/keys/api',
|
|
591
|
+
version: 'v1',
|
|
592
|
+
disableHooks: true,
|
|
593
|
+
});
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### `verifyKey(hashedKey, path, version, disableGetKeyHooks?)`
|
|
597
|
+
|
|
598
|
+
Verifies a hashed key against a stored key.
|
|
599
|
+
|
|
600
|
+
**Parameters:**
|
|
601
|
+
- `hashedKey`: `string` - The hashed key to verify
|
|
602
|
+
- `path`: `string` - Storage path
|
|
603
|
+
- `version`: `string | number` - Key version
|
|
604
|
+
- `disableGetKeyHooks?`: `boolean` - Disable hooks in getKey call (default: `true`)
|
|
605
|
+
|
|
606
|
+
**Returns:** `Promise<boolean>`
|
|
607
|
+
|
|
608
|
+
**Example:**
|
|
609
|
+
```typescript
|
|
610
|
+
const isValid = await keyManager.verifyKey(hashedKey, '/keys/api', 'v1');
|
|
611
|
+
if (isValid) {
|
|
612
|
+
console.log('Key is valid!');
|
|
613
|
+
} else {
|
|
614
|
+
console.log('Key is invalid!');
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// Verification with hooks enabled
|
|
618
|
+
const isValid = await keyManager.verifyKey(hashedKey, '/keys/api', 'v1', false);
|
|
580
619
|
```
|
|
581
620
|
|
|
621
|
+
**Notes:**
|
|
622
|
+
- Uses PBKDF2 verification if the key has a `secret` field
|
|
623
|
+
- Falls back to direct hash comparison otherwise
|
|
624
|
+
- Verifies against expired keys if no ready key is available
|
|
625
|
+
|
|
582
626
|
### `useHooks(hooks)`
|
|
583
627
|
|
|
584
628
|
Sets multiple hooks at once.
|
|
@@ -602,12 +646,16 @@ Sets a single hook.
|
|
|
602
646
|
|
|
603
647
|
## 🎯 Use Cases
|
|
604
648
|
|
|
605
|
-
- **API Key Management** - Secure storage and rotation of API keys
|
|
606
|
-
- **Token Rotation** - Automatic credential rotation for
|
|
607
|
-
- **Secret Management** - File-based secret storage with expiration
|
|
608
|
-
- **Multi-Version Keys** - Support for multiple key versions simultaneously
|
|
609
|
-
- **Custom Persistence** - Integrate with databases or
|
|
610
|
-
- **Backend Services** - Production-ready key management for Node.js applications
|
|
649
|
+
- **API Key Management** - Secure storage and rotation of API keys for third-party services
|
|
650
|
+
- **Token Rotation** - Automatic credential rotation for OAuth tokens, JWT secrets, and access tokens
|
|
651
|
+
- **Secret Management** - File-based secret storage with expiration for application secrets
|
|
652
|
+
- **Multi-Version Keys** - Support for multiple key versions simultaneously during rotation periods
|
|
653
|
+
- **Custom Persistence** - Integrate with databases, cloud storage, or key management services
|
|
654
|
+
- **Backend Services** - Production-ready key management for Node.js applications and microservices
|
|
655
|
+
- **Encryption Keys** - Manage encryption keys for data protection with automatic rotation
|
|
656
|
+
- **Session Keys** - Rotate session encryption keys periodically for enhanced security
|
|
657
|
+
- **Database Credentials** - Rotate database passwords and connection strings securely
|
|
658
|
+
- **Service-to-Service Authentication** - Manage keys for inter-service communication
|
|
611
659
|
|
|
612
660
|
---
|
|
613
661
|
|
|
@@ -615,6 +663,7 @@ Sets a single hook.
|
|
|
615
663
|
|
|
616
664
|
See the full changelog for each version:
|
|
617
665
|
|
|
666
|
+
- **[v1.1.2](https://github.com/DucAnh2611/key-rotation-manager/tree/master/changelogs/1.1.2.md)** - Key verification, hook control, enhanced documentation
|
|
618
667
|
- **[v1.1.1](https://github.com/DucAnh2611/key-rotation-manager/tree/master/changelogs/1.1.1.md)** - Native crypto, zero dependencies, bug fixes
|
|
619
668
|
- **[v1.0.10](https://github.com/DucAnh2611/key-rotation-manager/tree/master/changelogs/1.0.10.md)** - Hooks system, enhanced gitIgnore configuration
|
|
620
669
|
|
|
@@ -653,4 +702,24 @@ This project is licensed under the MIT License - see the [LICENSE](https://githu
|
|
|
653
702
|
|
|
654
703
|
---
|
|
655
704
|
|
|
705
|
+
## 🔍 Search Keywords
|
|
706
|
+
|
|
707
|
+
This package is optimized for searches related to:
|
|
708
|
+
- key rotation
|
|
709
|
+
- key management
|
|
710
|
+
- cryptographic key storage
|
|
711
|
+
- API key rotation
|
|
712
|
+
- secret rotation
|
|
713
|
+
- credential management
|
|
714
|
+
- token rotation
|
|
715
|
+
- key versioning
|
|
716
|
+
- automatic key rotation
|
|
717
|
+
- secure key storage
|
|
718
|
+
- Node.js key management
|
|
719
|
+
- TypeScript key management
|
|
720
|
+
- production key rotation
|
|
721
|
+
- enterprise key management
|
|
722
|
+
|
|
723
|
+
---
|
|
724
|
+
|
|
656
725
|
**Made with ❤️ for secure key management**
|
package/dist/index.cjs
CHANGED
|
@@ -187,7 +187,10 @@ var isType = (data) => {
|
|
|
187
187
|
stringNumber: typeof data === "string" || typeof data === "number",
|
|
188
188
|
boolean: typeof data === "boolean",
|
|
189
189
|
null: data === null,
|
|
190
|
-
undefined: data === void 0
|
|
190
|
+
undefined: data === void 0,
|
|
191
|
+
optionalNumber: typeof data === "undefined" || typeof data === "number" && !Number.isNaN(Number(data)),
|
|
192
|
+
optionalString: typeof data === "undefined" || typeof data === "string",
|
|
193
|
+
optionalStringNumber: typeof data === "undefined" || typeof data === "string" || typeof data === "number"
|
|
191
194
|
};
|
|
192
195
|
};
|
|
193
196
|
var CryptoService = class {
|
|
@@ -638,33 +641,33 @@ var KeyManager = class extends Store {
|
|
|
638
641
|
const { path, version } = options;
|
|
639
642
|
const key = await this.getKeyByStore(path, String(version));
|
|
640
643
|
if (!key) {
|
|
641
|
-
this.runKeyHook("onKeyNotFound", path, version);
|
|
644
|
+
if (!options.disableHooks) this.runKeyHook("onKeyNotFound", path, version);
|
|
642
645
|
this.sysLog(`Key not found!`, { path, version });
|
|
643
646
|
return { expired: null, ready: null };
|
|
644
647
|
}
|
|
645
648
|
const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);
|
|
646
649
|
if (!ok && isExpired && isRenewable && key) {
|
|
647
650
|
if (!options.onRotate) {
|
|
648
|
-
this.runKeyHook("onKeyMissingRotateOption", key, options);
|
|
651
|
+
if (!options.disableHooks) this.runKeyHook("onKeyMissingRotateOption", key, options);
|
|
649
652
|
this.sysLog(`Key missing rotate option!`, { path, version });
|
|
650
|
-
return { expired:
|
|
653
|
+
return { expired: key, ready: null };
|
|
651
654
|
}
|
|
652
655
|
const renew = await this.newKey({
|
|
653
656
|
type: key.type,
|
|
654
657
|
...options.onRotate
|
|
655
658
|
});
|
|
656
659
|
const resGetKey = { expired: key, ready: renew.key };
|
|
657
|
-
this.runKeyHook("onKeyRenewed", resGetKey, options);
|
|
660
|
+
if (!options.disableHooks) this.runKeyHook("onKeyRenewed", resGetKey, options);
|
|
658
661
|
this.sysLog(`Key renewed!`, { path, version });
|
|
659
662
|
return resGetKey;
|
|
660
663
|
}
|
|
661
664
|
if (!ok && isExpired && !isRenewable && key) {
|
|
662
|
-
this.runKeyHook("onKeyExpired", path, key);
|
|
665
|
+
if (!options.disableHooks) this.runKeyHook("onKeyExpired", path, key);
|
|
663
666
|
this.sysLog(`Key expired!`, { path, version });
|
|
664
667
|
return { expired: key, ready: null };
|
|
665
668
|
}
|
|
666
669
|
if (!ok) {
|
|
667
|
-
this.runKeyHook("onKeyInvalid", key, message, errorOn);
|
|
670
|
+
if (!options.disableHooks) this.runKeyHook("onKeyInvalid", key, message, errorOn);
|
|
668
671
|
this.sysLog(`Key invalid!`, { path, version });
|
|
669
672
|
return { expired: null, ready: null };
|
|
670
673
|
}
|
|
@@ -710,15 +713,16 @@ var KeyManager = class extends Store {
|
|
|
710
713
|
async newKey(options, variables = {}) {
|
|
711
714
|
const { rotate, duration, type, unit, merge, keyLength } = options;
|
|
712
715
|
const { key, length: kLength } = this.cryptoService.generateKey(keyLength);
|
|
713
|
-
const { salt } = this.cryptoService.generateSalt();
|
|
716
|
+
const { salt: secret } = this.cryptoService.generateSalt();
|
|
714
717
|
this.sysLog(`Key generated
|
|
715
718
|
Options:`, options);
|
|
716
|
-
const hashedKey = this.cryptoService.hash(key,
|
|
719
|
+
const hashedKey = this.cryptoService.hash(key, secret);
|
|
717
720
|
const now = /* @__PURE__ */ new Date();
|
|
718
721
|
const keyGenerated = {
|
|
719
722
|
from: now.toISOString(),
|
|
720
723
|
to: duration && unit ? addDuration(now, duration, unit).toISOString() : "NON_EXPIRED",
|
|
721
724
|
key,
|
|
725
|
+
secret,
|
|
722
726
|
hashed: hashedKey,
|
|
723
727
|
hashedBytes: kLength,
|
|
724
728
|
type,
|
|
@@ -733,6 +737,49 @@ Options:`, options);
|
|
|
733
737
|
});
|
|
734
738
|
return { key: keyGenerated, path };
|
|
735
739
|
}
|
|
740
|
+
/**
|
|
741
|
+
* Verify a key by hashed key and path and version
|
|
742
|
+
* @param hashedKey Hashed key to verify
|
|
743
|
+
* @param path Path to the key
|
|
744
|
+
* @param version Version of the key
|
|
745
|
+
* @param disableGetKeyHooks Disable getKey method hooks, should not use hooks in this method
|
|
746
|
+
* @returns True if the key is valid, false otherwise
|
|
747
|
+
*
|
|
748
|
+
* @example
|
|
749
|
+
* ```ts
|
|
750
|
+
* const isValid = await keyManager.verifyKey(hashedKey, path, version);
|
|
751
|
+
* if (isValid) {
|
|
752
|
+
* console.log('Key is valid!');
|
|
753
|
+
* } else {
|
|
754
|
+
* console.log('Key is invalid!');
|
|
755
|
+
* }
|
|
756
|
+
* ```
|
|
757
|
+
*
|
|
758
|
+
* @note
|
|
759
|
+
* 1. This use getKey method to get key, so disableGetKeyHooks option is set to true, if disableGetKeyHooks is not provided, it will be set to true
|
|
760
|
+
*
|
|
761
|
+
* 2. Get key from store
|
|
762
|
+
* - If the key is expired, the expired key will be used to verify the key
|
|
763
|
+
* - If the key is not expired, the ready key will be used to verify the key
|
|
764
|
+
*
|
|
765
|
+
* 3. If the key is not found, the function will return false
|
|
766
|
+
*
|
|
767
|
+
* 4. Verify key strategy
|
|
768
|
+
* - If the key is found and secret is provided, compare original key with hashed key using secret
|
|
769
|
+
* - If the key is found and secret is not provided, compare original key with hashed key
|
|
770
|
+
*
|
|
771
|
+
*/
|
|
772
|
+
async verifyKey(hashedKey, path, version, disableGetKeyHooks = true) {
|
|
773
|
+
const { ready, expired } = await this.getKey({ path, version: String(version), disableHooks: disableGetKeyHooks });
|
|
774
|
+
if (!ready && !expired) {
|
|
775
|
+
this.sysLog(`Key not found to verify!`, { path, version });
|
|
776
|
+
return false;
|
|
777
|
+
}
|
|
778
|
+
const key = expired ?? ready;
|
|
779
|
+
this.sysLog("Verifying key...", { hashedKey, path, version, validateMethod: key.secret ? "verifyHash(key, hashedKey, secret)" : "hashedKey === key.hashed" });
|
|
780
|
+
if (key.secret) return this.cryptoService.verifyHash(key.key, hashedKey, key.secret);
|
|
781
|
+
return hashedKey === key.hashed;
|
|
782
|
+
}
|
|
736
783
|
async getKeyByStore(path, version) {
|
|
737
784
|
if (this.getKeyFn) {
|
|
738
785
|
return this.getKeyFn(path, version);
|
|
@@ -757,7 +804,8 @@ Options:`, options);
|
|
|
757
804
|
rotate: "boolean",
|
|
758
805
|
type: "string",
|
|
759
806
|
version: "stringNumber",
|
|
760
|
-
hashedBytes: "number"
|
|
807
|
+
hashedBytes: "number",
|
|
808
|
+
secret: "optionalString"
|
|
761
809
|
};
|
|
762
810
|
for (const [field, type] of Object.entries(typeChecks)) {
|
|
763
811
|
if (!isType(requiredKeyGenerated[field])[type])
|
package/dist/index.cjs.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","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"]}
|
|
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 optionalNumber: typeof data === \"undefined\" || (typeof data === 'number' && !Number.isNaN(Number(data))),\n optionalString: typeof data === \"undefined\" || typeof data === 'string',\n optionalStringNumber: typeof data === \"undefined\" || typeof data === 'string' || typeof data === 'number',\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 if (!options.disableHooks) 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 if (!options.disableHooks) this.runKeyHook('onKeyMissingRotateOption', key, options);\n this.sysLog(`Key missing rotate option!`, { path, version });\n return { expired: key, 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 if (!options.disableHooks) this.runKeyHook('onKeyRenewed', resGetKey, options);\n this.sysLog(`Key renewed!`, { path, version });\n return resGetKey;\n }\n\n if (!ok && isExpired && !isRenewable && key) {\n if (!options.disableHooks) this.runKeyHook('onKeyExpired', path, key);\n this.sysLog(`Key expired!`, { path, version });\n return { expired: key, ready: null };\n }\n\n if (!ok) {\n if (!options.disableHooks) 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: secret } = this.cryptoService.generateSalt();\n\n this.sysLog(`Key generated\\nOptions:`, options);\n\n const hashedKey = this.cryptoService.hash(key, secret);\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 secret: secret,\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 /**\n * Verify a key by hashed key and path and version\n * @param hashedKey Hashed key to verify\n * @param path Path to the key\n * @param version Version of the key\n * @param disableGetKeyHooks Disable getKey method hooks, should not use hooks in this method\n * @returns True if the key is valid, false otherwise\n * \n * @example\n * ```ts\n * const isValid = await keyManager.verifyKey(hashedKey, path, version);\n * if (isValid) {\n * console.log('Key is valid!');\n * } else {\n * console.log('Key is invalid!');\n * }\n * ```\n * \n * @note\n * 1. This use getKey method to get key, so disableGetKeyHooks option is set to true, if disableGetKeyHooks is not provided, it will be set to true \n * \n * 2. Get key from store\n * - If the key is expired, the expired key will be used to verify the key\n * - If the key is not expired, the ready key will be used to verify the key\n * \n * 3. If the key is not found, the function will return false\n * \n * 4. Verify key strategy\n * - If the key is found and secret is provided, compare original key with hashed key using secret\n * - If the key is found and secret is not provided, compare original key with hashed key\n * \n */\n public async verifyKey(hashedKey: string, path: string, version: string | number, disableGetKeyHooks: boolean = true): Promise<boolean> {\n const { ready, expired } = await this.getKey({ path, version: String(version), disableHooks: disableGetKeyHooks });\n\n if (!ready && !expired) {\n this.sysLog(`Key not found to verify!`, { path, version });\n return false;\n }\n\n // if expire -> expired key, if not expire -> ready key\n // case both key appear when onRotate options is set\n const key = (expired ?? ready) as TKeyGenerated;\n\n this.sysLog('Verifying key...', { hashedKey, path, version, validateMethod: key.secret ? 'verifyHash(key, hashedKey, secret)' : 'hashedKey === key.hashed' });\n if (key.secret) return this.cryptoService.verifyHash(key.key, hashedKey, key.secret);\n\n return hashedKey === key.hashed;\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 secret: 'optionalString',\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.d.cts
CHANGED
|
@@ -169,6 +169,7 @@ type TGetKey = {
|
|
|
169
169
|
type TGetKeyOptions = {
|
|
170
170
|
path: string;
|
|
171
171
|
version: string;
|
|
172
|
+
disableHooks?: boolean;
|
|
172
173
|
onRotate?: Omit<Required<TGenerateKeyOptions>, 'type' | 'keyLength' | 'merge'> & Pick<TGenerateKeyOptions, 'keyLength' | 'merge'>;
|
|
173
174
|
};
|
|
174
175
|
type TKeyManagerHooks = {
|
|
@@ -250,6 +251,10 @@ type TKeyGenerated = {
|
|
|
250
251
|
* Auto renew on expired
|
|
251
252
|
*/
|
|
252
253
|
rotate: boolean;
|
|
254
|
+
/**
|
|
255
|
+
* Secret used to hash the key
|
|
256
|
+
*/
|
|
257
|
+
secret?: string;
|
|
253
258
|
};
|
|
254
259
|
type TKeyPrimitive = string | number;
|
|
255
260
|
type TKeyVariablesData = TKeyPrimitive | TKeyPrimitive[];
|
|
@@ -450,6 +455,39 @@ declare class KeyManager extends Store {
|
|
|
450
455
|
key: TKeyGenerated;
|
|
451
456
|
path: string;
|
|
452
457
|
}>;
|
|
458
|
+
/**
|
|
459
|
+
* Verify a key by hashed key and path and version
|
|
460
|
+
* @param hashedKey Hashed key to verify
|
|
461
|
+
* @param path Path to the key
|
|
462
|
+
* @param version Version of the key
|
|
463
|
+
* @param disableGetKeyHooks Disable getKey method hooks, should not use hooks in this method
|
|
464
|
+
* @returns True if the key is valid, false otherwise
|
|
465
|
+
*
|
|
466
|
+
* @example
|
|
467
|
+
* ```ts
|
|
468
|
+
* const isValid = await keyManager.verifyKey(hashedKey, path, version);
|
|
469
|
+
* if (isValid) {
|
|
470
|
+
* console.log('Key is valid!');
|
|
471
|
+
* } else {
|
|
472
|
+
* console.log('Key is invalid!');
|
|
473
|
+
* }
|
|
474
|
+
* ```
|
|
475
|
+
*
|
|
476
|
+
* @note
|
|
477
|
+
* 1. This use getKey method to get key, so disableGetKeyHooks option is set to true, if disableGetKeyHooks is not provided, it will be set to true
|
|
478
|
+
*
|
|
479
|
+
* 2. Get key from store
|
|
480
|
+
* - If the key is expired, the expired key will be used to verify the key
|
|
481
|
+
* - If the key is not expired, the ready key will be used to verify the key
|
|
482
|
+
*
|
|
483
|
+
* 3. If the key is not found, the function will return false
|
|
484
|
+
*
|
|
485
|
+
* 4. Verify key strategy
|
|
486
|
+
* - If the key is found and secret is provided, compare original key with hashed key using secret
|
|
487
|
+
* - If the key is found and secret is not provided, compare original key with hashed key
|
|
488
|
+
*
|
|
489
|
+
*/
|
|
490
|
+
verifyKey(hashedKey: string, path: string, version: string | number, disableGetKeyHooks?: boolean): Promise<boolean>;
|
|
453
491
|
private getKeyByStore;
|
|
454
492
|
private saveKeyToStore;
|
|
455
493
|
private validateKey;
|
package/dist/index.d.ts
CHANGED
|
@@ -169,6 +169,7 @@ type TGetKey = {
|
|
|
169
169
|
type TGetKeyOptions = {
|
|
170
170
|
path: string;
|
|
171
171
|
version: string;
|
|
172
|
+
disableHooks?: boolean;
|
|
172
173
|
onRotate?: Omit<Required<TGenerateKeyOptions>, 'type' | 'keyLength' | 'merge'> & Pick<TGenerateKeyOptions, 'keyLength' | 'merge'>;
|
|
173
174
|
};
|
|
174
175
|
type TKeyManagerHooks = {
|
|
@@ -250,6 +251,10 @@ type TKeyGenerated = {
|
|
|
250
251
|
* Auto renew on expired
|
|
251
252
|
*/
|
|
252
253
|
rotate: boolean;
|
|
254
|
+
/**
|
|
255
|
+
* Secret used to hash the key
|
|
256
|
+
*/
|
|
257
|
+
secret?: string;
|
|
253
258
|
};
|
|
254
259
|
type TKeyPrimitive = string | number;
|
|
255
260
|
type TKeyVariablesData = TKeyPrimitive | TKeyPrimitive[];
|
|
@@ -450,6 +455,39 @@ declare class KeyManager extends Store {
|
|
|
450
455
|
key: TKeyGenerated;
|
|
451
456
|
path: string;
|
|
452
457
|
}>;
|
|
458
|
+
/**
|
|
459
|
+
* Verify a key by hashed key and path and version
|
|
460
|
+
* @param hashedKey Hashed key to verify
|
|
461
|
+
* @param path Path to the key
|
|
462
|
+
* @param version Version of the key
|
|
463
|
+
* @param disableGetKeyHooks Disable getKey method hooks, should not use hooks in this method
|
|
464
|
+
* @returns True if the key is valid, false otherwise
|
|
465
|
+
*
|
|
466
|
+
* @example
|
|
467
|
+
* ```ts
|
|
468
|
+
* const isValid = await keyManager.verifyKey(hashedKey, path, version);
|
|
469
|
+
* if (isValid) {
|
|
470
|
+
* console.log('Key is valid!');
|
|
471
|
+
* } else {
|
|
472
|
+
* console.log('Key is invalid!');
|
|
473
|
+
* }
|
|
474
|
+
* ```
|
|
475
|
+
*
|
|
476
|
+
* @note
|
|
477
|
+
* 1. This use getKey method to get key, so disableGetKeyHooks option is set to true, if disableGetKeyHooks is not provided, it will be set to true
|
|
478
|
+
*
|
|
479
|
+
* 2. Get key from store
|
|
480
|
+
* - If the key is expired, the expired key will be used to verify the key
|
|
481
|
+
* - If the key is not expired, the ready key will be used to verify the key
|
|
482
|
+
*
|
|
483
|
+
* 3. If the key is not found, the function will return false
|
|
484
|
+
*
|
|
485
|
+
* 4. Verify key strategy
|
|
486
|
+
* - If the key is found and secret is provided, compare original key with hashed key using secret
|
|
487
|
+
* - If the key is found and secret is not provided, compare original key with hashed key
|
|
488
|
+
*
|
|
489
|
+
*/
|
|
490
|
+
verifyKey(hashedKey: string, path: string, version: string | number, disableGetKeyHooks?: boolean): Promise<boolean>;
|
|
453
491
|
private getKeyByStore;
|
|
454
492
|
private saveKeyToStore;
|
|
455
493
|
private validateKey;
|
package/dist/index.js
CHANGED
|
@@ -181,7 +181,10 @@ var isType = (data) => {
|
|
|
181
181
|
stringNumber: typeof data === "string" || typeof data === "number",
|
|
182
182
|
boolean: typeof data === "boolean",
|
|
183
183
|
null: data === null,
|
|
184
|
-
undefined: data === void 0
|
|
184
|
+
undefined: data === void 0,
|
|
185
|
+
optionalNumber: typeof data === "undefined" || typeof data === "number" && !Number.isNaN(Number(data)),
|
|
186
|
+
optionalString: typeof data === "undefined" || typeof data === "string",
|
|
187
|
+
optionalStringNumber: typeof data === "undefined" || typeof data === "string" || typeof data === "number"
|
|
185
188
|
};
|
|
186
189
|
};
|
|
187
190
|
var CryptoService = class {
|
|
@@ -632,33 +635,33 @@ var KeyManager = class extends Store {
|
|
|
632
635
|
const { path, version } = options;
|
|
633
636
|
const key = await this.getKeyByStore(path, String(version));
|
|
634
637
|
if (!key) {
|
|
635
|
-
this.runKeyHook("onKeyNotFound", path, version);
|
|
638
|
+
if (!options.disableHooks) this.runKeyHook("onKeyNotFound", path, version);
|
|
636
639
|
this.sysLog(`Key not found!`, { path, version });
|
|
637
640
|
return { expired: null, ready: null };
|
|
638
641
|
}
|
|
639
642
|
const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);
|
|
640
643
|
if (!ok && isExpired && isRenewable && key) {
|
|
641
644
|
if (!options.onRotate) {
|
|
642
|
-
this.runKeyHook("onKeyMissingRotateOption", key, options);
|
|
645
|
+
if (!options.disableHooks) this.runKeyHook("onKeyMissingRotateOption", key, options);
|
|
643
646
|
this.sysLog(`Key missing rotate option!`, { path, version });
|
|
644
|
-
return { expired:
|
|
647
|
+
return { expired: key, ready: null };
|
|
645
648
|
}
|
|
646
649
|
const renew = await this.newKey({
|
|
647
650
|
type: key.type,
|
|
648
651
|
...options.onRotate
|
|
649
652
|
});
|
|
650
653
|
const resGetKey = { expired: key, ready: renew.key };
|
|
651
|
-
this.runKeyHook("onKeyRenewed", resGetKey, options);
|
|
654
|
+
if (!options.disableHooks) this.runKeyHook("onKeyRenewed", resGetKey, options);
|
|
652
655
|
this.sysLog(`Key renewed!`, { path, version });
|
|
653
656
|
return resGetKey;
|
|
654
657
|
}
|
|
655
658
|
if (!ok && isExpired && !isRenewable && key) {
|
|
656
|
-
this.runKeyHook("onKeyExpired", path, key);
|
|
659
|
+
if (!options.disableHooks) this.runKeyHook("onKeyExpired", path, key);
|
|
657
660
|
this.sysLog(`Key expired!`, { path, version });
|
|
658
661
|
return { expired: key, ready: null };
|
|
659
662
|
}
|
|
660
663
|
if (!ok) {
|
|
661
|
-
this.runKeyHook("onKeyInvalid", key, message, errorOn);
|
|
664
|
+
if (!options.disableHooks) this.runKeyHook("onKeyInvalid", key, message, errorOn);
|
|
662
665
|
this.sysLog(`Key invalid!`, { path, version });
|
|
663
666
|
return { expired: null, ready: null };
|
|
664
667
|
}
|
|
@@ -704,15 +707,16 @@ var KeyManager = class extends Store {
|
|
|
704
707
|
async newKey(options, variables = {}) {
|
|
705
708
|
const { rotate, duration, type, unit, merge, keyLength } = options;
|
|
706
709
|
const { key, length: kLength } = this.cryptoService.generateKey(keyLength);
|
|
707
|
-
const { salt } = this.cryptoService.generateSalt();
|
|
710
|
+
const { salt: secret } = this.cryptoService.generateSalt();
|
|
708
711
|
this.sysLog(`Key generated
|
|
709
712
|
Options:`, options);
|
|
710
|
-
const hashedKey = this.cryptoService.hash(key,
|
|
713
|
+
const hashedKey = this.cryptoService.hash(key, secret);
|
|
711
714
|
const now = /* @__PURE__ */ new Date();
|
|
712
715
|
const keyGenerated = {
|
|
713
716
|
from: now.toISOString(),
|
|
714
717
|
to: duration && unit ? addDuration(now, duration, unit).toISOString() : "NON_EXPIRED",
|
|
715
718
|
key,
|
|
719
|
+
secret,
|
|
716
720
|
hashed: hashedKey,
|
|
717
721
|
hashedBytes: kLength,
|
|
718
722
|
type,
|
|
@@ -727,6 +731,49 @@ Options:`, options);
|
|
|
727
731
|
});
|
|
728
732
|
return { key: keyGenerated, path };
|
|
729
733
|
}
|
|
734
|
+
/**
|
|
735
|
+
* Verify a key by hashed key and path and version
|
|
736
|
+
* @param hashedKey Hashed key to verify
|
|
737
|
+
* @param path Path to the key
|
|
738
|
+
* @param version Version of the key
|
|
739
|
+
* @param disableGetKeyHooks Disable getKey method hooks, should not use hooks in this method
|
|
740
|
+
* @returns True if the key is valid, false otherwise
|
|
741
|
+
*
|
|
742
|
+
* @example
|
|
743
|
+
* ```ts
|
|
744
|
+
* const isValid = await keyManager.verifyKey(hashedKey, path, version);
|
|
745
|
+
* if (isValid) {
|
|
746
|
+
* console.log('Key is valid!');
|
|
747
|
+
* } else {
|
|
748
|
+
* console.log('Key is invalid!');
|
|
749
|
+
* }
|
|
750
|
+
* ```
|
|
751
|
+
*
|
|
752
|
+
* @note
|
|
753
|
+
* 1. This use getKey method to get key, so disableGetKeyHooks option is set to true, if disableGetKeyHooks is not provided, it will be set to true
|
|
754
|
+
*
|
|
755
|
+
* 2. Get key from store
|
|
756
|
+
* - If the key is expired, the expired key will be used to verify the key
|
|
757
|
+
* - If the key is not expired, the ready key will be used to verify the key
|
|
758
|
+
*
|
|
759
|
+
* 3. If the key is not found, the function will return false
|
|
760
|
+
*
|
|
761
|
+
* 4. Verify key strategy
|
|
762
|
+
* - If the key is found and secret is provided, compare original key with hashed key using secret
|
|
763
|
+
* - If the key is found and secret is not provided, compare original key with hashed key
|
|
764
|
+
*
|
|
765
|
+
*/
|
|
766
|
+
async verifyKey(hashedKey, path, version, disableGetKeyHooks = true) {
|
|
767
|
+
const { ready, expired } = await this.getKey({ path, version: String(version), disableHooks: disableGetKeyHooks });
|
|
768
|
+
if (!ready && !expired) {
|
|
769
|
+
this.sysLog(`Key not found to verify!`, { path, version });
|
|
770
|
+
return false;
|
|
771
|
+
}
|
|
772
|
+
const key = expired ?? ready;
|
|
773
|
+
this.sysLog("Verifying key...", { hashedKey, path, version, validateMethod: key.secret ? "verifyHash(key, hashedKey, secret)" : "hashedKey === key.hashed" });
|
|
774
|
+
if (key.secret) return this.cryptoService.verifyHash(key.key, hashedKey, key.secret);
|
|
775
|
+
return hashedKey === key.hashed;
|
|
776
|
+
}
|
|
730
777
|
async getKeyByStore(path, version) {
|
|
731
778
|
if (this.getKeyFn) {
|
|
732
779
|
return this.getKeyFn(path, version);
|
|
@@ -751,7 +798,8 @@ Options:`, options);
|
|
|
751
798
|
rotate: "boolean",
|
|
752
799
|
type: "string",
|
|
753
800
|
version: "stringNumber",
|
|
754
|
-
hashedBytes: "number"
|
|
801
|
+
hashedBytes: "number",
|
|
802
|
+
secret: "optionalString"
|
|
755
803
|
};
|
|
756
804
|
for (const [field, type] of Object.entries(typeChecks)) {
|
|
757
805
|
if (!isType(requiredKeyGenerated[field])[type])
|
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: 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"]}
|
|
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 optionalNumber: typeof data === \"undefined\" || (typeof data === 'number' && !Number.isNaN(Number(data))),\n optionalString: typeof data === \"undefined\" || typeof data === 'string',\n optionalStringNumber: typeof data === \"undefined\" || typeof data === 'string' || typeof data === 'number',\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 if (!options.disableHooks) 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 if (!options.disableHooks) this.runKeyHook('onKeyMissingRotateOption', key, options);\n this.sysLog(`Key missing rotate option!`, { path, version });\n return { expired: key, 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 if (!options.disableHooks) this.runKeyHook('onKeyRenewed', resGetKey, options);\n this.sysLog(`Key renewed!`, { path, version });\n return resGetKey;\n }\n\n if (!ok && isExpired && !isRenewable && key) {\n if (!options.disableHooks) this.runKeyHook('onKeyExpired', path, key);\n this.sysLog(`Key expired!`, { path, version });\n return { expired: key, ready: null };\n }\n\n if (!ok) {\n if (!options.disableHooks) 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: secret } = this.cryptoService.generateSalt();\n\n this.sysLog(`Key generated\\nOptions:`, options);\n\n const hashedKey = this.cryptoService.hash(key, secret);\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 secret: secret,\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 /**\n * Verify a key by hashed key and path and version\n * @param hashedKey Hashed key to verify\n * @param path Path to the key\n * @param version Version of the key\n * @param disableGetKeyHooks Disable getKey method hooks, should not use hooks in this method\n * @returns True if the key is valid, false otherwise\n * \n * @example\n * ```ts\n * const isValid = await keyManager.verifyKey(hashedKey, path, version);\n * if (isValid) {\n * console.log('Key is valid!');\n * } else {\n * console.log('Key is invalid!');\n * }\n * ```\n * \n * @note\n * 1. This use getKey method to get key, so disableGetKeyHooks option is set to true, if disableGetKeyHooks is not provided, it will be set to true \n * \n * 2. Get key from store\n * - If the key is expired, the expired key will be used to verify the key\n * - If the key is not expired, the ready key will be used to verify the key\n * \n * 3. If the key is not found, the function will return false\n * \n * 4. Verify key strategy\n * - If the key is found and secret is provided, compare original key with hashed key using secret\n * - If the key is found and secret is not provided, compare original key with hashed key\n * \n */\n public async verifyKey(hashedKey: string, path: string, version: string | number, disableGetKeyHooks: boolean = true): Promise<boolean> {\n const { ready, expired } = await this.getKey({ path, version: String(version), disableHooks: disableGetKeyHooks });\n\n if (!ready && !expired) {\n this.sysLog(`Key not found to verify!`, { path, version });\n return false;\n }\n\n // if expire -> expired key, if not expire -> ready key\n // case both key appear when onRotate options is set\n const key = (expired ?? ready) as TKeyGenerated;\n\n this.sysLog('Verifying key...', { hashedKey, path, version, validateMethod: key.secret ? 'verifyHash(key, hashedKey, secret)' : 'hashedKey === key.hashed' });\n if (key.secret) return this.cryptoService.verifyHash(key.key, hashedKey, key.secret);\n\n return hashedKey === key.hashed;\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 secret: 'optionalString',\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,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "key-rotation-manager",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.1.2",
|
|
4
|
+
"description": "Production-ready cryptographic key management library for Node.js with automatic rotation, expiration, versioning, and flexible storage. Supports AES-256-CBC encryption, PBKDF2 key derivation, file-based storage, custom hooks, and TypeScript.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -27,11 +27,26 @@
|
|
|
27
27
|
"prepublishOnly": "npm run build"
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
30
|
+
"key-rotation",
|
|
31
|
+
"key-management",
|
|
32
|
+
"secret-management",
|
|
33
|
+
"api-key-rotation",
|
|
34
|
+
"credential-management",
|
|
35
|
+
"encryption",
|
|
36
|
+
"cryptography",
|
|
30
37
|
"typescript",
|
|
31
|
-
"
|
|
38
|
+
"nodejs"
|
|
32
39
|
],
|
|
33
40
|
"author": "Duco",
|
|
34
41
|
"license": "MIT",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/DucAnh2611/key-rotation-manager.git"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/DucAnh2611/key-rotation-manager#readme",
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/DucAnh2611/key-rotation-manager/issues"
|
|
49
|
+
},
|
|
35
50
|
"engines": {
|
|
36
51
|
"node": ">=18.0.0"
|
|
37
52
|
},
|