mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-05-19 11:08:47 +02:00
Add cookie-based SPA auth and update container plumbing
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>
This commit is contained in:
@@ -1,33 +1,40 @@
|
||||
import { createContext, useContext, useState, useEffect, type ReactNode } from 'react';
|
||||
import { createContext, useContext, useState, useEffect, type ReactNode } from "react";
|
||||
import { logout as apiLogout } from "@/lib/api";
|
||||
|
||||
interface AuthCtx {
|
||||
isAuthenticated: boolean;
|
||||
logout: () => void;
|
||||
isLoading: boolean;
|
||||
logout: () => Promise<void>;
|
||||
setAuthenticated: (v: boolean) => void;
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthCtx>({
|
||||
isAuthenticated: false,
|
||||
logout: () => {},
|
||||
isLoading: true,
|
||||
logout: async () => {},
|
||||
setAuthenticated: () => {},
|
||||
});
|
||||
|
||||
export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
const [isAuthenticated, setAuthenticated] = useState(!!localStorage.getItem('token'));
|
||||
const [isAuthenticated, setAuthenticated] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const check = () => setAuthenticated(!!localStorage.getItem('token'));
|
||||
window.addEventListener('storage', check);
|
||||
return () => window.removeEventListener('storage', check);
|
||||
// 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 = () => {
|
||||
localStorage.removeItem('token');
|
||||
const logout = async () => {
|
||||
await apiLogout();
|
||||
setAuthenticated(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ isAuthenticated, logout, setAuthenticated }}>
|
||||
<AuthContext.Provider value={{ isAuthenticated, isLoading, logout, setAuthenticated }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user