Re-check session on tab focus to fix stale user name in sidebar footer
If a different user logs into a child app while the portal tab is open, the portal cookie changes but the in-memory user state goes stale. Now AuthGate re-fetches /api/auth/me on visibilitychange and focus events, updating state only when the user identity actually changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d0fb78da51
commit
2b4de33289
1 changed files with 32 additions and 4 deletions
|
|
@ -18,16 +18,44 @@ export function AuthGate({ children }: Props) {
|
|||
const [checking, setChecking] = useState(true)
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
const userRef = useRef<User | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
function fetchMe(isInitial = false) {
|
||||
fetch('/api/auth/me', { credentials: 'include' })
|
||||
.then(r => r.ok ? r.json() : null)
|
||||
.then(data => {
|
||||
if (data) setUser(data)
|
||||
else navigate('/login', { replace: true, state: { from: location.pathname } })
|
||||
if (data) {
|
||||
// Only update state if the user identity has changed, to avoid re-renders on every focus
|
||||
if (!userRef.current || userRef.current.id !== data.id) {
|
||||
userRef.current = data
|
||||
setUser(data)
|
||||
}
|
||||
} else {
|
||||
navigate('/login', { replace: true, state: isInitial ? { from: location.pathname } : undefined })
|
||||
}
|
||||
})
|
||||
.catch(() => navigate('/login', { replace: true }))
|
||||
.finally(() => setChecking(false))
|
||||
.finally(() => { if (isInitial) setChecking(false) })
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchMe(true)
|
||||
|
||||
// Re-check session on tab focus / visibility — catches the case where a
|
||||
// different user logged into a child app and the portal cookie changed.
|
||||
let pending = false
|
||||
function onVisible() {
|
||||
if (document.visibilityState !== 'visible' || pending) return
|
||||
pending = true
|
||||
setTimeout(() => { pending = false; fetchMe() }, 100)
|
||||
}
|
||||
|
||||
document.addEventListener('visibilitychange', onVisible)
|
||||
window.addEventListener('focus', onVisible)
|
||||
return () => {
|
||||
document.removeEventListener('visibilitychange', onVisible)
|
||||
window.removeEventListener('focus', onVisible)
|
||||
}
|
||||
}, [])
|
||||
|
||||
if (checking) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue