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:
2026-04-02 14:54:15 +03:00
parent c730cfaa45
commit 670948f113
243 changed files with 15971 additions and 535 deletions
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
import{a as u,b as g,s as a}from"../chunks/BJdXET8u.js";import"../chunks/BSEsuAwr.js";import{p as l,h as v,t as d,e as _,c as o,r as p,s as x}from"../chunks/DKemW7Dm.js";import{i as $}from"../chunks/BlV-f-zB.js";import{s as b,p as m}from"../chunks/CWhLh9u1.js";const k={get error(){return m.error},get status(){return m.status}};b.updated.check;const i=k;var E=g("<h1> </h1> <p> </p>",1);function A(c,n){l(n,!1),$();var t=E(),r=v(t),f=o(r,!0);p(r);var s=x(r,2),h=o(s,!0);p(s),d(()=>{var e;a(f,i.status),a(h,(e=i.error)==null?void 0:e.message)}),u(c,t),_()}export{A as component};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
import{a as P,s as v,b as S}from"../chunks/BJdXET8u.js";import"../chunks/BSEsuAwr.js";import{p as z,h as C,t as I,e as M,f as O,c as e,$ as B,s as a,r}from"../chunks/DKemW7Dm.js";import{s as F,a as G}from"../chunks/BSXRhUWv.js";import{h as H}from"../chunks/ecfdBtDb.js";import{i as T}from"../chunks/BlV-f-zB.js";import{g as f}from"../chunks/CWhLh9u1.js";import{t as q}from"../chunks/kfynmD3Z.js";import{P as A}from"../chunks/DsQCf6vC.js";import{I as D}from"../chunks/DrzuxmSv.js";const Y=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));var E=S('<div class="mb-6"><a href="/proxies" class="inline-flex items-center gap-1 text-sm text-[var(--text-secondary)] hover:text-[var(--color-brand-600)] transition-colors"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 12H5"></path><path d="m12 19-7-7 7-7"></path></svg> </a></div> <div class="mb-6 flex items-center gap-3"><div class="flex h-10 w-10 items-center justify-center rounded-xl bg-[var(--color-brand-50)] text-[var(--color-brand-600)]"><!></div> <h1 class="text-xl font-bold text-[var(--text-primary)]"> </h1></div> <div class="mx-auto max-w-2xl rounded-2xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-6 shadow-[var(--shadow-sm)]"><!></div>',1);function Z(x,h){z(h,!1);const t=()=>G(q,"$t",u),[u,_]=F();function b(n){f("/proxies")}function g(){f("/proxies")}T();var d=E();H("1eyu80y",n=>{O((l,j)=>{B.title=`${l??""} - ${j??""}`},[()=>t()("proxies.form.title"),()=>t()("app.name")])});var o=C(d),m=e(o),$=a(e(m));r(m),r(o);var s=a(o,2),i=e(s),y=e(i);D(y,{size:22}),r(i);var c=a(i,2),w=e(c,!0);r(c),r(s);var p=a(s,2),k=e(p);A(k,{mode:"create",onsave:b,oncancel:g}),r(p),I((n,l)=>{v($,` ${n??""}`),v(w,l)},[()=>t()("common.back"),()=>t()("proxies.form.title")]),P(x,d),M(),_()}export{Z as component,Y as universal};
@@ -0,0 +1 @@
import{a as p,s as n,b as v}from"../chunks/BJdXET8u.js";import{o as N}from"../chunks/phMGo29-.js";import{p as Q,h as R,t as b,e as U,f as V,c as t,d as h,g as i,$ as W,s as d,r as a,a as y,u as X}from"../chunks/DKemW7Dm.js";import{i as Y,s as Z,a as z}from"../chunks/BSXRhUWv.js";import{h as ee}from"../chunks/ecfdBtDb.js";import{p as re}from"../chunks/DELaSNrV.js";import{g as $}from"../chunks/CWhLh9u1.js";import{t as te}from"../chunks/Bpb8V1MF.js";import{t as ae}from"../chunks/kfynmD3Z.js";import{P as oe}from"../chunks/DsQCf6vC.js";import{I as se}from"../chunks/DrzuxmSv.js";import{I as ie}from"../chunks/BFW91e3Y.js";const ke=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));var de=v('<div class="flex items-center justify-center py-20"><!> <span class="ml-2 text-sm text-[var(--text-secondary)]"> </span></div>'),ne=v('<div class="rounded-xl border border-red-200 bg-red-50 p-6 text-center dark:border-red-900 dark:bg-red-950"><p class="text-sm text-red-700 dark:text-red-300"> </p> <a href="/proxies" class="mt-3 inline-block rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700 transition-colors"> </a></div>'),le=v('<div class="mx-auto max-w-2xl rounded-2xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-6 shadow-[var(--shadow-sm)]"><!></div>'),ce=v('<div class="mb-6"><a href="/proxies" class="inline-flex items-center gap-1 text-sm text-[var(--text-secondary)] hover:text-[var(--color-brand-600)] transition-colors"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 12H5"></path><path d="m12 19-7-7 7-7"></path></svg> </a></div> <div class="mb-6 flex items-center gap-3"><div class="flex h-10 w-10 items-center justify-center rounded-xl bg-[var(--color-brand-50)] text-[var(--color-brand-600)]"><!></div> <h1 class="text-xl font-bold text-[var(--text-primary)]"> </h1></div> <!>',1);function we(M,S){Q(S,!0);const T=()=>z(re,"$page",k),s=()=>z(ae,"$t",k),[k,C]=Z();let m=y(null),w=y(!0),x=y("");const F=X(()=>T().params.id);N(async()=>{try{h(m,await te(i(F)),!0)}catch(e){h(x,e instanceof Error?e.message:"Failed to load proxy",!0)}finally{h(w,!1)}});function O(e){$("/proxies")}function B(e){$("/proxies")}function D(){$("/proxies")}var j=ce();ee("57j31g",e=>{V((r,o)=>{W.title=`${r??""} - ${o??""}`},[()=>s()("proxies.form.editTitle"),()=>s()("app.name")])});var f=R(j),I=t(f),E=d(t(I));a(I),a(f);var u=d(f,2),_=t(u),G=t(_);se(G,{size:22}),a(_);var P=d(_,2),H=t(P,!0);a(P),a(u);var L=d(u,2);{var q=e=>{var r=de(),o=t(r);ie(o,{size:24,class:"text-[var(--color-brand-500)]"});var l=d(o,2),c=t(l,!0);a(l),a(r),b(g=>n(c,g),[()=>s()("common.loading")]),p(e,r)},A=e=>{var r=ne(),o=t(r),l=t(o,!0);a(o);var c=d(o,2),g=t(c,!0);a(c),a(r),b(K=>{n(l,i(x)),n(g,K)},[()=>s()("common.back")]),p(e,r)},J=e=>{var r=le(),o=t(r);oe(o,{mode:"edit",get proxy(){return i(m)},onsave:O,ondelete:B,oncancel:D}),a(r),p(e,r)};Y(L,e=>{i(w)?e(q):i(x)?e(A,1):i(m)&&e(J,2)})}b((e,r)=>{n(E,` ${e??""}`),n(H,r)},[()=>s()("common.back"),()=>s()("proxies.form.editTitle")]),p(M,j),U(),C()}export{we as component,ke as universal};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,2 @@
import{a as y,f as H,s as M,b as A}from"../chunks/BJdXET8u.js";import{t as w,p as J,e as L,c as o,r as s,s as b,g as t,u as v}from"../chunks/DKemW7Dm.js";import{p as S,s as N,a as j,i as O}from"../chunks/BSXRhUWv.js";import{s as Q}from"../chunks/CnPWu_ZO.js";import{e as R,i as T}from"../chunks/CZnXUJhL.js";import{s as _,a as B,c as U,t as X}from"../chunks/kfynmD3Z.js";import{p as Y}from"../chunks/DELaSNrV.js";import{I as Z}from"../chunks/CWCQOKDd.js";import{I as tt}from"../chunks/DqoiTw6k.js";import{I as et}from"../chunks/DhEbbC3M.js";var rt=H('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M3 5v14a9 3 0 0 0 18 0V5"></path><path d="M3 12a9 3 0 0 0 18 0"></path></svg>');function at(g,n){const f=S(n,"size",3,20),p=S(n,"class",3,"");var i=rt();w(()=>{_(i,"width",f()),_(i,"height",f()),B(i,0,U(p()))}),y(g,i)}var st=A("<li><a><!> </a></li>"),it=A('<div class="mx-auto max-w-4xl"><h1 class="mb-6 text-2xl font-bold text-[var(--text-primary)]"> </h1> <div class="flex flex-col gap-6 sm:flex-row"><nav class="w-full flex-shrink-0 sm:w-48"><ul class="flex gap-1 overflow-x-auto sm:flex-col sm:space-y-0.5"></ul></nav> <div class="flex-1 min-w-0"><!></div></div></div>');function dt(g,n){J(n,!0);const f=()=>j(Y,"$page",i),p=()=>j(X,"$t",i),[i,C]=N(),D=[{href:"/settings",labelKey:"settings.general",icon:"general"},{href:"/settings/registries",labelKey:"settings.registries",icon:"registries"},{href:"/settings/credentials",labelKey:"settings.credentials",icon:"credentials"},{href:"/settings/auth",labelKey:"settings.authentication",icon:"auth"}];let I=v(()=>f().url.pathname);function c(l){return l==="/settings"?t(I)==="/settings":t(I).startsWith(l)}var h=it(),d=o(h),P=o(d,!0);s(d);var k=b(d,2),u=o(k),z=o(u);R(z,21,()=>D,T,(l,r)=>{var m=st(),x=o(m),$=o(x);{var W=e=>{{let a=v(()=>c(t(r).href)?"text-[var(--color-brand-600)]":"text-[var(--text-tertiary)]");Z(e,{size:16,get class(){return t(a)}})}},q=e=>{{let a=v(()=>c(t(r).href)?"text-[var(--color-brand-600)]":"text-[var(--text-tertiary)]");at(e,{size:16,get class(){return t(a)}})}},E=e=>{{let a=v(()=>c(t(r).href)?"text-[var(--color-brand-600)]":"text-[var(--text-tertiary)]");tt(e,{size:16,get class(){return t(a)}})}},F=e=>{{let a=v(()=>c(t(r).href)?"text-[var(--color-brand-600)]":"text-[var(--text-tertiary)]");et(e,{size:16,get class(){return t(a)}})}};O($,e=>{t(r).icon==="general"?e(W):t(r).icon==="registries"?e(q,1):t(r).icon==="credentials"?e(E,2):t(r).icon==="auth"&&e(F,3)})}var G=b($);s(x),s(m),w((e,a)=>{_(x,"href",t(r).href),B(x,1,`flex items-center gap-2.5 whitespace-nowrap rounded-lg px-3 py-2 text-sm font-medium transition-all duration-150
${e??""}`),M(G,` ${a??""}`)},[()=>c(t(r).href)?"bg-[var(--color-brand-50)] text-[var(--color-brand-700)] shadow-sm":"text-[var(--text-secondary)] hover:bg-[var(--surface-card-hover)] hover:text-[var(--text-primary)]",()=>p()(t(r).labelKey)]),y(l,m)}),s(z),s(u);var K=b(u,2),V=o(K);Q(V,()=>n.children),s(K),s(k),s(h),w(l=>M(P,l),[()=>p()("settings.title")]),y(g,h),L(),C()}export{dt as component};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long