46 lines
2.7 KiB
TypeScript
46 lines
2.7 KiB
TypeScript
export interface Status {
|
|
version: string; node_id: string; name: string;
|
|
host: {
|
|
collected_at: string; hostname: string; os: string; architecture: string; cpus: number;
|
|
memory_kib: number | null; available_kib: number | null;
|
|
networks: { name: string; up: boolean; addresses: string[]; addresses_readable: boolean }[];
|
|
networks_readable: boolean;
|
|
usb: { port: string; vendor: string; product_id: string; product: string; speed_mbps: string }[];
|
|
usb_readable: boolean; warnings: string[];
|
|
};
|
|
}
|
|
|
|
export class APIError extends Error { constructor(message: string, public status: number) { super(message); } }
|
|
export type DesktopAction = "authorize" | "install-tailscale" | "connect-tailscale" | "configure-system";
|
|
export function environmentSetupAvailable(): boolean {
|
|
return (window as Window & { missionCoreDesktop?: { environmentSetup?: boolean } }).missionCoreDesktop?.environmentSetup === true;
|
|
}
|
|
export function networkSetupAvailable(): boolean {
|
|
return (window as Window & { missionCoreDesktop?: { networkSetup?: boolean } }).missionCoreDesktop?.networkSetup === true;
|
|
}
|
|
export function desktopAction(action: DesktopAction): boolean {
|
|
if (action === "configure-system" ? !environmentSetupAvailable() : action !== "authorize" && !networkSetupAvailable()) return false;
|
|
const host = window as Window & { webkit?: { messageHandlers?: { node?: { postMessage: (message: string) => void } } } };
|
|
const channel = host.webkit?.messageHandlers?.node;
|
|
if (!channel) return false;
|
|
channel.postMessage(action);
|
|
return true;
|
|
}
|
|
export function desktopLogin(): boolean { return desktopAction("authorize"); }
|
|
export async function request<T>(path: string, method = "GET", body?: unknown): Promise<T> {
|
|
const res = await fetch(path, { method, credentials: "same-origin", cache: "no-store", headers: body === undefined ? {} : {"Content-Type": "application/json"}, body: body === undefined ? undefined : JSON.stringify(body), signal: AbortSignal.timeout(10000) }).catch(() => { throw new Error("БК не ответил вовремя. Обновите сведения; действие могло продолжиться на борту."); });
|
|
if (!res.ok) {
|
|
const error = await res.json().catch(() => ({}));
|
|
throw new APIError(error.error ?? "Не удалось выполнить запрос к ноде", res.status);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
export async function loginFromLaunch(): Promise<void> {
|
|
const params = new URLSearchParams(location.hash.slice(1));
|
|
const token = params.get("login");
|
|
// Remove the one-use credential from history before any asynchronous work.
|
|
if (location.hash) history.replaceState(null, "", location.pathname);
|
|
if (token) await request("/api/session", "POST", { token });
|
|
}
|