Files

43 lines
1.9 KiB
JavaScript
Raw Permalink Normal View History

+5
2026-08-19 14:12:06 -05:00
// Chromium derives safeStorage's backend from the running desktop and falls back
// to the "basic_text" store for anything it has no mapping for, which is every
// wlroots-style compositor (Hyprland, sway, niri, river, ...).
// safeStorage.isEncryptionAvailable() reports false for that store, so every
// credential the desktop app persists through it -- the remote sync JWT, the
// Electron auth cookie -- is refused at the point of writing. The refusal is
// invisible from the outside: the user signs in, nothing is stored, and the next
// sync tick reports the session as expired rather than as never saved.
//
// Those desktops still run an ordinary Secret Service (gnome-keyring, KWallet's
// compatibility service, KeePassXC, ...), so naming the libsecret backend is
// enough to make encryption available again. Desktops whose auto-detection
// already resolves to KWallet keep it, and an explicit --password-store from the
// user always wins.
//
// Moving a machine off "basic_text" cannot orphan stored secrets: nothing was
// ever written there, because isEncryptionAvailable() gated every write.
const KWALLET_DESKTOPS = /\b(kde|plasma|lxqt)\b/i;
const LIBSECRET_STORE = "gnome-libsecret";
/**
* Picks safeStorage's backend on Linux, and returns the store it selected (or
* null when auto-detection was left to decide).
*
* Must run before the app is ready: Chromium reads the switch when the store is
* first opened, and appending it afterwards has no effect.
*/
function selectLinuxPasswordStore(commandLine, env) {
if (commandLine.hasSwitch("password-store")) {
return null;
}
const desktop = `${env.XDG_CURRENT_DESKTOP || ""}:${env.DESKTOP_SESSION || ""}`;
if (KWALLET_DESKTOPS.test(desktop)) {
return null;
}
commandLine.appendSwitch("password-store", LIBSECRET_STORE);
return LIBSECRET_STORE;
}
module.exports = { selectLinuxPasswordStore };