File size: 2,430 Bytes
064bfd6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 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 {
// sync IO: called from sync context (SecureStorage interface)
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 } {
// sync IO: called from sync context (SecureStorage interface)
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 {
// sync IO: called from sync context (SecureStorage interface)
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
|