diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 28a81bd..60ec188 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -56,6 +56,9 @@ "backend_changed": "Clear data and reload?", "backend_changed_detail": "Unable to access secret from system keyring, it appears to have changed.", "backend_changed_title": "Failed to load database", + "backend_no_encryption": "Your system has a supported keyring but encryption is not available.", + "backend_no_encryption_detail": "Electron has detected that encryption is not available on your keyring %(backend)s. Please ensure that you have the keyring installed. If you do have the keyring installed, please reboot and try again. Optionally, you can allow %(brand)s to use a weaker form of encryption.", + "backend_no_encryption_title": "No encryption support", "unknown_backend_override": "Your system has an unsupported keyring meaning the database cannot be opened.", "unknown_backend_override_details": "Please check the logs for more details.", "unknown_backend_override_title": "Failed to load database", diff --git a/src/store.ts b/src/store.ts index d78c615..c061298 100644 --- a/src/store.ts +++ b/src/store.ts @@ -241,8 +241,9 @@ class Store extends ElectronStore { // Linux safeStorage support is hellish, the support varies on the Desktop Environment used rather than the store itself. // https://github.com/electron/electron/issues/39789 https://github.com/microsoft/vscode/issues/185212 const selectedSafeStorageBackend = safeStorage.getSelectedStorageBackend(); + const isEncryptionAvailable = safeStorage.isEncryptionAvailable(); console.info( - `safeStorage backend '${selectedSafeStorageBackend}' selected, '${safeStorageBackend}' in config.`, + `safeStorage backend '${selectedSafeStorageBackend}' selected, '${safeStorageBackend}' in config, isEncryptionAvailable = ${isEncryptionAvailable}.`, ); if (selectedSafeStorageBackend === "unknown") { @@ -260,7 +261,38 @@ class Store extends ElectronStore { return this.upgradeLinuxBackend2(); } - if (!safeStorageBackend) { + // Whether we were using basic_text as a fallback before + const usingFallback = this.get("safeStorageBackendOverride") && safeStorageBackend === "basic_text"; + + if (this.mode === Mode.Encrypted && !isEncryptionAvailable && !usingFallback) { + // Sometimes we may have a working backend that for some reason does not support encryption at the moment. + // This may be because electron reported an incorrect backend or because of some known issues with the keyring itself. + // In any case, when this happens, we give the user an option to use a weaker form of encryption. + const { response } = await dialog.showMessageBox({ + title: _t("store|error|backend_no_encryption_title"), + message: _t("store|error|backend_no_encryption"), + detail: _t("store|error|backend_no_encryption_detail", { + backend: safeStorageBackend, + brand: global.vectorConfig.brand || "Element", + }), + type: "error", + buttons: [_t("action|cancel"), _t("store|error|unsupported_keyring_cta")], + defaultId: 0, + cancelId: 0, + }); + if (response === 0) { + throw new Error( + `Encryption support not available on backend ${safeStorageBackend} and user prohibits using weaker encryption.`, + ); + } + this.recordSafeStorageBackend("basic_text"); + this.set("safeStorageBackendOverride", true); + relaunchApp(); + } else if (usingFallback) { + // On the next run, don't use the fallback. + // This is so that we can check if the problems with the keyring fixed itself. + this.set("safeStorageBackendOverride", false); + } else if (!safeStorageBackend) { if (selectedSafeStorageBackend === "basic_text" && this.mode === Mode.Encrypted) { const { response } = await dialog.showMessageBox({ title: _t("store|error|unsupported_keyring_title"), @@ -349,7 +381,7 @@ class Store extends ElectronStore { relaunchApp(); } private upgradeLinuxBackend2(): void { - if (!this.secrets) throw new Error("safeStorage not ready"); + this.secrets = new PlaintextStorageWriter(this); console.info("Performing safeStorage migration"); const data = this.get("safeStorage"); if (data) { @@ -362,7 +394,7 @@ class Store extends ElectronStore { relaunchApp(); } private upgradeLinuxBackend3(): void { - if (!this.secrets) throw new Error("safeStorage not ready"); + this.secrets = new PlaintextStorageWriter(this); const selectedSafeStorageBackend = safeStorage.getSelectedStorageBackend(); console.info(`Finishing safeStorage migration to ${selectedSafeStorageBackend}`); const data = this.get("safeStorage");