mirror of
https://github.com/AeThex-Corporation/AeThex-OS.git
synced 2026-04-23 08:27:21 +00:00
Introduces authentication via JWT, session management with CSRF protection, and new admin routes for managing users, projects, and monitoring security. Enhances dashboard and home pages with dynamic metrics fetched from the backend. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 279f1558-c0e3-40e4-8217-be7e9f4c6eca Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: dcd55177-c240-4288-8fc0-652032c758f2 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/b984cb14-1d19-4944-922b-bc79e821ed35/279f1558-c0e3-40e4-8217-be7e9f4c6eca/2riq6Ir Replit-Helium-Checkpoint-Created: true
89 lines
2.3 KiB
TypeScript
89 lines
2.3 KiB
TypeScript
import { createContext, useContext, useState, useEffect, ReactNode } from "react";
|
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
|
|
interface User {
|
|
id: string;
|
|
username: string;
|
|
isAdmin: boolean;
|
|
}
|
|
|
|
interface AuthContextType {
|
|
user: User | null;
|
|
isLoading: boolean;
|
|
isAuthenticated: boolean;
|
|
isAdmin: boolean;
|
|
login: (username: string, password: string) => Promise<void>;
|
|
logout: () => Promise<void>;
|
|
}
|
|
|
|
const AuthContext = createContext<AuthContextType | null>(null);
|
|
|
|
export function AuthProvider({ children }: { children: ReactNode }) {
|
|
const queryClient = useQueryClient();
|
|
|
|
const { data: session, isLoading } = useQuery({
|
|
queryKey: ["session"],
|
|
queryFn: async () => {
|
|
const res = await fetch("/api/auth/session");
|
|
return res.json();
|
|
},
|
|
});
|
|
|
|
const loginMutation = useMutation({
|
|
mutationFn: async ({ username, password }: { username: string; password: string }) => {
|
|
const res = await fetch("/api/auth/login", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ username, password }),
|
|
});
|
|
if (!res.ok) {
|
|
const data = await res.json();
|
|
throw new Error(data.error || "Login failed");
|
|
}
|
|
return res.json();
|
|
},
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ["session"] });
|
|
},
|
|
});
|
|
|
|
const logoutMutation = useMutation({
|
|
mutationFn: async () => {
|
|
await fetch("/api/auth/logout", { method: "POST" });
|
|
},
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ["session"] });
|
|
},
|
|
});
|
|
|
|
const login = async (username: string, password: string) => {
|
|
await loginMutation.mutateAsync({ username, password });
|
|
};
|
|
|
|
const logout = async () => {
|
|
await logoutMutation.mutateAsync();
|
|
};
|
|
|
|
const value: AuthContextType = {
|
|
user: session?.authenticated ? session.user : null,
|
|
isLoading,
|
|
isAuthenticated: !!session?.authenticated,
|
|
isAdmin: session?.user?.isAdmin || false,
|
|
login,
|
|
logout,
|
|
};
|
|
|
|
return (
|
|
<AuthContext.Provider value={value}>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useAuth() {
|
|
const context = useContext(AuthContext);
|
|
if (!context) {
|
|
throw new Error("useAuth must be used within an AuthProvider");
|
|
}
|
|
return context;
|
|
}
|