2026-03-25 09:27:12 +08:00
|
|
|
import { useEffect, useState } from "react";
|
2026-04-05 18:41:06 +08:00
|
|
|
import { formatHeaders } from "@/lib/api";
|
2026-03-22 11:19:41 +08:00
|
|
|
|
|
|
|
|
interface AuthState {
|
|
|
|
|
loading: boolean;
|
|
|
|
|
authEnabled: boolean;
|
|
|
|
|
isAuthenticated: boolean;
|
2026-03-28 14:02:07 +08:00
|
|
|
mustChangePassword: boolean;
|
2026-04-06 15:48:51 +08:00
|
|
|
role: string | null;
|
|
|
|
|
permissions: string[];
|
2026-03-22 11:19:41 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-10 21:25:03 +08:00
|
|
|
const ALL_PERMISSIONS = [
|
|
|
|
|
"tools:use",
|
|
|
|
|
"files:own",
|
|
|
|
|
"files:all",
|
|
|
|
|
"apikeys:own",
|
|
|
|
|
"apikeys:all",
|
|
|
|
|
"pipelines:own",
|
|
|
|
|
"pipelines:all",
|
|
|
|
|
"settings:read",
|
|
|
|
|
"settings:write",
|
|
|
|
|
"users:manage",
|
|
|
|
|
"teams:manage",
|
|
|
|
|
"branding:manage",
|
|
|
|
|
];
|
|
|
|
|
|
2026-04-06 15:48:51 +08:00
|
|
|
export function useAuth() {
|
2026-03-22 11:19:41 +08:00
|
|
|
const [state, setState] = useState<AuthState>({
|
|
|
|
|
loading: true,
|
|
|
|
|
authEnabled: false,
|
|
|
|
|
isAuthenticated: false,
|
2026-03-28 14:02:07 +08:00
|
|
|
mustChangePassword: false,
|
2026-04-06 15:48:51 +08:00
|
|
|
role: null,
|
|
|
|
|
permissions: [],
|
2026-03-22 11:19:41 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2026-03-25 22:12:55 +08:00
|
|
|
async function checkAuth() {
|
|
|
|
|
try {
|
|
|
|
|
// Check if auth is enabled
|
|
|
|
|
const configRes = await fetch("/api/v1/config/auth");
|
|
|
|
|
const config = await configRes.json();
|
2026-03-22 11:19:41 +08:00
|
|
|
|
2026-03-25 22:12:55 +08:00
|
|
|
if (!config.authEnabled) {
|
2026-03-28 14:02:07 +08:00
|
|
|
setState({
|
|
|
|
|
loading: false,
|
|
|
|
|
authEnabled: false,
|
|
|
|
|
isAuthenticated: true,
|
|
|
|
|
mustChangePassword: false,
|
2026-04-06 15:48:51 +08:00
|
|
|
role: "admin",
|
2026-04-10 21:25:03 +08:00
|
|
|
permissions: ALL_PERMISSIONS,
|
2026-03-28 14:02:07 +08:00
|
|
|
});
|
2026-03-25 22:12:55 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2026-03-22 11:19:41 +08:00
|
|
|
|
2026-03-25 22:12:55 +08:00
|
|
|
// Auth is enabled — check if we have a valid session
|
|
|
|
|
const token = localStorage.getItem("stirling-token");
|
|
|
|
|
if (!token) {
|
2026-03-28 14:02:07 +08:00
|
|
|
setState({
|
|
|
|
|
loading: false,
|
|
|
|
|
authEnabled: true,
|
|
|
|
|
isAuthenticated: false,
|
|
|
|
|
mustChangePassword: false,
|
2026-04-06 15:48:51 +08:00
|
|
|
role: null,
|
|
|
|
|
permissions: [],
|
2026-03-28 14:02:07 +08:00
|
|
|
});
|
2026-03-25 22:12:55 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const sessionRes = await fetch("/api/auth/session", {
|
2026-04-05 18:41:06 +08:00
|
|
|
headers: formatHeaders(),
|
2026-03-25 22:12:55 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (sessionRes.ok) {
|
2026-03-28 14:02:07 +08:00
|
|
|
const session = await sessionRes.json();
|
|
|
|
|
const mustChange = session.user?.mustChangePassword === true;
|
|
|
|
|
setState({
|
|
|
|
|
loading: false,
|
|
|
|
|
authEnabled: true,
|
|
|
|
|
isAuthenticated: true,
|
|
|
|
|
mustChangePassword: mustChange,
|
2026-04-06 15:48:51 +08:00
|
|
|
role: session.user?.role ?? null,
|
|
|
|
|
permissions: session.user?.permissions ?? [],
|
2026-03-28 14:02:07 +08:00
|
|
|
});
|
2026-03-25 22:12:55 +08:00
|
|
|
} else {
|
|
|
|
|
localStorage.removeItem("stirling-token");
|
2026-03-28 14:02:07 +08:00
|
|
|
setState({
|
|
|
|
|
loading: false,
|
|
|
|
|
authEnabled: true,
|
|
|
|
|
isAuthenticated: false,
|
|
|
|
|
mustChangePassword: false,
|
2026-04-06 15:48:51 +08:00
|
|
|
role: null,
|
|
|
|
|
permissions: [],
|
2026-03-28 14:02:07 +08:00
|
|
|
});
|
2026-03-25 22:12:55 +08:00
|
|
|
}
|
|
|
|
|
} catch {
|
|
|
|
|
// Can't reach API — assume no auth needed (dev mode)
|
2026-03-28 14:02:07 +08:00
|
|
|
setState({
|
|
|
|
|
loading: false,
|
|
|
|
|
authEnabled: false,
|
|
|
|
|
isAuthenticated: true,
|
|
|
|
|
mustChangePassword: false,
|
2026-04-06 15:48:51 +08:00
|
|
|
role: "admin",
|
2026-04-10 21:25:03 +08:00
|
|
|
permissions: ALL_PERMISSIONS,
|
2026-03-28 14:02:07 +08:00
|
|
|
});
|
2026-03-22 11:19:41 +08:00
|
|
|
}
|
|
|
|
|
}
|
2026-03-25 22:12:55 +08:00
|
|
|
|
|
|
|
|
checkAuth();
|
|
|
|
|
}, []);
|
2026-03-22 11:19:41 +08:00
|
|
|
|
2026-04-06 15:48:51 +08:00
|
|
|
const hasPermission = (permission: string) => state.permissions.includes(permission);
|
|
|
|
|
|
|
|
|
|
return { ...state, hasPermission };
|
2026-03-22 11:19:41 +08:00
|
|
|
}
|