feat(auth): session expiration policy (3d idle / 14d absolute) + per-account override + bulk revoke #168

Merged
chihlasm merged 13 commits from feat/session-expiration-policy into main 2026-05-14 04:33:50 +00:00
34 changed files with 8 additions and 5 deletions
Showing only changes of commit cbb4b25671 - Show all commits

View File

@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react'
import { useEffect, useReducer } from 'react'
import { useAuthStore } from '@/store/authStore'
const SOON_MS = 5 * 60 * 1000 // 5 minutes
@@ -53,14 +53,17 @@ function computeState(token: ReturnType<typeof useAuthStore.getState>['token']):
*/
export function useAuthSessionExpiry(): ExpiryState {
const token = useAuthStore((s) => s.token)
const [state, setState] = useState<ExpiryState>(() => computeState(token))
// Derived state — computed during render, not synced via setState in an
// effect. The reducer here is only a tick counter that forces re-render on
// the 30s cadence so the relative timestamps stay current. See React 19
// guidance: https://react.dev/learn/you-might-not-need-an-effect
const [, tick] = useReducer((n: number) => n + 1, 0)
useEffect(() => {
setState(computeState(token))
if (!token?.idle_expires_at || !token?.absolute_expires_at) return
const interval = window.setInterval(() => setState(computeState(token)), 30_000)
const interval = window.setInterval(tick, 30_000)
return () => window.clearInterval(interval)
}, [token])
return state
return computeState(token)
}