Files
sloth-manager/frontend/src/api/dns.js
T
2026-06-02 01:00:27 +02:00

220 lines
7.9 KiB
JavaScript

const BASE = (process.env.REACT_APP_API_URL || 'http://localhost:3001') + '/api';
export function getToken() {
return localStorage.getItem('dns_token');
}
export function setToken(token) {
if (token) localStorage.setItem('dns_token', token);
else localStorage.removeItem('dns_token');
}
function authHeaders() {
const token = getToken();
return token ? { Authorization: `Bearer ${token}` } : {};
}
async function handleResponse(res) {
if (res.status === 401) {
setToken(null);
window.dispatchEvent(new Event('auth:logout'));
throw new Error('Session expired — please log in again');
}
if (!res.ok) {
const body = await res.json().catch(() => ({}));
throw new Error(body.error || `HTTP ${res.status} ${res.statusText}`);
}
return res.json();
}
// ─── Auth ─────────────────────────────────────────────────────────────────────
export async function login(username, password) {
const res = await fetch(`${BASE}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password }),
});
return handleResponse(res);
}
export async function getMe() {
return handleResponse(await fetch(`${BASE}/auth/me`, { headers: authHeaders() }));
}
export async function changePassword(currentPassword, newPassword) {
return handleResponse(await fetch(`${BASE}/auth/change-password`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify({ currentPassword, newPassword }),
}));
}
// ─── Users ────────────────────────────────────────────────────────────────────
export async function getUsers() {
return handleResponse(await fetch(`${BASE}/users`, { headers: authHeaders() }));
}
export async function createUser(username, password) {
return handleResponse(await fetch(`${BASE}/users`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify({ username, password }),
}));
}
export async function deleteUser(id) {
return handleResponse(await fetch(`${BASE}/users/${id}`, {
method: 'DELETE', headers: authHeaders(),
}));
}
export async function resetUserPassword(id, newPassword) {
return handleResponse(await fetch(`${BASE}/users/${id}/password`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify({ newPassword }),
}));
}
// ─── IPAM ─────────────────────────────────────────────────────────────────────
export async function getIpam() {
return handleResponse(await fetch(`${BASE}/ipam`, { headers: authHeaders() }));
}
export async function createIpEntry(data) {
return handleResponse(await fetch(`${BASE}/ipam`, {
method: 'POST', headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify(data),
}));
}
export async function updateIpEntry(id, data) {
return handleResponse(await fetch(`${BASE}/ipam/${id}`, {
method: 'PUT', headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify(data),
}));
}
export async function deleteIpEntry(id) {
return handleResponse(await fetch(`${BASE}/ipam/${id}`, {
method: 'DELETE', headers: authHeaders(),
}));
}
// ─── Secrets ──────────────────────────────────────────────────────────────────
export async function getSecrets() {
return handleResponse(await fetch(`${BASE}/secrets`, { headers: authHeaders() }));
}
export async function createSecret(data) {
return handleResponse(await fetch(`${BASE}/secrets`, {
method: 'POST', headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify(data),
}));
}
export async function updateSecret(id, data) {
return handleResponse(await fetch(`${BASE}/secrets/${id}`, {
method: 'PUT', headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify(data),
}));
}
export async function deleteSecret(id) {
return handleResponse(await fetch(`${BASE}/secrets/${id}`, {
method: 'DELETE', headers: authHeaders(),
}));
}
export async function getAuditLog({ limit, offset, user, action, provider, category } = {}) {
const qs = new URLSearchParams();
if (limit) qs.set('limit', limit);
if (offset) qs.set('offset', offset);
if (user) qs.set('user', user);
if (action) qs.set('action', action);
if (provider) qs.set('provider', provider);
if (category) qs.set('category', category);
return handleResponse(await fetch(`${BASE}/audit?${qs}`, { headers: authHeaders() }));
}
export async function getProviderHealth() {
return handleResponse(await fetch(`${BASE}/health/providers`, { headers: authHeaders() }));
}
export async function getProviders() {
return handleResponse(await fetch(`${BASE}/providers`, { headers: authHeaders() }));
}
export async function getStats() {
return handleResponse(await fetch(`${BASE}/stats`, { headers: authHeaders() }));
}
export async function getAllDomains() {
return handleResponse(await fetch(`${BASE}/domains`, { headers: authHeaders() }));
}
export async function getSettings() {
return handleResponse(await fetch(`${BASE}/settings`, { headers: authHeaders() }));
}
export async function saveSettings(settings) {
return handleResponse(await fetch(`${BASE}/settings`, {
method: 'PUT', headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify(settings),
}));
}
export async function clearCache() {
return handleResponse(await fetch(`${BASE}/settings/clear-cache`, { method: 'POST', headers: authHeaders() }));
}
export async function testNotification(gotify) {
return handleResponse(await fetch(`${BASE}/settings/test-notification`, {
method: 'POST', headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify(gotify),
}));
}
export async function getSyncStatus(provider) {
return handleResponse(await fetch(`${BASE}/sync-status/${provider}`, { headers: authHeaders() }));
}
export async function getZones(provider) {
return handleResponse(await fetch(`${BASE}/zones/${provider}`, { headers: authHeaders() }));
}
export async function getRecords(provider, zoneId) {
return handleResponse(await fetch(`${BASE}/records/${provider}/${encodeURIComponent(zoneId)}`, { headers: authHeaders() }));
}
export async function syncRecords(provider, zoneId, zoneName) {
return handleResponse(await fetch(`${BASE}/records/sync/${provider}/${encodeURIComponent(zoneId)}`, {
method: 'POST', headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify({ zoneName }),
}));
}
export async function addRecord(provider, zoneId, record) {
return handleResponse(await fetch(`${BASE}/records/${provider}/${encodeURIComponent(zoneId)}`, {
method: 'POST', headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify(record),
}));
}
export async function updateRecord(provider, zoneId, recordId, record) {
return handleResponse(await fetch(`${BASE}/records/${provider}/${encodeURIComponent(zoneId)}/${encodeURIComponent(recordId)}`, {
method: 'PUT', headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify(record),
}));
}
export async function deleteRecord(provider, zoneId, recordId) {
return handleResponse(await fetch(`${BASE}/records/${provider}/${encodeURIComponent(zoneId)}/${encodeURIComponent(recordId)}`, {
method: 'DELETE', headers: authHeaders(),
}));
}