42e7bedea4
The honeyDue Go API no longer owns identity — Ory Kratos at
NEXT_PUBLIC_KRATOS_URL does. Rewrite the web app's auth layer to use Kratos
browser self-service flows and the ory_kratos_session cookie.
- Kratos client (src/lib/kratos/): flow init/fetch/submit, whoami, logout,
message helpers, and the useKratosFlow lifecycle hook.
- Generic flow renderer (src/components/auth/): KratosFlowForm renders
ui.nodes (inputs, oidc social buttons, hidden csrf), KratosMessages
surfaces flow-level messages, AuthGate guards /app via whoami.
- Auth pages (login/register/forgot-password/verify-email/reset-password)
rewritten as Kratos login/registration/recovery/verification/settings
flows. Password change in settings now uses the Kratos settings flow.
- Proxy + serverFetch forward the ory_kratos_session cookie to the Go API
instead of "Authorization: Token". Deleted /api/auth/{login,logout,me}.
- Middleware does a cheap ory_kratos_session cookie pre-filter; AuthGate's
whoami call is authoritative.
- auth store rewritten around whoami + GET /auth/me; removed dead auth API
functions, types/auth, validations/auth, code-input.
- Added NEXT_PUBLIC_KRATOS_URL to config (.env.example) and CLAUDE.md.
npm run build passes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
44 lines
1.5 KiB
TypeScript
44 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
import { useRouter } from 'next/navigation';
|
|
import { useDataProvider, useQueryKeyPrefix } from '@/lib/demo/data-provider-context';
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Auth hooks
|
|
// ---------------------------------------------------------------------------
|
|
// Identity is owned by Ory Kratos. `getCurrentUser` reads the honeyDue-side
|
|
// profile from the Go API (authenticated via the Kratos session cookie);
|
|
// `logout` drives the Kratos browser logout flow.
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export function useCurrentUser() {
|
|
const { auth } = useDataProvider();
|
|
const qk = useQueryKeyPrefix();
|
|
return useQuery({
|
|
queryKey: qk('auth', 'user'),
|
|
queryFn: () => auth.getCurrentUser(),
|
|
retry: false,
|
|
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
});
|
|
}
|
|
|
|
export function useLogout() {
|
|
const queryClient = useQueryClient();
|
|
const router = useRouter();
|
|
const { auth, basePath } = useDataProvider();
|
|
|
|
return useMutation({
|
|
mutationFn: () => auth.logout(),
|
|
onSuccess: () => {
|
|
queryClient.clear();
|
|
// In demo mode there is no Kratos session — just route back to /demo.
|
|
// In real mode, auth.logout() already hands the browser off to the
|
|
// Kratos logout flow, so this router.push is only a fallback.
|
|
if (basePath.startsWith('/demo')) {
|
|
router.push('/demo');
|
|
}
|
|
},
|
|
});
|
|
}
|