refactor: replace hand-rolled OIDC with @logto/react SDK
All checks were successful
CI / build (push) Successful in 38s
CI / docker (push) Successful in 48s

The hand-rolled OIDC flow (manual PKCE, token exchange, URL
construction) was fragile and accumulated multiple bugs. Replaced
with the official @logto/react SDK which handles PKCE, token
exchange, storage, and refresh automatically.

- Add @logto/react SDK dependency
- Add LogtoProvider with runtime config in main.tsx
- Add TokenSync component bridging SDK tokens to API client
- Add useAuth hook replacing Zustand auth store
- Simplify LoginPage to signIn(), CallbackPage to useHandleSignInCallback()
- Delete pkce.ts and auth-store.ts (replaced by SDK)
- Fix react-router-dom → react-router imports in page files
- All 17 React Query hooks unchanged (token provider pattern)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-05 01:17:47 +02:00
parent 84667170f1
commit 0843a33383
19 changed files with 320 additions and 224 deletions

43
ui/src/auth/useAuth.ts Normal file
View File

@@ -0,0 +1,43 @@
import { useLogto } from '@logto/react';
import { useState, useEffect, useCallback } from 'react';
interface IdTokenClaims {
sub?: string;
email?: string;
name?: string;
username?: string;
roles?: string[];
organization_id?: string;
[key: string]: unknown;
}
export function useAuth() {
const { isAuthenticated, isLoading, getIdTokenClaims, signOut, signIn } = useLogto();
const [claims, setClaims] = useState<IdTokenClaims | null>(null);
useEffect(() => {
if (isAuthenticated) {
getIdTokenClaims().then((c) => setClaims(c as IdTokenClaims));
} else {
setClaims(null);
}
}, [isAuthenticated, getIdTokenClaims]);
const username = claims?.username ?? claims?.name ?? claims?.email ?? claims?.sub ?? null;
const roles = (claims?.roles as string[]) ?? [];
const tenantId = (claims?.organization_id as string) ?? null;
const logout = useCallback(() => {
signOut(window.location.origin + '/login');
}, [signOut]);
return {
isAuthenticated,
isLoading,
username,
roles,
tenantId,
logout,
signIn,
};
}