UNPKG

@giancarl021/cli-core-vault-extension

Version:

Plain and secure storage extension for the @giancarl021/cli-core npm package

106 lines (103 loc) 3.51 kB
import { AsyncEntry } from '@napi-rs/keyring'; import FSEntryFactoryBuilder from './FSEntryFactoryBuilder.js'; // Factory that creates a SecretEntry using the system keychain. const KeyringEntryFactory = (appName, key) => new AsyncEntry(appName, key); /** * Secret storage service. * @param appName The name of the application using the secret storage. * @returns An object with methods to get, set, and remove secrets. */ function SecretStorage(appName, fallbackStorageOptions) { let initialized = false; let EntryFactory; /** * Initialize the storage engine if not already initialized. * @remarks If using filesystem fallback, this will set up the necessary file and encryption. * Otherwise this initialization will result in a no-op. */ function _init() { if (initialized) return; if (!fallbackStorageOptions || !fallbackStorageOptions.useFilesystem) { EntryFactory = KeyringEntryFactory; initialized = true; return; } EntryFactory = FSEntryFactoryBuilder(fallbackStorageOptions.filePath, fallbackStorageOptions.encryptionKey); initialized = true; } // Initialize immediately if lazyInitialization is `false` or // if using system keychain if (!fallbackStorageOptions?.lazyInitialization) { _init(); } /** * Get a secret value by its key. * @param key The key of the secret to retrieve. * @returns The secret value, or undefined if not found. */ async function get(key) { _init(); const entry = EntryFactory(appName, key); let password; try { password = (await entry.getPassword()) ?? undefined; } catch (err) { const _err = err; throw new Error(`Failed to access the system keychain. Make sure your environment supports it: ${_err.message}`); } return password; } /** * Set a secret value by its key. * @param key The key of the secret to set. * @param value The secret value to store. */ async function set(key, value) { _init(); const entry = EntryFactory(appName, key); try { await entry.setPassword(value); } catch (err) { const _err = err; throw new Error(`Failed to access the system keychain. Make sure your environment supports it: ${_err.message}`); } } /** * Remove a secret by its key. * @param key The key of the secret to remove. */ async function remove(key) { _init(); const entry = EntryFactory(appName, key); try { await entry.deletePassword(); } catch (err) { const _err = err; throw new Error(`Failed to access the system keychain. Make sure your environment supports it: ${_err.message}`); } } return { /** * Get a secret value by its key. * @param key The key of the secret to retrieve. * @returns The secret value, or undefined if not found. */ get, /** * Set a secret value by its key. * @param key The key of the secret to set. * @param value The secret value to store. */ set, /** * Remove a secret by its key. * @param key The key of the secret to remove. */ remove }; } export { SecretStorage as default };