[grade=B urn:ump:wokpmecjfauc7jvnxyyyu4fq3zkkvwge455a5mxlmi3pdzkfdw3a] feat(DC-171): DNS provider plug-in parity phase 1 — BIND 9 AXFR listing + capability honesty
RFC2136/BIND9 adapter gains listRecords via AXFR zone transfer (dig with the same TSIG identity as nsupdate; temp 0600 keyfile, always cleaned up; transfer-denial errors carry the exact allow-transfer fix). TSIG fields validated (name charset, HMAC algorithm whitelist, base64 secret) before keyfile interpolation. Capability honesty at every surface: GET /dns/records 501s name the active provider + its supported capabilities + zone-transfer pointer; MCP dashcaddy_list_dns attaches actionable guidance for AI clients; setup wizard shows per-provider capability hints at choice time (parity-pinned by tests against the adapters). Also fixed a latent rfc2136 bug: this._log instance property shadowed the prototype logging method — every nsupdate call threw since the DC-170-era refactor. CHANGELOG stale 'protocol-impossible' DC-171 entry superseded. Judge: grade B, zero blockers (urn:ump:wokpmecjfauc7jvnxyyyu4fq3zkkvwge455a5mxlmi3pdzkfdw3a). Polish applied post-grade: stale changelog entry corrected, TSIG field validation + 4 extra failure-path tests (exact dig argv, ENOENT install hint, non-denial failure passthrough, hostile-field rejection), dns-records 501 test strengthened to pin provider name + capabilities. Suite: backend 174 suites / 3754 tests, frontend 68/68.
This commit is contained in:
10 files changed
+704
-238
No files matched your search
@@ -452,4 +452,33 @@ window.populateTimezoneSelect = function(selectEl, selectedTz) {
|
||||
location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
// ── DC-171: capability reporting at DNS provider CHOICE time ────────────
|
||||
// Per-provider honest capability hints. Keep in sync with the adapters'
|
||||
// getCapabilities() in dashcaddy-api/src/dns/dns-providers/ — the parity
|
||||
// test (dns-provider-parity.test.js) asserts every <option> value here has
|
||||
// a hint entry.
|
||||
const DNS_PROVIDER_HINTS = {
|
||||
technitium: '✅ Full management — records, zones and health checks via the Technitium API. DashCaddy can create, delete, list and resolve records.',
|
||||
cloudflare: '✅ Full management — records via the Cloudflare API token. DashCaddy can create, delete, list and resolve records.',
|
||||
rfc2136: '⚠️ Partial (push-only protocol) — records can be created, deleted and resolved, and listed via AXFR zone transfer if the server permits transfers for your key (BIND: allow-transfer { key <name>; };). Listing requires that server-side setting.',
|
||||
manual: 'ℹ️ No API control — DashCaddy shows the records you create yourself with your DNS provider\'s tools. Everything else (reverse proxy, SSL) works normally.',
|
||||
};
|
||||
function updateDnsProviderHints() {
|
||||
const select = document.getElementById('setup-dns-provider');
|
||||
const hints = document.getElementById('setup-dns-provider-hints');
|
||||
if (!select || !hints) return;
|
||||
hints.innerHTML = DNS_PROVIDER_HINTS[select.value]
|
||||
? `<strong>${escapeHint(select.selectedOptions[0]?.text || select.value)}</strong><br>${DNS_PROVIDER_HINTS[select.value]}`
|
||||
: '';
|
||||
}
|
||||
function escapeHint(s) {
|
||||
return String(s == null ? '' : s)
|
||||
.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
const dnsProviderSelect = document.getElementById('setup-dns-provider');
|
||||
if (dnsProviderSelect) {
|
||||
dnsProviderSelect.addEventListener('change', updateDnsProviderHints);
|
||||
updateDnsProviderHints();
|
||||
}
|
||||
})();
|
||||
Reference in new issue
Block a user