Skip to content

Commit ca60f34

Browse files
authored
fix: retroachievements setup now works on Linux without a keyring (#126)
Previously failed with a confusing "check your credentials" error when the system keyring wasn't available. Now falls back to plaintext storage. --- Uses a `plain:` prefix to distinguish unencrypted keys from encrypted ones, so existing encrypted keys keep working. Fixes #125
1 parent 86778ef commit ca60f34

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

src/main/db/queries/integrations.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,28 @@ const log = logger.scope('db:integrations');
77

88
const RA_USERNAME_KEY = 'integration.retroachievements.username';
99
const RA_API_KEY = 'integration.retroachievements.apiKey';
10+
const PLAINTEXT_PREFIX = 'plain:';
1011

1112
export const integrationsQueries = {
1213
getRetroAchievements(): RetroAchievementsConfig | null {
1314
const username = settingsQueries.get(RA_USERNAME_KEY);
14-
const encryptedApiKey = settingsQueries.get(RA_API_KEY);
15+
const storedApiKey = settingsQueries.get(RA_API_KEY);
1516

16-
if (!username || !encryptedApiKey) {
17+
if (!username || !storedApiKey) {
1718
return null;
1819
}
1920

21+
if (storedApiKey.startsWith(PLAINTEXT_PREFIX)) {
22+
return { username, apiKey: storedApiKey.slice(PLAINTEXT_PREFIX.length) };
23+
}
24+
2025
if (!safeStorage.isEncryptionAvailable()) {
21-
log.warn('Encryption not available on this system, cannot decrypt RetroAchievements API key');
26+
log.warn('Encryption not available and no plaintext fallback found');
2227
return null;
2328
}
2429

2530
try {
26-
const encryptedBuffer = Buffer.from(encryptedApiKey, 'base64');
31+
const encryptedBuffer = Buffer.from(storedApiKey, 'base64');
2732
const apiKey = safeStorage.decryptString(encryptedBuffer);
2833
return { username, apiKey };
2934
} catch (error) {
@@ -35,16 +40,19 @@ export const integrationsQueries = {
3540
setRetroAchievements(config: RetroAchievementsConfig) {
3641
const { username, apiKey } = config;
3742

38-
if (!safeStorage.isEncryptionAvailable()) {
39-
throw new Error('Encryption not available on this system, cannot store API key securely');
43+
if (safeStorage.isEncryptionAvailable()) {
44+
const encryptedApiKey = safeStorage.encryptString(apiKey);
45+
settingsQueries.setMany({
46+
[RA_USERNAME_KEY]: username,
47+
[RA_API_KEY]: encryptedApiKey.toString('base64'),
48+
});
49+
} else {
50+
log.warn('Secure storage unavailable, storing API key in plaintext');
51+
settingsQueries.setMany({
52+
[RA_USERNAME_KEY]: username,
53+
[RA_API_KEY]: PLAINTEXT_PREFIX + apiKey,
54+
});
4055
}
41-
42-
const encryptedApiKey = safeStorage.encryptString(apiKey);
43-
44-
settingsQueries.setMany({
45-
[RA_USERNAME_KEY]: username,
46-
[RA_API_KEY]: encryptedApiKey.toString('base64'),
47-
});
4856
},
4957

5058
removeRetroAchievements() {

0 commit comments

Comments
 (0)