wizard: block Next if external service cannot be verified
Unit Tests / test (push) Successful in 15m44s
Unit Tests / test (push) Successful in 15m44s
For pic_ngo: name must be confirmed available (not just format-valid). For cloudflare/duckdns: token is auto-verified on Next if not already done — invalid or unreachable service blocks proceeding. Only lan and http01 (no external dependency) allow Next without a live check. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -301,16 +301,20 @@ function Step2Domain({
|
||||
setCfStatus('checking');
|
||||
try {
|
||||
const res = await setupAPI.validate('cloudflare_token', { token: cloudflareToken });
|
||||
setCfStatus(res.data?.valid ? 'valid' : 'invalid');
|
||||
} catch { setCfStatus('invalid'); }
|
||||
const result = res.data?.valid ? 'valid' : 'invalid';
|
||||
setCfStatus(result);
|
||||
return result;
|
||||
} catch { setCfStatus('invalid'); return 'invalid'; }
|
||||
};
|
||||
|
||||
const verifyDns = async () => {
|
||||
setDnsStatus('checking');
|
||||
try {
|
||||
const res = await setupAPI.validate('duckdns_token', { subdomain: duckSub, token: duckdnsToken });
|
||||
setDnsStatus(res.data?.valid ? 'valid' : 'invalid');
|
||||
} catch { setDnsStatus('invalid'); }
|
||||
const result = res.data?.valid ? 'valid' : 'invalid';
|
||||
setDnsStatus(result);
|
||||
return result;
|
||||
} catch { setDnsStatus('invalid'); return 'invalid'; }
|
||||
};
|
||||
|
||||
const handleNext = async () => {
|
||||
@@ -324,14 +328,31 @@ function Step2Domain({
|
||||
setNextLoading(true);
|
||||
const result = await checkPicAvail(picName);
|
||||
setNextLoading(false);
|
||||
if (result === 'taken') e.name = 'This subdomain is already taken. Choose another.';
|
||||
if (result === 'taken')
|
||||
e.name = 'This subdomain is already taken. Choose another.';
|
||||
else if (result !== 'available')
|
||||
e.name = 'Could not reach the DDNS service. Check your connection or choose a different domain option.';
|
||||
}
|
||||
} else if (domainType === 'cloudflare') {
|
||||
if (!customDomain || !DOMAIN_RE.test(customDomain)) e.domain = 'Enter a valid domain (e.g. home.example.com).';
|
||||
if (!cloudflareToken.trim()) e.token = 'Cloudflare API token is required.';
|
||||
if (!cloudflareToken.trim()) {
|
||||
e.token = 'Cloudflare API token is required.';
|
||||
} else if (cfStatus !== 'valid') {
|
||||
setNextLoading(true);
|
||||
const result = await verifyCf();
|
||||
setNextLoading(false);
|
||||
if (result !== 'valid') e.token = 'Cloudflare token is invalid or could not be verified.';
|
||||
}
|
||||
} else if (domainType === 'duckdns') {
|
||||
if (!duckSub) e.name = 'DuckDNS subdomain is required.';
|
||||
if (!duckdnsToken.trim()) e.token = 'DuckDNS token is required.';
|
||||
if (!duckdnsToken.trim()) {
|
||||
e.token = 'DuckDNS token is required.';
|
||||
} else if (dnsStatus !== 'valid') {
|
||||
setNextLoading(true);
|
||||
const result = await verifyDns();
|
||||
setNextLoading(false);
|
||||
if (result !== 'valid') e.token = 'DuckDNS token is invalid or could not be verified.';
|
||||
}
|
||||
} else if (domainType === 'http01') {
|
||||
if (!customDomain || !DOMAIN_RE.test(customDomain)) e.domain = 'Enter a valid domain (e.g. home.example.com).';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user