Confirmed conditional login-persistence bug
Reviewed master at 886c36d8ebe861aa987059a1744d45b78797baae (v4.7.0). Suggested priority: P3.
If a user reaches the login screen with an old persistent credential still in localStorage, then logs in with “Stay logged in” unchecked, the new credential is written to sessionStorage but the old persistence flag/token remain. Reload chooses the old credential, undoing the successful new login.
Source: constructor chooses storage, setToken/setPersist.
Isolated reproduction
Initialize fake localStorage with odin_persist=1 and odin_token=revoked-session. Call the real API client's setPersist(false) and setToken('fresh-session', 60), then reconstruct the client as a page reload would.
sessionStorage credential: fresh-session
localStorage credential: revoked-session
reloaded credential equals latest session: false
Independently verified. Reachable after server-side invalidation while persistent storage remains. Normal explicit logout and the local expiry callback clear both stores, so those paths are not implicated. This is not a privilege bypass: the server still validates the stale credential.
Acceptance criteria
- Switching persistence mode and publishing a new session leaves one authoritative credential/storage choice.
- Clear stale credentials/flags from the previous storage mode.
- Test persistent-to-session, session-to-persistent, server-invalidated login, reload and normal logout.
No source changes were made.
Confirmed conditional login-persistence bug
Reviewed
masterat886c36d8ebe861aa987059a1744d45b78797baae(v4.7.0). Suggested priority: P3.If a user reaches the login screen with an old persistent credential still in localStorage, then logs in with “Stay logged in” unchecked, the new credential is written to sessionStorage but the old persistence flag/token remain. Reload chooses the old credential, undoing the successful new login.
Source: constructor chooses storage, setToken/setPersist.
Isolated reproduction
Initialize fake localStorage with
odin_persist=1andodin_token=revoked-session. Call the real API client'ssetPersist(false)andsetToken('fresh-session', 60), then reconstruct the client as a page reload would.Independently verified. Reachable after server-side invalidation while persistent storage remains. Normal explicit logout and the local expiry callback clear both stores, so those paths are not implicated. This is not a privilege bypass: the server still validates the stale credential.
Acceptance criteria
No source changes were made.