Some checks failed
Build and Deploy MITM Webserver / build (push) Failing after 3s
230 lines
6.3 KiB
TypeScript
230 lines
6.3 KiB
TypeScript
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
|
import { useCallback, useState } from 'react';
|
|
|
|
import * as api from '../api/apiClient';
|
|
import type {
|
|
BridgeCreateRequest,
|
|
BridgeInfo,
|
|
BridgeRemoveRequest,
|
|
FullState,
|
|
InterfaceInfo,
|
|
RouteInfo,
|
|
} from '../types/network';
|
|
import { SnifferStatusResponse } from '../types/sniffer';
|
|
|
|
const TEN_SECONDS = 1000 * 10;
|
|
const FIVE_SECONDS = 1000 * 5;
|
|
|
|
export function useBackendAPI() {
|
|
const queryClient = useQueryClient();
|
|
|
|
const [interfacesEnabled, setInterfacesEnabled] = useState(false);
|
|
const [linksEnabled, setLinksEnabled] = useState(false);
|
|
const [routesEnabled, setRoutesEnabled] = useState(false);
|
|
const [bridgesEnabled, setBridgesEnabled] = useState(false);
|
|
const [fullStateEnabled, setFullStateEnabled] = useState(false);
|
|
const [snifferStatusEnabled, setSnifferStatusEnabled] = useState(false);
|
|
|
|
const commonOptions = {
|
|
refetchOnWindowFocus: true,
|
|
staleTime: TEN_SECONDS,
|
|
};
|
|
|
|
const interfacesQuery = useQuery<InterfaceInfo[]>({
|
|
queryKey: ['interfaces'],
|
|
queryFn: api.fetchInterfaces,
|
|
enabled: interfacesEnabled,
|
|
...commonOptions,
|
|
});
|
|
|
|
const linksQuery = useQuery<InterfaceInfo[]>({
|
|
queryKey: ['links'],
|
|
queryFn: api.fetchLinks,
|
|
enabled: linksEnabled,
|
|
...commonOptions,
|
|
});
|
|
|
|
const routesQuery = useQuery<RouteInfo[]>({
|
|
queryKey: ['routes'],
|
|
queryFn: api.fetchRoutes,
|
|
enabled: routesEnabled,
|
|
...commonOptions,
|
|
});
|
|
|
|
const bridgesQuery = useQuery<BridgeInfo[]>({
|
|
queryKey: ['bridges'],
|
|
queryFn: api.fetchBridges,
|
|
enabled: bridgesEnabled,
|
|
...commonOptions,
|
|
});
|
|
|
|
const fullStateQuery = useQuery<FullState>({
|
|
queryKey: ['full-state'],
|
|
queryFn: api.fetchFullState,
|
|
enabled: fullStateEnabled,
|
|
...commonOptions,
|
|
});
|
|
|
|
const snifferStatusQuery = useQuery<SnifferStatusResponse>({
|
|
queryKey: ['sniffer-status'],
|
|
queryFn: api.fetchSnifferStatus,
|
|
enabled: snifferStatusEnabled,
|
|
...commonOptions,
|
|
});
|
|
|
|
const fetchInterfaces = useCallback(async () => {
|
|
const result = await queryClient.fetchQuery<InterfaceInfo[]>({
|
|
queryKey: ['interfaces'],
|
|
queryFn: api.fetchInterfaces,
|
|
staleTime: TEN_SECONDS,
|
|
});
|
|
setInterfacesEnabled(true);
|
|
return result;
|
|
}, [queryClient]);
|
|
|
|
const fetchLinks = useCallback(async () => {
|
|
const result = await queryClient.fetchQuery<InterfaceInfo[]>({
|
|
queryKey: ['links'],
|
|
queryFn: api.fetchLinks,
|
|
staleTime: TEN_SECONDS,
|
|
});
|
|
setLinksEnabled(true);
|
|
return result;
|
|
}, [queryClient]);
|
|
|
|
const fetchRoutes = useCallback(async () => {
|
|
const result = await queryClient.fetchQuery<RouteInfo[]>({
|
|
queryKey: ['routes'],
|
|
queryFn: api.fetchRoutes,
|
|
staleTime: TEN_SECONDS,
|
|
});
|
|
setRoutesEnabled(true);
|
|
return result;
|
|
}, [queryClient]);
|
|
|
|
const fetchBridges = useCallback(async () => {
|
|
const result = await queryClient.fetchQuery<BridgeInfo[]>({
|
|
queryKey: ['bridges'],
|
|
queryFn: api.fetchBridges,
|
|
staleTime: TEN_SECONDS,
|
|
});
|
|
setBridgesEnabled(true);
|
|
return result;
|
|
}, [queryClient]);
|
|
|
|
const fetchFullState = useCallback(async () => {
|
|
const result = await queryClient.fetchQuery<FullState>({
|
|
queryKey: ['full-state'],
|
|
queryFn: api.fetchFullState,
|
|
staleTime: FIVE_SECONDS,
|
|
});
|
|
setFullStateEnabled(true);
|
|
return result;
|
|
}, [queryClient]);
|
|
|
|
const fetchSnifferStatus = useCallback(async () => {
|
|
const result = await queryClient.fetchQuery<SnifferStatusResponse>({
|
|
queryKey: ['sniffer-status'],
|
|
queryFn: api.fetchSnifferStatus,
|
|
staleTime: FIVE_SECONDS,
|
|
});
|
|
setSnifferStatusEnabled(true);
|
|
return result;
|
|
}, [queryClient]);
|
|
|
|
const [isCreating, setIsCreating] = useState(false);
|
|
const [isRemoving, setIsRemoving] = useState(false);
|
|
|
|
async function createBridge(payload: BridgeCreateRequest) {
|
|
setIsCreating(true);
|
|
try {
|
|
await api.createBridge(payload);
|
|
await queryClient.invalidateQueries({ queryKey: ['bridges'] });
|
|
await queryClient.invalidateQueries({ queryKey: ['full-state'] });
|
|
await queryClient.invalidateQueries({ queryKey: ['interfaces'] });
|
|
} catch (error) {
|
|
const message =
|
|
error instanceof Error ? error.message : typeof error === 'string' ? error : 'Create bridge failed';
|
|
throw new Error(message);
|
|
} finally {
|
|
setIsCreating(false);
|
|
}
|
|
}
|
|
|
|
async function removeBridge(payload: BridgeRemoveRequest) {
|
|
setIsRemoving(true);
|
|
try {
|
|
await api.removeBridge(payload);
|
|
await queryClient.invalidateQueries({ queryKey: ['bridges'] });
|
|
await queryClient.invalidateQueries({ queryKey: ['full-state'] });
|
|
await queryClient.invalidateQueries({ queryKey: ['interfaces'] });
|
|
await queryClient.invalidateQueries({ queryKey: ['sniffer-status'] });
|
|
} catch (error) {
|
|
const message =
|
|
error instanceof Error ? error.message : typeof error === 'string' ? error : 'Remove bridge failed';
|
|
throw new Error(message);
|
|
} finally {
|
|
setIsRemoving(false);
|
|
}
|
|
}
|
|
|
|
function refreshInterfaces() {
|
|
return queryClient.invalidateQueries({ queryKey: ['interfaces'] });
|
|
}
|
|
|
|
function refreshLinks() {
|
|
return queryClient.invalidateQueries({ queryKey: ['links'] });
|
|
}
|
|
|
|
function refreshRoutes() {
|
|
return queryClient.invalidateQueries({ queryKey: ['routes'] });
|
|
}
|
|
|
|
function refreshBridges() {
|
|
return queryClient.invalidateQueries({ queryKey: ['bridges'] });
|
|
}
|
|
|
|
function refreshFullState() {
|
|
return queryClient.invalidateQueries({ queryKey: ['full-state'] });
|
|
}
|
|
|
|
function refreshSnifferStatus() {
|
|
return queryClient.invalidateQueries({ queryKey: ['sniffer-status'] });
|
|
}
|
|
|
|
function refreshAll() {
|
|
refreshInterfaces();
|
|
refreshLinks();
|
|
refreshRoutes();
|
|
refreshBridges();
|
|
refreshFullState();
|
|
refreshSnifferStatus();
|
|
}
|
|
|
|
return {
|
|
interfacesQuery,
|
|
linksQuery,
|
|
routesQuery,
|
|
bridgesQuery,
|
|
fullStateQuery,
|
|
snifferStatusQuery,
|
|
fetchInterfaces,
|
|
fetchLinks,
|
|
fetchRoutes,
|
|
fetchBridges,
|
|
fetchFullState,
|
|
fetchSnifferStatus,
|
|
createBridge,
|
|
removeBridge,
|
|
isCreating,
|
|
isRemoving,
|
|
refreshInterfaces,
|
|
refreshLinks,
|
|
refreshRoutes,
|
|
refreshBridges,
|
|
refreshFullState,
|
|
refreshSnifferStatus,
|
|
refreshAll,
|
|
};
|
|
}
|