@botbotgo/common 1.0.2 → 1.0.4

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.
@@ -230,12 +230,12 @@ func secMessage(_ status: OSStatus) -> String {
230
230
  }
231
231
 
232
232
  let env = ProcessInfo.processInfo.environment
233
- let op = env["EASYNET_KC_OP"] ?? ""
234
- let service = env["EASYNET_KC_SERVICE"] ?? ""
235
- let account = env["EASYNET_KC_ACCOUNT"] ?? ""
236
- let secret = env["EASYNET_KC_SECRET"] ?? ""
237
- let prompt = env["EASYNET_KC_PROMPT"] ?? ""
238
- let biometric = env["EASYNET_KC_BIOMETRIC"] ?? "none"
233
+ let op = env["BOTBOTGO_KC_OP"] ?? env["EASYNET_KC_OP"] ?? ""
234
+ let service = env["BOTBOTGO_KC_SERVICE"] ?? env["EASYNET_KC_SERVICE"] ?? ""
235
+ let account = env["BOTBOTGO_KC_ACCOUNT"] ?? env["EASYNET_KC_ACCOUNT"] ?? ""
236
+ let secret = env["BOTBOTGO_KC_SECRET"] ?? env["EASYNET_KC_SECRET"] ?? ""
237
+ let prompt = env["BOTBOTGO_KC_PROMPT"] ?? env["EASYNET_KC_PROMPT"] ?? ""
238
+ let biometric = env["BOTBOTGO_KC_BIOMETRIC"] ?? env["EASYNET_KC_BIOMETRIC"] ?? "none"
239
239
 
240
240
  if op.isEmpty || service.isEmpty || account.isEmpty {
241
241
  emit(["ok": false, "error": "Missing required env values"])
@@ -345,12 +345,12 @@ default:
345
345
  async function runSwiftKeychain(op, input) {
346
346
  const env = {
347
347
  ...process.env,
348
- EASYNET_KC_OP: op,
349
- EASYNET_KC_SERVICE: input.service,
350
- EASYNET_KC_ACCOUNT: input.account,
351
- EASYNET_KC_SECRET: input.secret ?? "",
352
- EASYNET_KC_PROMPT: input.prompt ?? "",
353
- EASYNET_KC_BIOMETRIC: normalizeBiometricPolicy(input.biometric)
348
+ BOTBOTGO_KC_OP: op,
349
+ BOTBOTGO_KC_SERVICE: input.service,
350
+ BOTBOTGO_KC_ACCOUNT: input.account,
351
+ BOTBOTGO_KC_SECRET: input.secret ?? "",
352
+ BOTBOTGO_KC_PROMPT: input.prompt ?? "",
353
+ BOTBOTGO_KC_BIOMETRIC: normalizeBiometricPolicy(input.biometric)
354
354
  };
355
355
  try {
356
356
  const { stdout } = await execFileAsync("xcrun", ["swift", "-e", SWIFT_KEYCHAIN_BRIDGE], {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/security-store/store.ts","../../src/security-store/backends/file/index.ts","../../src/security-store/backends/utils.ts","../../src/security-store/backends/keychain/index.ts","../../src/security-store/backends/keychain/constants.ts","../../src/security-store/backends/keychain/keytar.ts","../../src/security-store/backends/keychain/utils.ts","../../src/security-store/backends/keychain/swift-bridge.ts","../../src/security-store/backends/memory/index.ts","../../src/security-store/backends/index.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport {\n MASTER_KEY_LENGTH,\n createSecretStoreBackend,\n type BiometricPolicy,\n type SecretStoreBackend,\n type SecretStoreBackendName,\n} from \"./backends/index.js\";\n\nconst PREFIX = \"enc:v1:\";\nconst NONCE_LENGTH = 12;\nconst TAG_LENGTH = 16;\n\nfunction decodeBase64Strict(input: string): Buffer {\n const trimmed = input.trim();\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(trimmed) || trimmed.length % 4 !== 0) {\n throw new Error(\"Invalid base64 in encrypted payload\");\n }\n const decoded = Buffer.from(trimmed, \"base64\");\n if (decoded.toString(\"base64\") !== trimmed) {\n throw new Error(\"Invalid base64 in encrypted payload\");\n }\n return decoded;\n}\n\nfunction assertNonEmpty(value: string, field: string): string {\n const normalized = value.trim();\n if (normalized.length === 0) {\n throw new Error(`${field} must be a non-empty string.`);\n }\n return normalized;\n}\n\nexport interface CryptoManagerKeyStore {\n init?(): Promise<void>;\n get(): Promise<Buffer | null>;\n set(key: Buffer): Promise<void>;\n}\n\nexport interface CryptoManagerOptions {\n service: string;\n account: string;\n allowPlaintextFallback?: boolean;\n masterKey?: Buffer;\n masterKeyStore?: CryptoManagerKeyStore;\n}\n\nexport class CryptoManager {\n private readonly allowPlaintextFallback: boolean;\n private readonly masterKeyStore: CryptoManagerKeyStore | null;\n private masterKey: Buffer | null = null;\n\n constructor(options: CryptoManagerOptions) {\n this.allowPlaintextFallback = options.allowPlaintextFallback !== false;\n this.masterKeyStore = options.masterKeyStore ?? null;\n if (options.masterKey != null) {\n if (options.masterKey.length !== MASTER_KEY_LENGTH) {\n throw new Error(\n `masterKey must be ${MASTER_KEY_LENGTH} bytes, got ${options.masterKey.length}`,\n );\n }\n this.masterKey = Buffer.from(options.masterKey);\n }\n }\n\n async init(): Promise<void> {\n if (this.masterKey != null && this.masterKey.length === MASTER_KEY_LENGTH) return;\n if (this.masterKeyStore == null) {\n throw new Error(\"CryptoManager requires either masterKey or masterKeyStore.\");\n }\n if (this.masterKeyStore.init) await this.masterKeyStore.init();\n let key = await this.masterKeyStore.get();\n if (key != null) {\n this.masterKey = key;\n return;\n }\n const newKey = crypto.randomBytes(MASTER_KEY_LENGTH);\n await this.masterKeyStore.set(newKey);\n key = await this.masterKeyStore.get();\n if (key == null || key.length !== MASTER_KEY_LENGTH) {\n throw new Error(\"Master key write succeeded but readback failed.\");\n }\n this.masterKey = key;\n }\n\n encrypt(plainText: string): string {\n if (this.masterKey == null) {\n throw new Error(\"CryptoManager not initialized. Call init() first.\");\n }\n const nonce = crypto.randomBytes(NONCE_LENGTH);\n const cipher = crypto.createCipheriv(\"aes-256-gcm\", this.masterKey, nonce);\n const enc = Buffer.concat([cipher.update(plainText, \"utf8\"), cipher.final()]);\n const tag = cipher.getAuthTag();\n const payload = Buffer.concat([nonce, tag, enc]);\n return PREFIX + payload.toString(\"base64\");\n }\n\n decrypt(cipherText: string): string {\n if (this.masterKey == null) {\n throw new Error(\"CryptoManager not initialized. Call init() first.\");\n }\n if (!cipherText.startsWith(PREFIX)) {\n if (this.allowPlaintextFallback) return cipherText;\n throw new Error(\"Input is not an encrypted string (missing enc:v1: prefix)\");\n }\n const payload = decodeBase64Strict(cipherText.slice(PREFIX.length));\n if (payload.length < NONCE_LENGTH + TAG_LENGTH) {\n throw new Error(\"Encrypted payload too short\");\n }\n const nonce = payload.subarray(0, NONCE_LENGTH);\n const tag = payload.subarray(NONCE_LENGTH, NONCE_LENGTH + TAG_LENGTH);\n const ciphertext = payload.subarray(NONCE_LENGTH + TAG_LENGTH);\n const decipher = crypto.createDecipheriv(\"aes-256-gcm\", this.masterKey, nonce);\n decipher.setAuthTag(tag);\n return decipher.update(ciphertext, undefined, \"utf8\") + decipher.final(\"utf8\");\n }\n\n static isEncrypted(value: string): boolean {\n return value.startsWith(PREFIX);\n }\n}\n\nexport interface SecretStoreOptions {\n service: string;\n appBinPath?: string;\n appleDeveloperTeamId?: string | null;\n biometric?: BiometricPolicy;\n prompt?: string;\n masterAccount?: string;\n dataService?: string;\n backend?: SecretStoreBackendName | SecretStoreBackend;\n masterKey?: Buffer;\n}\n\nexport class SecretStore {\n private readonly manager: CryptoManager;\n private readonly dataService: string;\n private readonly backend: SecretStoreBackend;\n private readonly initializeBackend: () => Promise<void>;\n private initialized = false;\n private initializing: Promise<void> | null = null;\n\n constructor(options: SecretStoreOptions) {\n const service = assertNonEmpty(options.service, \"service\");\n const masterAccount = options.masterAccount?.trim() || \"master-key\";\n this.dataService = options.dataService?.trim() || `${service}.data`;\n this.backend = createSecretStoreBackend(options.backend, { service });\n const backend = this.backend;\n let backendInitPromise: Promise<void> | null = null;\n this.initializeBackend = async () => {\n if (!backend.init) return;\n if (!backendInitPromise) backendInitPromise = backend.init();\n await backendInitPromise;\n };\n const backendContext = {\n service,\n account: masterAccount,\n appBinPath: options.appBinPath,\n appleDeveloperTeamId: options.appleDeveloperTeamId,\n biometric: options.biometric,\n prompt: options.prompt,\n };\n this.manager = new CryptoManager({\n service,\n account: masterAccount,\n allowPlaintextFallback: true,\n masterKey: options.masterKey,\n masterKeyStore: options.masterKey\n ? undefined\n : {\n init: this.initializeBackend,\n get: async () => {\n if (!backend.getMasterKey) {\n throw new Error(\n \"Secret store backend does not support master key storage. Pass masterKey or implement getMasterKey/setMasterKey.\",\n );\n }\n return backend.getMasterKey(backendContext);\n },\n set: async (key: Buffer) => {\n if (!backend.setMasterKey) {\n throw new Error(\n \"Secret store backend does not support master key storage. Pass masterKey or implement getMasterKey/setMasterKey.\",\n );\n }\n await backend.setMasterKey(backendContext, key);\n },\n },\n });\n }\n\n async init(): Promise<void> {\n if (this.initialized) return;\n if (this.initializing) {\n await this.initializing;\n return;\n }\n this.initializing = (async () => {\n await this.initializeBackend();\n await this.manager.init();\n this.initialized = true;\n })();\n try {\n await this.initializing;\n } finally {\n this.initializing = null;\n }\n }\n\n async set(key: string, value: string): Promise<void> {\n await this.ensureInitialized();\n const account = assertNonEmpty(key, \"key\");\n const ciphertext = this.manager.encrypt(value);\n await this.backend.setSecret(this.dataService, account, ciphertext);\n }\n\n async get(key: string): Promise<string | undefined> {\n await this.ensureInitialized();\n const account = assertNonEmpty(key, \"key\");\n const ciphertext = await this.backend.getSecret(this.dataService, account);\n if (!ciphertext) return undefined;\n return this.manager.decrypt(ciphertext);\n }\n\n async delete(key: string): Promise<boolean> {\n await this.ensureInitialized();\n const account = assertNonEmpty(key, \"key\");\n return this.backend.deleteSecret(this.dataService, account);\n }\n\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n await this.init();\n }\n}\n\nexport async function createSecretStore(options: SecretStoreOptions): Promise<SecretStore> {\n const store = new SecretStore(options);\n await store.init();\n return store;\n}\n","import { chmod, mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { buildEntryKey, defaultFileStorePath } from \"../utils.js\";\nimport {\n type FileSecretStoreBackendOptions,\n type SecretStoreBackend,\n type SecretStoreBackendContext,\n} from \"../types.js\";\n\nconst FILE_STORE_VERSION = 1;\n\ninterface FileSecretStoreData {\n version: number;\n secrets: Record<string, string>;\n masterKeys: Record<string, string>;\n}\n\nfunction emptyFileStoreData(): FileSecretStoreData {\n return { version: FILE_STORE_VERSION, secrets: {}, masterKeys: {} };\n}\n\nexport class FileSecretStoreBackend implements SecretStoreBackend {\n private readonly filePath: string;\n private data: FileSecretStoreData | null = null;\n private loading: Promise<void> | null = null;\n private writeQueue = Promise.resolve();\n\n constructor(options: FileSecretStoreBackendOptions = {}) {\n this.filePath = options.filePath?.trim() || defaultFileStorePath(options.service);\n }\n\n async init(): Promise<void> {\n await this.ensureLoaded();\n }\n\n async getSecret(service: string, account: string): Promise<string | undefined> {\n await this.ensureLoaded();\n return this.data?.secrets[buildEntryKey(service, account)];\n }\n\n async setSecret(service: string, account: string, value: string): Promise<void> {\n await this.mutate((data) => {\n data.secrets[buildEntryKey(service, account)] = value;\n });\n }\n\n async deleteSecret(service: string, account: string): Promise<boolean> {\n let deleted = false;\n await this.mutate((data) => {\n const key = buildEntryKey(service, account);\n deleted = Object.hasOwn(data.secrets, key);\n delete data.secrets[key];\n });\n return deleted;\n }\n\n async getMasterKey(context: SecretStoreBackendContext): Promise<Buffer | null> {\n await this.ensureLoaded();\n const encoded = this.data?.masterKeys[buildEntryKey(context.service, context.account)];\n return encoded ? Buffer.from(encoded, \"base64\") : null;\n }\n\n async setMasterKey(context: SecretStoreBackendContext, key: Buffer): Promise<void> {\n await this.mutate((data) => {\n data.masterKeys[buildEntryKey(context.service, context.account)] = key.toString(\"base64\");\n });\n }\n\n private async ensureLoaded(): Promise<void> {\n if (this.data) return;\n if (!this.loading) this.loading = this.load();\n await this.loading;\n }\n\n private async load(): Promise<void> {\n const directory = path.dirname(this.filePath);\n await mkdir(directory, { recursive: true });\n await this.setPermissions(directory, 0o700);\n try {\n const raw = await readFile(this.filePath, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<FileSecretStoreData>;\n this.data = {\n version: FILE_STORE_VERSION,\n secrets: parsed.secrets ?? {},\n masterKeys: parsed.masterKeys ?? {},\n };\n await this.setPermissions(this.filePath, 0o600);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code !== \"ENOENT\") throw error;\n this.data = emptyFileStoreData();\n } finally {\n this.loading = null;\n }\n }\n\n private async mutate(update: (data: FileSecretStoreData) => void): Promise<void> {\n await this.ensureLoaded();\n this.writeQueue = this.writeQueue.then(async () => {\n const current = this.data ?? emptyFileStoreData();\n const next: FileSecretStoreData = {\n version: current.version,\n secrets: { ...current.secrets },\n masterKeys: { ...current.masterKeys },\n };\n update(next);\n await this.persist(next);\n this.data = next;\n });\n await this.writeQueue;\n }\n\n private async persist(data: FileSecretStoreData): Promise<void> {\n const directory = path.dirname(this.filePath);\n const tempPath = `${this.filePath}.${process.pid}.${Date.now()}.tmp`;\n await mkdir(directory, { recursive: true });\n await writeFile(tempPath, `${JSON.stringify(data, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: 0o600,\n });\n await rename(tempPath, this.filePath);\n await this.setPermissions(this.filePath, 0o600);\n }\n\n private async setPermissions(targetPath: string, mode: number): Promise<void> {\n try {\n await chmod(targetPath, mode);\n } catch {\n // Best-effort permission hardening.\n }\n }\n}\n","import { homedir } from \"node:os\";\nimport path from \"node:path\";\n\nexport function buildEntryKey(service: string, account: string): string {\n return `${service}:${account}`;\n}\n\nfunction sanitizeServiceName(service: string): string {\n return service.replace(/[^A-Za-z0-9._-]+/g, \"_\");\n}\n\nexport function defaultFileStorePath(service = \"default\"): string {\n return path.join(homedir(), \".botbotgo\", \"secret-store\", `${sanitizeServiceName(service)}.json`);\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { CODESIGN_BIN, MASTER_KEY_LENGTH, SECURITY_BIN } from \"./constants.js\";\nimport { getKeytar } from \"./keytar.js\";\nimport { resolvePrompt, runSwiftKeychainWithFallback } from \"./swift-bridge.js\";\nimport { type BiometricPolicy, type KeychainAccessOptions, type SecretStoreBackend, type SecretStoreBackendContext } from \"../types.js\";\nimport {\n assertMacOS,\n assertNonEmpty,\n isKeychainNotFoundError,\n normalizeAppleDeveloperTeamId,\n normalizeBiometricPolicy,\n resolveAppBinPath,\n isPackagedApp,\n} from \"./utils.js\";\n\nconst execFileAsync = promisify(execFile);\n\nasync function getSecretViaSecurityCli(service: string, account: string): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync(SECURITY_BIN, [\n \"find-generic-password\",\n \"-s\",\n service,\n \"-a\",\n account,\n \"-w\",\n ]);\n const value = (typeof stdout === \"string\" ? stdout : String(stdout)).replace(/\\r?\\n$/, \"\");\n return value.length > 0 ? value : null;\n } catch (error) {\n if (isKeychainNotFoundError(error)) return null;\n throw error;\n }\n}\n\nfunction isKeytarUnavailable(error: unknown): boolean {\n const text = error instanceof Error ? error.message : String(error ?? \"\");\n return text.includes(\"keytar is not available\");\n}\n\nasync function getPasswordViaKeytarOrCli(service: string, account: string): Promise<string | null> {\n try {\n return await getKeytar().getPassword(service, account);\n } catch (error) {\n if (!isKeytarUnavailable(error)) throw error;\n return getSecretViaSecurityCli(service, account);\n }\n}\n\nfunction buildAddGenericPasswordArgs(\n service: string,\n account: string,\n value: string,\n appBinPath?: string,\n): string[] {\n return [\n \"add-generic-password\",\n \"-s\",\n service,\n \"-a\",\n account,\n \"-w\",\n value,\n ...(appBinPath ? [\"-T\", appBinPath] : []),\n \"-U\",\n ];\n}\n\nasync function getKeychainPassword(\n service: string,\n account: string,\n biometric: BiometricPolicy,\n prompt?: string,\n): Promise<string | null> {\n if (biometric === \"none\") return getPasswordViaKeytarOrCli(service, account);\n const result = await runSwiftKeychainWithFallback(\"get\", {\n service,\n account,\n prompt: resolvePrompt(prompt),\n biometric,\n });\n if (!result) return getPasswordViaKeytarOrCli(service, account);\n if (!result.ok) throw new Error(result.error ?? \"Failed to get key from keychain.\");\n return result.found ? (result.value ?? \"\") : null;\n}\n\nexport async function getKeyFromKeychain(\n service: string,\n account: string,\n options: KeychainAccessOptions = {},\n): Promise<Buffer | null> {\n const normalizedService = assertNonEmpty(service, \"service\");\n const normalizedAccount = assertNonEmpty(account, \"account\");\n const biometric = normalizeBiometricPolicy(options.biometric);\n const password = await getKeychainPassword(\n normalizedService,\n normalizedAccount,\n biometric,\n options.prompt,\n );\n if (!password) return null;\n const buf = Buffer.from(password, \"base64\");\n if (buf.length !== MASTER_KEY_LENGTH) return null;\n return buf;\n}\n\nexport async function getSecretFromKeychain(\n service: string,\n account: string,\n): Promise<string | null> {\n const normalizedService = assertNonEmpty(service, \"service\");\n const normalizedAccount = assertNonEmpty(account, \"account\");\n return getPasswordViaKeytarOrCli(normalizedService, normalizedAccount);\n}\n\nexport async function getTeamIdFromBinary(appBinPath: string): Promise<string | null> {\n assertMacOS();\n const normalizedPath = assertNonEmpty(appBinPath, \"appBinPath\");\n try {\n const { stdout, stderr } = await execFileAsync(CODESIGN_BIN, [\"-dvvv\", normalizedPath], {\n encoding: \"utf8\",\n maxBuffer: 64 * 1024,\n });\n const combined = `${stdout ?? \"\"}\\n${stderr ?? \"\"}`;\n const match = /TeamIdentifier=(.+)/.exec(combined);\n if (!match) return null;\n const raw = match[1].trim();\n if (!raw || /^not\\s+set$/i.test(raw)) return null;\n const normalized = raw.match(/^[A-Za-z0-9]+$/)?.[0] ?? \"\";\n return normalized || null;\n } catch {\n return null;\n }\n}\n\nexport async function setKeyInKeychainWithAcl(\n service: string,\n account: string,\n keyBuffer: Buffer,\n appBinPath: string,\n appleDeveloperTeamId?: string | null,\n options: KeychainAccessOptions = {},\n): Promise<void> {\n assertMacOS();\n const normalizedService = assertNonEmpty(service, \"service\");\n const normalizedAccount = assertNonEmpty(account, \"account\");\n const normalizedAppBinPath = assertNonEmpty(appBinPath, \"appBinPath\");\n const biometric = normalizeBiometricPolicy(options.biometric);\n if (keyBuffer.length !== MASTER_KEY_LENGTH) {\n throw new Error(`Master key must be ${MASTER_KEY_LENGTH} bytes, got ${keyBuffer.length}`);\n }\n const b64 = keyBuffer.toString(\"base64\");\n if (biometric === \"none\") {\n await execFileAsync(\n SECURITY_BIN,\n buildAddGenericPasswordArgs(\n normalizedService,\n normalizedAccount,\n b64,\n normalizedAppBinPath,\n ),\n );\n } else {\n const result = await runSwiftKeychainWithFallback(\"set\", {\n service: normalizedService,\n account: normalizedAccount,\n secret: b64,\n biometric,\n });\n if (!result) {\n await execFileAsync(\n SECURITY_BIN,\n buildAddGenericPasswordArgs(\n normalizedService,\n normalizedAccount,\n b64,\n normalizedAppBinPath,\n ),\n );\n } else if (!result.ok) {\n throw new Error(result.error ?? \"Failed to store key in keychain.\");\n }\n }\n const normalizedTeamId = normalizeAppleDeveloperTeamId(appleDeveloperTeamId);\n if (normalizedTeamId) {\n try {\n await execFileAsync(SECURITY_BIN, [\n \"set-generic-password-partition-list\",\n \"-s\",\n normalizedService,\n \"-a\",\n normalizedAccount,\n \"-S\",\n `teamid:${normalizedTeamId}`,\n ]);\n } catch {\n // Best-effort hardening; keep key if partition update fails.\n }\n }\n}\n\nexport async function setSecretInKeychain(\n service: string,\n account: string,\n value: string,\n): Promise<void> {\n assertMacOS();\n const normalizedService = assertNonEmpty(service, \"service\");\n const normalizedAccount = assertNonEmpty(account, \"account\");\n await execFileAsync(\n SECURITY_BIN,\n buildAddGenericPasswordArgs(normalizedService, normalizedAccount, value),\n );\n}\n\nexport async function deleteSecretFromKeychain(\n service: string,\n account: string,\n): Promise<boolean> {\n assertMacOS();\n const normalizedService = assertNonEmpty(service, \"service\");\n const normalizedAccount = assertNonEmpty(account, \"account\");\n try {\n await execFileAsync(SECURITY_BIN, [\n \"delete-generic-password\",\n \"-s\",\n normalizedService,\n \"-a\",\n normalizedAccount,\n ]);\n return true;\n } catch (error) {\n if (isKeychainNotFoundError(error)) return false;\n throw error;\n }\n}\n\nexport class KeychainSecretStoreBackend implements SecretStoreBackend {\n async getSecret(service: string, account: string): Promise<string | undefined> {\n return (await getSecretFromKeychain(service, account)) ?? undefined;\n }\n\n async setSecret(service: string, account: string, value: string): Promise<void> {\n await setSecretInKeychain(service, account, value);\n }\n\n async deleteSecret(service: string, account: string): Promise<boolean> {\n return deleteSecretFromKeychain(service, account);\n }\n\n async getMasterKey(context: SecretStoreBackendContext): Promise<Buffer | null> {\n return getKeyFromKeychain(context.service, context.account, {\n biometric: context.biometric,\n prompt: context.prompt,\n });\n }\n\n async setMasterKey(context: SecretStoreBackendContext, key: Buffer): Promise<void> {\n const appPath = resolveAppBinPath(context.appBinPath);\n const teamId = context.appleDeveloperTeamId ?? (await getTeamIdFromBinary(appPath));\n await setKeyInKeychainWithAcl(context.service, context.account, key, appPath, teamId, {\n biometric: context.biometric,\n prompt: context.prompt,\n });\n }\n}\n\nexport { MASTER_KEY_LENGTH, isPackagedApp };\n","export const SECURITY_BIN = \"/usr/bin/security\";\nexport const CODESIGN_BIN = \"/usr/bin/codesign\";\nexport const MASTER_KEY_LENGTH = 32;\nexport const DEFAULT_BIOMETRIC_PROMPT = \"Authenticate to access secure data\";\n","import { createRequire } from \"node:module\";\nimport { assertMacOS } from \"./utils.js\";\n\ninterface KeytarLike {\n getPassword: (service: string, account: string) => Promise<string | null>;\n}\n\nconst require = createRequire(import.meta.url);\n\nlet keytar: KeytarLike | null = null;\n\nexport function getKeytar(): KeytarLike {\n assertMacOS();\n if (keytar === null) {\n try {\n const loaded = require(\"keytar\") as Partial<KeytarLike>;\n if (!loaded || typeof loaded.getPassword !== \"function\") {\n throw new Error(\"keytar.getPassword() is unavailable.\");\n }\n keytar = loaded as KeytarLike;\n } catch {\n throw new Error(\n \"keytar is not available. Install keytar to use Keychain features on macOS.\",\n );\n }\n }\n return keytar;\n}\n","import { type BiometricPolicy } from \"../types.js\";\n\nexport function assertMacOS(): void {\n if (process.platform !== \"darwin\") {\n throw new Error(\"This module is only supported on macOS.\");\n }\n}\n\nexport function assertNonEmpty(value: string, field: string): string {\n const normalized = value.trim();\n if (normalized.length === 0) {\n throw new Error(`${field} must be a non-empty string.`);\n }\n return normalized;\n}\n\nexport function normalizeAppleDeveloperTeamId(\n teamId: string | null | undefined,\n): string | undefined {\n const value = teamId?.trim();\n if (!value) return undefined;\n if (!/^[A-Za-z0-9]{10}$/.test(value)) {\n throw new Error(\"appleDeveloperTeamId must be a 10-character alphanumeric string.\");\n }\n return value;\n}\n\nexport function normalizeBiometricPolicy(policy: BiometricPolicy | undefined): BiometricPolicy {\n if (!policy) return \"none\";\n if (\n policy === \"none\" ||\n policy === \"auto\" ||\n policy === \"user-presence\" ||\n policy === \"biometry-current-set\"\n ) {\n return policy;\n }\n return \"none\";\n}\n\nexport function resolveSwiftBiometricPolicy(\n policy: BiometricPolicy,\n): Exclude<BiometricPolicy, \"none\" | \"auto\"> {\n return policy === \"biometry-current-set\" ? \"biometry-current-set\" : \"user-presence\";\n}\n\nexport function isSwiftUnavailableError(error: unknown): boolean {\n const text = error instanceof Error ? `${error.message}` : String(error ?? \"\");\n return (\n text.includes(\"spawn xcrun ENOENT\") ||\n text.includes(\"xcrun: error\") ||\n text.includes('unable to find utility \"swift\"') ||\n text.includes(\"invalid active developer path\") ||\n text.includes(\"tool 'swift' requires Xcode\")\n );\n}\n\nexport function isSwiftEntitlementError(error: unknown): boolean {\n const text = error instanceof Error ? `${error.message}` : String(error ?? \"\");\n return (\n text.includes(\"A required entitlement isn't present.\") ||\n text.includes(\"errSecMissingEntitlement\")\n );\n}\n\nexport function isKeychainNotFoundError(error: unknown): boolean {\n const text = error instanceof Error ? `${error.message}` : String(error ?? \"\");\n return (\n text.includes(\"could not be found\") ||\n text.includes(\"The specified item could not be found\")\n );\n}\n\nexport function isPackagedApp(): boolean {\n return process.execPath.includes(\".app/Contents/MacOS/\");\n}\n\nexport function resolveAppBinPath(appBinPath?: string): string {\n if (appBinPath) return appBinPath;\n if (isPackagedApp()) return process.execPath;\n throw new Error(\n \"appBinPath is required when not running from a packaged .app (process.execPath does not contain .app/Contents/MacOS/)\",\n );\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { DEFAULT_BIOMETRIC_PROMPT } from \"./constants.js\";\nimport { type BiometricPolicy } from \"../types.js\";\nimport {\n isSwiftEntitlementError,\n isSwiftUnavailableError,\n normalizeBiometricPolicy,\n resolveSwiftBiometricPolicy,\n} from \"./utils.js\";\n\nconst execFileAsync = promisify(execFile);\n\ntype SwiftOp = \"set\" | \"get\";\n\ninterface SwiftResult {\n ok: boolean;\n found?: boolean;\n value?: string;\n error?: string;\n}\n\nconst SWIFT_KEYCHAIN_BRIDGE = `\nimport Foundation\nimport Security\n\nfunc emit(_ obj: [String: Any]) {\n let data = try! JSONSerialization.data(withJSONObject: obj, options: [])\n print(String(data: data, encoding: .utf8)!)\n}\n\nfunc secMessage(_ status: OSStatus) -> String {\n if let msg = SecCopyErrorMessageString(status, nil) { return msg as String }\n return \"OSStatus \\\\(status)\"\n}\n\nlet env = ProcessInfo.processInfo.environment\nlet op = env[\"EASYNET_KC_OP\"] ?? \"\"\nlet service = env[\"EASYNET_KC_SERVICE\"] ?? \"\"\nlet account = env[\"EASYNET_KC_ACCOUNT\"] ?? \"\"\nlet secret = env[\"EASYNET_KC_SECRET\"] ?? \"\"\nlet prompt = env[\"EASYNET_KC_PROMPT\"] ?? \"\"\nlet biometric = env[\"EASYNET_KC_BIOMETRIC\"] ?? \"none\"\n\nif op.isEmpty || service.isEmpty || account.isEmpty {\n emit([\"ok\": false, \"error\": \"Missing required env values\"])\n exit(2)\n}\n\nfunc buildBaseQuery() -> [String: Any] {\n return [\n kSecClass as String: kSecClassGenericPassword,\n kSecAttrService as String: service,\n kSecAttrAccount as String: account\n ]\n}\n\nfunc buildAccessControl(_ policy: String) -> SecAccessControl? {\n if policy == \"none\" { return nil }\n var flags: SecAccessControlCreateFlags = []\n if policy == \"user-presence\" {\n flags.insert(.userPresence)\n } else if policy == \"biometry-current-set\" {\n flags.insert(.biometryCurrentSet)\n } else {\n flags.insert(.userPresence)\n }\n var err: Unmanaged<CFError>?\n let ac = SecAccessControlCreateWithFlags(\n nil,\n kSecAttrAccessibleWhenUnlockedThisDeviceOnly,\n flags,\n &err\n )\n return ac\n}\n\nswitch op {\ncase \"set\":\n guard let data = secret.data(using: .utf8) else {\n emit([\"ok\": false, \"error\": \"Secret is not valid UTF-8\"])\n exit(2)\n }\n var add = buildBaseQuery()\n add[kSecValueData as String] = data\n\n if biometric != \"none\" {\n guard let ac = buildAccessControl(biometric) else {\n emit([\"ok\": false, \"error\": \"Failed to build access control\"])\n exit(1)\n }\n add[kSecAttrAccessControl as String] = ac\n _ = SecItemDelete(buildBaseQuery() as CFDictionary)\n let status = SecItemAdd(add as CFDictionary, nil)\n if status != errSecSuccess {\n emit([\"ok\": false, \"error\": secMessage(status)])\n exit(1)\n }\n emit([\"ok\": true])\n exit(0)\n }\n\n let addStatus = SecItemAdd(add as CFDictionary, nil)\n if addStatus == errSecSuccess {\n emit([\"ok\": true])\n exit(0)\n }\n if addStatus == errSecDuplicateItem {\n let updateStatus = SecItemUpdate(buildBaseQuery() as CFDictionary, [kSecValueData as String: data] as CFDictionary)\n if updateStatus == errSecSuccess {\n emit([\"ok\": true])\n exit(0)\n }\n emit([\"ok\": false, \"error\": secMessage(updateStatus)])\n exit(1)\n }\n emit([\"ok\": false, \"error\": secMessage(addStatus)])\n exit(1)\n\ncase \"get\":\n var query = buildBaseQuery()\n query[kSecReturnData as String] = true\n query[kSecMatchLimit as String] = kSecMatchLimitOne\n if !prompt.isEmpty {\n query[kSecUseOperationPrompt as String] = prompt\n }\n var item: CFTypeRef?\n let status = SecItemCopyMatching(query as CFDictionary, &item)\n if status == errSecItemNotFound {\n emit([\"ok\": true, \"found\": false])\n exit(0)\n }\n if status != errSecSuccess {\n emit([\"ok\": false, \"error\": secMessage(status)])\n exit(1)\n }\n guard let data = item as? Data else {\n emit([\"ok\": false, \"error\": \"Unexpected keychain data\"])\n exit(1)\n }\n let value = String(data: data, encoding: .utf8) ?? \"\"\n emit([\"ok\": true, \"found\": true, \"value\": value])\n exit(0)\n\ndefault:\n emit([\"ok\": false, \"error\": \"Unsupported operation\"])\n exit(2)\n}\n`;\n\nasync function runSwiftKeychain(\n op: SwiftOp,\n input: {\n service: string;\n account: string;\n secret?: string;\n prompt?: string;\n biometric?: BiometricPolicy;\n },\n): Promise<SwiftResult> {\n const env = {\n ...process.env,\n EASYNET_KC_OP: op,\n EASYNET_KC_SERVICE: input.service,\n EASYNET_KC_ACCOUNT: input.account,\n EASYNET_KC_SECRET: input.secret ?? \"\",\n EASYNET_KC_PROMPT: input.prompt ?? \"\",\n EASYNET_KC_BIOMETRIC: normalizeBiometricPolicy(input.biometric),\n };\n try {\n const { stdout } = await execFileAsync(\"xcrun\", [\"swift\", \"-e\", SWIFT_KEYCHAIN_BRIDGE], {\n env,\n encoding: \"utf8\",\n maxBuffer: 1024 * 1024,\n });\n return JSON.parse(stdout.trim()) as SwiftResult;\n } catch (error) {\n const err = error as {\n message?: string;\n stderr?: string | Buffer;\n stdout?: string | Buffer;\n };\n const stderr =\n typeof err.stderr === \"string\"\n ? err.stderr.trim()\n : Buffer.isBuffer(err.stderr)\n ? err.stderr.toString(\"utf8\").trim()\n : \"\";\n const stdout =\n typeof err.stdout === \"string\"\n ? err.stdout.trim()\n : Buffer.isBuffer(err.stdout)\n ? err.stdout.toString(\"utf8\").trim()\n : \"\";\n const details = [\n err.message ?? String(error),\n stderr ? `stderr: ${stderr}` : \"\",\n stdout ? `stdout: ${stdout}` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n throw new Error(`Swift keychain bridge failed for op=${op}.\\n${details}`);\n }\n}\n\nexport async function runSwiftKeychainWithFallback(\n op: SwiftOp,\n input: {\n service: string;\n account: string;\n secret?: string;\n prompt?: string;\n biometric: BiometricPolicy;\n },\n): Promise<SwiftResult | undefined> {\n const policy = resolveSwiftBiometricPolicy(input.biometric);\n try {\n return await runSwiftKeychain(op, { ...input, biometric: policy });\n } catch (error) {\n if (isSwiftUnavailableError(error)) return undefined;\n if (input.biometric === \"auto\" && isSwiftEntitlementError(error)) return undefined;\n throw error;\n }\n}\n\nexport function resolvePrompt(prompt?: string): string {\n return prompt?.trim() || DEFAULT_BIOMETRIC_PROMPT;\n}\n","import { buildEntryKey } from \"../utils.js\";\nimport { type SecretStoreBackend, type SecretStoreBackendContext } from \"../types.js\";\n\nexport class MemorySecretStoreBackend implements SecretStoreBackend {\n private readonly secrets = new Map<string, string>();\n private readonly masterKeys = new Map<string, Buffer>();\n\n async getSecret(service: string, account: string): Promise<string | undefined> {\n return this.secrets.get(buildEntryKey(service, account));\n }\n\n async setSecret(service: string, account: string, value: string): Promise<void> {\n this.secrets.set(buildEntryKey(service, account), value);\n }\n\n async deleteSecret(service: string, account: string): Promise<boolean> {\n return this.secrets.delete(buildEntryKey(service, account));\n }\n\n async getMasterKey(context: SecretStoreBackendContext): Promise<Buffer | null> {\n const key = this.masterKeys.get(buildEntryKey(context.service, context.account));\n return key ? Buffer.from(key) : null;\n }\n\n async setMasterKey(context: SecretStoreBackendContext, key: Buffer): Promise<void> {\n this.masterKeys.set(buildEntryKey(context.service, context.account), Buffer.from(key));\n }\n}\n","import { FileSecretStoreBackend } from \"./file/index.js\";\nimport { KeychainSecretStoreBackend } from \"./keychain/index.js\";\nimport { MemorySecretStoreBackend } from \"./memory/index.js\";\nimport {\n type CreateSecretStoreBackendOptions,\n type SecretStoreBackend,\n type SecretStoreBackendName,\n} from \"./types.js\";\n\nexport function createSecretStoreBackend(\n backend: SecretStoreBackendName | SecretStoreBackend = \"keychain\",\n options: CreateSecretStoreBackendOptions = {},\n): SecretStoreBackend {\n if (backend === \"keychain\") return new KeychainSecretStoreBackend();\n if (backend === \"memory\") return new MemorySecretStoreBackend();\n if (backend === \"file\") {\n return new FileSecretStoreBackend({ service: options.service });\n }\n return backend;\n}\n\nexport { FileSecretStoreBackend } from \"./file/index.js\";\nexport { KeychainSecretStoreBackend } from \"./keychain/index.js\";\nexport { MemorySecretStoreBackend } from \"./memory/index.js\";\nexport {\n MASTER_KEY_LENGTH,\n deleteSecretFromKeychain,\n getKeyFromKeychain,\n getSecretFromKeychain,\n getTeamIdFromBinary,\n isPackagedApp,\n setKeyInKeychainWithAcl,\n setSecretInKeychain,\n} from \"./keychain/index.js\";\nexport type {\n BiometricPolicy,\n CreateSecretStoreBackendOptions,\n FileSecretStoreBackendOptions,\n KeychainAccessOptions,\n SecretStoreBackend,\n SecretStoreBackendContext,\n SecretStoreBackendName,\n} from \"./types.js\";\n"],"mappings":"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","names":["path","path","execFile","promisify","require","execFileAsync","promisify","execFile","assertNonEmpty"]}
1
+ {"version":3,"sources":["../../src/security-store/store.ts","../../src/security-store/backends/file/index.ts","../../src/security-store/backends/utils.ts","../../src/security-store/backends/keychain/index.ts","../../src/security-store/backends/keychain/constants.ts","../../src/security-store/backends/keychain/keytar.ts","../../src/security-store/backends/keychain/utils.ts","../../src/security-store/backends/keychain/swift-bridge.ts","../../src/security-store/backends/memory/index.ts","../../src/security-store/backends/index.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport {\n MASTER_KEY_LENGTH,\n createSecretStoreBackend,\n type BiometricPolicy,\n type SecretStoreBackend,\n type SecretStoreBackendName,\n} from \"./backends/index.js\";\n\nconst PREFIX = \"enc:v1:\";\nconst NONCE_LENGTH = 12;\nconst TAG_LENGTH = 16;\n\nfunction decodeBase64Strict(input: string): Buffer {\n const trimmed = input.trim();\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(trimmed) || trimmed.length % 4 !== 0) {\n throw new Error(\"Invalid base64 in encrypted payload\");\n }\n const decoded = Buffer.from(trimmed, \"base64\");\n if (decoded.toString(\"base64\") !== trimmed) {\n throw new Error(\"Invalid base64 in encrypted payload\");\n }\n return decoded;\n}\n\nfunction assertNonEmpty(value: string, field: string): string {\n const normalized = value.trim();\n if (normalized.length === 0) {\n throw new Error(`${field} must be a non-empty string.`);\n }\n return normalized;\n}\n\nexport interface CryptoManagerKeyStore {\n init?(): Promise<void>;\n get(): Promise<Buffer | null>;\n set(key: Buffer): Promise<void>;\n}\n\nexport interface CryptoManagerOptions {\n service: string;\n account: string;\n allowPlaintextFallback?: boolean;\n masterKey?: Buffer;\n masterKeyStore?: CryptoManagerKeyStore;\n}\n\nexport class CryptoManager {\n private readonly allowPlaintextFallback: boolean;\n private readonly masterKeyStore: CryptoManagerKeyStore | null;\n private masterKey: Buffer | null = null;\n\n constructor(options: CryptoManagerOptions) {\n this.allowPlaintextFallback = options.allowPlaintextFallback !== false;\n this.masterKeyStore = options.masterKeyStore ?? null;\n if (options.masterKey != null) {\n if (options.masterKey.length !== MASTER_KEY_LENGTH) {\n throw new Error(\n `masterKey must be ${MASTER_KEY_LENGTH} bytes, got ${options.masterKey.length}`,\n );\n }\n this.masterKey = Buffer.from(options.masterKey);\n }\n }\n\n async init(): Promise<void> {\n if (this.masterKey != null && this.masterKey.length === MASTER_KEY_LENGTH) return;\n if (this.masterKeyStore == null) {\n throw new Error(\"CryptoManager requires either masterKey or masterKeyStore.\");\n }\n if (this.masterKeyStore.init) await this.masterKeyStore.init();\n let key = await this.masterKeyStore.get();\n if (key != null) {\n this.masterKey = key;\n return;\n }\n const newKey = crypto.randomBytes(MASTER_KEY_LENGTH);\n await this.masterKeyStore.set(newKey);\n key = await this.masterKeyStore.get();\n if (key == null || key.length !== MASTER_KEY_LENGTH) {\n throw new Error(\"Master key write succeeded but readback failed.\");\n }\n this.masterKey = key;\n }\n\n encrypt(plainText: string): string {\n if (this.masterKey == null) {\n throw new Error(\"CryptoManager not initialized. Call init() first.\");\n }\n const nonce = crypto.randomBytes(NONCE_LENGTH);\n const cipher = crypto.createCipheriv(\"aes-256-gcm\", this.masterKey, nonce);\n const enc = Buffer.concat([cipher.update(plainText, \"utf8\"), cipher.final()]);\n const tag = cipher.getAuthTag();\n const payload = Buffer.concat([nonce, tag, enc]);\n return PREFIX + payload.toString(\"base64\");\n }\n\n decrypt(cipherText: string): string {\n if (this.masterKey == null) {\n throw new Error(\"CryptoManager not initialized. Call init() first.\");\n }\n if (!cipherText.startsWith(PREFIX)) {\n if (this.allowPlaintextFallback) return cipherText;\n throw new Error(\"Input is not an encrypted string (missing enc:v1: prefix)\");\n }\n const payload = decodeBase64Strict(cipherText.slice(PREFIX.length));\n if (payload.length < NONCE_LENGTH + TAG_LENGTH) {\n throw new Error(\"Encrypted payload too short\");\n }\n const nonce = payload.subarray(0, NONCE_LENGTH);\n const tag = payload.subarray(NONCE_LENGTH, NONCE_LENGTH + TAG_LENGTH);\n const ciphertext = payload.subarray(NONCE_LENGTH + TAG_LENGTH);\n const decipher = crypto.createDecipheriv(\"aes-256-gcm\", this.masterKey, nonce);\n decipher.setAuthTag(tag);\n return decipher.update(ciphertext, undefined, \"utf8\") + decipher.final(\"utf8\");\n }\n\n static isEncrypted(value: string): boolean {\n return value.startsWith(PREFIX);\n }\n}\n\nexport interface SecretStoreOptions {\n service: string;\n appBinPath?: string;\n appleDeveloperTeamId?: string | null;\n biometric?: BiometricPolicy;\n prompt?: string;\n masterAccount?: string;\n dataService?: string;\n backend?: SecretStoreBackendName | SecretStoreBackend;\n masterKey?: Buffer;\n}\n\nexport class SecretStore {\n private readonly manager: CryptoManager;\n private readonly dataService: string;\n private readonly backend: SecretStoreBackend;\n private readonly initializeBackend: () => Promise<void>;\n private initialized = false;\n private initializing: Promise<void> | null = null;\n\n constructor(options: SecretStoreOptions) {\n const service = assertNonEmpty(options.service, \"service\");\n const masterAccount = options.masterAccount?.trim() || \"master-key\";\n this.dataService = options.dataService?.trim() || `${service}.data`;\n this.backend = createSecretStoreBackend(options.backend, { service });\n const backend = this.backend;\n let backendInitPromise: Promise<void> | null = null;\n this.initializeBackend = async () => {\n if (!backend.init) return;\n if (!backendInitPromise) backendInitPromise = backend.init();\n await backendInitPromise;\n };\n const backendContext = {\n service,\n account: masterAccount,\n appBinPath: options.appBinPath,\n appleDeveloperTeamId: options.appleDeveloperTeamId,\n biometric: options.biometric,\n prompt: options.prompt,\n };\n this.manager = new CryptoManager({\n service,\n account: masterAccount,\n allowPlaintextFallback: true,\n masterKey: options.masterKey,\n masterKeyStore: options.masterKey\n ? undefined\n : {\n init: this.initializeBackend,\n get: async () => {\n if (!backend.getMasterKey) {\n throw new Error(\n \"Secret store backend does not support master key storage. Pass masterKey or implement getMasterKey/setMasterKey.\",\n );\n }\n return backend.getMasterKey(backendContext);\n },\n set: async (key: Buffer) => {\n if (!backend.setMasterKey) {\n throw new Error(\n \"Secret store backend does not support master key storage. Pass masterKey or implement getMasterKey/setMasterKey.\",\n );\n }\n await backend.setMasterKey(backendContext, key);\n },\n },\n });\n }\n\n async init(): Promise<void> {\n if (this.initialized) return;\n if (this.initializing) {\n await this.initializing;\n return;\n }\n this.initializing = (async () => {\n await this.initializeBackend();\n await this.manager.init();\n this.initialized = true;\n })();\n try {\n await this.initializing;\n } finally {\n this.initializing = null;\n }\n }\n\n async set(key: string, value: string): Promise<void> {\n await this.ensureInitialized();\n const account = assertNonEmpty(key, \"key\");\n const ciphertext = this.manager.encrypt(value);\n await this.backend.setSecret(this.dataService, account, ciphertext);\n }\n\n async get(key: string): Promise<string | undefined> {\n await this.ensureInitialized();\n const account = assertNonEmpty(key, \"key\");\n const ciphertext = await this.backend.getSecret(this.dataService, account);\n if (!ciphertext) return undefined;\n return this.manager.decrypt(ciphertext);\n }\n\n async delete(key: string): Promise<boolean> {\n await this.ensureInitialized();\n const account = assertNonEmpty(key, \"key\");\n return this.backend.deleteSecret(this.dataService, account);\n }\n\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n await this.init();\n }\n}\n\nexport async function createSecretStore(options: SecretStoreOptions): Promise<SecretStore> {\n const store = new SecretStore(options);\n await store.init();\n return store;\n}\n","import { chmod, mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { buildEntryKey, defaultFileStorePath } from \"../utils.js\";\nimport {\n type FileSecretStoreBackendOptions,\n type SecretStoreBackend,\n type SecretStoreBackendContext,\n} from \"../types.js\";\n\nconst FILE_STORE_VERSION = 1;\n\ninterface FileSecretStoreData {\n version: number;\n secrets: Record<string, string>;\n masterKeys: Record<string, string>;\n}\n\nfunction emptyFileStoreData(): FileSecretStoreData {\n return { version: FILE_STORE_VERSION, secrets: {}, masterKeys: {} };\n}\n\nexport class FileSecretStoreBackend implements SecretStoreBackend {\n private readonly filePath: string;\n private data: FileSecretStoreData | null = null;\n private loading: Promise<void> | null = null;\n private writeQueue = Promise.resolve();\n\n constructor(options: FileSecretStoreBackendOptions = {}) {\n this.filePath = options.filePath?.trim() || defaultFileStorePath(options.service);\n }\n\n async init(): Promise<void> {\n await this.ensureLoaded();\n }\n\n async getSecret(service: string, account: string): Promise<string | undefined> {\n await this.ensureLoaded();\n return this.data?.secrets[buildEntryKey(service, account)];\n }\n\n async setSecret(service: string, account: string, value: string): Promise<void> {\n await this.mutate((data) => {\n data.secrets[buildEntryKey(service, account)] = value;\n });\n }\n\n async deleteSecret(service: string, account: string): Promise<boolean> {\n let deleted = false;\n await this.mutate((data) => {\n const key = buildEntryKey(service, account);\n deleted = Object.hasOwn(data.secrets, key);\n delete data.secrets[key];\n });\n return deleted;\n }\n\n async getMasterKey(context: SecretStoreBackendContext): Promise<Buffer | null> {\n await this.ensureLoaded();\n const encoded = this.data?.masterKeys[buildEntryKey(context.service, context.account)];\n return encoded ? Buffer.from(encoded, \"base64\") : null;\n }\n\n async setMasterKey(context: SecretStoreBackendContext, key: Buffer): Promise<void> {\n await this.mutate((data) => {\n data.masterKeys[buildEntryKey(context.service, context.account)] = key.toString(\"base64\");\n });\n }\n\n private async ensureLoaded(): Promise<void> {\n if (this.data) return;\n if (!this.loading) this.loading = this.load();\n await this.loading;\n }\n\n private async load(): Promise<void> {\n const directory = path.dirname(this.filePath);\n await mkdir(directory, { recursive: true });\n await this.setPermissions(directory, 0o700);\n try {\n const raw = await readFile(this.filePath, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<FileSecretStoreData>;\n this.data = {\n version: FILE_STORE_VERSION,\n secrets: parsed.secrets ?? {},\n masterKeys: parsed.masterKeys ?? {},\n };\n await this.setPermissions(this.filePath, 0o600);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code !== \"ENOENT\") throw error;\n this.data = emptyFileStoreData();\n } finally {\n this.loading = null;\n }\n }\n\n private async mutate(update: (data: FileSecretStoreData) => void): Promise<void> {\n await this.ensureLoaded();\n this.writeQueue = this.writeQueue.then(async () => {\n const current = this.data ?? emptyFileStoreData();\n const next: FileSecretStoreData = {\n version: current.version,\n secrets: { ...current.secrets },\n masterKeys: { ...current.masterKeys },\n };\n update(next);\n await this.persist(next);\n this.data = next;\n });\n await this.writeQueue;\n }\n\n private async persist(data: FileSecretStoreData): Promise<void> {\n const directory = path.dirname(this.filePath);\n const tempPath = `${this.filePath}.${process.pid}.${Date.now()}.tmp`;\n await mkdir(directory, { recursive: true });\n await writeFile(tempPath, `${JSON.stringify(data, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: 0o600,\n });\n await rename(tempPath, this.filePath);\n await this.setPermissions(this.filePath, 0o600);\n }\n\n private async setPermissions(targetPath: string, mode: number): Promise<void> {\n try {\n await chmod(targetPath, mode);\n } catch {\n // Best-effort permission hardening.\n }\n }\n}\n","import { homedir } from \"node:os\";\nimport path from \"node:path\";\n\nexport function buildEntryKey(service: string, account: string): string {\n return `${service}:${account}`;\n}\n\nfunction sanitizeServiceName(service: string): string {\n return service.replace(/[^A-Za-z0-9._-]+/g, \"_\");\n}\n\nexport function defaultFileStorePath(service = \"default\"): string {\n return path.join(homedir(), \".botbotgo\", \"secret-store\", `${sanitizeServiceName(service)}.json`);\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { CODESIGN_BIN, MASTER_KEY_LENGTH, SECURITY_BIN } from \"./constants.js\";\nimport { getKeytar } from \"./keytar.js\";\nimport { resolvePrompt, runSwiftKeychainWithFallback } from \"./swift-bridge.js\";\nimport { type BiometricPolicy, type KeychainAccessOptions, type SecretStoreBackend, type SecretStoreBackendContext } from \"../types.js\";\nimport {\n assertMacOS,\n assertNonEmpty,\n isKeychainNotFoundError,\n normalizeAppleDeveloperTeamId,\n normalizeBiometricPolicy,\n resolveAppBinPath,\n isPackagedApp,\n} from \"./utils.js\";\n\nconst execFileAsync = promisify(execFile);\n\nasync function getSecretViaSecurityCli(service: string, account: string): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync(SECURITY_BIN, [\n \"find-generic-password\",\n \"-s\",\n service,\n \"-a\",\n account,\n \"-w\",\n ]);\n const value = (typeof stdout === \"string\" ? stdout : String(stdout)).replace(/\\r?\\n$/, \"\");\n return value.length > 0 ? value : null;\n } catch (error) {\n if (isKeychainNotFoundError(error)) return null;\n throw error;\n }\n}\n\nfunction isKeytarUnavailable(error: unknown): boolean {\n const text = error instanceof Error ? error.message : String(error ?? \"\");\n return text.includes(\"keytar is not available\");\n}\n\nasync function getPasswordViaKeytarOrCli(service: string, account: string): Promise<string | null> {\n try {\n return await getKeytar().getPassword(service, account);\n } catch (error) {\n if (!isKeytarUnavailable(error)) throw error;\n return getSecretViaSecurityCli(service, account);\n }\n}\n\nfunction buildAddGenericPasswordArgs(\n service: string,\n account: string,\n value: string,\n appBinPath?: string,\n): string[] {\n return [\n \"add-generic-password\",\n \"-s\",\n service,\n \"-a\",\n account,\n \"-w\",\n value,\n ...(appBinPath ? [\"-T\", appBinPath] : []),\n \"-U\",\n ];\n}\n\nasync function getKeychainPassword(\n service: string,\n account: string,\n biometric: BiometricPolicy,\n prompt?: string,\n): Promise<string | null> {\n if (biometric === \"none\") return getPasswordViaKeytarOrCli(service, account);\n const result = await runSwiftKeychainWithFallback(\"get\", {\n service,\n account,\n prompt: resolvePrompt(prompt),\n biometric,\n });\n if (!result) return getPasswordViaKeytarOrCli(service, account);\n if (!result.ok) throw new Error(result.error ?? \"Failed to get key from keychain.\");\n return result.found ? (result.value ?? \"\") : null;\n}\n\nexport async function getKeyFromKeychain(\n service: string,\n account: string,\n options: KeychainAccessOptions = {},\n): Promise<Buffer | null> {\n const normalizedService = assertNonEmpty(service, \"service\");\n const normalizedAccount = assertNonEmpty(account, \"account\");\n const biometric = normalizeBiometricPolicy(options.biometric);\n const password = await getKeychainPassword(\n normalizedService,\n normalizedAccount,\n biometric,\n options.prompt,\n );\n if (!password) return null;\n const buf = Buffer.from(password, \"base64\");\n if (buf.length !== MASTER_KEY_LENGTH) return null;\n return buf;\n}\n\nexport async function getSecretFromKeychain(\n service: string,\n account: string,\n): Promise<string | null> {\n const normalizedService = assertNonEmpty(service, \"service\");\n const normalizedAccount = assertNonEmpty(account, \"account\");\n return getPasswordViaKeytarOrCli(normalizedService, normalizedAccount);\n}\n\nexport async function getTeamIdFromBinary(appBinPath: string): Promise<string | null> {\n assertMacOS();\n const normalizedPath = assertNonEmpty(appBinPath, \"appBinPath\");\n try {\n const { stdout, stderr } = await execFileAsync(CODESIGN_BIN, [\"-dvvv\", normalizedPath], {\n encoding: \"utf8\",\n maxBuffer: 64 * 1024,\n });\n const combined = `${stdout ?? \"\"}\\n${stderr ?? \"\"}`;\n const match = /TeamIdentifier=(.+)/.exec(combined);\n if (!match) return null;\n const raw = match[1].trim();\n if (!raw || /^not\\s+set$/i.test(raw)) return null;\n const normalized = raw.match(/^[A-Za-z0-9]+$/)?.[0] ?? \"\";\n return normalized || null;\n } catch {\n return null;\n }\n}\n\nexport async function setKeyInKeychainWithAcl(\n service: string,\n account: string,\n keyBuffer: Buffer,\n appBinPath: string,\n appleDeveloperTeamId?: string | null,\n options: KeychainAccessOptions = {},\n): Promise<void> {\n assertMacOS();\n const normalizedService = assertNonEmpty(service, \"service\");\n const normalizedAccount = assertNonEmpty(account, \"account\");\n const normalizedAppBinPath = assertNonEmpty(appBinPath, \"appBinPath\");\n const biometric = normalizeBiometricPolicy(options.biometric);\n if (keyBuffer.length !== MASTER_KEY_LENGTH) {\n throw new Error(`Master key must be ${MASTER_KEY_LENGTH} bytes, got ${keyBuffer.length}`);\n }\n const b64 = keyBuffer.toString(\"base64\");\n if (biometric === \"none\") {\n await execFileAsync(\n SECURITY_BIN,\n buildAddGenericPasswordArgs(\n normalizedService,\n normalizedAccount,\n b64,\n normalizedAppBinPath,\n ),\n );\n } else {\n const result = await runSwiftKeychainWithFallback(\"set\", {\n service: normalizedService,\n account: normalizedAccount,\n secret: b64,\n biometric,\n });\n if (!result) {\n await execFileAsync(\n SECURITY_BIN,\n buildAddGenericPasswordArgs(\n normalizedService,\n normalizedAccount,\n b64,\n normalizedAppBinPath,\n ),\n );\n } else if (!result.ok) {\n throw new Error(result.error ?? \"Failed to store key in keychain.\");\n }\n }\n const normalizedTeamId = normalizeAppleDeveloperTeamId(appleDeveloperTeamId);\n if (normalizedTeamId) {\n try {\n await execFileAsync(SECURITY_BIN, [\n \"set-generic-password-partition-list\",\n \"-s\",\n normalizedService,\n \"-a\",\n normalizedAccount,\n \"-S\",\n `teamid:${normalizedTeamId}`,\n ]);\n } catch {\n // Best-effort hardening; keep key if partition update fails.\n }\n }\n}\n\nexport async function setSecretInKeychain(\n service: string,\n account: string,\n value: string,\n): Promise<void> {\n assertMacOS();\n const normalizedService = assertNonEmpty(service, \"service\");\n const normalizedAccount = assertNonEmpty(account, \"account\");\n await execFileAsync(\n SECURITY_BIN,\n buildAddGenericPasswordArgs(normalizedService, normalizedAccount, value),\n );\n}\n\nexport async function deleteSecretFromKeychain(\n service: string,\n account: string,\n): Promise<boolean> {\n assertMacOS();\n const normalizedService = assertNonEmpty(service, \"service\");\n const normalizedAccount = assertNonEmpty(account, \"account\");\n try {\n await execFileAsync(SECURITY_BIN, [\n \"delete-generic-password\",\n \"-s\",\n normalizedService,\n \"-a\",\n normalizedAccount,\n ]);\n return true;\n } catch (error) {\n if (isKeychainNotFoundError(error)) return false;\n throw error;\n }\n}\n\nexport class KeychainSecretStoreBackend implements SecretStoreBackend {\n async getSecret(service: string, account: string): Promise<string | undefined> {\n return (await getSecretFromKeychain(service, account)) ?? undefined;\n }\n\n async setSecret(service: string, account: string, value: string): Promise<void> {\n await setSecretInKeychain(service, account, value);\n }\n\n async deleteSecret(service: string, account: string): Promise<boolean> {\n return deleteSecretFromKeychain(service, account);\n }\n\n async getMasterKey(context: SecretStoreBackendContext): Promise<Buffer | null> {\n return getKeyFromKeychain(context.service, context.account, {\n biometric: context.biometric,\n prompt: context.prompt,\n });\n }\n\n async setMasterKey(context: SecretStoreBackendContext, key: Buffer): Promise<void> {\n const appPath = resolveAppBinPath(context.appBinPath);\n const teamId = context.appleDeveloperTeamId ?? (await getTeamIdFromBinary(appPath));\n await setKeyInKeychainWithAcl(context.service, context.account, key, appPath, teamId, {\n biometric: context.biometric,\n prompt: context.prompt,\n });\n }\n}\n\nexport { MASTER_KEY_LENGTH, isPackagedApp };\n","export const SECURITY_BIN = \"/usr/bin/security\";\nexport const CODESIGN_BIN = \"/usr/bin/codesign\";\nexport const MASTER_KEY_LENGTH = 32;\nexport const DEFAULT_BIOMETRIC_PROMPT = \"Authenticate to access secure data\";\n","import { createRequire } from \"node:module\";\nimport { assertMacOS } from \"./utils.js\";\n\ninterface KeytarLike {\n getPassword: (service: string, account: string) => Promise<string | null>;\n}\n\nconst require = createRequire(import.meta.url);\n\nlet keytar: KeytarLike | null = null;\n\nexport function getKeytar(): KeytarLike {\n assertMacOS();\n if (keytar === null) {\n try {\n const loaded = require(\"keytar\") as Partial<KeytarLike>;\n if (!loaded || typeof loaded.getPassword !== \"function\") {\n throw new Error(\"keytar.getPassword() is unavailable.\");\n }\n keytar = loaded as KeytarLike;\n } catch {\n throw new Error(\n \"keytar is not available. Install keytar to use Keychain features on macOS.\",\n );\n }\n }\n return keytar;\n}\n","import { type BiometricPolicy } from \"../types.js\";\n\nexport function assertMacOS(): void {\n if (process.platform !== \"darwin\") {\n throw new Error(\"This module is only supported on macOS.\");\n }\n}\n\nexport function assertNonEmpty(value: string, field: string): string {\n const normalized = value.trim();\n if (normalized.length === 0) {\n throw new Error(`${field} must be a non-empty string.`);\n }\n return normalized;\n}\n\nexport function normalizeAppleDeveloperTeamId(\n teamId: string | null | undefined,\n): string | undefined {\n const value = teamId?.trim();\n if (!value) return undefined;\n if (!/^[A-Za-z0-9]{10}$/.test(value)) {\n throw new Error(\"appleDeveloperTeamId must be a 10-character alphanumeric string.\");\n }\n return value;\n}\n\nexport function normalizeBiometricPolicy(policy: BiometricPolicy | undefined): BiometricPolicy {\n if (!policy) return \"none\";\n if (\n policy === \"none\" ||\n policy === \"auto\" ||\n policy === \"user-presence\" ||\n policy === \"biometry-current-set\"\n ) {\n return policy;\n }\n return \"none\";\n}\n\nexport function resolveSwiftBiometricPolicy(\n policy: BiometricPolicy,\n): Exclude<BiometricPolicy, \"none\" | \"auto\"> {\n return policy === \"biometry-current-set\" ? \"biometry-current-set\" : \"user-presence\";\n}\n\nexport function isSwiftUnavailableError(error: unknown): boolean {\n const text = error instanceof Error ? `${error.message}` : String(error ?? \"\");\n return (\n text.includes(\"spawn xcrun ENOENT\") ||\n text.includes(\"xcrun: error\") ||\n text.includes('unable to find utility \"swift\"') ||\n text.includes(\"invalid active developer path\") ||\n text.includes(\"tool 'swift' requires Xcode\")\n );\n}\n\nexport function isSwiftEntitlementError(error: unknown): boolean {\n const text = error instanceof Error ? `${error.message}` : String(error ?? \"\");\n return (\n text.includes(\"A required entitlement isn't present.\") ||\n text.includes(\"errSecMissingEntitlement\")\n );\n}\n\nexport function isKeychainNotFoundError(error: unknown): boolean {\n const text = error instanceof Error ? `${error.message}` : String(error ?? \"\");\n return (\n text.includes(\"could not be found\") ||\n text.includes(\"The specified item could not be found\")\n );\n}\n\nexport function isPackagedApp(): boolean {\n return process.execPath.includes(\".app/Contents/MacOS/\");\n}\n\nexport function resolveAppBinPath(appBinPath?: string): string {\n if (appBinPath) return appBinPath;\n if (isPackagedApp()) return process.execPath;\n throw new Error(\n \"appBinPath is required when not running from a packaged .app (process.execPath does not contain .app/Contents/MacOS/)\",\n );\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { DEFAULT_BIOMETRIC_PROMPT } from \"./constants.js\";\nimport { type BiometricPolicy } from \"../types.js\";\nimport {\n isSwiftEntitlementError,\n isSwiftUnavailableError,\n normalizeBiometricPolicy,\n resolveSwiftBiometricPolicy,\n} from \"./utils.js\";\n\nconst execFileAsync = promisify(execFile);\n\ntype SwiftOp = \"set\" | \"get\";\n\ninterface SwiftResult {\n ok: boolean;\n found?: boolean;\n value?: string;\n error?: string;\n}\n\nconst SWIFT_KEYCHAIN_BRIDGE = `\nimport Foundation\nimport Security\n\nfunc emit(_ obj: [String: Any]) {\n let data = try! JSONSerialization.data(withJSONObject: obj, options: [])\n print(String(data: data, encoding: .utf8)!)\n}\n\nfunc secMessage(_ status: OSStatus) -> String {\n if let msg = SecCopyErrorMessageString(status, nil) { return msg as String }\n return \"OSStatus \\\\(status)\"\n}\n\nlet env = ProcessInfo.processInfo.environment\nlet op = env[\"BOTBOTGO_KC_OP\"] ?? env[\"EASYNET_KC_OP\"] ?? \"\"\nlet service = env[\"BOTBOTGO_KC_SERVICE\"] ?? env[\"EASYNET_KC_SERVICE\"] ?? \"\"\nlet account = env[\"BOTBOTGO_KC_ACCOUNT\"] ?? env[\"EASYNET_KC_ACCOUNT\"] ?? \"\"\nlet secret = env[\"BOTBOTGO_KC_SECRET\"] ?? env[\"EASYNET_KC_SECRET\"] ?? \"\"\nlet prompt = env[\"BOTBOTGO_KC_PROMPT\"] ?? env[\"EASYNET_KC_PROMPT\"] ?? \"\"\nlet biometric = env[\"BOTBOTGO_KC_BIOMETRIC\"] ?? env[\"EASYNET_KC_BIOMETRIC\"] ?? \"none\"\n\nif op.isEmpty || service.isEmpty || account.isEmpty {\n emit([\"ok\": false, \"error\": \"Missing required env values\"])\n exit(2)\n}\n\nfunc buildBaseQuery() -> [String: Any] {\n return [\n kSecClass as String: kSecClassGenericPassword,\n kSecAttrService as String: service,\n kSecAttrAccount as String: account\n ]\n}\n\nfunc buildAccessControl(_ policy: String) -> SecAccessControl? {\n if policy == \"none\" { return nil }\n var flags: SecAccessControlCreateFlags = []\n if policy == \"user-presence\" {\n flags.insert(.userPresence)\n } else if policy == \"biometry-current-set\" {\n flags.insert(.biometryCurrentSet)\n } else {\n flags.insert(.userPresence)\n }\n var err: Unmanaged<CFError>?\n let ac = SecAccessControlCreateWithFlags(\n nil,\n kSecAttrAccessibleWhenUnlockedThisDeviceOnly,\n flags,\n &err\n )\n return ac\n}\n\nswitch op {\ncase \"set\":\n guard let data = secret.data(using: .utf8) else {\n emit([\"ok\": false, \"error\": \"Secret is not valid UTF-8\"])\n exit(2)\n }\n var add = buildBaseQuery()\n add[kSecValueData as String] = data\n\n if biometric != \"none\" {\n guard let ac = buildAccessControl(biometric) else {\n emit([\"ok\": false, \"error\": \"Failed to build access control\"])\n exit(1)\n }\n add[kSecAttrAccessControl as String] = ac\n _ = SecItemDelete(buildBaseQuery() as CFDictionary)\n let status = SecItemAdd(add as CFDictionary, nil)\n if status != errSecSuccess {\n emit([\"ok\": false, \"error\": secMessage(status)])\n exit(1)\n }\n emit([\"ok\": true])\n exit(0)\n }\n\n let addStatus = SecItemAdd(add as CFDictionary, nil)\n if addStatus == errSecSuccess {\n emit([\"ok\": true])\n exit(0)\n }\n if addStatus == errSecDuplicateItem {\n let updateStatus = SecItemUpdate(buildBaseQuery() as CFDictionary, [kSecValueData as String: data] as CFDictionary)\n if updateStatus == errSecSuccess {\n emit([\"ok\": true])\n exit(0)\n }\n emit([\"ok\": false, \"error\": secMessage(updateStatus)])\n exit(1)\n }\n emit([\"ok\": false, \"error\": secMessage(addStatus)])\n exit(1)\n\ncase \"get\":\n var query = buildBaseQuery()\n query[kSecReturnData as String] = true\n query[kSecMatchLimit as String] = kSecMatchLimitOne\n if !prompt.isEmpty {\n query[kSecUseOperationPrompt as String] = prompt\n }\n var item: CFTypeRef?\n let status = SecItemCopyMatching(query as CFDictionary, &item)\n if status == errSecItemNotFound {\n emit([\"ok\": true, \"found\": false])\n exit(0)\n }\n if status != errSecSuccess {\n emit([\"ok\": false, \"error\": secMessage(status)])\n exit(1)\n }\n guard let data = item as? Data else {\n emit([\"ok\": false, \"error\": \"Unexpected keychain data\"])\n exit(1)\n }\n let value = String(data: data, encoding: .utf8) ?? \"\"\n emit([\"ok\": true, \"found\": true, \"value\": value])\n exit(0)\n\ndefault:\n emit([\"ok\": false, \"error\": \"Unsupported operation\"])\n exit(2)\n}\n`;\n\nasync function runSwiftKeychain(\n op: SwiftOp,\n input: {\n service: string;\n account: string;\n secret?: string;\n prompt?: string;\n biometric?: BiometricPolicy;\n },\n): Promise<SwiftResult> {\n const env = {\n ...process.env,\n BOTBOTGO_KC_OP: op,\n BOTBOTGO_KC_SERVICE: input.service,\n BOTBOTGO_KC_ACCOUNT: input.account,\n BOTBOTGO_KC_SECRET: input.secret ?? \"\",\n BOTBOTGO_KC_PROMPT: input.prompt ?? \"\",\n BOTBOTGO_KC_BIOMETRIC: normalizeBiometricPolicy(input.biometric),\n };\n try {\n const { stdout } = await execFileAsync(\"xcrun\", [\"swift\", \"-e\", SWIFT_KEYCHAIN_BRIDGE], {\n env,\n encoding: \"utf8\",\n maxBuffer: 1024 * 1024,\n });\n return JSON.parse(stdout.trim()) as SwiftResult;\n } catch (error) {\n const err = error as {\n message?: string;\n stderr?: string | Buffer;\n stdout?: string | Buffer;\n };\n const stderr =\n typeof err.stderr === \"string\"\n ? err.stderr.trim()\n : Buffer.isBuffer(err.stderr)\n ? err.stderr.toString(\"utf8\").trim()\n : \"\";\n const stdout =\n typeof err.stdout === \"string\"\n ? err.stdout.trim()\n : Buffer.isBuffer(err.stdout)\n ? err.stdout.toString(\"utf8\").trim()\n : \"\";\n const details = [\n err.message ?? String(error),\n stderr ? `stderr: ${stderr}` : \"\",\n stdout ? `stdout: ${stdout}` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n throw new Error(`Swift keychain bridge failed for op=${op}.\\n${details}`);\n }\n}\n\nexport async function runSwiftKeychainWithFallback(\n op: SwiftOp,\n input: {\n service: string;\n account: string;\n secret?: string;\n prompt?: string;\n biometric: BiometricPolicy;\n },\n): Promise<SwiftResult | undefined> {\n const policy = resolveSwiftBiometricPolicy(input.biometric);\n try {\n return await runSwiftKeychain(op, { ...input, biometric: policy });\n } catch (error) {\n if (isSwiftUnavailableError(error)) return undefined;\n if (input.biometric === \"auto\" && isSwiftEntitlementError(error)) return undefined;\n throw error;\n }\n}\n\nexport function resolvePrompt(prompt?: string): string {\n return prompt?.trim() || DEFAULT_BIOMETRIC_PROMPT;\n}\n","import { buildEntryKey } from \"../utils.js\";\nimport { type SecretStoreBackend, type SecretStoreBackendContext } from \"../types.js\";\n\nexport class MemorySecretStoreBackend implements SecretStoreBackend {\n private readonly secrets = new Map<string, string>();\n private readonly masterKeys = new Map<string, Buffer>();\n\n async getSecret(service: string, account: string): Promise<string | undefined> {\n return this.secrets.get(buildEntryKey(service, account));\n }\n\n async setSecret(service: string, account: string, value: string): Promise<void> {\n this.secrets.set(buildEntryKey(service, account), value);\n }\n\n async deleteSecret(service: string, account: string): Promise<boolean> {\n return this.secrets.delete(buildEntryKey(service, account));\n }\n\n async getMasterKey(context: SecretStoreBackendContext): Promise<Buffer | null> {\n const key = this.masterKeys.get(buildEntryKey(context.service, context.account));\n return key ? Buffer.from(key) : null;\n }\n\n async setMasterKey(context: SecretStoreBackendContext, key: Buffer): Promise<void> {\n this.masterKeys.set(buildEntryKey(context.service, context.account), Buffer.from(key));\n }\n}\n","import { FileSecretStoreBackend } from \"./file/index.js\";\nimport { KeychainSecretStoreBackend } from \"./keychain/index.js\";\nimport { MemorySecretStoreBackend } from \"./memory/index.js\";\nimport {\n type CreateSecretStoreBackendOptions,\n type SecretStoreBackend,\n type SecretStoreBackendName,\n} from \"./types.js\";\n\nexport function createSecretStoreBackend(\n backend: SecretStoreBackendName | SecretStoreBackend = \"keychain\",\n options: CreateSecretStoreBackendOptions = {},\n): SecretStoreBackend {\n if (backend === \"keychain\") return new KeychainSecretStoreBackend();\n if (backend === \"memory\") return new MemorySecretStoreBackend();\n if (backend === \"file\") {\n return new FileSecretStoreBackend({ service: options.service });\n }\n return backend;\n}\n\nexport { FileSecretStoreBackend } from \"./file/index.js\";\nexport { KeychainSecretStoreBackend } from \"./keychain/index.js\";\nexport { MemorySecretStoreBackend } from \"./memory/index.js\";\nexport {\n MASTER_KEY_LENGTH,\n deleteSecretFromKeychain,\n getKeyFromKeychain,\n getSecretFromKeychain,\n getTeamIdFromBinary,\n isPackagedApp,\n setKeyInKeychainWithAcl,\n setSecretInKeychain,\n} from \"./keychain/index.js\";\nexport type {\n BiometricPolicy,\n CreateSecretStoreBackendOptions,\n FileSecretStoreBackendOptions,\n KeychainAccessOptions,\n SecretStoreBackend,\n SecretStoreBackendContext,\n SecretStoreBackendName,\n} from \"./types.js\";\n"],"mappings":"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","names":["path","path","execFile","promisify","require","execFileAsync","promisify","execFile","assertNonEmpty"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/common",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Shared runtime utilities for BotBotGo agent projects",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -93,9 +93,11 @@
93
93
  "release": "semantic-release"
94
94
  },
95
95
  "dependencies": {
96
- "keytar": "^7.9.0",
97
96
  "yaml": "^2.8.1"
98
97
  },
98
+ "optionalDependencies": {
99
+ "keytar": "^7.9.0"
100
+ },
99
101
  "peerDependencies": {},
100
102
  "peerDependenciesMeta": {},
101
103
  "devDependencies": {