File size: 2,481 Bytes
39e315a | 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 86 87 | import { execaSync } from 'execa'
import { jsonParse, jsonStringify } from '../slowOperations.js'
import {
CREDENTIALS_SERVICE_SUFFIX,
getSecureStorageServiceName,
getUsername,
} from './macOsKeychainHelpers.js'
import type { SecureStorage, SecureStorageData } from './index.js'
/**
* Linux-specific secure storage implementation using the secret-tool CLI.
* secret-tool interacts with the Secret Service API (GNOME Keyring, KWallet, etc.).
*/
export const linuxSecretStorage: SecureStorage = {
name: 'libsecret',
read(): SecureStorageData | null {
try {
const username = getUsername()
const serviceName = getSecureStorageServiceName(
CREDENTIALS_SERVICE_SUFFIX,
)
// secret-tool lookup service [service] account [account]
const result = execaSync(
'secret-tool',
['lookup', 'service', serviceName, 'account', username],
{ reject: false },
)
if (result.exitCode === 0 && result.stdout) {
return jsonParse(result.stdout)
}
} catch {
// fall through
}
return null
},
async readAsync(): Promise<SecureStorageData | null> {
// Reusing sync implementation for simplicity as it wraps a CLI call
return this.read()
},
update(data: SecureStorageData): { success: boolean; warning?: string } {
try {
const username = getUsername()
const serviceName = getSecureStorageServiceName(
CREDENTIALS_SERVICE_SUFFIX,
)
const payload = jsonStringify(data)
// secret-tool store --label=[label] service [service] account [account]
// The payload is passed via stdin
const result = execaSync(
'secret-tool',
[
'store',
'--label',
serviceName,
'service',
serviceName,
'account',
username,
],
{ input: payload, reject: false },
)
return { success: result.exitCode === 0 }
} catch {
return { success: false }
}
},
delete(): boolean {
try {
const username = getUsername()
const serviceName = getSecureStorageServiceName(
CREDENTIALS_SERVICE_SUFFIX,
)
// secret-tool clear service [service] account [account]
const result = execaSync(
'secret-tool',
['clear', 'service', serviceName, 'account', username],
{ reject: false },
)
return result.exitCode === 0
} catch {
return false
}
},
}
|