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 [checking, setChecking] = useState(true)
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
const userRef = useRef<User | null>(null)
|
||||||
|
|
||||||
useEffect(() => {
|
function fetchMe(isInitial = false) {
|
||||||
fetch('/api/auth/me', { credentials: 'include' })
|
fetch('/api/auth/me', { credentials: 'include' })
|
||||||
.then(r => r.ok ? r.json() : null)
|
.then(r => r.ok ? r.json() : null)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data) setUser(data)
|
if (data) {
|
||||||
else navigate('/login', { replace: true, state: { from: location.pathname } })
|
// 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 }))
|
.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) {
|
if (checking) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue