theseus 0.3.51: profile relocation looks for the actual old dir name

0.3.50's relocateProfile checked for %APPDATA%\Theseus Navigator\, but
Electron's userData path is derived from app.getName(), which reads
package.json's top-level "name" ("theseus-navigator") because there is
no top-level productName — the "productName": "Theseus Navigator" in
this file lives under "build", where electron-builder reads it for the
installer, not where Electron reads it for the runtime path. So the
folder the user's Theseus writes to is %APPDATA%\theseus-navigator\,
never %APPDATA%\Theseus Navigator\.

On 0.3.50 that meant relocateProfile found nothing at its search path,
returned the new Theseus\ location, and Electron happily created a
fresh empty profile there. The user's addons, vault, bookmarks and
settings stayed in theseus-navigator\ but the running Theseus was no
longer looking at them. Losing the vault is not something the user
can recover from.

Check both candidate names — the one the code was written for and the
one that actually exists — and migrate whichever is present. If the
new Theseus\ already exists (Windows fresh installs after 0.3.51), we
leave it alone.
This commit is contained in:
Local Dev 2026-09-21 22:52:57 +02:00
parent 56b3f2f206
commit 8d02a2464b
3 changed files with 19 additions and 7 deletions

20
main.js
View file

@ -32,11 +32,23 @@ if (process.env.THESEUS_USER_DATA) {
catch (e) { console.warn("profile relocation failed:", e?.message); }
}
function relocateProfile(appData) {
const oldDir = path.join(appData, "Theseus Navigator");
const newDir = path.join(appData, "Theseus");
if (!fs.existsSync(newDir) && fs.existsSync(oldDir)) {
try { fs.renameSync(oldDir, newDir); }
catch { fs.cpSync(oldDir, newDir, { recursive: true }); }
// Two possible previous locations: "Theseus Navigator" (what the code
// originally checked for, based on the assumed productName), and
// "theseus-navigator" (what Electron ACTUALLY used because package.json
// has no top-level productName, so app.getName() falls back to the "name"
// field). Whichever exists is the profile the user has been running
// against; migrate it in place so 0.3.51 does not silently create a fresh
// Theseus\ next to a still-populated old dir the user cannot see.
if (fs.existsSync(newDir)) return newDir;
for (const candidate of ["Theseus Navigator", "theseus-navigator"]) {
const oldDir = path.join(appData, candidate);
if (!fs.existsSync(oldDir)) continue;
try { fs.renameSync(oldDir, newDir); return newDir; }
catch {
try { fs.cpSync(oldDir, newDir, { recursive: true }); return newDir; }
catch (e) { console.warn(`[profile] relocate ${candidate} failed:`, e?.message); }
}
}
return newDir;
}

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "theseus-navigator",
"version": "0.3.50",
"version": "0.3.51",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "theseus-navigator",
"version": "0.3.50",
"version": "0.3.51",
"dependencies": {
"@bch-wc2/interfaces": "^0.0.16",
"@bitauth/libauth": "^3.1.0-next.8",

View file

@ -1,6 +1,6 @@
{
"name": "theseus-navigator",
"version": "0.3.50",
"version": "0.3.51",
"description": "Theseus Navigator — a browser that follows the thread. By Silent Mode, a Deviant project.",
"author": "Silent Mode",
"main": "main.js",