mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 20:30:45 +08:00
feat(auth): add local login, audit, API keys, and system admin UI
Gate netx Web/API/WebCRT with JWT and per-user API tokens, bootstrap an admin with forced password change, and expose users/audit/API-key management under a System section. MCP can reuse data/auth/mcp_token without extra env for local labs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
14f14d34bd
commit
6d4cd741ef
35 changed files with 2699 additions and 21 deletions
|
|
@ -8,16 +8,38 @@ import { NePage } from "./pages/NePage";
|
|||
import { UmePage } from "./pages/UmePage";
|
||||
import { WebcrtPage } from "./pages/WebcrtPage";
|
||||
import { TopologyPage } from "./pages/TopologyPage";
|
||||
import { LoginPage } from "./pages/LoginPage";
|
||||
import { UsersPage } from "./pages/UsersPage";
|
||||
import { AuditPage } from "./pages/AuditPage";
|
||||
import { ApiTokensPage } from "./pages/ApiTokensPage";
|
||||
import { ForceChangePasswordPage } from "./pages/ForceChangePasswordPage";
|
||||
import { fetchIntegrationStatus } from "./services/api";
|
||||
import { useAuth } from "./auth/AuthContext";
|
||||
|
||||
function App() {
|
||||
function ProtectedApp() {
|
||||
const { ready, user } = useAuth();
|
||||
const integrationsQuery = useQuery({
|
||||
queryKey: queryKeys.integrationsStatus,
|
||||
queryFn: fetchIntegrationStatus,
|
||||
refetchInterval: 5000,
|
||||
staleTime: 2000,
|
||||
enabled: ready && Boolean(user) && !user?.must_change_password,
|
||||
});
|
||||
|
||||
if (!ready) {
|
||||
return (
|
||||
<div className="login-page">
|
||||
<div className="login-card">Loading…</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (!user) {
|
||||
return <Navigate to="/login" replace />;
|
||||
}
|
||||
if (user.must_change_password) {
|
||||
return <ForceChangePasswordPage />;
|
||||
}
|
||||
|
||||
return (
|
||||
<AppLayout
|
||||
connections={{
|
||||
|
|
@ -53,10 +75,22 @@ function App() {
|
|||
<Route path="/collect" element={<CollectPage />} />
|
||||
<Route path="/webcrt" element={<WebcrtPage />} />
|
||||
<Route path="/topology" element={<TopologyPage />} />
|
||||
<Route path="/users" element={<UsersPage />} />
|
||||
<Route path="/audit" element={<AuditPage />} />
|
||||
<Route path="/api-keys" element={<ApiTokensPage />} />
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
</AppLayout>
|
||||
);
|
||||
}
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/*" element={<ProtectedApp />} />
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue