2f0597c81b
Includes c2-core (FastAPI/MQTT/Firestore), discord-bot (slash commands), frontend (Next.js admin UI), and mosquitto config.
59 lines
2.1 KiB
TypeScript
59 lines
2.1 KiB
TypeScript
import { auth } from "@/lib/firebase";
|
|
|
|
const BASE = process.env.NEXT_PUBLIC_C2_URL ?? "http://localhost:8000";
|
|
|
|
async function request<T>(path: string, options?: RequestInit): Promise<T> {
|
|
const user = auth.currentUser;
|
|
const token = user ? await user.getIdToken() : null;
|
|
|
|
const res = await fetch(`${BASE}${path}`, {
|
|
...options,
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
...(options?.headers as Record<string, string> | undefined),
|
|
},
|
|
});
|
|
if (!res.ok) throw new Error(`C2 API error ${res.status}: ${await res.text()}`);
|
|
if (res.status === 204) return undefined as T;
|
|
return res.json();
|
|
}
|
|
|
|
export const c2api = {
|
|
// Nodes
|
|
getNodes: () => request<unknown[]>("/nodes"),
|
|
getNode: (id: string) => request<unknown>(`/nodes/${id}`),
|
|
sendCommand: (nodeId: string, payload: object) =>
|
|
request(`/nodes/${nodeId}/command`, { method: "POST", body: JSON.stringify(payload) }),
|
|
assignSystem: (nodeId: string, systemId: string) =>
|
|
request(`/nodes/${nodeId}/config/${systemId}`, { method: "POST" }),
|
|
|
|
// Systems
|
|
getSystems: () => request<unknown[]>("/systems"),
|
|
createSystem: (body: object) =>
|
|
request("/systems", { method: "POST", body: JSON.stringify(body) }),
|
|
updateSystem: (id: string, body: object) =>
|
|
request(`/systems/${id}`, { method: "PUT", body: JSON.stringify(body) }),
|
|
deleteSystem: (id: string) =>
|
|
request(`/systems/${id}`, { method: "DELETE" }),
|
|
|
|
// Tokens
|
|
getTokens: () => request<unknown[]>("/tokens"),
|
|
addToken: (body: { name: string; token: string }) =>
|
|
request("/tokens", { method: "POST", body: JSON.stringify(body) }),
|
|
deleteToken: (id: string) =>
|
|
request(`/tokens/${id}`, { method: "DELETE" }),
|
|
|
|
// Node approval
|
|
approveNode: (id: string) =>
|
|
request(`/nodes/${id}/approve`, { method: "POST" }),
|
|
rejectNode: (id: string) =>
|
|
request(`/nodes/${id}/reject`, { method: "POST" }),
|
|
|
|
// Calls
|
|
getCalls: (params?: Record<string, string>) => {
|
|
const qs = params ? "?" + new URLSearchParams(params).toString() : "";
|
|
return request<unknown[]>(`/calls${qs}`);
|
|
},
|
|
};
|