fix(hub,web): extend JWT expiration and harden visibility refresh (#442)

- Extend JWT expiration from 15 minutes to 4 hours in both auth and
  bind endpoints. 15 minutes was too short — browser timer throttling
  in background tabs prevented the scheduled refresh from firing
  before expiration, causing unexpected logouts.

- Change the visibility/focus refresh from conditional (minTtlMs) to
  forced, so returning to a backgrounded tab always re-authenticates
  regardless of remaining token TTL. This eliminates the race between
  timer throttling and token expiration.

HAPI is a self-hosted tool, so the longer token lifetime is an
acceptable security tradeoff. The auth source (Telegram initData or
CLI access token) is still validated on every refresh.

Closes #412
This commit is contained in:
Haoqing Wang
2026-04-11 22:03:50 +08:00
committed by GitHub
parent 73e3d6e774
commit 9a48d5af3a
3 changed files with 3 additions and 3 deletions
+1 -1
View File
@@ -71,7 +71,7 @@ export function createAuthRoutes(jwtSecret: Uint8Array, store: Store): Hono<WebA
const token = await new SignJWT({ uid: userId, ns: namespace })
.setProtectedHeader({ alg: 'HS256' })
.setIssuedAt()
.setExpirationTime('15m')
.setExpirationTime('4h')
.sign(jwtSecret)
return c.json({
+1 -1
View File
@@ -51,7 +51,7 @@ export function createBindRoutes(jwtSecret: Uint8Array, store: Store): Hono<WebA
const token = await new SignJWT({ uid: userId, ns: namespace })
.setProtectedHeader({ alg: 'HS256' })
.setIssuedAt()
.setExpirationTime('15m')
.setExpirationTime('4h')
.sign(jwtSecret)
return c.json({
+1 -1
View File
@@ -267,7 +267,7 @@ export function useAuth(authSource: AuthSource | null, baseUrl: string): {
}
const handleActive = () => {
void refreshAuth({ minTtlMs: 60_000 })
void refreshAuth({ force: true })
}
const handleVisibilityChange = () => {