fix: address code review findings for DNS management
- CRITICAL: Change DNS zones endpoint from GET to POST to avoid leaking API token in URL query parameters - HIGH: Add sync.RWMutex to protect dnsProvider field in Server, Deployer, and proxy Manager against concurrent read/write races - HIGH: Capture old DNS provider reference synchronously before launching background cleanup goroutine - HIGH: Use getDNS()/getDNSProviderLocked() accessors instead of direct field reads in all DNS operations
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
const TOKEN_KEY = "auth_token";
|
||||
function getAuthToken() {
|
||||
if (typeof localStorage !== "undefined") {
|
||||
return localStorage.getItem(TOKEN_KEY);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function clearAuth() {
|
||||
if (typeof localStorage !== "undefined") {
|
||||
localStorage.removeItem(TOKEN_KEY);
|
||||
}
|
||||
}
|
||||
class ApiError extends Error {
|
||||
constructor(message, status) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
this.name = "ApiError";
|
||||
}
|
||||
}
|
||||
async function request(path, init) {
|
||||
const token = getAuthToken();
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
...init?.headers
|
||||
};
|
||||
if (token) {
|
||||
headers["Authorization"] = `Bearer ${token}`;
|
||||
}
|
||||
const res = await fetch(path, {
|
||||
...init,
|
||||
headers
|
||||
});
|
||||
if (res.status === 401 && typeof window !== "undefined" && !path.includes("/auth/")) {
|
||||
clearAuth();
|
||||
window.location.href = "/login";
|
||||
throw new ApiError("Authentication required", 401);
|
||||
}
|
||||
let envelope;
|
||||
try {
|
||||
envelope = await res.json();
|
||||
} catch {
|
||||
throw new ApiError(
|
||||
`Server returned non-JSON response (HTTP ${res.status})`,
|
||||
res.status
|
||||
);
|
||||
}
|
||||
if (!envelope.success) {
|
||||
throw new ApiError(envelope.error ?? "Unknown API error", res.status);
|
||||
}
|
||||
return envelope.data;
|
||||
}
|
||||
function post(path, body) {
|
||||
return request(path, {
|
||||
method: "POST",
|
||||
body: body !== void 0 ? JSON.stringify(body) : void 0
|
||||
});
|
||||
}
|
||||
function validateProxy(host, port) {
|
||||
return post("/api/proxies/validate", { host, port });
|
||||
}
|
||||
function cleanupStaleContainer(id) {
|
||||
return post(`/api/containers/stale/${id}/cleanup`);
|
||||
}
|
||||
function bulkCleanupStaleContainers() {
|
||||
return post("/api/containers/stale/cleanup");
|
||||
}
|
||||
export {
|
||||
bulkCleanupStaleContainers as b,
|
||||
cleanupStaleContainer as c,
|
||||
validateProxy as v
|
||||
};
|
||||
Reference in New Issue
Block a user