mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-05-19 08:28:48 +02:00
Backend now exposes /api/auth/login + /api/auth/logout setting an httpOnly ws_token cookie, and get_current_user accepts either the cookie (SPA) or a Bearer token (n8n/CLI). AuthContext probes the cookie via /api/v1/auth/me. Dockerfiles and compose files updated for the new agent service deps and CopilotKit dev sidecar. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
44 lines
1.2 KiB
TypeScript
44 lines
1.2 KiB
TypeScript
import { createContext, useContext, useState, useEffect, type ReactNode } from "react";
|
|
import { logout as apiLogout } from "@/lib/api";
|
|
|
|
interface AuthCtx {
|
|
isAuthenticated: boolean;
|
|
isLoading: boolean;
|
|
logout: () => Promise<void>;
|
|
setAuthenticated: (v: boolean) => void;
|
|
}
|
|
|
|
const AuthContext = createContext<AuthCtx>({
|
|
isAuthenticated: false,
|
|
isLoading: true,
|
|
logout: async () => {},
|
|
setAuthenticated: () => {},
|
|
});
|
|
|
|
export function AuthProvider({ children }: { children: ReactNode }) {
|
|
const [isAuthenticated, setAuthenticated] = useState(false);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
// Probe auth state by hitting a protected endpoint.
|
|
// If the ws_token cookie is valid, the server returns 200; else 401.
|
|
fetch("/api/v1/auth/me", { credentials: "include" })
|
|
.then((r) => setAuthenticated(r.ok))
|
|
.catch(() => setAuthenticated(false))
|
|
.finally(() => setIsLoading(false));
|
|
}, []);
|
|
|
|
const logout = async () => {
|
|
await apiLogout();
|
|
setAuthenticated(false);
|
|
};
|
|
|
|
return (
|
|
<AuthContext.Provider value={{ isAuthenticated, isLoading, logout, setAuthenticated }}>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
}
|
|
|
|
export const useAuth = () => useContext(AuthContext);
|