mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-08-05 02:45:28 +00:00
Merge 9ac08fe5da into fb8c391a88
This commit is contained in:
commit
c748351027
2 changed files with 49 additions and 2 deletions
31
CHANGELOG.md
Normal file
31
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to Odysseus will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- **auth: prevent spurious login redirect on mobile during text input**
|
||||
The global `window.fetch` 401 interceptor (`static/app.js`) unconditionally
|
||||
redirected to `/login` on any background API call that returned 401. On mobile,
|
||||
when the user backgrounded the app (switched apps, locked phone), session
|
||||
cookies could become stale. When they returned, background fetches (task
|
||||
notification polling every 30s, calendar refetch on tab resume, notes badge
|
||||
refresh) received 401 responses and triggered an immediate redirect to
|
||||
`/login`, which wiped the user's unsent text input and chat state.
|
||||
|
||||
This was especially noticeable on mobile browsers which aggressively suspend
|
||||
background tabs and expire cookies faster than desktop browsers.
|
||||
|
||||
The fix adds three improvements to the 401 interceptor:
|
||||
1. **Retry once after 2s** — catches transient 401s from stale cookies on
|
||||
mobile tab resume that resolve on retry.
|
||||
2. **Deduplication** — prevents multiple stacked redirects from concurrent
|
||||
background fetches (e.g. task polling + calendar refetch simultaneously
|
||||
hitting 401).
|
||||
3. **Typing guard** — if the user is actively typing in the message input
|
||||
when the redirect fires, it defers until the input loses focus, preserving
|
||||
the draft.
|
||||
|
|
@ -185,11 +185,27 @@ function initRailHoverLabels() {
|
|||
});
|
||||
}
|
||||
|
||||
// Redirect to login on 401 from any fetch
|
||||
// Redirect to login on 401 from any fetch — but retry once first to avoid
|
||||
// spurious redirects on mobile when background tabs resume after cookie staleness.
|
||||
// If the user is mid-typing, delay the redirect so their draft isn't wiped.
|
||||
let _401Cooldown = false;
|
||||
const _origFetch = window.fetch;
|
||||
window.fetch = async function(...args) {
|
||||
const res = await _origFetch.apply(this, args);
|
||||
if (res.status === 401 && !String(args[0]).includes('/api/auth/')) {
|
||||
if (res.status !== 401 || String(args[0]).includes('/api/auth/')) return res;
|
||||
if (_401Cooldown) return res;
|
||||
_401Cooldown = true;
|
||||
await new Promise(r => setTimeout(r, 2000));
|
||||
try {
|
||||
const retry = await _origFetch.apply(this, args);
|
||||
if (retry.status !== 401) { _401Cooldown = false; return res; }
|
||||
} catch (_) {}
|
||||
const msgInput = document.getElementById('message');
|
||||
const isTyping = msgInput && msgInput === document.activeElement && msgInput.value.trim().length > 0;
|
||||
if (isTyping) {
|
||||
const _onBlur = () => { msgInput.removeEventListener('blur', _onBlur); window.location.href = '/login'; };
|
||||
msgInput.addEventListener('blur', _onBlur);
|
||||
} else {
|
||||
window.location.href = '/login';
|
||||
}
|
||||
return res;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue