fix: resolve auth:expired race condition and force SW cache refresh
- Add _pendingLoginRedirect flag in router.js to handle auth:expired
events that fire during active navigation (isNavigating=true).
Previously the navigate('/login') call was silently dropped, leaving
the user stuck on the dashboard with an error toast.
- Bump SHELL_CACHE v33→v34 and PAGES_CACHE v28→v29 to force cache
invalidation on iOS devices still running the pre-CSRF-fix code.
- Add err.status to dashboard error log for easier diagnostics.
This commit is contained in:
@@ -655,7 +655,7 @@ export async function render(container, { user }) {
|
|||||||
weather = weatherRes.data ?? null;
|
weather = weatherRes.data ?? null;
|
||||||
widgetConfig = prefsRes.data?.dashboard_widgets ?? DEFAULT_WIDGET_CONFIG;
|
widgetConfig = prefsRes.data?.dashboard_widgets ?? DEFAULT_WIDGET_CONFIG;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[Dashboard] Ladefehler:', err.message);
|
console.error('[Dashboard] Ladefehler:', err.message, 'Status:', err.status ?? 'network');
|
||||||
window.oikos?.showToast(t('dashboard.loadError'), 'warning');
|
window.oikos?.showToast(t('dashboard.loadError'), 'warning');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -115,6 +115,9 @@ async function importPage(pagePath) {
|
|||||||
let currentUser = null;
|
let currentUser = null;
|
||||||
let currentPath = null;
|
let currentPath = null;
|
||||||
let isNavigating = false;
|
let isNavigating = false;
|
||||||
|
// Gesetzt wenn auth:expired waehrend einer laufenden Navigation feuert.
|
||||||
|
// Die Weiterleitung zu /login wird nach Abschluss der Navigation nachgeholt.
|
||||||
|
let _pendingLoginRedirect = false;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// Router
|
// Router
|
||||||
@@ -189,6 +192,13 @@ async function navigate(path, userOrPushState = true, pushState = true) {
|
|||||||
updateThemeColorForRoute(route);
|
updateThemeColorForRoute(route);
|
||||||
} finally {
|
} finally {
|
||||||
isNavigating = false;
|
isNavigating = false;
|
||||||
|
// auth:expired kann waehrend einer Navigation gefeuert haben (z.B. wenn ein
|
||||||
|
// paralleler API-Call 401 zurueckgab). Jetzt wo die Navigation abgeschlossen
|
||||||
|
// ist, holen wir die Login-Weiterleitung nach.
|
||||||
|
if (_pendingLoginRedirect) {
|
||||||
|
_pendingLoginRedirect = false;
|
||||||
|
navigate('/login');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,7 +521,13 @@ window.addEventListener('popstate', (e) => {
|
|||||||
window.addEventListener('auth:expired', () => {
|
window.addEventListener('auth:expired', () => {
|
||||||
currentUser = null;
|
currentUser = null;
|
||||||
stopReminders();
|
stopReminders();
|
||||||
|
if (isNavigating) {
|
||||||
|
// navigate('/login') kann nicht sofort aufgerufen werden - wird im finally-Block
|
||||||
|
// der laufenden Navigation nachgeholt.
|
||||||
|
_pendingLoginRedirect = true;
|
||||||
|
} else {
|
||||||
navigate('/login');
|
navigate('/login');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sprache geändert: Navigation neu rendern damit Labels aktualisiert werden
|
// Sprache geändert: Navigation neu rendern damit Labels aktualisiert werden
|
||||||
|
|||||||
+2
-2
@@ -12,8 +12,8 @@
|
|||||||
* API: Immer Netzwerk (kein Caching von Nutzerdaten)
|
* API: Immer Netzwerk (kein Caching von Nutzerdaten)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const SHELL_CACHE = 'oikos-shell-v33';
|
const SHELL_CACHE = 'oikos-shell-v34';
|
||||||
const PAGES_CACHE = 'oikos-pages-v28';
|
const PAGES_CACHE = 'oikos-pages-v29';
|
||||||
const ASSETS_CACHE = 'oikos-assets-v27';
|
const ASSETS_CACHE = 'oikos-assets-v27';
|
||||||
const ALL_CACHES = [SHELL_CACHE, PAGES_CACHE, ASSETS_CACHE];
|
const ALL_CACHES = [SHELL_CACHE, PAGES_CACHE, ASSETS_CACHE];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user