| import { chmodSync } from 'fs' |
| import { join } from 'path' |
| import { getClaudeConfigHomeDir } from '../envUtils.js' |
| import { getErrnoCode } from '../errors.js' |
| import { getFsImplementation } from '../fsOperations.js' |
| import { |
| jsonParse, |
| jsonStringify, |
| writeFileSync_DEPRECATED, |
| } from '../slowOperations.js' |
| import type { SecureStorage, SecureStorageData } from './types.js' |
|
|
| function getStoragePath(): { storageDir: string; storagePath: string } { |
| const storageDir = getClaudeConfigHomeDir() |
| const storageFileName = '.credentials.json' |
| return { storageDir, storagePath: join(storageDir, storageFileName) } |
| } |
|
|
| export const plainTextStorage = { |
| name: 'plaintext', |
| read(): SecureStorageData | null { |
| |
| const { storagePath } = getStoragePath() |
| try { |
| const data = getFsImplementation().readFileSync(storagePath, { |
| encoding: 'utf8', |
| }) |
| return jsonParse(data) |
| } catch { |
| return null |
| } |
| }, |
| async readAsync(): Promise<SecureStorageData | null> { |
| const { storagePath } = getStoragePath() |
| try { |
| const data = await getFsImplementation().readFile(storagePath, { |
| encoding: 'utf8', |
| }) |
| return jsonParse(data) |
| } catch { |
| return null |
| } |
| }, |
| update(data: SecureStorageData): { success: boolean; warning?: string } { |
| |
| try { |
| const { storageDir, storagePath } = getStoragePath() |
| try { |
| getFsImplementation().mkdirSync(storageDir) |
| } catch (e: unknown) { |
| const code = getErrnoCode(e) |
| if (code !== 'EEXIST') { |
| throw e |
| } |
| } |
|
|
| writeFileSync_DEPRECATED(storagePath, jsonStringify(data), { |
| encoding: 'utf8', |
| flush: false, |
| }) |
| chmodSync(storagePath, 0o600) |
| return { |
| success: true, |
| warning: 'Warning: Storing credentials in plaintext.', |
| } |
| } catch { |
| return { success: false } |
| } |
| }, |
| delete(): boolean { |
| |
| const { storagePath } = getStoragePath() |
| try { |
| getFsImplementation().unlinkSync(storagePath) |
| return true |
| } catch (e: unknown) { |
| const code = getErrnoCode(e) |
| if (code === 'ENOENT') { |
| return true |
| } |
| return false |
| } |
| }, |
| } satisfies SecureStorage |
|
|