@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
JavaScript
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 };