fix: handle 401 gracefully on web; add Bearer token auth for Tauri
- fetchMe() no longer surfaces 401 as a user-facing error (it just means 'no session', not a failure) - API client auto-clears auth state on 401 mid-session so the user gets redirected to login instead of seeing 'ERR: Request failed: 401' - Session middleware now accepts Authorization: Bearer <token> header as fallback when no cookie is present (for Tauri/native clients) - Login, register, and WebAuthn endpoints expose X-Session-Token header so non-browser clients can capture the token
This commit is contained in:
@@ -40,6 +40,19 @@ async function request<T>(method: string, path: string, body?: unknown): Promise
|
||||
const ra = response.headers.get('Retry-After');
|
||||
err.retryAfter = retryAfter ?? (ra ? parseInt(ra, 10) : undefined);
|
||||
}
|
||||
|
||||
// Auto-logout on 401 for any non-login endpoint so expired sessions
|
||||
// redirect to the login page instead of showing cryptic errors.
|
||||
if (response.status === 401 && !path.startsWith('/auth/login') && !path.startsWith('/auth/register')) {
|
||||
// Dynamically import to avoid circular deps
|
||||
import('../stores/auth.ts').then(({ useAuthStore }) => {
|
||||
const state = useAuthStore.getState();
|
||||
if (state.isAuthenticated) {
|
||||
useAuthStore.setState({ user: null, isAuthenticated: false, error: null });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,12 +151,19 @@ export const useAuthStore = create<AuthState>((set) => ({
|
||||
set({ user, isAuthenticated: true, isLoading: false });
|
||||
autoSubscribePush();
|
||||
} catch (error) {
|
||||
// 401 from /auth/me simply means "no active session" — not a
|
||||
// user-facing error. Only surface non-auth failures.
|
||||
const isAuthError =
|
||||
error instanceof Error && (error as import('../lib/api.ts').ApiError).status === 401;
|
||||
set({
|
||||
user: null,
|
||||
isAuthenticated: false,
|
||||
isLoading: false,
|
||||
error:
|
||||
error instanceof Error ? error.message : "Failed to fetch user",
|
||||
error: isAuthError
|
||||
? null
|
||||
: error instanceof Error
|
||||
? error.message
|
||||
: "Failed to fetch user",
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user