Files
Agentic-OS/frontend/lib/auth.tsx
nearxos 6185b9b85a Initial commit: Agentic OS troubleshooting platform
Self-hosted, Docker-based agentic troubleshooting platform: FastAPI backend +
LangGraph agent, Next.js UI, tiered LLM routing (local Ollama -> Gemini ->
DeepSeek -> OpenRouter), MCP server manager, encrypted device credentials,
RBAC, audit log, project-memory + Obsidian integrations, and editable
troubleshooting decision rules tuned for the GeneseasX vessel stack.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 22:11:07 +03:00

76 lines
1.8 KiB
TypeScript

"use client";
import { createContext, useCallback, useContext, useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { api, login as apiLogin, setToken, getToken } from "./api";
type Me = {
id: number;
email: string;
full_name: string | null;
role: "admin" | "support" | "readonly";
is_active: boolean;
};
type AuthCtx = {
user: Me | null;
loading: boolean;
login: (email: string, password: string) => Promise<void>;
logout: () => void;
};
const Ctx = createContext<AuthCtx>({
user: null,
loading: true,
login: async () => {},
logout: () => {},
});
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<Me | null>(null);
const [loading, setLoading] = useState(true);
const router = useRouter();
const loadMe = useCallback(async () => {
if (!getToken()) {
setUser(null);
setLoading(false);
return;
}
try {
const me = await api<Me>("/api/auth/me");
setUser(me);
} catch {
setUser(null);
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
loadMe();
}, [loadMe]);
const login = async (email: string, password: string) => {
const res = await apiLogin(email, password);
setToken(res.access_token);
await loadMe();
router.push("/");
};
const logout = () => {
setToken(null);
setUser(null);
router.push("/login");
};
return <Ctx.Provider value={{ user, loading, login, logout }}>{children}</Ctx.Provider>;
}
export const useAuth = () => useContext(Ctx);
export function roleAtLeast(role: string | undefined, min: "readonly" | "support" | "admin") {
const rank: Record<string, number> = { readonly: 0, support: 1, admin: 2 };
return (rank[role || "readonly"] ?? 0) >= rank[min];
}