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 @@
|
||||
import { a as attr, b as attr_class, c as clsx, h as head, e as escape_html, s as store_get, g as stringify, f as ensure_array_like, u as unsubscribe_stores, i as derived } from "../../chunks/index.js";
|
||||
import { t } from "../../chunks/index2.js";
|
||||
import { I as IconDeploy } from "../../chunks/IconDeploy.js";
|
||||
import { I as IconAlert } from "../../chunks/IconAlert.js";
|
||||
import { S as SkeletonCard } from "../../chunks/SkeletonCard.js";
|
||||
import "clsx";
|
||||
function IconServer($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect><rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect><line x1="6" x2="6.01" y1="6" y2="6"></line><line x1="6" x2="6.01" y1="18" y2="18"></line></svg>`);
|
||||
}
|
||||
function IconBox($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"></path><path d="m3.3 7 8.7 5 8.7-5"></path><path d="M12 22V12"></path></svg>`);
|
||||
}
|
||||
function IconClock($$renderer, $$props) {
|
||||
const { size = 20, class: c = "" } = $$props;
|
||||
$$renderer.push(`<svg xmlns="http://www.w3.org/2000/svg"${attr("width", size)}${attr("height", size)} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"${attr_class(clsx(c))} aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>`);
|
||||
}
|
||||
function SystemHealthCard($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
{
|
||||
$$renderer2.push("<!--[-1-->");
|
||||
}
|
||||
$$renderer2.push(`<!--]-->`);
|
||||
});
|
||||
}
|
||||
function _page($$renderer, $$props) {
|
||||
$$renderer.component(($$renderer2) => {
|
||||
var $$store_subs;
|
||||
let projects = [];
|
||||
let instancesByProject = {};
|
||||
let staleContainers = [];
|
||||
const totalProjects = derived(() => projects.length);
|
||||
const totalRunning = derived(() => Object.values(instancesByProject).flat().filter((i) => i.status === "running").length);
|
||||
const totalFailed = derived(() => Object.values(instancesByProject).flat().filter((i) => i.status === "failed").length);
|
||||
const totalStale = derived(() => staleContainers.length);
|
||||
head("1uha8ag", $$renderer2, ($$renderer3) => {
|
||||
$$renderer3.title(($$renderer4) => {
|
||||
$$renderer4.push(`<title>${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.title"))} - ${escape_html(store_get($$store_subs ??= {}, "$t", t)("app.name"))}</title>`);
|
||||
});
|
||||
});
|
||||
$$renderer2.push(`<div class="space-y-6"><div class="flex items-center justify-between"><h1 class="text-2xl font-bold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.title"))}</h1> <a href="/deploy" class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-brand-600)] px-4 py-2.5 text-sm font-medium text-white shadow-sm transition-all duration-150 hover:bg-[var(--color-brand-700)] active:animate-press">`);
|
||||
IconDeploy($$renderer2, { size: 16 });
|
||||
$$renderer2.push(`<!----> ${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.quickDeploy"))}</a></div> <div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4"><div class="flex items-center gap-4 rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-5 shadow-[var(--shadow-sm)]"><div class="flex h-12 w-12 items-center justify-center rounded-xl bg-[var(--color-brand-50)] text-[var(--color-brand-600)]">`);
|
||||
IconBox($$renderer2, { size: 24 });
|
||||
$$renderer2.push(`<!----></div> <div><p class="text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.totalProjects"))}</p> <p class="mt-0.5 text-2xl font-bold text-[var(--text-primary)]">${escape_html(totalProjects())}</p></div></div> <div class="flex items-center gap-4 rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-5 shadow-[var(--shadow-sm)]"><div class="flex h-12 w-12 items-center justify-center rounded-xl bg-emerald-50 text-emerald-600">`);
|
||||
IconServer($$renderer2, { size: 24 });
|
||||
$$renderer2.push(`<!----></div> <div><p class="text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.runningInstances"))}</p> <p class="mt-0.5 text-2xl font-bold text-emerald-600">${escape_html(totalRunning())}</p></div></div> <div class="flex items-center gap-4 rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-5 shadow-[var(--shadow-sm)]"><div${attr_class(`flex h-12 w-12 items-center justify-center rounded-xl ${stringify(totalFailed() > 0 ? "bg-red-50 text-red-600" : "bg-gray-50 text-gray-400")}`)}>`);
|
||||
IconAlert($$renderer2, { size: 24 });
|
||||
$$renderer2.push(`<!----></div> <div><p class="text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.failedInstances"))}</p> <p${attr_class(`mt-0.5 text-2xl font-bold ${stringify(totalFailed() > 0 ? "text-red-600" : "text-[var(--text-primary)]")}`)}>${escape_html(totalFailed())}</p></div></div> <a href="/containers/stale" class="flex items-center gap-4 rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-5 shadow-[var(--shadow-sm)] transition-colors hover:bg-[var(--surface-card-hover)]"><div${attr_class(`flex h-12 w-12 items-center justify-center rounded-xl ${stringify(totalStale() > 0 ? "bg-amber-50 text-amber-600" : "bg-gray-50 text-gray-400")}`)}>`);
|
||||
IconClock($$renderer2, { size: 24 });
|
||||
$$renderer2.push(`<!----></div> <div><p class="text-sm text-[var(--text-secondary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.staleContainers"))}</p> <p${attr_class(`mt-0.5 text-2xl font-bold ${stringify(totalStale() > 0 ? "text-amber-600" : "text-[var(--text-primary)]")}`)}>${escape_html(totalStale())}</p></div></a></div> `);
|
||||
SystemHealthCard($$renderer2);
|
||||
$$renderer2.push(`<!----> <div><h2 class="text-lg font-semibold text-[var(--text-primary)]">${escape_html(store_get($$store_subs ??= {}, "$t", t)("dashboard.projects"))}</h2> `);
|
||||
{
|
||||
$$renderer2.push("<!--[0-->");
|
||||
$$renderer2.push(`<div class="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3"><!--[-->`);
|
||||
const each_array = ensure_array_like(Array(3));
|
||||
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
||||
each_array[$$index];
|
||||
SkeletonCard($$renderer2);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div>`);
|
||||
}
|
||||
$$renderer2.push(`<!--]--></div></div>`);
|
||||
if ($$store_subs) unsubscribe_stores($$store_subs);
|
||||
});
|
||||
}
|
||||
export {
|
||||
_page as default
|
||||
};
|
||||
Reference in New Issue
Block a user