@fgv/ts-extras 5.1.0-21 → 5.1.0-23

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.
Files changed (72) hide show
  1. package/dist/packlets/ai-assist/index.js +2 -0
  2. package/dist/packlets/ai-assist/index.js.map +1 -1
  3. package/dist/packlets/ai-assist/jsonCompletion.js +95 -0
  4. package/dist/packlets/ai-assist/jsonCompletion.js.map +1 -0
  5. package/dist/packlets/ai-assist/jsonResponse.js +149 -0
  6. package/dist/packlets/ai-assist/jsonResponse.js.map +1 -0
  7. package/dist/packlets/crypto-utils/keystore/keyStore.js +81 -0
  8. package/dist/packlets/crypto-utils/keystore/keyStore.js.map +1 -1
  9. package/dist/packlets/crypto-utils/model.js.map +1 -1
  10. package/dist/packlets/crypto-utils/nodeCryptoProvider.js +9 -1
  11. package/dist/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -1
  12. package/dist/packlets/csv/csvFileHelpers.js +0 -14
  13. package/dist/packlets/csv/csvFileHelpers.js.map +1 -1
  14. package/dist/packlets/csv/csvHelpers.js +14 -0
  15. package/dist/packlets/csv/csvHelpers.js.map +1 -1
  16. package/dist/packlets/csv/index.browser.js +1 -3
  17. package/dist/packlets/csv/index.browser.js.map +1 -1
  18. package/dist/packlets/record-jar/index.browser.js +1 -3
  19. package/dist/packlets/record-jar/index.browser.js.map +1 -1
  20. package/dist/packlets/record-jar/recordJarFileHelpers.js +0 -18
  21. package/dist/packlets/record-jar/recordJarFileHelpers.js.map +1 -1
  22. package/dist/packlets/record-jar/recordJarHelpers.js +18 -0
  23. package/dist/packlets/record-jar/recordJarHelpers.js.map +1 -1
  24. package/dist/ts-extras.d.ts +239 -5
  25. package/lib/packlets/ai-assist/index.d.ts +2 -0
  26. package/lib/packlets/ai-assist/index.d.ts.map +1 -1
  27. package/lib/packlets/ai-assist/index.js +7 -1
  28. package/lib/packlets/ai-assist/index.js.map +1 -1
  29. package/lib/packlets/ai-assist/jsonCompletion.d.ts +93 -0
  30. package/lib/packlets/ai-assist/jsonCompletion.d.ts.map +1 -0
  31. package/lib/packlets/ai-assist/jsonCompletion.js +99 -0
  32. package/lib/packlets/ai-assist/jsonCompletion.js.map +1 -0
  33. package/lib/packlets/ai-assist/jsonResponse.d.ts +91 -0
  34. package/lib/packlets/ai-assist/jsonResponse.d.ts.map +1 -0
  35. package/lib/packlets/ai-assist/jsonResponse.js +154 -0
  36. package/lib/packlets/ai-assist/jsonResponse.js.map +1 -0
  37. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts +43 -1
  38. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts.map +1 -1
  39. package/lib/packlets/crypto-utils/keystore/keyStore.js +81 -0
  40. package/lib/packlets/crypto-utils/keystore/keyStore.js.map +1 -1
  41. package/lib/packlets/crypto-utils/model.d.ts +10 -1
  42. package/lib/packlets/crypto-utils/model.d.ts.map +1 -1
  43. package/lib/packlets/crypto-utils/model.js.map +1 -1
  44. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts +7 -1
  45. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts.map +1 -1
  46. package/lib/packlets/crypto-utils/nodeCryptoProvider.js +8 -0
  47. package/lib/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -1
  48. package/lib/packlets/csv/csvFileHelpers.d.ts +0 -10
  49. package/lib/packlets/csv/csvFileHelpers.d.ts.map +1 -1
  50. package/lib/packlets/csv/csvFileHelpers.js +0 -15
  51. package/lib/packlets/csv/csvFileHelpers.js.map +1 -1
  52. package/lib/packlets/csv/csvHelpers.d.ts +10 -0
  53. package/lib/packlets/csv/csvHelpers.d.ts.map +1 -1
  54. package/lib/packlets/csv/csvHelpers.js +15 -0
  55. package/lib/packlets/csv/csvHelpers.js.map +1 -1
  56. package/lib/packlets/csv/index.browser.d.ts +0 -1
  57. package/lib/packlets/csv/index.browser.d.ts.map +1 -1
  58. package/lib/packlets/csv/index.browser.js +1 -5
  59. package/lib/packlets/csv/index.browser.js.map +1 -1
  60. package/lib/packlets/record-jar/index.browser.d.ts +0 -1
  61. package/lib/packlets/record-jar/index.browser.d.ts.map +1 -1
  62. package/lib/packlets/record-jar/index.browser.js +1 -5
  63. package/lib/packlets/record-jar/index.browser.js.map +1 -1
  64. package/lib/packlets/record-jar/recordJarFileHelpers.d.ts +0 -11
  65. package/lib/packlets/record-jar/recordJarFileHelpers.d.ts.map +1 -1
  66. package/lib/packlets/record-jar/recordJarFileHelpers.js +0 -19
  67. package/lib/packlets/record-jar/recordJarFileHelpers.js.map +1 -1
  68. package/lib/packlets/record-jar/recordJarHelpers.d.ts +11 -0
  69. package/lib/packlets/record-jar/recordJarHelpers.d.ts.map +1 -1
  70. package/lib/packlets/record-jar/recordJarHelpers.js +19 -0
  71. package/lib/packlets/record-jar/recordJarHelpers.js.map +1 -1
  72. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"keyStore.js","sourceRoot":"","sources":["../../../../src/packlets/crypto-utils/keystore/keyStore.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { JsonValue } from '@fgv/ts-json-base';\nimport { captureResult, fail, Result, succeed } from '@fgv/ts-utils';\nimport * as Constants from '../constants';\nimport { createEncryptedFile } from '../encryptedFile';\nimport {\n ICryptoProvider,\n IEncryptedFile,\n IEncryptionConfig,\n IEncryptionProvider,\n SecretProvider\n} from '../model';\nimport {\n DEFAULT_KEYSTORE_ITERATIONS,\n DEFAULT_SECRET_ITERATIONS,\n IAddKeyPairOptions,\n IAddKeyPairResult,\n IAddSecretFromPasswordOptions,\n IAddSecretFromPasswordResult,\n IAddSecretOptions,\n IAddSecretResult,\n IImportKeyOptions,\n IImportSecretOptions,\n IKeyStoreAsymmetricEntry,\n IKeyStoreCreateParams,\n IKeyStoreEntry,\n IKeyStoreEntryJson,\n IKeyStoreFile,\n IKeyStoreOpenParams,\n IKeyStoreSymmetricEntry,\n IKeyStoreVaultContents,\n IRemoveSecretResult,\n KEYSTORE_FORMAT,\n KeyStoreLockState,\n KeyStoreSecretType,\n MIN_SALT_LENGTH\n} from './model';\nimport { IPrivateKeyStorage } from './privateKeyStorage';\nimport { keystoreFile, keystoreVaultContents } from './converters';\n\n/**\n * Gets the current ISO timestamp.\n */\nfunction getCurrentTimestamp(): string {\n return new Date().toISOString();\n}\n\n// ============================================================================\n// KeyStore Class\n// ============================================================================\n\n/**\n * Password-protected key store for managing encryption secrets.\n *\n * The KeyStore provides a secure vault for storing named encryption keys.\n * The vault is encrypted at rest using a master password via PBKDF2 key derivation.\n *\n * @example\n * ```typescript\n * // Create new key store\n * const keystore = KeyStore.create({ cryptoProvider: nodeCryptoProvider }).orThrow();\n * await keystore.initialize('master-password');\n *\n * // Add secrets\n * await keystore.addSecret('my-key', { description: 'Production key' });\n *\n * // Save to file\n * const fileContent = await keystore.save();\n *\n * // Later: Open existing key store\n * const keystore2 = KeyStore.open({\n * cryptoProvider: nodeCryptoProvider,\n * keystoreFile: fileContent.value\n * }).orThrow();\n * await keystore2.unlock('master-password');\n *\n * // Use as secret provider for encrypted file loading\n * const encryptionConfig = keystore2.getEncryptionConfig().orThrow();\n * ```\n *\n * @public\n */\nexport class KeyStore implements IEncryptionProvider {\n private readonly _cryptoProvider: ICryptoProvider;\n private readonly _privateKeyStorage: IPrivateKeyStorage | undefined;\n private readonly _iterations: number;\n private _keystoreFile: IKeyStoreFile | undefined;\n private _salt: Uint8Array | undefined;\n private _secrets: Map<string, IKeyStoreEntry> | undefined;\n private _state: KeyStoreLockState;\n private _dirty: boolean;\n private _isNew: boolean;\n\n private constructor(\n cryptoProvider: ICryptoProvider,\n iterations: number,\n keystoreFile: IKeyStoreFile | undefined,\n isNew: boolean,\n privateKeyStorage: IPrivateKeyStorage | undefined\n ) {\n this._cryptoProvider = cryptoProvider;\n this._privateKeyStorage = privateKeyStorage;\n this._iterations = iterations;\n this._keystoreFile = keystoreFile;\n this._state = 'locked';\n this._dirty = false;\n this._isNew = isNew;\n }\n\n // ============================================================================\n // Factory Methods\n // ============================================================================\n\n /**\n * Creates a new, empty key store.\n * Call `initialize(password)` to set the master password.\n * @param params - Creation parameters\n * @returns Success with new KeyStore instance, or Failure if parameters invalid\n * @public\n */\n public static create(params: IKeyStoreCreateParams): Result<KeyStore> {\n const iterations = params.iterations ?? DEFAULT_KEYSTORE_ITERATIONS;\n if (iterations < 1) {\n return fail('Iterations must be at least 1');\n }\n return succeed(\n new KeyStore(params.cryptoProvider, iterations, undefined, true, params.privateKeyStorage)\n );\n }\n\n /**\n * Opens an existing encrypted key store.\n * Call `unlock(password)` to decrypt and access secrets.\n * @param params - Open parameters including the encrypted file\n * @returns Success with KeyStore instance, or Failure if file format invalid\n * @public\n */\n public static open(params: IKeyStoreOpenParams): Result<KeyStore> {\n // Validate the file format\n const fileResult = keystoreFile.convert(params.keystoreFile);\n if (fileResult.isFailure()) {\n return fail(`Invalid key store file: ${fileResult.message}`);\n }\n\n const iterations = fileResult.value.keyDerivation.iterations;\n return succeed(\n new KeyStore(params.cryptoProvider, iterations, fileResult.value, false, params.privateKeyStorage)\n );\n }\n\n // ============================================================================\n // Lifecycle Methods\n // ============================================================================\n\n /**\n * Initializes a new key store with the master password.\n * Generates a random salt for key derivation.\n * Only valid for newly created (not opened) key stores.\n * @param password - The master password\n * @returns Success with this instance when initialized, Failure if already initialized or opened\n * @public\n */\n public async initialize(password: string): Promise<Result<KeyStore>> {\n if (!this._isNew) {\n return fail('Cannot initialize an opened key store - use unlock() instead');\n }\n if (this._state === 'unlocked') {\n return fail('Key store is already initialized');\n }\n if (!password || password.length === 0) {\n return fail('Password cannot be empty');\n }\n\n // Generate salt for this key store using crypto provider\n const saltResult = this._cryptoProvider.generateRandomBytes(MIN_SALT_LENGTH);\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (saltResult.isFailure()) {\n return fail(`Failed to generate salt: ${saltResult.message}`);\n }\n\n this._salt = saltResult.value;\n this._secrets = new Map();\n this._state = 'unlocked';\n this._dirty = true; // New store needs to be saved\n\n return succeed(this);\n }\n\n /**\n * Unlocks an existing key store with the master password.\n * Decrypts the vault and loads secrets into memory.\n * @param password - The master password\n * @returns Success with this instance when unlocked, Failure if password incorrect\n * @public\n */\n public async unlock(password: string): Promise<Result<KeyStore>> {\n if (this._isNew) {\n return fail('Cannot unlock a new key store - use initialize() instead');\n }\n /* c8 ignore next 6 - error paths tested but coverage intermittently missed */\n if (this._state === 'unlocked') {\n return fail('Key store is already unlocked');\n }\n if (!this._keystoreFile) {\n return fail('No key store file to unlock');\n }\n\n const keyDerivation = this._keystoreFile.keyDerivation;\n const saltResult = this._cryptoProvider.fromBase64(keyDerivation.salt);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (saltResult.isFailure()) {\n return fail(`Invalid salt in key store file: ${saltResult.message}`);\n }\n const salt = saltResult.value;\n\n // Derive the key from password\n const keyResult = await this._cryptoProvider.deriveKey(password, salt, keyDerivation.iterations);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (keyResult.isFailure()) {\n return fail(`Key derivation failed: ${keyResult.message}`);\n }\n\n return this._decryptVault(keyResult.value);\n }\n\n /**\n * Unlocks an existing key store with a pre-derived key, bypassing\n * PBKDF2 key derivation. Use this when the derived key has been\n * stored externally (e.g., in another key store) and the original\n * password is no longer available.\n *\n * The supplied key must have been derived from the correct password\n * using the key store file's own PBKDF2 parameters (salt and\n * iteration count).\n *\n * @param derivedKey - The pre-derived master key (32 bytes for AES-256)\n * @returns Success with this instance when unlocked, Failure if key is incorrect\n * @public\n */\n public async unlockWithKey(derivedKey: Uint8Array): Promise<Result<KeyStore>> {\n if (this._isNew) {\n return fail('Cannot unlock a new key store - use initialize() instead');\n }\n if (this._state === 'unlocked') {\n return fail('Key store is already unlocked');\n }\n if (derivedKey.length !== Constants.AES_256_KEY_SIZE) {\n return fail(`Key must be ${Constants.AES_256_KEY_SIZE} bytes, got ${derivedKey.length}`);\n }\n /* c8 ignore next 3 - defensive coding: unreachable via public API (open sets file, create sets isNew) */\n if (!this._keystoreFile) {\n return fail('No key store file to unlock');\n }\n\n return this._decryptVault(derivedKey);\n }\n\n /**\n * Locks the key store, clearing all secrets from memory.\n * @param force - If true, discards unsaved changes\n * @returns Success when locked, Failure if unsaved changes and !force\n * @public\n */\n public lock(force?: boolean): Result<KeyStore> {\n if (this._state === 'locked') {\n return succeed(this);\n }\n\n if (this._dirty && !force) {\n return fail('Unsaved changes - use force=true to discard or save() first');\n }\n\n // Clear secrets from memory (overwrite for security)\n if (this._secrets) {\n for (const entry of this._secrets.values()) {\n if (entry.type !== 'asymmetric-keypair') {\n entry.key.fill(0);\n }\n }\n this._secrets.clear();\n this._secrets = undefined;\n }\n\n this._state = 'locked';\n this._dirty = false;\n\n return succeed(this);\n }\n\n /**\n * Checks if the key store is unlocked.\n * @public\n */\n public get isUnlocked(): boolean {\n return this._state === 'unlocked';\n }\n\n /**\n * Checks if there are unsaved changes.\n * @public\n */\n public get isDirty(): boolean {\n return this._dirty;\n }\n\n /**\n * Whether this is a newly created key store (not opened from a file).\n * A new key store must be initialized with a password before use.\n * An opened key store must be unlocked with the existing password.\n * @public\n */\n public get isNew(): boolean {\n return this._isNew;\n }\n\n /**\n * Gets the current lock state.\n * @public\n */\n public get state(): KeyStoreLockState {\n return this._state;\n }\n\n /**\n * Gets the crypto provider used by this key store.\n * Available regardless of lock state.\n * @public\n */\n public get cryptoProvider(): ICryptoProvider {\n return this._cryptoProvider;\n }\n\n // ============================================================================\n // Secret Management\n // ============================================================================\n\n /**\n * Lists all secret names in the key store.\n * @returns Success with array of secret names, Failure if locked\n * @public\n */\n public listSecrets(): Result<readonly string[]> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n return succeed(Array.from(this._secrets.keys()));\n }\n\n /**\n * Gets a secret by name. Returns the {@link CryptoUtils.KeyStore.IKeyStoreEntry | discriminated union}\n * — callers must check `entry.type` before accessing `key`/`id` since asymmetric\n * entries carry no raw key material.\n * @param name - Name of the secret\n * @returns Success with secret entry, Failure if not found or locked\n * @public\n */\n public getSecret(name: string): Result<IKeyStoreEntry> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n const entry = this._secrets.get(name);\n if (!entry) {\n return fail(`Secret '${name}' not found`);\n }\n return succeed(entry);\n }\n\n /**\n * Returns the public-key JWK for an asymmetric-keypair entry.\n * Available without {@link CryptoUtils.KeyStore.IPrivateKeyStorage} since the\n * public key lives in the vault metadata directly.\n * @param name - Name of the entry\n * @returns Success with the JWK, Failure if not found, locked, or wrong type\n * @public\n */\n public getPublicKeyJwk(name: string): Result<JsonWebKey> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n const entry = this._secrets.get(name);\n if (!entry) {\n return fail(`Secret '${name}' not found`);\n }\n if (entry.type !== 'asymmetric-keypair') {\n return fail(`Secret '${name}' is not an asymmetric keypair (type: ${entry.type})`);\n }\n return succeed(entry.publicKeyJwk);\n }\n\n /**\n * Checks if a secret exists.\n * @param name - Name of the secret\n * @returns Success with boolean, Failure if locked\n * @public\n */\n public hasSecret(name: string): Result<boolean> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n return succeed(this._secrets.has(name));\n }\n\n /**\n * Adds a new secret with a randomly generated key.\n * @param name - Unique name for the secret\n * @param options - Optional description\n * @returns Success with the generated entry, Failure if locked or name invalid\n * @public\n */\n public async addSecret(name: string, options?: IAddSecretOptions): Promise<Result<IAddSecretResult>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!name || name.length === 0) {\n return fail('Secret name cannot be empty');\n }\n\n // Generate a new random key\n const keyResult = await this._cryptoProvider.generateKey();\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (keyResult.isFailure()) {\n return fail(`Failed to generate key: ${keyResult.message}`);\n }\n\n const entry: IKeyStoreSymmetricEntry = {\n name,\n type: 'encryption-key',\n key: keyResult.value,\n description: options?.description,\n createdAt: getCurrentTimestamp()\n };\n\n const existing = this._secrets.get(name);\n const warning = existing ? await this._releaseEntryResources(existing) : undefined;\n\n this._secrets.set(name, entry);\n this._dirty = true;\n\n return succeed({ entry, replaced: existing !== undefined, warning });\n }\n\n /**\n * Imports raw 32-byte key material into the vault.\n *\n * Always validates that the key is exactly 32 bytes (AES-256). The optional\n * `type` field is a classification label stored with the entry; it does not\n * change the validation rules. For importing UTF-8 API key strings (variable\n * length), use {@link KeyStore.importApiKey} instead.\n *\n * @param name - Unique name for the secret\n * @param key - The 32-byte AES-256 key material\n * @param options - Optional type classification, description, whether to replace existing\n * @returns Success with entry, Failure if locked, key invalid, or exists and !replace\n * @public\n */\n public async importSecret(\n name: string,\n key: Uint8Array,\n options?: IImportKeyOptions\n ): Promise<Result<IAddSecretResult>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!name || name.length === 0) {\n return fail('Secret name cannot be empty');\n }\n if (key.length !== Constants.AES_256_KEY_SIZE) {\n return fail(`Key must be ${Constants.AES_256_KEY_SIZE} bytes, got ${key.length}`);\n }\n\n const existing = this._secrets.get(name);\n if (existing && !options?.replace) {\n return fail(`Secret '${name}' already exists - use replace=true to overwrite`);\n }\n\n const entry: IKeyStoreSymmetricEntry = {\n name,\n type: options?.type ?? 'encryption-key',\n key: new Uint8Array(key), // Copy to prevent external modification\n description: options?.description,\n createdAt: getCurrentTimestamp()\n };\n\n const warning = existing ? await this._releaseEntryResources(existing) : undefined;\n this._secrets.set(name, entry);\n this._dirty = true;\n\n return succeed({ entry, replaced: existing !== undefined, warning });\n }\n\n /**\n * Adds a secret derived from a password using PBKDF2.\n *\n * Generates a random salt, derives a 32-byte AES-256 key from the password,\n * and stores it in the vault. Returns the key derivation parameters so they\n * can be stored alongside encrypted files, enabling decryption with just the\n * password (without unlocking the keystore).\n *\n * @param name - Unique name for the secret\n * @param password - Password to derive the key from\n * @param options - Optional description, iterations, replace flag\n * @returns Success with entry and keyDerivation params, Failure if locked or invalid\n * @public\n */\n public async addSecretFromPassword(\n name: string,\n password: string,\n options?: IAddSecretFromPasswordOptions\n ): Promise<Result<IAddSecretFromPasswordResult>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!name || name.length === 0) {\n return fail('Secret name cannot be empty');\n }\n if (!password || password.length === 0) {\n return fail('Password cannot be empty');\n }\n\n const existing = this._secrets.get(name);\n if (existing && !options?.replace) {\n return fail(`Secret '${name}' already exists - use replace=true to overwrite`);\n }\n\n const iterations = options?.iterations ?? DEFAULT_SECRET_ITERATIONS;\n\n // Generate a random salt for this secret's key derivation\n const saltResult = this._cryptoProvider.generateRandomBytes(MIN_SALT_LENGTH);\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (saltResult.isFailure()) {\n return fail(`Failed to generate salt: ${saltResult.message}`);\n }\n\n // Derive the key from password\n const keyResult = await this._cryptoProvider.deriveKey(password, saltResult.value, iterations);\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (keyResult.isFailure()) {\n return fail(`Key derivation failed: ${keyResult.message}`);\n }\n\n const entry: IKeyStoreSymmetricEntry = {\n name,\n type: 'encryption-key',\n key: keyResult.value,\n description: options?.description,\n createdAt: getCurrentTimestamp()\n };\n\n const warning = existing ? await this._releaseEntryResources(existing) : undefined;\n this._secrets.set(name, entry);\n this._dirty = true;\n\n return succeed({\n entry,\n replaced: existing !== undefined,\n warning,\n keyDerivation: {\n kdf: 'pbkdf2',\n salt: this._cryptoProvider.toBase64(saltResult.value),\n iterations\n }\n });\n }\n\n /**\n * Removes a secret by name. Vault-first: the in-memory vault entry is dropped\n * before any storage cleanup runs. For asymmetric-keypair entries, best-effort\n * calls {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete on the entry's\n * `id`; a failure is reported via `warning` on the result but does not roll\n * back the vault removal.\n * @param name - Name of the secret to remove\n * @returns Success with removed entry (and optional warning), Failure if not found or locked\n * @public\n */\n public async removeSecret(name: string): Promise<Result<IRemoveSecretResult>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n\n const entry = this._secrets.get(name);\n if (!entry) {\n return fail(`Secret '${name}' not found`);\n }\n\n // Vault-first: drop the in-memory entry before touching storage so a\n // storage failure cannot block removal.\n this._secrets.delete(name);\n this._dirty = true;\n\n const warning = await this._releaseEntryResources(entry);\n return succeed({ entry, warning });\n }\n\n /**\n * Imports an API key string into the vault.\n * The string is UTF-8 encoded and stored with type `'api-key'`.\n * @param name - Unique name for the secret\n * @param apiKey - The API key string\n * @param options - Optional description, whether to replace existing\n * @returns Success with entry, Failure if locked, empty, or exists and !replace\n * @public\n */\n public async importApiKey(\n name: string,\n apiKey: string,\n options?: IImportSecretOptions\n ): Promise<Result<IAddSecretResult>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!name || name.length === 0) {\n return fail('Secret name cannot be empty');\n }\n if (!apiKey || apiKey.length === 0) {\n return fail('API key cannot be empty');\n }\n\n const existing = this._secrets.get(name);\n if (existing && !options?.replace) {\n return fail(`Secret '${name}' already exists - use replace=true to overwrite`);\n }\n\n const encoder = new TextEncoder();\n const entry: IKeyStoreSymmetricEntry = {\n name,\n type: 'api-key',\n key: encoder.encode(apiKey),\n description: options?.description,\n createdAt: getCurrentTimestamp()\n };\n\n const warning = existing ? await this._releaseEntryResources(existing) : undefined;\n this._secrets.set(name, entry);\n this._dirty = true;\n\n return succeed({ entry, replaced: existing !== undefined, warning });\n }\n\n /**\n * Retrieves an API key string by name.\n * Only works for secrets with type `'api-key'`.\n * @param name - Name of the secret\n * @returns Success with the API key string, Failure if not found, locked, or wrong type\n * @public\n */\n public getApiKey(name: string): Result<string> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n const entry = this._secrets.get(name);\n if (!entry) {\n return fail(`Secret '${name}' not found`);\n }\n if (entry.type !== 'api-key') {\n return fail(`Secret '${name}' is not an API key (type: ${entry.type})`);\n }\n const decoder = new TextDecoder();\n return succeed(decoder.decode(entry.key));\n }\n\n // ============================================================================\n // Asymmetric Keypair Management\n // ============================================================================\n\n /**\n * Adds a new asymmetric keypair to the vault. Storage-first: the private key\n * is stored under a freshly-minted `id` before the public-key vault entry is\n * committed. If the storage call fails, no vault entry is written and the\n * operation returns Failure.\n *\n * When `replace: true` displaces an existing entry (asymmetric or symmetric),\n * a fresh `id` is minted; the displaced entry's resources are released\n * best-effort. Failure of the storage delete is reported via `warning` on the\n * result but does not roll back the replacement.\n *\n * Requires a {@link CryptoUtils.KeyStore.IPrivateKeyStorage} backend\n * supplied at construction.\n *\n * @param name - Unique name for the entry\n * @param options - Algorithm, optional description, replace flag\n * @returns Success with the new entry, Failure if locked, no provider, or storage write failed\n * @public\n */\n public async addKeyPair(name: string, options: IAddKeyPairOptions): Promise<Result<IAddKeyPairResult>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!name || name.length === 0) {\n return fail('Entry name cannot be empty');\n }\n if (!this._privateKeyStorage) {\n return fail('No private key storage configured');\n }\n\n const existing = this._secrets.get(name);\n if (existing && !options.replace) {\n return fail(`Secret '${name}' already exists - use replace=true to overwrite`);\n }\n\n // Generate the keypair before touching storage. extractable=true on backends\n // that round-trip via JWK; extractable=false on backends that hold CryptoKey\n // refs directly.\n const extractable = !this._privateKeyStorage.supportsNonExtractable;\n const keyPairResult = await this._cryptoProvider.generateKeyPair(options.algorithm, extractable);\n /* c8 ignore next 3 - crypto provider errors covered in nodeCryptoProvider tests; cannot be triggered here without mocking */\n if (keyPairResult.isFailure()) {\n return fail(`Failed to generate keypair for '${name}': ${keyPairResult.message}`);\n }\n const { publicKey, privateKey } = keyPairResult.value;\n\n const jwkResult = await this._cryptoProvider.exportPublicKeyJwk(publicKey);\n /* c8 ignore next 3 - export of an extractable freshly-generated public key is hard to fail */\n if (jwkResult.isFailure()) {\n return fail(`Failed to export public key for '${name}': ${jwkResult.message}`);\n }\n\n const idResult = this._generateId();\n /* c8 ignore next 3 - random-bytes failure is hard to trigger with a healthy provider */\n if (idResult.isFailure()) {\n return fail(`Failed to mint storage id for '${name}': ${idResult.message}`);\n }\n const id = idResult.value;\n\n // Storage-first: write the private key before committing the vault entry.\n const storeResult = await this._privateKeyStorage.store(id, privateKey);\n if (storeResult.isFailure()) {\n return fail(`Failed to persist private key for '${name}': ${storeResult.message}`);\n }\n\n const entry: IKeyStoreAsymmetricEntry = {\n name,\n type: 'asymmetric-keypair',\n id,\n algorithm: options.algorithm,\n publicKeyJwk: jwkResult.value,\n description: options.description,\n createdAt: getCurrentTimestamp()\n };\n\n const warning = existing ? await this._releaseEntryResources(existing) : undefined;\n this._secrets.set(name, entry);\n this._dirty = true;\n\n return succeed({ entry, replaced: existing !== undefined, warning });\n }\n\n /**\n * Retrieves the keypair for an asymmetric-keypair entry. The private key is\n * loaded from {@link CryptoUtils.KeyStore.IPrivateKeyStorage} on every call —\n * the keystore never caches private `CryptoKey` references between calls.\n * The public key is re-imported from the vault's JWK so callers always\n * receive a `CryptoKey` rather than the JWK form.\n * @param name - Name of the entry\n * @returns Success with `{ publicKey, privateKey }`, Failure if not found,\n * locked, wrong type, no provider, or storage load failed.\n * @public\n */\n public async getKeyPair(name: string): Promise<Result<{ publicKey: CryptoKey; privateKey: CryptoKey }>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n const entry = this._secrets.get(name);\n if (!entry) {\n return fail(`Secret '${name}' not found`);\n }\n if (entry.type !== 'asymmetric-keypair') {\n return fail(`Secret '${name}' is not an asymmetric keypair (type: ${entry.type})`);\n }\n if (!this._privateKeyStorage) {\n return fail('No private key storage configured');\n }\n\n const privateResult = await this._privateKeyStorage.load(entry.id);\n if (privateResult.isFailure()) {\n return fail(`Failed to load private key for '${name}': ${privateResult.message}`);\n }\n\n const publicResult = await this._cryptoProvider.importPublicKeyJwk(entry.publicKeyJwk, entry.algorithm);\n /* c8 ignore next 3 - vault JWKs that previously exported cleanly are extremely unlikely to fail re-import */\n if (publicResult.isFailure()) {\n return fail(`Failed to re-import public key for '${name}': ${publicResult.message}`);\n }\n\n return succeed({ publicKey: publicResult.value, privateKey: privateResult.value });\n }\n\n /**\n * Lists secret names filtered by type.\n * @param type - The secret type to filter by\n * @returns Success with array of matching secret names, Failure if locked\n * @public\n */\n public listSecretsByType(type: KeyStoreSecretType): Result<readonly string[]> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n const names: string[] = [];\n for (const [name, entry] of this._secrets) {\n if (entry.type === type) {\n names.push(name);\n }\n }\n return succeed(names);\n }\n\n /**\n * Renames a secret.\n * @param oldName - Current name\n * @param newName - New name\n * @returns Success with updated entry, Failure if source not found, target exists, or locked\n * @public\n */\n public renameSecret(oldName: string, newName: string): Result<IKeyStoreEntry> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!newName || newName.length === 0) {\n return fail('New name cannot be empty');\n }\n\n const entry = this._secrets.get(oldName);\n if (!entry) {\n return fail(`Secret '${oldName}' not found`);\n }\n\n if (oldName !== newName && this._secrets.has(newName)) {\n return fail(`Secret '${newName}' already exists`);\n }\n\n // Create new entry with new name. For asymmetric entries the spread\n // preserves `id` so the storage handle survives the rename.\n const newEntry: IKeyStoreEntry = {\n ...entry,\n name: newName\n };\n\n this._secrets.delete(oldName);\n this._secrets.set(newName, newEntry);\n this._dirty = true;\n\n return succeed(newEntry);\n }\n\n // ============================================================================\n // Persistence\n // ============================================================================\n\n /**\n * Saves the key store, returning the encrypted file content.\n * Requires the master password to encrypt.\n * @param password - The master password\n * @returns Success with IKeyStoreFile, Failure if locked\n * @public\n */\n public async save(password: string): Promise<Result<IKeyStoreFile>> {\n if (!this._secrets || !this._salt) {\n return fail('Key store is locked');\n }\n if (!password || password.length === 0) {\n return fail('Password cannot be empty');\n }\n\n // Derive the encryption key\n const keyResult = await this._cryptoProvider.deriveKey(password, this._salt, this._iterations);\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (keyResult.isFailure()) {\n return fail(`Key derivation failed: ${keyResult.message}`);\n }\n\n return this._encryptVault(keyResult.value);\n }\n\n /**\n * Saves the key store using a pre-derived key, bypassing PBKDF2 key\n * derivation. Use this when the derived key has been stored externally\n * (e.g., in another key store) and the original password is no longer\n * available.\n *\n * The supplied key must be the same key that was (or would be) derived\n * from the master password using the key store's PBKDF2 parameters.\n *\n * @param derivedKey - The pre-derived master key (32 bytes for AES-256)\n * @returns Success with IKeyStoreFile, Failure if locked or key invalid\n * @public\n */\n public async saveWithKey(derivedKey: Uint8Array): Promise<Result<IKeyStoreFile>> {\n if (!this._secrets || !this._salt) {\n return fail('Key store is locked');\n }\n if (derivedKey.length !== Constants.AES_256_KEY_SIZE) {\n return fail(`Key must be ${Constants.AES_256_KEY_SIZE} bytes, got ${derivedKey.length}`);\n }\n\n return this._encryptVault(derivedKey);\n }\n\n /**\n * Changes the master password.\n * Re-encrypts the vault with the new password-derived key.\n * @param currentPassword - Current master password (for verification)\n * @param newPassword - New master password\n * @returns Success when password changed, Failure if locked or current password incorrect\n * @public\n */\n public async changePassword(currentPassword: string, newPassword: string): Promise<Result<KeyStore>> {\n if (!this._secrets || !this._salt) {\n return fail('Key store is locked');\n }\n if (!newPassword || newPassword.length === 0) {\n return fail('New password cannot be empty');\n }\n\n // Verify current password by trying to derive and re-encrypt\n // (For opened stores, we'd need to verify against the stored file)\n if (this._keystoreFile) {\n const saltResult = this._cryptoProvider.fromBase64(this._keystoreFile.keyDerivation.salt);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (saltResult.isFailure()) {\n return fail(`Invalid salt in key store file: ${saltResult.message}`);\n }\n\n const keyResult = await this._cryptoProvider.deriveKey(\n currentPassword,\n saltResult.value,\n this._keystoreFile.keyDerivation.iterations\n );\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (keyResult.isFailure()) {\n return fail(`Key derivation failed: ${keyResult.message}`);\n }\n\n // Try to decrypt to verify password\n const ivResult = this._cryptoProvider.fromBase64(this._keystoreFile.iv);\n const authTagResult = this._cryptoProvider.fromBase64(this._keystoreFile.authTag);\n const encryptedDataResult = this._cryptoProvider.fromBase64(this._keystoreFile.encryptedData);\n\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (ivResult.isFailure() || authTagResult.isFailure() || encryptedDataResult.isFailure()) {\n return fail('Invalid key store file format');\n }\n\n const decryptResult = await this._cryptoProvider.decrypt(\n encryptedDataResult.value,\n keyResult.value,\n ivResult.value,\n authTagResult.value\n );\n if (decryptResult.isFailure()) {\n return fail('Current password is incorrect');\n }\n }\n\n // Generate new salt for the new password using crypto provider\n const saltResult = this._cryptoProvider.generateRandomBytes(MIN_SALT_LENGTH);\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (saltResult.isFailure()) {\n return fail(`Failed to generate salt: ${saltResult.message}`);\n }\n\n this._salt = saltResult.value;\n this._dirty = true;\n\n // Save with new password\n const saveResult = await this.save(newPassword);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (saveResult.isFailure()) {\n return fail(saveResult.message);\n }\n return succeed(this);\n }\n\n // ============================================================================\n // IEncryptionProvider\n // ============================================================================\n\n /** {@inheritDoc IEncryptionProvider.encryptByName} */\n public async encryptByName<TMetadata = JsonValue>(\n secretName: string,\n content: JsonValue,\n metadata?: TMetadata\n ): Promise<Result<IEncryptedFile<TMetadata>>> {\n const secretResult = this.getSecret(secretName);\n if (secretResult.isFailure()) {\n return fail(`encryptByName: ${secretResult.message}`);\n }\n if (secretResult.value.type === 'asymmetric-keypair') {\n return fail(\n `encryptByName: secret '${secretName}' is an asymmetric keypair, not symmetric key material`\n );\n }\n\n return createEncryptedFile({\n content,\n secretName,\n key: secretResult.value.key,\n cryptoProvider: this._cryptoProvider,\n metadata\n });\n }\n\n // ============================================================================\n // Integration with IEncryptionConfig\n // ============================================================================\n\n /**\n * Creates a SecretProvider function for use with IEncryptionConfig.\n * The returned function looks up secrets from this key store.\n * @returns Success with SecretProvider, Failure if locked\n * @public\n */\n public getSecretProvider(): Result<SecretProvider> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n\n const secrets = this._secrets;\n const provider: SecretProvider = async (secretName: string): Promise<Result<Uint8Array>> => {\n const entry = secrets.get(secretName);\n if (!entry) {\n return fail(`Secret '${secretName}' not found in key store`);\n }\n if (entry.type === 'asymmetric-keypair') {\n return fail(`Secret '${secretName}' is an asymmetric keypair, not symmetric key material`);\n }\n return succeed(entry.key);\n };\n\n return succeed(provider);\n }\n\n /**\n * Creates a partial IEncryptionConfig using this key store as the secret source.\n * @returns Partial config that can be spread into a full IEncryptionConfig\n * @public\n */\n public getEncryptionConfig(): Result<Pick<IEncryptionConfig, 'secretProvider' | 'cryptoProvider'>> {\n const providerResult = this.getSecretProvider();\n if (providerResult.isFailure()) {\n return fail(providerResult.message);\n }\n\n return succeed({\n secretProvider: providerResult.value,\n cryptoProvider: this._cryptoProvider\n });\n }\n\n // ============================================================================\n // Private: Vault Encryption / Decryption\n // ============================================================================\n\n /**\n * Encrypts the vault with a derived key and returns the key store file.\n * Shared by `save()` and `saveWithKey()`.\n */\n private async _encryptVault(derivedKey: Uint8Array): Promise<Result<IKeyStoreFile>> {\n // _secrets and _salt are guaranteed non-undefined by callers\n const secrets = this._secrets!;\n const salt = this._salt!;\n\n // Build vault contents\n const secretEntries: Record<string, IKeyStoreEntryJson> = {};\n for (const [name, entry] of secrets) {\n if (entry.type === 'asymmetric-keypair') {\n secretEntries[name] = {\n name: entry.name,\n type: entry.type,\n id: entry.id,\n algorithm: entry.algorithm,\n publicKeyJwk: entry.publicKeyJwk,\n description: entry.description,\n createdAt: entry.createdAt\n };\n } else {\n secretEntries[name] = {\n name: entry.name,\n type: entry.type,\n key: this._cryptoProvider.toBase64(entry.key),\n description: entry.description,\n createdAt: entry.createdAt\n };\n }\n }\n\n const vaultContents: IKeyStoreVaultContents = {\n version: KEYSTORE_FORMAT,\n secrets: secretEntries\n };\n\n // Serialize and encrypt\n const jsonResult = captureResult(() => JSON.stringify(vaultContents));\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (jsonResult.isFailure()) {\n return fail(`Failed to serialize vault: ${jsonResult.message}`);\n }\n\n const encryptResult = await this._cryptoProvider.encrypt(jsonResult.value, derivedKey);\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (encryptResult.isFailure()) {\n return fail(`Encryption failed: ${encryptResult.message}`);\n }\n\n const { iv, authTag, encryptedData } = encryptResult.value;\n\n const keystoreFileData: IKeyStoreFile = {\n format: KEYSTORE_FORMAT,\n algorithm: Constants.DEFAULT_ALGORITHM,\n iv: this._cryptoProvider.toBase64(iv),\n authTag: this._cryptoProvider.toBase64(authTag),\n encryptedData: this._cryptoProvider.toBase64(encryptedData),\n keyDerivation: {\n kdf: 'pbkdf2',\n salt: this._cryptoProvider.toBase64(salt),\n iterations: this._iterations\n }\n };\n\n this._keystoreFile = keystoreFileData;\n this._dirty = false;\n this._isNew = false;\n\n return succeed(keystoreFileData);\n }\n\n /**\n * Decrypts the vault with a derived key and loads secrets into memory.\n * Shared by `unlock()` and `unlockWithKey()`.\n */\n private async _decryptVault(derivedKey: Uint8Array): Promise<Result<KeyStore>> {\n const keystoreFile = this._keystoreFile;\n if (keystoreFile === undefined) {\n return fail('No key store file loaded');\n }\n\n const ivResult = this._cryptoProvider.fromBase64(keystoreFile.iv);\n const authTagResult = this._cryptoProvider.fromBase64(keystoreFile.authTag);\n const encryptedDataResult = this._cryptoProvider.fromBase64(keystoreFile.encryptedData);\n\n /* c8 ignore next 9 - base64 decode errors tested but coverage intermittently missed */\n if (ivResult.isFailure()) {\n return fail(`Invalid IV in key store file: ${ivResult.message}`);\n }\n if (authTagResult.isFailure()) {\n return fail(`Invalid auth tag in key store file: ${authTagResult.message}`);\n }\n if (encryptedDataResult.isFailure()) {\n return fail(`Invalid encrypted data in key store file: ${encryptedDataResult.message}`);\n }\n\n const decryptResult = await this._cryptoProvider.decrypt(\n encryptedDataResult.value,\n derivedKey,\n ivResult.value,\n authTagResult.value\n );\n if (decryptResult.isFailure()) {\n return fail('Incorrect password or corrupted key store');\n }\n\n // Parse the vault contents\n const parseResult = captureResult(() => JSON.parse(decryptResult.value) as unknown);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (parseResult.isFailure()) {\n return fail(`Failed to parse vault contents: ${parseResult.message}`);\n }\n\n const vaultResult = keystoreVaultContents.convert(parseResult.value);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (vaultResult.isFailure()) {\n return fail(`Invalid vault format: ${vaultResult.message}`);\n }\n\n // Build secrets into local variables to avoid partial state on failure\n const saltResult = this._cryptoProvider.fromBase64(keystoreFile.keyDerivation.salt);\n if (saltResult.isFailure()) {\n return fail(`Invalid salt in key store file: ${saltResult.message}`);\n }\n const secrets = new Map<string, IKeyStoreEntry>();\n for (const [name, jsonEntry] of Object.entries(vaultResult.value.secrets)) {\n if (jsonEntry.type === 'asymmetric-keypair') {\n const entry: IKeyStoreAsymmetricEntry = {\n name,\n type: jsonEntry.type,\n id: jsonEntry.id,\n algorithm: jsonEntry.algorithm,\n publicKeyJwk: jsonEntry.publicKeyJwk,\n description: jsonEntry.description,\n createdAt: jsonEntry.createdAt\n };\n secrets.set(name, entry);\n } else {\n const keyBytesResult = this._cryptoProvider.fromBase64(jsonEntry.key);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (keyBytesResult.isFailure()) {\n return fail(`Invalid key for secret '${name}': ${keyBytesResult.message}`);\n }\n const entry: IKeyStoreSymmetricEntry = {\n name,\n type: jsonEntry.type,\n key: keyBytesResult.value,\n description: jsonEntry.description,\n createdAt: jsonEntry.createdAt\n };\n secrets.set(name, entry);\n }\n }\n\n // All validation passed — commit state atomically\n this._salt = saltResult.value;\n this._secrets = secrets;\n this._state = 'unlocked';\n this._dirty = false;\n\n return succeed(this);\n }\n\n // ============================================================================\n // Private: Helpers for asymmetric flows\n // ============================================================================\n\n /**\n * Releases the resources held by an entry being displaced from the vault.\n * Symmetric entries get their key buffer zeroed in place. Asymmetric entries\n * have their private-key blob best-effort deleted from\n * {@link CryptoUtils.KeyStore.IPrivateKeyStorage}; if the storage call fails,\n * a warning string is returned but the displacement still proceeds — the\n * orphaned blob is left for consumer-side GC. Without a configured provider,\n * asymmetric cleanup is silently skipped.\n * @returns A warning string if storage cleanup failed, otherwise undefined.\n */\n private async _releaseEntryResources(entry: IKeyStoreEntry): Promise<string | undefined> {\n if (entry.type === 'asymmetric-keypair') {\n if (!this._privateKeyStorage) {\n return undefined;\n }\n const deleteResult = await this._privateKeyStorage.delete(entry.id);\n if (deleteResult.isFailure()) {\n return `Failed to delete prior storage blob for '${entry.name}' (id ${entry.id}): ${deleteResult.message}`;\n }\n return undefined;\n }\n entry.key.fill(0);\n return undefined;\n }\n\n /**\n * Mints a fresh UUID v4 storage handle using the crypto provider's\n * {@link CryptoUtils.ICryptoProvider.generateRandomBytes | generateRandomBytes}.\n * Random-bytes failures propagate as Failure.\n */\n private _generateId(): Result<string> {\n return this._cryptoProvider.generateRandomBytes(16).onSuccess((bytes) => {\n // Per RFC 4122 §4.4: set version (4) and variant (10xx) bits.\n // eslint-disable-next-line no-bitwise\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n // eslint-disable-next-line no-bitwise\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return succeed(\n `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(\n 20,\n 32\n )}`\n );\n });\n }\n}\n"]}
1
+ {"version":3,"file":"keyStore.js","sourceRoot":"","sources":["../../../../src/packlets/crypto-utils/keystore/keyStore.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { JsonValue } from '@fgv/ts-json-base';\nimport { captureResult, fail, Result, succeed } from '@fgv/ts-utils';\nimport * as Constants from '../constants';\nimport { createEncryptedFile } from '../encryptedFile';\nimport {\n ICryptoProvider,\n IEncryptedFile,\n IEncryptionConfig,\n IEncryptionProvider,\n IKeyDerivationParams,\n SecretProvider\n} from '../model';\nimport {\n DEFAULT_KEYSTORE_ITERATIONS,\n DEFAULT_SECRET_ITERATIONS,\n IAddKeyPairOptions,\n IAddKeyPairResult,\n IAddSecretFromPasswordOptions,\n IAddSecretFromPasswordResult,\n IAddSecretOptions,\n IAddSecretResult,\n IImportKeyOptions,\n IImportSecretOptions,\n IKeyStoreAsymmetricEntry,\n IKeyStoreCreateParams,\n IKeyStoreEntry,\n IKeyStoreEntryJson,\n IKeyStoreFile,\n IKeyStoreOpenParams,\n IKeyStoreSymmetricEntry,\n IKeyStoreVaultContents,\n IRemoveSecretResult,\n KEYSTORE_FORMAT,\n KeyStoreLockState,\n KeyStoreSecretType,\n MIN_SALT_LENGTH\n} from './model';\nimport { IPrivateKeyStorage } from './privateKeyStorage';\nimport { keystoreFile, keystoreVaultContents } from './converters';\n\n/**\n * Gets the current ISO timestamp.\n */\nfunction getCurrentTimestamp(): string {\n return new Date().toISOString();\n}\n\n// ============================================================================\n// KeyStore Class\n// ============================================================================\n\n/**\n * Password-protected key store for managing encryption secrets.\n *\n * The KeyStore provides a secure vault for storing named encryption keys.\n * The vault is encrypted at rest using a master password via PBKDF2 key derivation.\n *\n * @example\n * ```typescript\n * // Create new key store\n * const keystore = KeyStore.create({ cryptoProvider: nodeCryptoProvider }).orThrow();\n * await keystore.initialize('master-password');\n *\n * // Add secrets\n * await keystore.addSecret('my-key', { description: 'Production key' });\n *\n * // Save to file\n * const fileContent = await keystore.save();\n *\n * // Later: Open existing key store\n * const keystore2 = KeyStore.open({\n * cryptoProvider: nodeCryptoProvider,\n * keystoreFile: fileContent.value\n * }).orThrow();\n * await keystore2.unlock('master-password');\n *\n * // Use as secret provider for encrypted file loading\n * const encryptionConfig = keystore2.getEncryptionConfig().orThrow();\n * ```\n *\n * @public\n */\nexport class KeyStore implements IEncryptionProvider {\n private readonly _cryptoProvider: ICryptoProvider;\n private readonly _privateKeyStorage: IPrivateKeyStorage | undefined;\n private readonly _iterations: number;\n private _keystoreFile: IKeyStoreFile | undefined;\n private _salt: Uint8Array | undefined;\n private _secrets: Map<string, IKeyStoreEntry> | undefined;\n private _state: KeyStoreLockState;\n private _dirty: boolean;\n private _isNew: boolean;\n\n private constructor(\n cryptoProvider: ICryptoProvider,\n iterations: number,\n keystoreFile: IKeyStoreFile | undefined,\n isNew: boolean,\n privateKeyStorage: IPrivateKeyStorage | undefined\n ) {\n this._cryptoProvider = cryptoProvider;\n this._privateKeyStorage = privateKeyStorage;\n this._iterations = iterations;\n this._keystoreFile = keystoreFile;\n this._state = 'locked';\n this._dirty = false;\n this._isNew = isNew;\n }\n\n // ============================================================================\n // Factory Methods\n // ============================================================================\n\n /**\n * Creates a new, empty key store.\n * Call `initialize(password)` to set the master password.\n * @param params - Creation parameters\n * @returns Success with new KeyStore instance, or Failure if parameters invalid\n * @public\n */\n public static create(params: IKeyStoreCreateParams): Result<KeyStore> {\n const iterations = params.iterations ?? DEFAULT_KEYSTORE_ITERATIONS;\n if (iterations < 1) {\n return fail('Iterations must be at least 1');\n }\n return succeed(\n new KeyStore(params.cryptoProvider, iterations, undefined, true, params.privateKeyStorage)\n );\n }\n\n /**\n * Opens an existing encrypted key store.\n * Call `unlock(password)` to decrypt and access secrets.\n * @param params - Open parameters including the encrypted file\n * @returns Success with KeyStore instance, or Failure if file format invalid\n * @public\n */\n public static open(params: IKeyStoreOpenParams): Result<KeyStore> {\n // Validate the file format\n const fileResult = keystoreFile.convert(params.keystoreFile);\n if (fileResult.isFailure()) {\n return fail(`Invalid key store file: ${fileResult.message}`);\n }\n\n const iterations = fileResult.value.keyDerivation.iterations;\n return succeed(\n new KeyStore(params.cryptoProvider, iterations, fileResult.value, false, params.privateKeyStorage)\n );\n }\n\n // ============================================================================\n // Lifecycle Methods\n // ============================================================================\n\n /**\n * Initializes a new key store with the master password.\n * Generates a random salt for key derivation.\n * Only valid for newly created (not opened) key stores.\n * @param password - The master password\n * @returns Success with this instance when initialized, Failure if already initialized or opened\n * @public\n */\n public async initialize(password: string): Promise<Result<KeyStore>> {\n if (!this._isNew) {\n return fail('Cannot initialize an opened key store - use unlock() instead');\n }\n if (this._state === 'unlocked') {\n return fail('Key store is already initialized');\n }\n if (!password || password.length === 0) {\n return fail('Password cannot be empty');\n }\n\n // Generate salt for this key store using crypto provider\n const saltResult = this._cryptoProvider.generateRandomBytes(MIN_SALT_LENGTH);\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (saltResult.isFailure()) {\n return fail(`Failed to generate salt: ${saltResult.message}`);\n }\n\n this._salt = saltResult.value;\n this._secrets = new Map();\n this._state = 'unlocked';\n this._dirty = true; // New store needs to be saved\n\n return succeed(this);\n }\n\n /**\n * Unlocks an existing key store with the master password.\n * Decrypts the vault and loads secrets into memory.\n * @param password - The master password\n * @returns Success with this instance when unlocked, Failure if password incorrect\n * @public\n */\n public async unlock(password: string): Promise<Result<KeyStore>> {\n if (this._isNew) {\n return fail('Cannot unlock a new key store - use initialize() instead');\n }\n /* c8 ignore next 6 - error paths tested but coverage intermittently missed */\n if (this._state === 'unlocked') {\n return fail('Key store is already unlocked');\n }\n if (!this._keystoreFile) {\n return fail('No key store file to unlock');\n }\n\n const keyDerivation = this._keystoreFile.keyDerivation;\n const saltResult = this._cryptoProvider.fromBase64(keyDerivation.salt);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (saltResult.isFailure()) {\n return fail(`Invalid salt in key store file: ${saltResult.message}`);\n }\n const salt = saltResult.value;\n\n // Derive the key from password\n const keyResult = await this._cryptoProvider.deriveKey(password, salt, keyDerivation.iterations);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (keyResult.isFailure()) {\n return fail(`Key derivation failed: ${keyResult.message}`);\n }\n\n return this._decryptVault(keyResult.value);\n }\n\n /**\n * Unlocks an existing key store with a pre-derived key, bypassing\n * PBKDF2 key derivation. Use this when the derived key has been\n * stored externally (e.g., in another key store) and the original\n * password is no longer available.\n *\n * The supplied key must have been derived from the correct password\n * using the key store file's own PBKDF2 parameters (salt and\n * iteration count).\n *\n * @param derivedKey - The pre-derived master key (32 bytes for AES-256)\n * @returns Success with this instance when unlocked, Failure if key is incorrect\n * @public\n */\n public async unlockWithKey(derivedKey: Uint8Array): Promise<Result<KeyStore>> {\n if (this._isNew) {\n return fail('Cannot unlock a new key store - use initialize() instead');\n }\n if (this._state === 'unlocked') {\n return fail('Key store is already unlocked');\n }\n if (derivedKey.length !== Constants.AES_256_KEY_SIZE) {\n return fail(`Key must be ${Constants.AES_256_KEY_SIZE} bytes, got ${derivedKey.length}`);\n }\n /* c8 ignore next 3 - defensive coding: unreachable via public API (open sets file, create sets isNew) */\n if (!this._keystoreFile) {\n return fail('No key store file to unlock');\n }\n\n return this._decryptVault(derivedKey);\n }\n\n /**\n * Locks the key store, clearing all secrets from memory.\n * @param force - If true, discards unsaved changes\n * @returns Success when locked, Failure if unsaved changes and !force\n * @public\n */\n public lock(force?: boolean): Result<KeyStore> {\n if (this._state === 'locked') {\n return succeed(this);\n }\n\n if (this._dirty && !force) {\n return fail('Unsaved changes - use force=true to discard or save() first');\n }\n\n // Clear secrets from memory (overwrite for security)\n if (this._secrets) {\n for (const entry of this._secrets.values()) {\n if (entry.type !== 'asymmetric-keypair') {\n entry.key.fill(0);\n }\n }\n this._secrets.clear();\n this._secrets = undefined;\n }\n\n this._state = 'locked';\n this._dirty = false;\n\n return succeed(this);\n }\n\n /**\n * Checks if the key store is unlocked.\n * @public\n */\n public get isUnlocked(): boolean {\n return this._state === 'unlocked';\n }\n\n /**\n * Checks if there are unsaved changes.\n * @public\n */\n public get isDirty(): boolean {\n return this._dirty;\n }\n\n /**\n * Whether this is a newly created key store (not opened from a file).\n * A new key store must be initialized with a password before use.\n * An opened key store must be unlocked with the existing password.\n * @public\n */\n public get isNew(): boolean {\n return this._isNew;\n }\n\n /**\n * Gets the current lock state.\n * @public\n */\n public get state(): KeyStoreLockState {\n return this._state;\n }\n\n /**\n * Gets the crypto provider used by this key store.\n * Available regardless of lock state.\n * @public\n */\n public get cryptoProvider(): ICryptoProvider {\n return this._cryptoProvider;\n }\n\n // ============================================================================\n // Secret Management\n // ============================================================================\n\n /**\n * Lists all secret names in the key store.\n * @returns Success with array of secret names, Failure if locked\n * @public\n */\n public listSecrets(): Result<readonly string[]> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n return succeed(Array.from(this._secrets.keys()));\n }\n\n /**\n * Gets a secret by name. Returns the {@link CryptoUtils.KeyStore.IKeyStoreEntry | discriminated union}\n * — callers must check `entry.type` before accessing `key`/`id` since asymmetric\n * entries carry no raw key material.\n * @param name - Name of the secret\n * @returns Success with secret entry, Failure if not found or locked\n * @public\n */\n public getSecret(name: string): Result<IKeyStoreEntry> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n const entry = this._secrets.get(name);\n if (!entry) {\n return fail(`Secret '${name}' not found`);\n }\n return succeed(entry);\n }\n\n /**\n * Returns the public-key JWK for an asymmetric-keypair entry.\n * Available without {@link CryptoUtils.KeyStore.IPrivateKeyStorage} since the\n * public key lives in the vault metadata directly.\n * @param name - Name of the entry\n * @returns Success with the JWK, Failure if not found, locked, or wrong type\n * @public\n */\n public getPublicKeyJwk(name: string): Result<JsonWebKey> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n const entry = this._secrets.get(name);\n if (!entry) {\n return fail(`Secret '${name}' not found`);\n }\n if (entry.type !== 'asymmetric-keypair') {\n return fail(`Secret '${name}' is not an asymmetric keypair (type: ${entry.type})`);\n }\n return succeed(entry.publicKeyJwk);\n }\n\n /**\n * Checks if a secret exists.\n * @param name - Name of the secret\n * @returns Success with boolean, Failure if locked\n * @public\n */\n public hasSecret(name: string): Result<boolean> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n return succeed(this._secrets.has(name));\n }\n\n /**\n * Adds a new secret with a randomly generated key.\n * @param name - Unique name for the secret\n * @param options - Optional description\n * @returns Success with the generated entry, Failure if locked or name invalid\n * @public\n */\n public async addSecret(name: string, options?: IAddSecretOptions): Promise<Result<IAddSecretResult>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!name || name.length === 0) {\n return fail('Secret name cannot be empty');\n }\n\n // Generate a new random key\n const keyResult = await this._cryptoProvider.generateKey();\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (keyResult.isFailure()) {\n return fail(`Failed to generate key: ${keyResult.message}`);\n }\n\n const entry: IKeyStoreSymmetricEntry = {\n name,\n type: 'encryption-key',\n key: keyResult.value,\n description: options?.description,\n createdAt: getCurrentTimestamp()\n };\n\n const existing = this._secrets.get(name);\n const warning = existing ? await this._releaseEntryResources(existing) : undefined;\n\n this._secrets.set(name, entry);\n this._dirty = true;\n\n return succeed({ entry, replaced: existing !== undefined, warning });\n }\n\n /**\n * Imports raw 32-byte key material into the vault.\n *\n * Always validates that the key is exactly 32 bytes (AES-256). The optional\n * `type` field is a classification label stored with the entry; it does not\n * change the validation rules. For importing UTF-8 API key strings (variable\n * length), use {@link KeyStore.importApiKey} instead.\n *\n * @param name - Unique name for the secret\n * @param key - The 32-byte AES-256 key material\n * @param options - Optional type classification, description, whether to replace existing\n * @returns Success with entry, Failure if locked, key invalid, or exists and !replace\n * @public\n */\n public async importSecret(\n name: string,\n key: Uint8Array,\n options?: IImportKeyOptions\n ): Promise<Result<IAddSecretResult>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!name || name.length === 0) {\n return fail('Secret name cannot be empty');\n }\n if (key.length !== Constants.AES_256_KEY_SIZE) {\n return fail(`Key must be ${Constants.AES_256_KEY_SIZE} bytes, got ${key.length}`);\n }\n\n const existing = this._secrets.get(name);\n if (existing && !options?.replace) {\n return fail(`Secret '${name}' already exists - use replace=true to overwrite`);\n }\n\n const entry: IKeyStoreSymmetricEntry = {\n name,\n type: options?.type ?? 'encryption-key',\n key: new Uint8Array(key), // Copy to prevent external modification\n description: options?.description,\n createdAt: getCurrentTimestamp()\n };\n\n const warning = existing ? await this._releaseEntryResources(existing) : undefined;\n this._secrets.set(name, entry);\n this._dirty = true;\n\n return succeed({ entry, replaced: existing !== undefined, warning });\n }\n\n /**\n * Adds a secret derived from a password using PBKDF2.\n *\n * Generates a random salt, derives a 32-byte AES-256 key from the password,\n * and stores it in the vault. Returns the key derivation parameters so they\n * can be stored alongside encrypted files, enabling decryption with just the\n * password (without unlocking the keystore).\n *\n * @param name - Unique name for the secret\n * @param password - Password to derive the key from\n * @param options - Optional description, iterations, replace flag\n * @returns Success with entry and keyDerivation params, Failure if locked or invalid\n * @public\n */\n public async addSecretFromPassword(\n name: string,\n password: string,\n options?: IAddSecretFromPasswordOptions\n ): Promise<Result<IAddSecretFromPasswordResult>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!name || name.length === 0) {\n return fail('Secret name cannot be empty');\n }\n if (!password || password.length === 0) {\n return fail('Password cannot be empty');\n }\n\n const existing = this._secrets.get(name);\n if (existing && !options?.replace) {\n return fail(`Secret '${name}' already exists - use replace=true to overwrite`);\n }\n\n const iterations = options?.iterations ?? DEFAULT_SECRET_ITERATIONS;\n\n // Generate a random salt for this secret's key derivation\n const saltResult = this._cryptoProvider.generateRandomBytes(MIN_SALT_LENGTH);\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (saltResult.isFailure()) {\n return fail(`Failed to generate salt: ${saltResult.message}`);\n }\n\n // Derive the key from password\n const keyResult = await this._cryptoProvider.deriveKey(password, saltResult.value, iterations);\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (keyResult.isFailure()) {\n return fail(`Key derivation failed: ${keyResult.message}`);\n }\n\n const entry: IKeyStoreSymmetricEntry = {\n name,\n type: 'encryption-key',\n key: keyResult.value,\n description: options?.description,\n createdAt: getCurrentTimestamp()\n };\n\n const warning = existing ? await this._releaseEntryResources(existing) : undefined;\n this._secrets.set(name, entry);\n this._dirty = true;\n\n return succeed({\n entry,\n replaced: existing !== undefined,\n warning,\n keyDerivation: {\n kdf: 'pbkdf2',\n salt: this._cryptoProvider.toBase64(saltResult.value),\n iterations\n }\n });\n }\n\n /**\n * Verifies that a candidate password derives the same key material currently\n * stored under `name`, using the supplied\n * {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.\n *\n * The keystore does not persist per-slot key derivation parameters with the\n * entry — callers receive them from `addSecretFromPassword` and store them\n * alongside the encrypted artifact (or wherever else makes sense). Pass\n * those same parameters here for verification.\n *\n * Re-derives a key from `password` + `keyDerivation`, then compares it to\n * the stored key material in constant time. Restricted to entries of type\n * `'encryption-key'` — the type produced by `addSecretFromPassword`. Other\n * symmetric types (`'api-key'`) and asymmetric entries are rejected so\n * the boolean result reflects \"this slot accepts this password\" rather\n * than an incidental byte-equality match against unrelated material.\n *\n * Note: the keystore does not currently flag whether an `'encryption-key'`\n * entry was actually password-derived (vs. random via `addSecret` or raw\n * via `importSecret`). A `true` result therefore means \"the candidate\n * password produces the same 32 bytes currently stored\", which is what\n * the equivalent consumer-side helper (`verifyGatePassword`) already\n * implies for entries it manages.\n *\n * @param name - Name of the secret to verify against\n * @param password - Candidate password to test\n * @param keyDerivation - The key derivation parameters returned by\n * `addSecretFromPassword` when the secret was created. Only\n * `kdf: 'pbkdf2'` is supported.\n * @returns Success(true) when the candidate matches the stored key,\n * Success(false) when it does not, Failure if locked, secret missing,\n * wrong type, unsupported `kdf`, or key derivation fails\n * @public\n */\n public async verifySecretFromPassword(\n name: string,\n password: string,\n keyDerivation: IKeyDerivationParams\n ): Promise<Result<boolean>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!password || password.length === 0) {\n return fail('Password cannot be empty');\n }\n if (keyDerivation.kdf !== 'pbkdf2') {\n return fail(`Unsupported kdf '${keyDerivation.kdf}' (expected 'pbkdf2')`);\n }\n\n const entry = this._secrets.get(name);\n if (!entry) {\n return fail(`Secret '${name}' not found`);\n }\n if (entry.type !== 'encryption-key') {\n return fail(`Secret '${name}' is not a password-verifiable encryption key (type: ${entry.type})`);\n }\n\n const saltResult = this._cryptoProvider.fromBase64(keyDerivation.salt);\n if (saltResult.isFailure()) {\n return fail(`Invalid salt: ${saltResult.message}`);\n }\n\n const derivedResult = await this._cryptoProvider.deriveKey(\n password,\n saltResult.value,\n keyDerivation.iterations\n );\n /* c8 ignore next 3 - crypto provider errors covered in nodeCryptoProvider tests */\n if (derivedResult.isFailure()) {\n return fail(`Key derivation failed: ${derivedResult.message}`);\n }\n\n return succeed(KeyStore._timingSafeEqual(derivedResult.value, entry.key));\n }\n\n /**\n * Removes a secret by name. Vault-first: the in-memory vault entry is dropped\n * before any storage cleanup runs. For asymmetric-keypair entries, best-effort\n * calls {@link CryptoUtils.KeyStore.IPrivateKeyStorage}.delete on the entry's\n * `id`; a failure is reported via `warning` on the result but does not roll\n * back the vault removal.\n * @param name - Name of the secret to remove\n * @returns Success with removed entry (and optional warning), Failure if not found or locked\n * @public\n */\n public async removeSecret(name: string): Promise<Result<IRemoveSecretResult>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n\n const entry = this._secrets.get(name);\n if (!entry) {\n return fail(`Secret '${name}' not found`);\n }\n\n // Vault-first: drop the in-memory entry before touching storage so a\n // storage failure cannot block removal.\n this._secrets.delete(name);\n this._dirty = true;\n\n const warning = await this._releaseEntryResources(entry);\n return succeed({ entry, warning });\n }\n\n /**\n * Imports an API key string into the vault.\n * The string is UTF-8 encoded and stored with type `'api-key'`.\n * @param name - Unique name for the secret\n * @param apiKey - The API key string\n * @param options - Optional description, whether to replace existing\n * @returns Success with entry, Failure if locked, empty, or exists and !replace\n * @public\n */\n public async importApiKey(\n name: string,\n apiKey: string,\n options?: IImportSecretOptions\n ): Promise<Result<IAddSecretResult>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!name || name.length === 0) {\n return fail('Secret name cannot be empty');\n }\n if (!apiKey || apiKey.length === 0) {\n return fail('API key cannot be empty');\n }\n\n const existing = this._secrets.get(name);\n if (existing && !options?.replace) {\n return fail(`Secret '${name}' already exists - use replace=true to overwrite`);\n }\n\n const encoder = new TextEncoder();\n const entry: IKeyStoreSymmetricEntry = {\n name,\n type: 'api-key',\n key: encoder.encode(apiKey),\n description: options?.description,\n createdAt: getCurrentTimestamp()\n };\n\n const warning = existing ? await this._releaseEntryResources(existing) : undefined;\n this._secrets.set(name, entry);\n this._dirty = true;\n\n return succeed({ entry, replaced: existing !== undefined, warning });\n }\n\n /**\n * Retrieves an API key string by name.\n * Only works for secrets with type `'api-key'`.\n * @param name - Name of the secret\n * @returns Success with the API key string, Failure if not found, locked, or wrong type\n * @public\n */\n public getApiKey(name: string): Result<string> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n const entry = this._secrets.get(name);\n if (!entry) {\n return fail(`Secret '${name}' not found`);\n }\n if (entry.type !== 'api-key') {\n return fail(`Secret '${name}' is not an API key (type: ${entry.type})`);\n }\n const decoder = new TextDecoder();\n return succeed(decoder.decode(entry.key));\n }\n\n // ============================================================================\n // Asymmetric Keypair Management\n // ============================================================================\n\n /**\n * Adds a new asymmetric keypair to the vault. Storage-first: the private key\n * is stored under a freshly-minted `id` before the public-key vault entry is\n * committed. If the storage call fails, no vault entry is written and the\n * operation returns Failure.\n *\n * When `replace: true` displaces an existing entry (asymmetric or symmetric),\n * a fresh `id` is minted; the displaced entry's resources are released\n * best-effort. Failure of the storage delete is reported via `warning` on the\n * result but does not roll back the replacement.\n *\n * Requires a {@link CryptoUtils.KeyStore.IPrivateKeyStorage} backend\n * supplied at construction.\n *\n * @param name - Unique name for the entry\n * @param options - Algorithm, optional description, replace flag\n * @returns Success with the new entry, Failure if locked, no provider, or storage write failed\n * @public\n */\n public async addKeyPair(name: string, options: IAddKeyPairOptions): Promise<Result<IAddKeyPairResult>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!name || name.length === 0) {\n return fail('Entry name cannot be empty');\n }\n if (!this._privateKeyStorage) {\n return fail('No private key storage configured');\n }\n\n const existing = this._secrets.get(name);\n if (existing && !options.replace) {\n return fail(`Secret '${name}' already exists - use replace=true to overwrite`);\n }\n\n // Generate the keypair before touching storage. extractable=true on backends\n // that round-trip via JWK; extractable=false on backends that hold CryptoKey\n // refs directly.\n const extractable = !this._privateKeyStorage.supportsNonExtractable;\n const keyPairResult = await this._cryptoProvider.generateKeyPair(options.algorithm, extractable);\n /* c8 ignore next 3 - crypto provider errors covered in nodeCryptoProvider tests; cannot be triggered here without mocking */\n if (keyPairResult.isFailure()) {\n return fail(`Failed to generate keypair for '${name}': ${keyPairResult.message}`);\n }\n const { publicKey, privateKey } = keyPairResult.value;\n\n const jwkResult = await this._cryptoProvider.exportPublicKeyJwk(publicKey);\n /* c8 ignore next 3 - export of an extractable freshly-generated public key is hard to fail */\n if (jwkResult.isFailure()) {\n return fail(`Failed to export public key for '${name}': ${jwkResult.message}`);\n }\n\n const idResult = this._generateId();\n /* c8 ignore next 3 - random-bytes failure is hard to trigger with a healthy provider */\n if (idResult.isFailure()) {\n return fail(`Failed to mint storage id for '${name}': ${idResult.message}`);\n }\n const id = idResult.value;\n\n // Storage-first: write the private key before committing the vault entry.\n const storeResult = await this._privateKeyStorage.store(id, privateKey);\n if (storeResult.isFailure()) {\n return fail(`Failed to persist private key for '${name}': ${storeResult.message}`);\n }\n\n const entry: IKeyStoreAsymmetricEntry = {\n name,\n type: 'asymmetric-keypair',\n id,\n algorithm: options.algorithm,\n publicKeyJwk: jwkResult.value,\n description: options.description,\n createdAt: getCurrentTimestamp()\n };\n\n const warning = existing ? await this._releaseEntryResources(existing) : undefined;\n this._secrets.set(name, entry);\n this._dirty = true;\n\n return succeed({ entry, replaced: existing !== undefined, warning });\n }\n\n /**\n * Retrieves the keypair for an asymmetric-keypair entry. The private key is\n * loaded from {@link CryptoUtils.KeyStore.IPrivateKeyStorage} on every call —\n * the keystore never caches private `CryptoKey` references between calls.\n * The public key is re-imported from the vault's JWK so callers always\n * receive a `CryptoKey` rather than the JWK form.\n * @param name - Name of the entry\n * @returns Success with `{ publicKey, privateKey }`, Failure if not found,\n * locked, wrong type, no provider, or storage load failed.\n * @public\n */\n public async getKeyPair(name: string): Promise<Result<{ publicKey: CryptoKey; privateKey: CryptoKey }>> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n const entry = this._secrets.get(name);\n if (!entry) {\n return fail(`Secret '${name}' not found`);\n }\n if (entry.type !== 'asymmetric-keypair') {\n return fail(`Secret '${name}' is not an asymmetric keypair (type: ${entry.type})`);\n }\n if (!this._privateKeyStorage) {\n return fail('No private key storage configured');\n }\n\n const privateResult = await this._privateKeyStorage.load(entry.id);\n if (privateResult.isFailure()) {\n return fail(`Failed to load private key for '${name}': ${privateResult.message}`);\n }\n\n const publicResult = await this._cryptoProvider.importPublicKeyJwk(entry.publicKeyJwk, entry.algorithm);\n /* c8 ignore next 3 - vault JWKs that previously exported cleanly are extremely unlikely to fail re-import */\n if (publicResult.isFailure()) {\n return fail(`Failed to re-import public key for '${name}': ${publicResult.message}`);\n }\n\n return succeed({ publicKey: publicResult.value, privateKey: privateResult.value });\n }\n\n /**\n * Lists secret names filtered by type.\n * @param type - The secret type to filter by\n * @returns Success with array of matching secret names, Failure if locked\n * @public\n */\n public listSecretsByType(type: KeyStoreSecretType): Result<readonly string[]> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n const names: string[] = [];\n for (const [name, entry] of this._secrets) {\n if (entry.type === type) {\n names.push(name);\n }\n }\n return succeed(names);\n }\n\n /**\n * Renames a secret.\n * @param oldName - Current name\n * @param newName - New name\n * @returns Success with updated entry, Failure if source not found, target exists, or locked\n * @public\n */\n public renameSecret(oldName: string, newName: string): Result<IKeyStoreEntry> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n if (!newName || newName.length === 0) {\n return fail('New name cannot be empty');\n }\n\n const entry = this._secrets.get(oldName);\n if (!entry) {\n return fail(`Secret '${oldName}' not found`);\n }\n\n if (oldName !== newName && this._secrets.has(newName)) {\n return fail(`Secret '${newName}' already exists`);\n }\n\n // Create new entry with new name. For asymmetric entries the spread\n // preserves `id` so the storage handle survives the rename.\n const newEntry: IKeyStoreEntry = {\n ...entry,\n name: newName\n };\n\n this._secrets.delete(oldName);\n this._secrets.set(newName, newEntry);\n this._dirty = true;\n\n return succeed(newEntry);\n }\n\n // ============================================================================\n // Persistence\n // ============================================================================\n\n /**\n * Saves the key store, returning the encrypted file content.\n * Requires the master password to encrypt.\n * @param password - The master password\n * @returns Success with IKeyStoreFile, Failure if locked\n * @public\n */\n public async save(password: string): Promise<Result<IKeyStoreFile>> {\n if (!this._secrets || !this._salt) {\n return fail('Key store is locked');\n }\n if (!password || password.length === 0) {\n return fail('Password cannot be empty');\n }\n\n // Derive the encryption key\n const keyResult = await this._cryptoProvider.deriveKey(password, this._salt, this._iterations);\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (keyResult.isFailure()) {\n return fail(`Key derivation failed: ${keyResult.message}`);\n }\n\n return this._encryptVault(keyResult.value);\n }\n\n /**\n * Saves the key store using a pre-derived key, bypassing PBKDF2 key\n * derivation. Use this when the derived key has been stored externally\n * (e.g., in another key store) and the original password is no longer\n * available.\n *\n * The supplied key must be the same key that was (or would be) derived\n * from the master password using the key store's PBKDF2 parameters.\n *\n * @param derivedKey - The pre-derived master key (32 bytes for AES-256)\n * @returns Success with IKeyStoreFile, Failure if locked or key invalid\n * @public\n */\n public async saveWithKey(derivedKey: Uint8Array): Promise<Result<IKeyStoreFile>> {\n if (!this._secrets || !this._salt) {\n return fail('Key store is locked');\n }\n if (derivedKey.length !== Constants.AES_256_KEY_SIZE) {\n return fail(`Key must be ${Constants.AES_256_KEY_SIZE} bytes, got ${derivedKey.length}`);\n }\n\n return this._encryptVault(derivedKey);\n }\n\n /**\n * Changes the master password.\n * Re-encrypts the vault with the new password-derived key.\n * @param currentPassword - Current master password (for verification)\n * @param newPassword - New master password\n * @returns Success when password changed, Failure if locked or current password incorrect\n * @public\n */\n public async changePassword(currentPassword: string, newPassword: string): Promise<Result<KeyStore>> {\n if (!this._secrets || !this._salt) {\n return fail('Key store is locked');\n }\n if (!newPassword || newPassword.length === 0) {\n return fail('New password cannot be empty');\n }\n\n // Verify current password by trying to derive and re-encrypt\n // (For opened stores, we'd need to verify against the stored file)\n if (this._keystoreFile) {\n const saltResult = this._cryptoProvider.fromBase64(this._keystoreFile.keyDerivation.salt);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (saltResult.isFailure()) {\n return fail(`Invalid salt in key store file: ${saltResult.message}`);\n }\n\n const keyResult = await this._cryptoProvider.deriveKey(\n currentPassword,\n saltResult.value,\n this._keystoreFile.keyDerivation.iterations\n );\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (keyResult.isFailure()) {\n return fail(`Key derivation failed: ${keyResult.message}`);\n }\n\n // Try to decrypt to verify password\n const ivResult = this._cryptoProvider.fromBase64(this._keystoreFile.iv);\n const authTagResult = this._cryptoProvider.fromBase64(this._keystoreFile.authTag);\n const encryptedDataResult = this._cryptoProvider.fromBase64(this._keystoreFile.encryptedData);\n\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (ivResult.isFailure() || authTagResult.isFailure() || encryptedDataResult.isFailure()) {\n return fail('Invalid key store file format');\n }\n\n const decryptResult = await this._cryptoProvider.decrypt(\n encryptedDataResult.value,\n keyResult.value,\n ivResult.value,\n authTagResult.value\n );\n if (decryptResult.isFailure()) {\n return fail('Current password is incorrect');\n }\n }\n\n // Generate new salt for the new password using crypto provider\n const saltResult = this._cryptoProvider.generateRandomBytes(MIN_SALT_LENGTH);\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (saltResult.isFailure()) {\n return fail(`Failed to generate salt: ${saltResult.message}`);\n }\n\n this._salt = saltResult.value;\n this._dirty = true;\n\n // Save with new password\n const saveResult = await this.save(newPassword);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (saveResult.isFailure()) {\n return fail(saveResult.message);\n }\n return succeed(this);\n }\n\n // ============================================================================\n // IEncryptionProvider\n // ============================================================================\n\n /** {@inheritDoc IEncryptionProvider.encryptByName} */\n public async encryptByName<TMetadata = JsonValue>(\n secretName: string,\n content: JsonValue,\n metadata?: TMetadata\n ): Promise<Result<IEncryptedFile<TMetadata>>> {\n const secretResult = this.getSecret(secretName);\n if (secretResult.isFailure()) {\n return fail(`encryptByName: ${secretResult.message}`);\n }\n if (secretResult.value.type === 'asymmetric-keypair') {\n return fail(\n `encryptByName: secret '${secretName}' is an asymmetric keypair, not symmetric key material`\n );\n }\n\n return createEncryptedFile({\n content,\n secretName,\n key: secretResult.value.key,\n cryptoProvider: this._cryptoProvider,\n metadata\n });\n }\n\n // ============================================================================\n // Integration with IEncryptionConfig\n // ============================================================================\n\n /**\n * Creates a SecretProvider function for use with IEncryptionConfig.\n * The returned function looks up secrets from this key store.\n * @returns Success with SecretProvider, Failure if locked\n * @public\n */\n public getSecretProvider(): Result<SecretProvider> {\n if (!this._secrets) {\n return fail('Key store is locked');\n }\n\n const secrets = this._secrets;\n const provider: SecretProvider = async (secretName: string): Promise<Result<Uint8Array>> => {\n const entry = secrets.get(secretName);\n if (!entry) {\n return fail(`Secret '${secretName}' not found in key store`);\n }\n if (entry.type === 'asymmetric-keypair') {\n return fail(`Secret '${secretName}' is an asymmetric keypair, not symmetric key material`);\n }\n return succeed(entry.key);\n };\n\n return succeed(provider);\n }\n\n /**\n * Creates a partial IEncryptionConfig using this key store as the secret source.\n * @returns Partial config that can be spread into a full IEncryptionConfig\n * @public\n */\n public getEncryptionConfig(): Result<Pick<IEncryptionConfig, 'secretProvider' | 'cryptoProvider'>> {\n const providerResult = this.getSecretProvider();\n if (providerResult.isFailure()) {\n return fail(providerResult.message);\n }\n\n return succeed({\n secretProvider: providerResult.value,\n cryptoProvider: this._cryptoProvider\n });\n }\n\n // ============================================================================\n // Private: Vault Encryption / Decryption\n // ============================================================================\n\n /**\n * Encrypts the vault with a derived key and returns the key store file.\n * Shared by `save()` and `saveWithKey()`.\n */\n private async _encryptVault(derivedKey: Uint8Array): Promise<Result<IKeyStoreFile>> {\n // _secrets and _salt are guaranteed non-undefined by callers\n const secrets = this._secrets!;\n const salt = this._salt!;\n\n // Build vault contents\n const secretEntries: Record<string, IKeyStoreEntryJson> = {};\n for (const [name, entry] of secrets) {\n if (entry.type === 'asymmetric-keypair') {\n secretEntries[name] = {\n name: entry.name,\n type: entry.type,\n id: entry.id,\n algorithm: entry.algorithm,\n publicKeyJwk: entry.publicKeyJwk,\n description: entry.description,\n createdAt: entry.createdAt\n };\n } else {\n secretEntries[name] = {\n name: entry.name,\n type: entry.type,\n key: this._cryptoProvider.toBase64(entry.key),\n description: entry.description,\n createdAt: entry.createdAt\n };\n }\n }\n\n const vaultContents: IKeyStoreVaultContents = {\n version: KEYSTORE_FORMAT,\n secrets: secretEntries\n };\n\n // Serialize and encrypt\n const jsonResult = captureResult(() => JSON.stringify(vaultContents));\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (jsonResult.isFailure()) {\n return fail(`Failed to serialize vault: ${jsonResult.message}`);\n }\n\n const encryptResult = await this._cryptoProvider.encrypt(jsonResult.value, derivedKey);\n /* c8 ignore next 3 - crypto provider errors tested but coverage intermittently missed */\n if (encryptResult.isFailure()) {\n return fail(`Encryption failed: ${encryptResult.message}`);\n }\n\n const { iv, authTag, encryptedData } = encryptResult.value;\n\n const keystoreFileData: IKeyStoreFile = {\n format: KEYSTORE_FORMAT,\n algorithm: Constants.DEFAULT_ALGORITHM,\n iv: this._cryptoProvider.toBase64(iv),\n authTag: this._cryptoProvider.toBase64(authTag),\n encryptedData: this._cryptoProvider.toBase64(encryptedData),\n keyDerivation: {\n kdf: 'pbkdf2',\n salt: this._cryptoProvider.toBase64(salt),\n iterations: this._iterations\n }\n };\n\n this._keystoreFile = keystoreFileData;\n this._dirty = false;\n this._isNew = false;\n\n return succeed(keystoreFileData);\n }\n\n /**\n * Decrypts the vault with a derived key and loads secrets into memory.\n * Shared by `unlock()` and `unlockWithKey()`.\n */\n private async _decryptVault(derivedKey: Uint8Array): Promise<Result<KeyStore>> {\n const keystoreFile = this._keystoreFile;\n if (keystoreFile === undefined) {\n return fail('No key store file loaded');\n }\n\n const ivResult = this._cryptoProvider.fromBase64(keystoreFile.iv);\n const authTagResult = this._cryptoProvider.fromBase64(keystoreFile.authTag);\n const encryptedDataResult = this._cryptoProvider.fromBase64(keystoreFile.encryptedData);\n\n /* c8 ignore next 9 - base64 decode errors tested but coverage intermittently missed */\n if (ivResult.isFailure()) {\n return fail(`Invalid IV in key store file: ${ivResult.message}`);\n }\n if (authTagResult.isFailure()) {\n return fail(`Invalid auth tag in key store file: ${authTagResult.message}`);\n }\n if (encryptedDataResult.isFailure()) {\n return fail(`Invalid encrypted data in key store file: ${encryptedDataResult.message}`);\n }\n\n const decryptResult = await this._cryptoProvider.decrypt(\n encryptedDataResult.value,\n derivedKey,\n ivResult.value,\n authTagResult.value\n );\n if (decryptResult.isFailure()) {\n return fail('Incorrect password or corrupted key store');\n }\n\n // Parse the vault contents\n const parseResult = captureResult(() => JSON.parse(decryptResult.value) as unknown);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (parseResult.isFailure()) {\n return fail(`Failed to parse vault contents: ${parseResult.message}`);\n }\n\n const vaultResult = keystoreVaultContents.convert(parseResult.value);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (vaultResult.isFailure()) {\n return fail(`Invalid vault format: ${vaultResult.message}`);\n }\n\n // Build secrets into local variables to avoid partial state on failure\n const saltResult = this._cryptoProvider.fromBase64(keystoreFile.keyDerivation.salt);\n if (saltResult.isFailure()) {\n return fail(`Invalid salt in key store file: ${saltResult.message}`);\n }\n const secrets = new Map<string, IKeyStoreEntry>();\n for (const [name, jsonEntry] of Object.entries(vaultResult.value.secrets)) {\n if (jsonEntry.type === 'asymmetric-keypair') {\n const entry: IKeyStoreAsymmetricEntry = {\n name,\n type: jsonEntry.type,\n id: jsonEntry.id,\n algorithm: jsonEntry.algorithm,\n publicKeyJwk: jsonEntry.publicKeyJwk,\n description: jsonEntry.description,\n createdAt: jsonEntry.createdAt\n };\n secrets.set(name, entry);\n } else {\n const keyBytesResult = this._cryptoProvider.fromBase64(jsonEntry.key);\n /* c8 ignore next 3 - error path tested but coverage intermittently missed */\n if (keyBytesResult.isFailure()) {\n return fail(`Invalid key for secret '${name}': ${keyBytesResult.message}`);\n }\n const entry: IKeyStoreSymmetricEntry = {\n name,\n type: jsonEntry.type,\n key: keyBytesResult.value,\n description: jsonEntry.description,\n createdAt: jsonEntry.createdAt\n };\n secrets.set(name, entry);\n }\n }\n\n // All validation passed — commit state atomically\n this._salt = saltResult.value;\n this._secrets = secrets;\n this._state = 'unlocked';\n this._dirty = false;\n\n return succeed(this);\n }\n\n // ============================================================================\n // Private: Helpers for asymmetric flows\n // ============================================================================\n\n /**\n * Releases the resources held by an entry being displaced from the vault.\n * Symmetric entries get their key buffer zeroed in place. Asymmetric entries\n * have their private-key blob best-effort deleted from\n * {@link CryptoUtils.KeyStore.IPrivateKeyStorage}; if the storage call fails,\n * a warning string is returned but the displacement still proceeds — the\n * orphaned blob is left for consumer-side GC. Without a configured provider,\n * asymmetric cleanup is silently skipped.\n * @returns A warning string if storage cleanup failed, otherwise undefined.\n */\n private async _releaseEntryResources(entry: IKeyStoreEntry): Promise<string | undefined> {\n if (entry.type === 'asymmetric-keypair') {\n if (!this._privateKeyStorage) {\n return undefined;\n }\n const deleteResult = await this._privateKeyStorage.delete(entry.id);\n if (deleteResult.isFailure()) {\n return `Failed to delete prior storage blob for '${entry.name}' (id ${entry.id}): ${deleteResult.message}`;\n }\n return undefined;\n }\n entry.key.fill(0);\n return undefined;\n }\n\n /**\n * Constant-time byte comparison. Returns false immediately for length\n * mismatch (length is not secret); for equal-length inputs, walks the full\n * buffer accumulating differences via XOR so the running time does not leak\n * the position of the first differing byte.\n */\n private static _timingSafeEqual(a: Uint8Array, b: Uint8Array): boolean {\n /* c8 ignore next 3 - defensive: callers in this class only compare\n PBKDF2-derived 32-byte keys against encryption-key entries (also 32 bytes) */\n if (a.length !== b.length) {\n return false;\n }\n let diff = 0;\n for (let i = 0; i < a.length; i++) {\n // eslint-disable-next-line no-bitwise\n diff |= a[i] ^ b[i];\n }\n return diff === 0;\n }\n\n /**\n * Mints a fresh UUID v4 storage handle using the crypto provider's\n * {@link CryptoUtils.ICryptoProvider.generateRandomBytes | generateRandomBytes}.\n * Random-bytes failures propagate as Failure.\n */\n private _generateId(): Result<string> {\n return this._cryptoProvider.generateRandomBytes(16).onSuccess((bytes) => {\n // Per RFC 4122 §4.4: set version (4) and variant (10xx) bits.\n // eslint-disable-next-line no-bitwise\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n // eslint-disable-next-line no-bitwise\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n return succeed(\n `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(\n 20,\n 32\n )}`\n );\n });\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { JsonValue } from '@fgv/ts-json-base';
2
- import { Result } from '@fgv/ts-utils';
2
+ import { Result, Uuid } from '@fgv/ts-utils';
3
3
  import * as Constants from './constants';
4
4
  export { Constants };
5
5
  /**
@@ -229,6 +229,15 @@ export interface ICryptoProvider {
229
229
  * @returns Success with random bytes, or Failure with error
230
230
  */
231
231
  generateRandomBytes(length: number): Result<Uint8Array>;
232
+ /**
233
+ * Generates a cryptographically random UUIDv4 using the provider's
234
+ * underlying source of randomness. The default Node and browser
235
+ * implementations delegate to `globalThis.crypto.randomUUID`;
236
+ * deterministic providers (e.g. test stubs) may override to produce
237
+ * reproducible values.
238
+ * @returns Success with a canonical UUID, or Failure with error.
239
+ */
240
+ generateUuid(): Result<Uuid>;
232
241
  /**
233
242
  * Encodes binary data to base64 string.
234
243
  * @param data - Binary data to encode
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/model.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/model.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmeZ,0CAMC;AApeD,uDAAyC;AAChC,8BAAS;AAgIlB;;;GAGG;AACU,QAAA,oBAAoB,GAAoC;IACnE,YAAY;IACZ,eAAe;IACf,WAAW;IACX,SAAS;CACV,CAAC;AAyUF,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,IAAa;IAC3C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,GAAG,GAAG,IAA+B,CAAC;IAC5C,OAAO,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,qBAAqB,CAAC;AACxD,CAAC","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { JsonValue } from '@fgv/ts-json-base';\nimport { Result } from '@fgv/ts-utils';\n\nimport * as Constants from './constants';\nexport { Constants };\n\n// ============================================================================\n// Encryption Types\n// ============================================================================\n\n/**\n * Supported encryption algorithms.\n * @public\n */\nexport type EncryptionAlgorithm = typeof Constants.DEFAULT_ALGORITHM;\n\n/**\n * Format version for encrypted files.\n * @public\n */\nexport type EncryptedFileFormat = typeof Constants.ENCRYPTED_FILE_FORMAT;\n\n/**\n * Named secret for encryption/decryption.\n * @public\n */\nexport interface INamedSecret {\n /**\n * Unique name for this secret (referenced in encrypted files).\n */\n readonly name: string;\n\n /**\n * The actual secret key (32 bytes for AES-256).\n */\n readonly key: Uint8Array;\n}\n\n/**\n * Result of an encryption operation.\n * @public\n */\nexport interface IEncryptionResult {\n /**\n * Initialization vector used for encryption (12 bytes for GCM).\n */\n readonly iv: Uint8Array;\n\n /**\n * Authentication tag from GCM mode (16 bytes).\n */\n readonly authTag: Uint8Array;\n\n /**\n * The encrypted data.\n */\n readonly encryptedData: Uint8Array;\n}\n\n/**\n * Asymmetric keypair algorithms supported by the crypto provider.\n * - `'ecdsa-p256'`: ECDSA over the P-256 curve, for signing.\n * - `'rsa-oaep-2048'`: RSA-OAEP, 2048-bit modulus with SHA-256, for encryption.\n * - `'ecdh-p256'`: ECDH over the P-256 curve, for key agreement\n * (e.g. as the recipient keypair in\n * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} /\n * {@link CryptoUtils.ICryptoProvider.unwrapBytes | unwrapBytes}).\n * - `'ed25519'`: EdDSA over the Edwards25519 curve, for signing.\n * Deterministic — the per-signature nonce is derived from the private key\n * and message rather than sampled randomly, eliminating the random-nonce\n * reuse risk that ECDSA carries. Distinct from X25519 (key agreement over\n * the Montgomery form, Curve25519).\n * @public\n */\nexport type KeyPairAlgorithm = 'ecdsa-p256' | 'rsa-oaep-2048' | 'ecdh-p256' | 'ed25519';\n\n/**\n * Caller-supplied HKDF parameters that domain-separate one\n * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} call from another.\n * Two wraps that share recipient but differ on `salt` or `info` derive distinct\n * wrap keys, so callers should pick values that bind the wrap to its\n * application context (e.g. a content hash for `salt` and a secret name for\n * `info`).\n *\n * Both fields are required; pass an empty `Uint8Array` if the caller has no\n * value to bind on a given axis. Silent defaulting would hide protocol\n * mistakes, so the API does not pick defaults.\n * @public\n */\nexport interface IWrapBytesOptions {\n /**\n * HKDF salt. Domain-separates this wrap from others in different contexts.\n * Caller picks; common choices include a content hash, document id, channel\n * id, etc.\n */\n readonly salt: Uint8Array;\n\n /**\n * HKDF info. Further binds the derived key to a specific use within the\n * calling application. Caller picks; common choices include a secret name,\n * message type, or version tag.\n */\n readonly info: Uint8Array;\n}\n\n/**\n * Output of {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes}. The\n * shape is JSON-serializable so it can travel directly over the wire or be\n * persisted as-is.\n * @public\n */\nexport interface IWrappedBytes {\n /**\n * Sender's ephemeral ECDH P-256 public key as a JSON Web Key. The matching\n * ephemeral private key is dropped after the shared-secret derive.\n */\n readonly ephemeralPublicKey: JsonWebKey;\n\n /**\n * AES-GCM nonce, base64-encoded. 12 bytes (96 bits) — the standard AES-GCM\n * nonce length.\n */\n readonly nonce: string;\n\n /**\n * AES-GCM ciphertext concatenated with the 16-byte authentication tag,\n * base64-encoded. Tampering with either the nonce or the ciphertext causes\n * unwrap to fail GCM authentication.\n */\n readonly ciphertext: string;\n}\n\n/**\n * All valid key pair algorithms.\n * @public\n */\nexport const allKeyPairAlgorithms: ReadonlyArray<KeyPairAlgorithm> = [\n 'ecdsa-p256',\n 'rsa-oaep-2048',\n 'ecdh-p256',\n 'ed25519'\n];\n\n/**\n * Supported key derivation functions.\n * @public\n */\nexport type KeyDerivationFunction = 'pbkdf2';\n\n/**\n * Key derivation parameters stored in encrypted files.\n * Allows decryption with password without needing to know the original salt/iterations.\n * @public\n */\nexport interface IKeyDerivationParams {\n /**\n * Key derivation function used.\n */\n readonly kdf: KeyDerivationFunction;\n\n /**\n * Base64-encoded salt used for key derivation.\n */\n readonly salt: string;\n\n /**\n * Number of iterations used for key derivation.\n */\n readonly iterations: number;\n}\n\n/**\n * Generic encrypted file format.\n * This is the JSON structure stored in encrypted files.\n * @typeParam TMetadata - Type of optional unencrypted metadata\n * @public\n */\nexport interface IEncryptedFile<TMetadata = JsonValue> {\n /**\n * Format identifier for versioning.\n */\n readonly format: EncryptedFileFormat;\n\n /**\n * Name of the secret required to decrypt (references INamedSecret.name).\n */\n readonly secretName: string;\n\n /**\n * Algorithm used for encryption.\n */\n readonly algorithm: EncryptionAlgorithm;\n\n /**\n * Base64-encoded initialization vector.\n */\n readonly iv: string;\n\n /**\n * Base64-encoded authentication tag (for GCM mode).\n */\n readonly authTag: string;\n\n /**\n * Base64-encoded encrypted data (JSON string when decrypted).\n */\n readonly encryptedData: string;\n\n /**\n * Optional unencrypted metadata for display/filtering.\n */\n readonly metadata?: TMetadata;\n\n /**\n * Optional key derivation parameters.\n * If present, allows decryption using a password with these parameters.\n * If absent, a pre-derived key must be provided.\n */\n readonly keyDerivation?: IKeyDerivationParams;\n}\n\n// ============================================================================\n// Crypto Provider Interface\n// ============================================================================\n\n/**\n * Crypto provider interface for cross-platform encryption.\n * Implementations provided for Node.js (crypto module) and browser (Web Crypto API).\n * @public\n */\nexport interface ICryptoProvider {\n /**\n * Encrypts plaintext using AES-256-GCM.\n * @param plaintext - UTF-8 string to encrypt\n * @param key - 32-byte encryption key\n * @returns Success with encryption result, or Failure with error\n */\n encrypt(plaintext: string, key: Uint8Array): Promise<Result<IEncryptionResult>>;\n\n /**\n * Decrypts ciphertext using AES-256-GCM.\n * @param encryptedData - Encrypted bytes\n * @param key - 32-byte decryption key\n * @param iv - Initialization vector (12 bytes)\n * @param authTag - GCM authentication tag (16 bytes)\n * @returns Success with decrypted UTF-8 string, or Failure with error\n */\n decrypt(\n encryptedData: Uint8Array,\n key: Uint8Array,\n iv: Uint8Array,\n authTag: Uint8Array\n ): Promise<Result<string>>;\n\n /**\n * Generates a random 32-byte key suitable for AES-256.\n * @returns Success with generated key, or Failure with error\n */\n generateKey(): Promise<Result<Uint8Array>>;\n\n /**\n * Derives a key from a password using PBKDF2.\n * @param password - Password string\n * @param salt - Salt bytes (should be at least 16 bytes)\n * @param iterations - Number of iterations (recommend 100000+)\n * @returns Success with derived 32-byte key, or Failure with error\n */\n deriveKey(password: string, salt: Uint8Array, iterations: number): Promise<Result<Uint8Array>>;\n\n /**\n * Computes a SHA-256 hash of the given data.\n * @param data - UTF-8 string to hash\n * @returns Success with hex-encoded hash string, or Failure with error\n */\n sha256(data: string): Promise<Result<string>>;\n\n // ============================================================================\n // Platform Utility Methods\n // ============================================================================\n\n /**\n * Generates cryptographically secure random bytes.\n * @param length - Number of bytes to generate\n * @returns Success with random bytes, or Failure with error\n */\n generateRandomBytes(length: number): Result<Uint8Array>;\n\n /**\n * Encodes binary data to base64 string.\n * @param data - Binary data to encode\n * @returns Base64-encoded string\n */\n toBase64(data: Uint8Array): string;\n\n /**\n * Decodes base64 string to binary data.\n * @param base64 - Base64-encoded string\n * @returns Success with decoded bytes, or Failure if invalid base64\n */\n fromBase64(base64: string): Result<Uint8Array>;\n\n // ============================================================================\n // Asymmetric Key Operations\n // ============================================================================\n\n /**\n * Generates a new asymmetric keypair for the requested algorithm.\n * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} to use.\n * @param extractable - Whether the resulting `CryptoKey` objects may be exported.\n * Set `false` on backends that store `CryptoKey` references directly (e.g.\n * IndexedDB). Set `true` when the private key must round-trip through JWK or\n * PKCS#8 (e.g. encrypted-file backends).\n * @returns Success with the generated `CryptoKeyPair`, or Failure with error context.\n */\n generateKeyPair(algorithm: KeyPairAlgorithm, extractable: boolean): Promise<Result<CryptoKeyPair>>;\n\n /**\n * Exports the public half of a keypair as a JSON Web Key.\n * @param publicKey - The public `CryptoKey` to export. Must be an `extractable`\n * key generated for an asymmetric algorithm.\n * @returns Success with the JWK, or Failure with error context.\n */\n exportPublicKeyJwk(publicKey: CryptoKey): Promise<Result<JsonWebKey>>;\n\n /**\n * Re-imports a public-key JWK as a `CryptoKey` usable for verification or\n * encryption (depending on algorithm).\n * @param jwk - The JSON Web Key produced by {@link CryptoUtils.ICryptoProvider.exportPublicKeyJwk | exportPublicKeyJwk}.\n * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} the\n * key was generated for. Determines the import parameters and key usages.\n * @returns Success with the imported public `CryptoKey`, or Failure with error context.\n */\n importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;\n\n /**\n * Wraps `plaintext` for delivery to the holder of the private key paired\n * with `recipientPublicKey`. Uses ECIES with ECDH P-256, HKDF-SHA256, and\n * AES-GCM-256.\n *\n * Generates a fresh ephemeral keypair per call; the ephemeral private key\n * is discarded after the shared-secret derive. Only the recipient (with the\n * matching private key) and the same HKDF parameters can recover\n * `plaintext`.\n *\n * Empty `plaintext` is permitted; the resulting wrap contains only the\n * 16-byte GCM authentication tag and round-trips back to an empty\n * `Uint8Array`.\n * @param plaintext - The bytes to wrap. Any length supported by AES-GCM\n * (in practice, well below 2^39 - 256 bits).\n * @param recipientPublicKey - The recipient's ECDH P-256 public `CryptoKey`.\n * Must have algorithm name `'ECDH'` and named curve `'P-256'`; mismatched\n * algorithm or curve yields a `Failure` with error context.\n * @param options - HKDF parameters; see {@link CryptoUtils.IWrapBytesOptions | IWrapBytesOptions}.\n * @returns `Success` with the wrapped payload, or `Failure` with error context.\n */\n wrapBytes(\n plaintext: Uint8Array,\n recipientPublicKey: CryptoKey,\n options: IWrapBytesOptions\n ): Promise<Result<IWrappedBytes>>;\n\n /**\n * Inverse of {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes}.\n * Recovers the original `plaintext` from a wrapped payload using the\n * recipient's private key.\n *\n * Returns a `Failure` (never throws) on any of:\n * - Tampered nonce or ciphertext (AES-GCM authentication fails)\n * - Wrong private key (different shared secret derives a different wrap key)\n * - Wrong HKDF parameters (different wrap key)\n * - Malformed `ephemeralPublicKey` JWK\n * - Malformed base64 in `nonce` or `ciphertext`\n * @param wrapped - The wrapped payload produced by `wrapBytes`.\n * @param recipientPrivateKey - The recipient's ECDH P-256 private\n * `CryptoKey`. Must have algorithm name `'ECDH'` and named curve `'P-256'`,\n * and key usages including `'deriveKey'` or `'deriveBits'`.\n * @param options - The same HKDF parameters used at wrap time.\n * @returns `Success` with the original `plaintext`, or `Failure` with error context.\n */\n unwrapBytes(\n wrapped: IWrappedBytes,\n recipientPrivateKey: CryptoKey,\n options: IWrapBytesOptions\n ): Promise<Result<Uint8Array>>;\n}\n\n// ============================================================================\n// Encryption Provider Interface\n// ============================================================================\n\n/**\n * High-level interface for encrypting JSON content by secret name.\n *\n * This abstraction unifies two common encryption workflows:\n * - **KeyStore**: looks up the named secret and crypto provider from the vault\n * - **DirectEncryptionProvider**: uses a pre-supplied key and crypto provider,\n * optionally bound to a specific secret name for safety\n *\n * Callers that need to encrypt (e.g. `EditableCollection.save()`) depend on\n * this interface rather than on `KeyStore` directly, allowing mix-and-match.\n *\n * @public\n */\nexport interface IEncryptionProvider {\n /**\n * Encrypts JSON content under a named secret.\n *\n * @param secretName - Name of the secret to encrypt with\n * @param content - JSON-safe content to encrypt\n * @param metadata - Optional unencrypted metadata to include in the encrypted file\n * @returns Success with encrypted file structure, or Failure with error context\n */\n encryptByName<TMetadata = JsonValue>(\n secretName: string,\n content: JsonValue,\n metadata?: TMetadata\n ): Promise<Result<IEncryptedFile<TMetadata>>>;\n}\n\n// ============================================================================\n// Encryption Configuration\n// ============================================================================\n\n/**\n * Behavior when an encrypted file cannot be decrypted.\n * @public\n */\nexport type EncryptedFileErrorMode =\n | 'fail' // Return failure, abort loading\n | 'skip' // Skip file silently, continue loading others\n | 'warn'; // Log warning, skip file, continue loading\n\n/**\n * Function type for dynamic secret retrieval.\n * @public\n */\nexport type SecretProvider = (secretName: string) => Promise<Result<Uint8Array>>;\n\n/**\n * Configuration for encrypted file handling during loading.\n * @public\n */\nexport interface IEncryptionConfig {\n /**\n * Named secrets available for decryption.\n */\n readonly secrets?: ReadonlyArray<INamedSecret>;\n\n /**\n * Alternative: dynamic secret provider function.\n * Called when a secret is not found in the secrets array.\n */\n readonly secretProvider?: SecretProvider;\n\n /**\n * Crypto provider implementation (Node.js or browser).\n */\n readonly cryptoProvider: ICryptoProvider;\n\n /**\n * Behavior when decryption key is missing (default: 'fail').\n */\n readonly onMissingKey?: EncryptedFileErrorMode;\n\n /**\n * Behavior when decryption fails (default: 'fail').\n */\n readonly onDecryptionError?: EncryptedFileErrorMode;\n}\n\n// ============================================================================\n// Detection Helper\n// ============================================================================\n\n/**\n * Checks if a JSON object appears to be an encrypted file.\n * Uses the format field as a discriminator.\n * @param json - JSON object to check\n * @returns true if the object has the encrypted file format field\n * @public\n */\nexport function isEncryptedFile(json: unknown): boolean {\n if (typeof json !== 'object' || json === null) {\n return false;\n }\n const obj = json as Record<string, unknown>;\n return obj.format === Constants.ENCRYPTED_FILE_FORMAT;\n}\n"]}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/model.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6eZ,0CAMC;AA9eD,uDAAyC;AAChC,8BAAS;AAgIlB;;;GAGG;AACU,QAAA,oBAAoB,GAAoC;IACnE,YAAY;IACZ,eAAe;IACf,WAAW;IACX,SAAS;CACV,CAAC;AAmVF,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,IAAa;IAC3C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,GAAG,GAAG,IAA+B,CAAC;IAC5C,OAAO,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,qBAAqB,CAAC;AACxD,CAAC","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { JsonValue } from '@fgv/ts-json-base';\nimport { Result, Uuid } from '@fgv/ts-utils';\n\nimport * as Constants from './constants';\nexport { Constants };\n\n// ============================================================================\n// Encryption Types\n// ============================================================================\n\n/**\n * Supported encryption algorithms.\n * @public\n */\nexport type EncryptionAlgorithm = typeof Constants.DEFAULT_ALGORITHM;\n\n/**\n * Format version for encrypted files.\n * @public\n */\nexport type EncryptedFileFormat = typeof Constants.ENCRYPTED_FILE_FORMAT;\n\n/**\n * Named secret for encryption/decryption.\n * @public\n */\nexport interface INamedSecret {\n /**\n * Unique name for this secret (referenced in encrypted files).\n */\n readonly name: string;\n\n /**\n * The actual secret key (32 bytes for AES-256).\n */\n readonly key: Uint8Array;\n}\n\n/**\n * Result of an encryption operation.\n * @public\n */\nexport interface IEncryptionResult {\n /**\n * Initialization vector used for encryption (12 bytes for GCM).\n */\n readonly iv: Uint8Array;\n\n /**\n * Authentication tag from GCM mode (16 bytes).\n */\n readonly authTag: Uint8Array;\n\n /**\n * The encrypted data.\n */\n readonly encryptedData: Uint8Array;\n}\n\n/**\n * Asymmetric keypair algorithms supported by the crypto provider.\n * - `'ecdsa-p256'`: ECDSA over the P-256 curve, for signing.\n * - `'rsa-oaep-2048'`: RSA-OAEP, 2048-bit modulus with SHA-256, for encryption.\n * - `'ecdh-p256'`: ECDH over the P-256 curve, for key agreement\n * (e.g. as the recipient keypair in\n * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} /\n * {@link CryptoUtils.ICryptoProvider.unwrapBytes | unwrapBytes}).\n * - `'ed25519'`: EdDSA over the Edwards25519 curve, for signing.\n * Deterministic — the per-signature nonce is derived from the private key\n * and message rather than sampled randomly, eliminating the random-nonce\n * reuse risk that ECDSA carries. Distinct from X25519 (key agreement over\n * the Montgomery form, Curve25519).\n * @public\n */\nexport type KeyPairAlgorithm = 'ecdsa-p256' | 'rsa-oaep-2048' | 'ecdh-p256' | 'ed25519';\n\n/**\n * Caller-supplied HKDF parameters that domain-separate one\n * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} call from another.\n * Two wraps that share recipient but differ on `salt` or `info` derive distinct\n * wrap keys, so callers should pick values that bind the wrap to its\n * application context (e.g. a content hash for `salt` and a secret name for\n * `info`).\n *\n * Both fields are required; pass an empty `Uint8Array` if the caller has no\n * value to bind on a given axis. Silent defaulting would hide protocol\n * mistakes, so the API does not pick defaults.\n * @public\n */\nexport interface IWrapBytesOptions {\n /**\n * HKDF salt. Domain-separates this wrap from others in different contexts.\n * Caller picks; common choices include a content hash, document id, channel\n * id, etc.\n */\n readonly salt: Uint8Array;\n\n /**\n * HKDF info. Further binds the derived key to a specific use within the\n * calling application. Caller picks; common choices include a secret name,\n * message type, or version tag.\n */\n readonly info: Uint8Array;\n}\n\n/**\n * Output of {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes}. The\n * shape is JSON-serializable so it can travel directly over the wire or be\n * persisted as-is.\n * @public\n */\nexport interface IWrappedBytes {\n /**\n * Sender's ephemeral ECDH P-256 public key as a JSON Web Key. The matching\n * ephemeral private key is dropped after the shared-secret derive.\n */\n readonly ephemeralPublicKey: JsonWebKey;\n\n /**\n * AES-GCM nonce, base64-encoded. 12 bytes (96 bits) — the standard AES-GCM\n * nonce length.\n */\n readonly nonce: string;\n\n /**\n * AES-GCM ciphertext concatenated with the 16-byte authentication tag,\n * base64-encoded. Tampering with either the nonce or the ciphertext causes\n * unwrap to fail GCM authentication.\n */\n readonly ciphertext: string;\n}\n\n/**\n * All valid key pair algorithms.\n * @public\n */\nexport const allKeyPairAlgorithms: ReadonlyArray<KeyPairAlgorithm> = [\n 'ecdsa-p256',\n 'rsa-oaep-2048',\n 'ecdh-p256',\n 'ed25519'\n];\n\n/**\n * Supported key derivation functions.\n * @public\n */\nexport type KeyDerivationFunction = 'pbkdf2';\n\n/**\n * Key derivation parameters stored in encrypted files.\n * Allows decryption with password without needing to know the original salt/iterations.\n * @public\n */\nexport interface IKeyDerivationParams {\n /**\n * Key derivation function used.\n */\n readonly kdf: KeyDerivationFunction;\n\n /**\n * Base64-encoded salt used for key derivation.\n */\n readonly salt: string;\n\n /**\n * Number of iterations used for key derivation.\n */\n readonly iterations: number;\n}\n\n/**\n * Generic encrypted file format.\n * This is the JSON structure stored in encrypted files.\n * @typeParam TMetadata - Type of optional unencrypted metadata\n * @public\n */\nexport interface IEncryptedFile<TMetadata = JsonValue> {\n /**\n * Format identifier for versioning.\n */\n readonly format: EncryptedFileFormat;\n\n /**\n * Name of the secret required to decrypt (references INamedSecret.name).\n */\n readonly secretName: string;\n\n /**\n * Algorithm used for encryption.\n */\n readonly algorithm: EncryptionAlgorithm;\n\n /**\n * Base64-encoded initialization vector.\n */\n readonly iv: string;\n\n /**\n * Base64-encoded authentication tag (for GCM mode).\n */\n readonly authTag: string;\n\n /**\n * Base64-encoded encrypted data (JSON string when decrypted).\n */\n readonly encryptedData: string;\n\n /**\n * Optional unencrypted metadata for display/filtering.\n */\n readonly metadata?: TMetadata;\n\n /**\n * Optional key derivation parameters.\n * If present, allows decryption using a password with these parameters.\n * If absent, a pre-derived key must be provided.\n */\n readonly keyDerivation?: IKeyDerivationParams;\n}\n\n// ============================================================================\n// Crypto Provider Interface\n// ============================================================================\n\n/**\n * Crypto provider interface for cross-platform encryption.\n * Implementations provided for Node.js (crypto module) and browser (Web Crypto API).\n * @public\n */\nexport interface ICryptoProvider {\n /**\n * Encrypts plaintext using AES-256-GCM.\n * @param plaintext - UTF-8 string to encrypt\n * @param key - 32-byte encryption key\n * @returns Success with encryption result, or Failure with error\n */\n encrypt(plaintext: string, key: Uint8Array): Promise<Result<IEncryptionResult>>;\n\n /**\n * Decrypts ciphertext using AES-256-GCM.\n * @param encryptedData - Encrypted bytes\n * @param key - 32-byte decryption key\n * @param iv - Initialization vector (12 bytes)\n * @param authTag - GCM authentication tag (16 bytes)\n * @returns Success with decrypted UTF-8 string, or Failure with error\n */\n decrypt(\n encryptedData: Uint8Array,\n key: Uint8Array,\n iv: Uint8Array,\n authTag: Uint8Array\n ): Promise<Result<string>>;\n\n /**\n * Generates a random 32-byte key suitable for AES-256.\n * @returns Success with generated key, or Failure with error\n */\n generateKey(): Promise<Result<Uint8Array>>;\n\n /**\n * Derives a key from a password using PBKDF2.\n * @param password - Password string\n * @param salt - Salt bytes (should be at least 16 bytes)\n * @param iterations - Number of iterations (recommend 100000+)\n * @returns Success with derived 32-byte key, or Failure with error\n */\n deriveKey(password: string, salt: Uint8Array, iterations: number): Promise<Result<Uint8Array>>;\n\n /**\n * Computes a SHA-256 hash of the given data.\n * @param data - UTF-8 string to hash\n * @returns Success with hex-encoded hash string, or Failure with error\n */\n sha256(data: string): Promise<Result<string>>;\n\n // ============================================================================\n // Platform Utility Methods\n // ============================================================================\n\n /**\n * Generates cryptographically secure random bytes.\n * @param length - Number of bytes to generate\n * @returns Success with random bytes, or Failure with error\n */\n generateRandomBytes(length: number): Result<Uint8Array>;\n\n /**\n * Generates a cryptographically random UUIDv4 using the provider's\n * underlying source of randomness. The default Node and browser\n * implementations delegate to `globalThis.crypto.randomUUID`;\n * deterministic providers (e.g. test stubs) may override to produce\n * reproducible values.\n * @returns Success with a canonical UUID, or Failure with error.\n */\n generateUuid(): Result<Uuid>;\n\n /**\n * Encodes binary data to base64 string.\n * @param data - Binary data to encode\n * @returns Base64-encoded string\n */\n toBase64(data: Uint8Array): string;\n\n /**\n * Decodes base64 string to binary data.\n * @param base64 - Base64-encoded string\n * @returns Success with decoded bytes, or Failure if invalid base64\n */\n fromBase64(base64: string): Result<Uint8Array>;\n\n // ============================================================================\n // Asymmetric Key Operations\n // ============================================================================\n\n /**\n * Generates a new asymmetric keypair for the requested algorithm.\n * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} to use.\n * @param extractable - Whether the resulting `CryptoKey` objects may be exported.\n * Set `false` on backends that store `CryptoKey` references directly (e.g.\n * IndexedDB). Set `true` when the private key must round-trip through JWK or\n * PKCS#8 (e.g. encrypted-file backends).\n * @returns Success with the generated `CryptoKeyPair`, or Failure with error context.\n */\n generateKeyPair(algorithm: KeyPairAlgorithm, extractable: boolean): Promise<Result<CryptoKeyPair>>;\n\n /**\n * Exports the public half of a keypair as a JSON Web Key.\n * @param publicKey - The public `CryptoKey` to export. Must be an `extractable`\n * key generated for an asymmetric algorithm.\n * @returns Success with the JWK, or Failure with error context.\n */\n exportPublicKeyJwk(publicKey: CryptoKey): Promise<Result<JsonWebKey>>;\n\n /**\n * Re-imports a public-key JWK as a `CryptoKey` usable for verification or\n * encryption (depending on algorithm).\n * @param jwk - The JSON Web Key produced by {@link CryptoUtils.ICryptoProvider.exportPublicKeyJwk | exportPublicKeyJwk}.\n * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} the\n * key was generated for. Determines the import parameters and key usages.\n * @returns Success with the imported public `CryptoKey`, or Failure with error context.\n */\n importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;\n\n /**\n * Wraps `plaintext` for delivery to the holder of the private key paired\n * with `recipientPublicKey`. Uses ECIES with ECDH P-256, HKDF-SHA256, and\n * AES-GCM-256.\n *\n * Generates a fresh ephemeral keypair per call; the ephemeral private key\n * is discarded after the shared-secret derive. Only the recipient (with the\n * matching private key) and the same HKDF parameters can recover\n * `plaintext`.\n *\n * Empty `plaintext` is permitted; the resulting wrap contains only the\n * 16-byte GCM authentication tag and round-trips back to an empty\n * `Uint8Array`.\n * @param plaintext - The bytes to wrap. Any length supported by AES-GCM\n * (in practice, well below 2^39 - 256 bits).\n * @param recipientPublicKey - The recipient's ECDH P-256 public `CryptoKey`.\n * Must have algorithm name `'ECDH'` and named curve `'P-256'`; mismatched\n * algorithm or curve yields a `Failure` with error context.\n * @param options - HKDF parameters; see {@link CryptoUtils.IWrapBytesOptions | IWrapBytesOptions}.\n * @returns `Success` with the wrapped payload, or `Failure` with error context.\n */\n wrapBytes(\n plaintext: Uint8Array,\n recipientPublicKey: CryptoKey,\n options: IWrapBytesOptions\n ): Promise<Result<IWrappedBytes>>;\n\n /**\n * Inverse of {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes}.\n * Recovers the original `plaintext` from a wrapped payload using the\n * recipient's private key.\n *\n * Returns a `Failure` (never throws) on any of:\n * - Tampered nonce or ciphertext (AES-GCM authentication fails)\n * - Wrong private key (different shared secret derives a different wrap key)\n * - Wrong HKDF parameters (different wrap key)\n * - Malformed `ephemeralPublicKey` JWK\n * - Malformed base64 in `nonce` or `ciphertext`\n * @param wrapped - The wrapped payload produced by `wrapBytes`.\n * @param recipientPrivateKey - The recipient's ECDH P-256 private\n * `CryptoKey`. Must have algorithm name `'ECDH'` and named curve `'P-256'`,\n * and key usages including `'deriveKey'` or `'deriveBits'`.\n * @param options - The same HKDF parameters used at wrap time.\n * @returns `Success` with the original `plaintext`, or `Failure` with error context.\n */\n unwrapBytes(\n wrapped: IWrappedBytes,\n recipientPrivateKey: CryptoKey,\n options: IWrapBytesOptions\n ): Promise<Result<Uint8Array>>;\n}\n\n// ============================================================================\n// Encryption Provider Interface\n// ============================================================================\n\n/**\n * High-level interface for encrypting JSON content by secret name.\n *\n * This abstraction unifies two common encryption workflows:\n * - **KeyStore**: looks up the named secret and crypto provider from the vault\n * - **DirectEncryptionProvider**: uses a pre-supplied key and crypto provider,\n * optionally bound to a specific secret name for safety\n *\n * Callers that need to encrypt (e.g. `EditableCollection.save()`) depend on\n * this interface rather than on `KeyStore` directly, allowing mix-and-match.\n *\n * @public\n */\nexport interface IEncryptionProvider {\n /**\n * Encrypts JSON content under a named secret.\n *\n * @param secretName - Name of the secret to encrypt with\n * @param content - JSON-safe content to encrypt\n * @param metadata - Optional unencrypted metadata to include in the encrypted file\n * @returns Success with encrypted file structure, or Failure with error context\n */\n encryptByName<TMetadata = JsonValue>(\n secretName: string,\n content: JsonValue,\n metadata?: TMetadata\n ): Promise<Result<IEncryptedFile<TMetadata>>>;\n}\n\n// ============================================================================\n// Encryption Configuration\n// ============================================================================\n\n/**\n * Behavior when an encrypted file cannot be decrypted.\n * @public\n */\nexport type EncryptedFileErrorMode =\n | 'fail' // Return failure, abort loading\n | 'skip' // Skip file silently, continue loading others\n | 'warn'; // Log warning, skip file, continue loading\n\n/**\n * Function type for dynamic secret retrieval.\n * @public\n */\nexport type SecretProvider = (secretName: string) => Promise<Result<Uint8Array>>;\n\n/**\n * Configuration for encrypted file handling during loading.\n * @public\n */\nexport interface IEncryptionConfig {\n /**\n * Named secrets available for decryption.\n */\n readonly secrets?: ReadonlyArray<INamedSecret>;\n\n /**\n * Alternative: dynamic secret provider function.\n * Called when a secret is not found in the secrets array.\n */\n readonly secretProvider?: SecretProvider;\n\n /**\n * Crypto provider implementation (Node.js or browser).\n */\n readonly cryptoProvider: ICryptoProvider;\n\n /**\n * Behavior when decryption key is missing (default: 'fail').\n */\n readonly onMissingKey?: EncryptedFileErrorMode;\n\n /**\n * Behavior when decryption fails (default: 'fail').\n */\n readonly onDecryptionError?: EncryptedFileErrorMode;\n}\n\n// ============================================================================\n// Detection Helper\n// ============================================================================\n\n/**\n * Checks if a JSON object appears to be an encrypted file.\n * Uses the format field as a discriminator.\n * @param json - JSON object to check\n * @returns true if the object has the encrypted file format field\n * @public\n */\nexport function isEncryptedFile(json: unknown): boolean {\n if (typeof json !== 'object' || json === null) {\n return false;\n }\n const obj = json as Record<string, unknown>;\n return obj.format === Constants.ENCRYPTED_FILE_FORMAT;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Result } from '@fgv/ts-utils';
1
+ import { Result, Uuid } from '@fgv/ts-utils';
2
2
  import { ICryptoProvider, IEncryptionResult, IWrapBytesOptions, IWrappedBytes, KeyPairAlgorithm } from './model';
3
3
  /**
4
4
  * Node.js implementation of {@link CryptoUtils.ICryptoProvider} using the built-in crypto module.
@@ -47,6 +47,12 @@ export declare class NodeCryptoProvider implements ICryptoProvider {
47
47
  * @returns Success with random bytes, or Failure with error
48
48
  */
49
49
  generateRandomBytes(length: number): Result<Uint8Array>;
50
+ /**
51
+ * Generates a cryptographically random UUIDv4 via the platform Web Crypto API.
52
+ * @returns `Success` with the generated UUID, or `Failure` if the runtime
53
+ * does not expose `globalThis.crypto.randomUUID`.
54
+ */
55
+ generateUuid(): Result<Uuid>;
50
56
  /**
51
57
  * Encodes binary data to base64 string.
52
58
  * @param data - Binary data to encode
@@ -1 +1 @@
1
- {"version":3,"file":"nodeCryptoProvider.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/nodeCryptoProvider.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAoD,MAAM,EAAoB,MAAM,eAAe,CAAC;AAG3G,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IACxD;;;;;OAKG;IACU,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IA0B5F;;;;;;;OAOG;IACU,OAAO,CAClB,aAAa,EAAE,UAAU,EACzB,GAAG,EAAE,UAAU,EACf,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAyB1B;;;OAGG;IACU,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAOvD;;;;;;OAMG;IACU,SAAS,CACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IA2B9B;;;;OAIG;IACU,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAY1D;;;;OAIG;IACI,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;IAO9D;;;;OAIG;IACI,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IAIzC;;;;OAIG;IACI,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;IAYrD;;;;;OAKG;IACU,eAAe,CAC1B,SAAS,EAAE,gBAAgB,EAC3B,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAqBjC;;;;;;;;;OASG;IACU,kBAAkB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAQlF;;;;;OAKG;IACU,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAQzG;;;;;;;;OAQG;IACU,SAAS,CACpB,SAAS,EAAE,UAAU,EACrB,kBAAkB,EAAE,SAAS,EAC7B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAoCjC;;;;;;;OAOG;IACU,WAAW,CACtB,OAAO,EAAE,aAAa,EACtB,mBAAmB,EAAE,SAAS,EAC9B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;CAuD/B;AA8BD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAA6C,CAAC"}
1
+ {"version":3,"file":"nodeCryptoProvider.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/nodeCryptoProvider.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,MAAM,EAGN,IAAI,EACL,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IACxD;;;;;OAKG;IACU,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IA0B5F;;;;;;;OAOG;IACU,OAAO,CAClB,aAAa,EAAE,UAAU,EACzB,GAAG,EAAE,UAAU,EACf,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAyB1B;;;OAGG;IACU,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAOvD;;;;;;OAMG;IACU,SAAS,CACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IA2B9B;;;;OAIG;IACU,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAY1D;;;;OAIG;IACI,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;IAO9D;;;;OAIG;IACI,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC;IAInC;;;;OAIG;IACI,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IAIzC;;;;OAIG;IACI,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;IAYrD;;;;;OAKG;IACU,eAAe,CAC1B,SAAS,EAAE,gBAAgB,EAC3B,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAqBjC;;;;;;;;;OASG;IACU,kBAAkB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAQlF;;;;;OAKG;IACU,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAQzG;;;;;;;;OAQG;IACU,SAAS,CACpB,SAAS,EAAE,UAAU,EACrB,kBAAkB,EAAE,SAAS,EAC7B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAoCjC;;;;;;;OAOG;IACU,WAAW,CACtB,OAAO,EAAE,aAAa,EACtB,mBAAmB,EAAE,SAAS,EAC9B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;CAuD/B;AA8BD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAA6C,CAAC"}
@@ -179,6 +179,14 @@ class NodeCryptoProvider {
179
179
  }
180
180
  return (0, ts_utils_1.captureResult)(() => new Uint8Array(crypto.randomBytes(length)));
181
181
  }
182
+ /**
183
+ * Generates a cryptographically random UUIDv4 via the platform Web Crypto API.
184
+ * @returns `Success` with the generated UUID, or `Failure` if the runtime
185
+ * does not expose `globalThis.crypto.randomUUID`.
186
+ */
187
+ generateUuid() {
188
+ return (0, ts_utils_1.captureResult)(() => (0, ts_utils_1.generateUuid)());
189
+ }
182
190
  /**
183
191
  * Encodes binary data to base64 string.
184
192
  * @param data - Binary data to encode