feat: phase 1C JWT UI, events/hosts API, Vue frontend
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
const TOKEN_KEY = "sac_token";
|
||||
|
||||
export function getToken(): string | null {
|
||||
return localStorage.getItem(TOKEN_KEY);
|
||||
}
|
||||
|
||||
export function setToken(token: string): void {
|
||||
localStorage.setItem(TOKEN_KEY, token);
|
||||
}
|
||||
|
||||
export function clearToken(): void {
|
||||
localStorage.removeItem(TOKEN_KEY);
|
||||
}
|
||||
|
||||
export async function apiFetch<T>(path: string, init: RequestInit = {}): Promise<T> {
|
||||
const headers = new Headers(init.headers);
|
||||
if (!headers.has("Content-Type") && init.body) {
|
||||
headers.set("Content-Type", "application/json");
|
||||
}
|
||||
const token = getToken();
|
||||
if (token) {
|
||||
headers.set("Authorization", `Bearer ${token}`);
|
||||
}
|
||||
const res = await fetch(path, { ...init, headers });
|
||||
if (res.status === 401) {
|
||||
clearToken();
|
||||
window.location.href = "/login";
|
||||
throw new Error("Unauthorized");
|
||||
}
|
||||
if (!res.ok) {
|
||||
const text = await res.text();
|
||||
throw new Error(text || res.statusText);
|
||||
}
|
||||
return res.json() as Promise<T>;
|
||||
}
|
||||
|
||||
export interface TokenResponse {
|
||||
access_token: string;
|
||||
token_type: string;
|
||||
}
|
||||
|
||||
export interface EventSummary {
|
||||
id: number;
|
||||
event_id: string;
|
||||
host_id: number;
|
||||
hostname: string;
|
||||
occurred_at: string;
|
||||
received_at: string;
|
||||
category: string;
|
||||
type: string;
|
||||
severity: string;
|
||||
title: string;
|
||||
summary: string;
|
||||
}
|
||||
|
||||
export interface EventListResponse {
|
||||
items: EventSummary[];
|
||||
total: number;
|
||||
page: number;
|
||||
page_size: number;
|
||||
}
|
||||
|
||||
export interface EventDetail extends EventSummary {
|
||||
details: Record<string, unknown> | null;
|
||||
raw: Record<string, unknown> | null;
|
||||
payload: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface HostSummary {
|
||||
id: number;
|
||||
hostname: string;
|
||||
display_name: string | null;
|
||||
os_family: string;
|
||||
product: string;
|
||||
product_version: string | null;
|
||||
ipv4: string | null;
|
||||
last_seen_at: string;
|
||||
event_count: number | null;
|
||||
}
|
||||
|
||||
export interface HostListResponse {
|
||||
items: HostSummary[];
|
||||
total: number;
|
||||
page: number;
|
||||
page_size: number;
|
||||
}
|
||||
Reference in New Issue
Block a user