feat(auth): centralized api client with Authorization header

This commit is contained in:
2026-08-06 16:30:20 +00:00
parent 60d8835e99
commit 133f059f13
+46 -14
View File
@@ -1,27 +1,59 @@
import type { NetObject, ServiceInfo } from '../types';
import { getToken, clearSession } from './session';
import type { ServiceInfo } from '../types';
const AGENT_BASE = '/api';
const BACKEND = '/backend';
const AGENT = '/api';
export async function fetchObjects(): Promise<NetObject[]> {
return [
{ id: '1', name: 'Site HQ', slug: 'site-hq', type: 'site', status: 'active' },
{ id: '2', name: 'Rack A', slug: 'rack-a', type: 'rack', status: 'active' },
{ id: '3', name: 'Server Proxmox', slug: 'server-proxmox', type: 'physical_host', vendor: 'Dell', model: 'R730', status: 'active' },
{ id: '4', name: 'Switch Core', slug: 'switch-core', type: 'switch', vendor: 'Mikrotik', status: 'active' },
{ id: '5', name: 'Firewall Edge', slug: 'firewall-edge', type: 'firewall', status: 'active' },
];
export async function apiFetch(path: string, init: RequestInit = {}): Promise<Response> {
const token = getToken();
const headers: Record<string, string> = {
'Content-Type': 'application/json',
...(init.headers as Record<string, string> ?? {}),
};
if (token) headers['Authorization'] = `Bearer ${token}`;
const res = await fetch(`${BACKEND}${path}`, { ...init, headers });
if (res.status === 401) { clearSession(); window.location.reload(); }
return res;
}
export async function apiGet<T>(path: string): Promise<T> {
const res = await apiFetch(path);
if (!res.ok) throw new Error(`GET ${path} failed: ${res.status}`);
return res.json();
}
export async function apiPost<T>(path: string, body?: unknown): Promise<T> {
const res = await apiFetch(path, { method: 'POST', body: body ? JSON.stringify(body) : undefined });
if (!res.ok) {
const err = await res.json().catch(() => null);
throw new Error(err?.detail ?? `POST ${path} failed: ${res.status}`);
}
return res.json();
}
export async function apiPatch<T>(path: string, body?: unknown): Promise<T> {
const res = await apiFetch(path, { method: 'PATCH', body: body ? JSON.stringify(body) : undefined });
if (!res.ok) {
const err = await res.json().catch(() => null);
throw new Error(err?.detail ?? `PATCH ${path} failed: ${res.status}`);
}
return res.json();
}
export async function apiDelete(path: string): Promise<void> {
const res = await apiFetch(path, { method: 'DELETE' });
if (!res.ok) throw new Error(`DELETE ${path} failed: ${res.status}`);
}
// Legacy agent calls (unauthenticated local agent)
export async function fetchServices(): Promise<ServiceInfo[]> {
const res = await fetch(`${AGENT_BASE}/services`);
const res = await fetch(`${AGENT}/services`);
if (!res.ok) throw new Error('Impossibile leggere lo stato dei servizi');
return res.json();
}
export async function serviceAction(name: string, action: 'start' | 'stop' | 'restart') {
const res = await fetch(`${AGENT_BASE}/services/${encodeURIComponent(name)}/${action}`, {
method: 'POST',
});
const res = await fetch(`${AGENT}/services/${encodeURIComponent(name)}/${action}`, { method: 'POST' });
if (!res.ok) throw new Error(`Azione ${action} fallita su ${name}`);
return res.json();
}