fix(fuse,core,cli,gui): show a refused session as expired, not offline

A refresh token Proton refused, or a deleted or disabled account, was
treated as a lost connection: the mount came up "offline", the probe
retried forever and logged only at debug, and nothing told the user that
only signing in again helps (issue #35).

session_revoked() names those errors. The root fetch, probe, drain,
event poll, event seed and photos root now set session_expired, log one
warning naming `pdfs login`, and stop retrying. Cached files stay
readable and changes stay queued.

Response::Status carries session_expired (serde default false). The
tray shows "Session expired — sign in again" with a Sign In Again…
item that opens the app's sign-in page; the app's status and Sync card
say the same with a button. `pdfs status` and `pdfs diagnose` report it.
New strings are translated in every catalog.

docs/BUGS.md B202.
This commit is contained in:
nvrl committed 2026-10-09 11:27:09 +02:00
1 parent 6363125fec
commit bf43476e88
24 files changed
+2915 -2416

No files matched your search

+26 -13
View File
@@ -2024,9 +2024,11 @@ fn cmd_status() -> Result<()> {
staged_oldest_secs,
paused,
paused_until,
session_expired,
..
}) => {
let state = match (online, paused) {
_ if session_expired => ", session expired: run `pdfs login`",
(_, true) => ", sync paused",
(false, false) => ", offline",
(true, false) => "",
@@ -3429,6 +3431,7 @@ fn cmd_diagnose() -> Result<()> {
Ok(CtlResponse::Status {
mountpoint,
online,
session_expired,
pending_uploads,
pending_changes,
..
@@ -3450,19 +3453,29 @@ fn cmd_diagnose() -> Result<()> {
|kind| format!("{mountpoint} ({kind})"),
),
);
report.finding(
if online {
DiagnoseLevel::Ok
} else {
DiagnoseLevel::Warn
},
" network",
if online {
"online"
} else {
"offline; cached data remains available"
},
);
// A refused session reads as offline too, but no connection will
// bring it back, and the keyring check above cannot tell.
if session_expired {
report.finding(
DiagnoseLevel::Fail,
" session",
"Proton refused it (expired or revoked) — run `pdfs login`",
);
} else {
report.finding(
if online {
DiagnoseLevel::Ok
} else {
DiagnoseLevel::Warn
},
" network",
if online {
"online"
} else {
"offline; cached data remains available"
},
);
}
let pending = pending_uploads + pending_changes;
report.finding(
if pending == 0 {