diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-01-01 21:28:33 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-01-01 21:28:33 +0900 |
| commit | 1d31f2ec8921bb58d74458b057bbb31f4877c335 (patch) | |
| tree | 695e24534c9529d4271aa7ed544eaadb697c93b6 /src/client/api | |
| parent | bf286c11d3244afb5132271dac656109934150e0 (diff) | |
| download | kioku-1d31f2ec8921bb58d74458b057bbb31f4877c335.tar.gz kioku-1d31f2ec8921bb58d74458b057bbb31f4877c335.tar.zst kioku-1d31f2ec8921bb58d74458b057bbb31f4877c335.zip | |
fix(auth): redirect to login when session expires
When the refresh token fails (session expired), the ApiClient now
notifies the AuthProvider via a callback. This triggers a logout
and React state update, causing ProtectedRoute to redirect to /login.
Closes #7
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src/client/api')
| -rw-r--r-- | src/client/api/client.ts | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/src/client/api/client.ts b/src/client/api/client.ts index b39f064..c91160d 100644 --- a/src/client/api/client.ts +++ b/src/client/api/client.ts @@ -58,10 +58,13 @@ export function createClient(baseUrl: string): Client { return hc<AppType>(baseUrl); } +export type SessionExpiredCallback = () => void; + export class ApiClient { private tokenStorage: TokenStorage; private refreshPromise: Promise<boolean> | null = null; private baseUrl: string; + private sessionExpiredCallback: SessionExpiredCallback | null = null; public readonly rpc: Client; constructor(options: ApiClientOptions = {}) { @@ -70,6 +73,13 @@ export class ApiClient { this.rpc = this.createAuthenticatedClient(); } + onSessionExpired(callback: SessionExpiredCallback): () => void { + this.sessionExpiredCallback = callback; + return () => { + this.sessionExpiredCallback = null; + }; + } + private createAuthenticatedClient(): Client { return hc<AppType>(this.baseUrl, { fetch: async (input: RequestInfo | URL, init?: RequestInit) => { @@ -156,8 +166,9 @@ export class ApiClient { }); if (!res.ok) { - // Clear tokens if refresh fails + // Clear tokens if refresh fails and notify listeners this.tokenStorage.clearTokens(); + this.sessionExpiredCallback?.(); return false; } |
