Fix clear storage not working

It failed because it went looking for the focused / first window to
clear the storage on, but we called it before we had a window. Just
rewrite it without electron-clear-storage which doesn't really seem
necessary as a dependency, and also relaunched the app when clearing
stprage (you-had-one-job.gif). Pass the session in explicitly so it's
clear it needs it.
This commit is contained in:
David Baker 2025-06-04 16:01:03 +01:00
parent cf88e520a0
commit 6901bff548
5 changed files with 38 additions and 30 deletions

View File

@ -58,7 +58,6 @@
},
"dependencies": {
"@sentry/electron": "^6.0.0",
"@standardnotes/electron-clear-data": "^1.0.5",
"auto-launch": "^5.0.5",
"counterpart": "^0.18.6",
"electron-store": "^10.0.0",

View File

@ -453,14 +453,6 @@ app.on("ready", async () => {
store,
});
try {
console.debug("Ensuring storage is ready");
await store.safeStorageReady();
} catch (e) {
console.error(e);
app.exit(1);
}
// Load the previous window state with fallback to defaults
const mainWindowState = windowStateKeeper({
defaultWidth: 1024,
@ -492,6 +484,15 @@ app.on("ready", async () => {
webgl: true,
},
});
try {
console.debug("Ensuring storage is ready");
if (!await store.prepareSafeStorage(global.mainWindow.webContents.session)) return;
} catch (e) {
console.error(e);
app.exit(1);
}
void global.mainWindow.loadURL("vector://vector/webapp/");
if (process.platform === "darwin") {

View File

@ -174,7 +174,7 @@ ipcMain.on("ipcCall", async function (_ev: IpcMainEvent, payload) {
break;
case "clearStorage":
await clearDataAndRelaunch();
await clearDataAndRelaunch(global.mainWindow.webContents.session);
return; // the app is about to stop, we don't need to reply to the IPC
case "breadcrumbs": {

View File

@ -16,8 +16,7 @@ limitations under the License.
import ElectronStore from "electron-store";
import keytar from "keytar-forked";
import { app, safeStorage, dialog, type SafeStorage } from "electron";
import { clearAllUserData, relaunchApp } from "@standardnotes/electron-clear-data";
import { app, safeStorage, dialog, type SafeStorage, type Session } from "electron";
import { _t } from "./language-helper.js";
@ -61,12 +60,18 @@ const safeStorageBackendMap: Omit<
kwallet5: "kwallet5",
};
function relaunchApp(): void {
app.relaunch();
app.exit();
}
/**
* Clear all data and relaunch the app.
*/
export async function clearDataAndRelaunch(): Promise<void> {
export async function clearDataAndRelaunch(electronSession: Session): Promise<void> {
Store.instance?.clear();
clearAllUserData();
electronSession.flushStorageData();
await electronSession.clearStorageData();
relaunchApp();
}
@ -230,7 +235,7 @@ class Store extends ElectronStore<StoreData> {
private safeStorageReadyPromise?: Promise<unknown>;
public async safeStorageReady(): Promise<void> {
if (!this.safeStorageReadyPromise) {
this.safeStorageReadyPromise = this.prepareSafeStorage();
throw new Error("prepareSafeStorage must be called before using storage methods");
}
await this.safeStorageReadyPromise;
}
@ -270,8 +275,13 @@ class Store extends ElectronStore<StoreData> {
* Prepare the safeStorage backend for use.
* We don't eagerly import from keytar as that would bring in data for all Element profiles and not just the current one,
* so we import lazily in getSecret.
*
* This will relaunch the app in some cases, in which case it will return false and the caller should abort startup.
*
* @param electronSession - The Electron session to use for storage (will be used to clear storage if necessary).
* @returns true if safeStorage was initialised successfully or false if the app will be relaunched
*/
private async prepareSafeStorage(): Promise<void> {
public async prepareSafeStorage(electronSession: Session): Promise<boolean> {
await app.whenReady();
// The backend the existing data is written with if any
@ -282,11 +292,13 @@ class Store extends ElectronStore<StoreData> {
// Handle migrations
if (existingSafeStorageBackend) {
if (existingSafeStorageBackend === "basic_text" && backend !== "plaintext" && backend !== "basic_text") {
return this.prepareMigrateBasicTextToPlaintext();
this.prepareMigrateBasicTextToPlaintext();
return false;
}
if (this.get("safeStorageBackendMigrate") && backend === "basic_text") {
return this.migrateBasicTextToPlaintext();
this.migrateBasicTextToPlaintext();
return false;
}
if (existingSafeStorageBackend === "plaintext" && backend !== "plaintext") {
@ -314,9 +326,10 @@ class Store extends ElectronStore<StoreData> {
if (existingSafeStorageBackend in safeStorageBackendMap && !this.get("safeStorageBackendOverride")) {
this.set("safeStorageBackendOverride", true);
return relaunchApp();
relaunchApp();
return false;
} else {
await this.consultUserBackendChangedUnableToMigrate();
await this.consultUserBackendChangedUnableToMigrate(electronSession);
}
}
@ -326,9 +339,11 @@ class Store extends ElectronStore<StoreData> {
} else {
this.secrets = new StorageWriter(this);
}
return true;
}
private async consultUserBackendChangedUnableToMigrate(): Promise<void> {
private async consultUserBackendChangedUnableToMigrate(electronSession: Session): Promise<void> {
const { response } = await dialog.showMessageBox({
title: _t("store|error|backend_changed_title"),
message: _t("store|error|backend_changed"),
@ -341,7 +356,7 @@ class Store extends ElectronStore<StoreData> {
if (response === 0) {
throw new Error("safeStorage backend changed and cannot migrate");
}
return clearDataAndRelaunch();
return clearDataAndRelaunch(electronSession);
}
private async consultUserConsentDegradedMode(backend: "plaintext" | "basic_text"): Promise<void> {

View File

@ -1048,7 +1048,6 @@
"@electron/node-gyp@https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2":
version "10.2.0-electron.1"
uid "06b29aafb7708acef8b3669835c8a7857ebc92d2"
resolved "https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2"
dependencies:
env-paths "^2.2.0"
@ -1334,7 +1333,6 @@
"@fastify/otel@github:getsentry/fastify-otel#otel-v1":
version "0.8.0"
uid ae3088d65e286bdc94ac5d722573537d6a6671bb
resolved "https://codeload.github.com/getsentry/fastify-otel/tar.gz/ae3088d65e286bdc94ac5d722573537d6a6671bb"
dependencies:
"@opentelemetry/core" "^1.30.1"
@ -2034,7 +2032,7 @@
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-9.18.0.tgz#682ad11030548eb0e0674ff091afc65319da6d8d"
integrity sha512-n0H13YVfynZJnKQLHoTlyBK2P960X8+B08za9VaRnJ4zikDx23Xk2Owtj006ZUItUKtKLFi70NyQGGDp7gVAyw==
dependencies:
"@fastify/otel" "github:getsentry/fastify-otel#otel-v1"
"@fastify/otel" getsentry/fastify-otel#otel-v1
"@opentelemetry/api" "^1.9.0"
"@opentelemetry/context-async-hooks" "^1.30.1"
"@opentelemetry/core" "^1.30.1"
@ -2127,11 +2125,6 @@
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"
integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==
"@standardnotes/electron-clear-data@^1.0.5":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@standardnotes/electron-clear-data/-/electron-clear-data-1.1.1.tgz#45eab118ed5d1ee9369b540d7e62a9ca96778335"
integrity sha512-R0YivtSwSQpNt5nPOi7YRTGlk6kpcz6/2/sAQZf6ZCU8vIGm1cBMo++6kkGQcDEumkwbmagxmLWinL9d1W5g3Q==
"@stylistic/eslint-plugin@^4.0.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin/-/eslint-plugin-4.4.0.tgz#e1a3c9fd7109411d32dc0bcb575d2b4066fbbc63"