mirror of
https://github.com/jakejarvis/rdapper.git
synced 2026-10-26 08:26:22 -04:00
fix: read .it DNSSEC from the domain, not the registrar section
.it's registrar section says "DNSSEC: yes" when the registrar supports DNSSEC,
and that line was read instead of the domain's own "Signed: no", so most
unsigned .it domains looked signed. Read DNSSEC from the first block that has
it, preferring "Signed"; accept .kr's Korean "서명" ("signed"), which now comes
first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2 files changed
+32
-5
No files matched your search
@@ -606,3 +606,19 @@ test("WHOIS date keys and forms across ccTLDs", () => {
|
||||
expect(rec("changed: 20200427 16:03:40\n").updatedDate).toBe("2020-04-27T16:03:40Z");
|
||||
expect(rec("Registered On: Before 2001\n").creationDate).toBeUndefined();
|
||||
});
|
||||
|
||||
test("WHOIS DNSSEC comes from the domain's block, not the registrar's capability (.it)", () => {
|
||||
const it = `
|
||||
Domain: example.it
|
||||
Status: ok
|
||||
Signed: no
|
||||
|
||||
Registrar
|
||||
Organization: Example Registrar S.r.l.
|
||||
DNSSEC: yes
|
||||
`;
|
||||
expect(normalizeWhois("example.it", "it", it, "whois.nic.it").dnssec).toEqual({ enabled: false });
|
||||
// .kr writes the Korean section first
|
||||
const kr = "DNSSEC : 서명\n\nDNSSEC : signed\n";
|
||||
expect(normalizeWhois("example.kr", "kr", kr, "whois.kr").dnssec).toEqual({ enabled: true });
|
||||
});
|
||||
+16
-5
@@ -224,11 +224,13 @@ export function normalizeWhois(
|
||||
const registrant = contacts?.find((c) => c.type === "registrant");
|
||||
const privacyEnabled = isPrivacyContact(registrant);
|
||||
|
||||
// "signedDelegation", "Signed delegation", "yes", "active" (.bg, .md); not "unsigned" or
|
||||
// "Inactive". .kr repeats the field in Korean, so any value may carry the answer.
|
||||
const dnssecValues = [...(map.dnssec ?? []), ...(map["dnssec signed"] ?? [])]; // .rs
|
||||
const dnssec = dnssecValues.length
|
||||
? { enabled: dnssecValues.some((v) => /^(?:signed|yes|true|active)/i.test(v.trim())) }
|
||||
// "signedDelegation", "Signed delegation", "yes", "active" (.bg, .md), "서명" (.kr); not
|
||||
// "unsigned" or "Inactive". Read from the first block that has it, preferring "Signed": .it's
|
||||
// registrar section has "DNSSEC: yes" for the registrar's support, beside the domain's
|
||||
// "Signed: no".
|
||||
const dnssecValues = valuesOf(blocks, ["signed", "dnssec signed", "dnssec"]); // "dnssec signed": .rs
|
||||
const dnssec = dnssecValues
|
||||
? { enabled: dnssecValues.some((v) => /^(?:signed|yes|true|active|서명)/i.test(v.trim())) }
|
||||
: undefined;
|
||||
|
||||
// Simple lock derivation from statuses (the EPP code, or the registry's wording in raw)
|
||||
@@ -307,6 +309,15 @@ function parseNameserverLine(line: string, domain: string): Nameserver | undefin
|
||||
return ns;
|
||||
}
|
||||
|
||||
/** Values of the first key (by priority) present in the first block that has any of them. */
|
||||
function valuesOf(blocks: Array<Record<string, string[]>>, keys: string[]): string[] | undefined {
|
||||
for (const block of blocks) {
|
||||
const key = keys.find((k) => block[k]?.length);
|
||||
if (key) return block[key];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Status keys by preference: .fr lists EPP codes as "eppstatus" beside a plain "status: ACTIVE"
|
||||
const STATUS_KEYS = ["eppstatus", "domain status", "status", "registration status"];
|
||||
|
||||
|
||||
Reference in new issue
Block a user