mirror of
https://github.com/jakejarvis/rdapper.git
synced 2026-09-23 01:25:31 -04:00
feat: add contact redacted flag, placeholder detection, and country name/code resolution
- Add `redacted?: boolean` to `Contact`; set when any field was dropped as a placeholder, the name matches a privacy-service heuristic, or an RFC 9537 redaction targets that entity's role - Add `isPlaceholderValue` to `privacy.ts` to identify boilerplate registrar strings (`"Please query the RDDS…"`, `"redacted"`, `"n/a"`, etc.) used in place of real email/phone/fax values; drop them from the contact during finalization - Add `countries.ts` backed by `Intl.DisplayNames` (with a curated `ALIASES` table for common alternate names) providing `countryNameFromCode`, `countryCodeFromName`, and `resolveCountry`; a two-letter `country` value is now treated as a code and expanded to a full name - Introduce `finalizeContact` in `contacts.ts` to centralise all contact post-processing (placeholder stripping, country resolution, `redacted` flag); call it from both RDAP and WHOIS normalizers - Wire RFC 9537 redaction role-matching into `extractContacts` via a new `redactionTargetsRole` helper so entities targeted by a `redacted` entry automatically receive `redacted: true` - Add `countries.test.ts` and extend RDAP/WHOIS normalizer tests to cover placeholder stripping, country fill-in, and redaction flag propagation
This commit is contained in:
@@ -280,3 +280,24 @@ Name servers:
|
||||
expect(rec.registrar).toEqual({ name: "epag", url: "http://www.epag.de" });
|
||||
expect(rec.nameservers?.map((n) => n.host)).toEqual(["ns1.vercel-dns.com", "ns2.vercel-dns.com"]);
|
||||
});
|
||||
|
||||
test("WHOIS resolves country code/name and flags placeholder contact values", () => {
|
||||
const rec = normalizeWhois(
|
||||
"example.com",
|
||||
"com",
|
||||
`Domain Name: EXAMPLE.COM
|
||||
Registrant Name: Jane Doe
|
||||
Registrant Email: Please query the RDDS service of the Registrar of Record identified in this output
|
||||
Registrant Country: DE
|
||||
Admin Name: John Roe
|
||||
Admin Country: Canada
|
||||
`,
|
||||
"whois.example",
|
||||
);
|
||||
const registrant = rec.contacts?.find((c) => c.type === "registrant");
|
||||
expect(registrant).toMatchObject({ country: "Germany", countryCode: "DE", redacted: true });
|
||||
expect(registrant?.email).toBeUndefined();
|
||||
const admin = rec.contacts?.find((c) => c.type === "admin");
|
||||
expect(admin).toMatchObject({ country: "Canada", countryCode: "CA" });
|
||||
expect(admin?.redacted).toBeUndefined();
|
||||
});
|
||||
|
||||
+16
-15
@@ -1,4 +1,5 @@
|
||||
import { toISOFromTokens } from "../lib/dates";
|
||||
import { finalizeContact } from "../lib/contacts";
|
||||
import { isPrivacyName } from "../lib/privacy";
|
||||
import { parseKeyValueLines, uniq } from "../lib/text";
|
||||
import type { Contact, DomainRecord, Nameserver, RegistrarInfo } from "../types";
|
||||
@@ -358,21 +359,21 @@ function collectContacts(map: Record<string, string[]>): Contact[] | undefined {
|
||||
const country = anyValue(map, countryKeys);
|
||||
|
||||
if (name || org || email || phone || street?.length) {
|
||||
contacts.push({
|
||||
type: r.role,
|
||||
name: name || undefined,
|
||||
organization: org || undefined,
|
||||
email: email || undefined,
|
||||
phone: phone || undefined,
|
||||
fax: fax || undefined,
|
||||
street: street,
|
||||
city: city || undefined,
|
||||
state: state || undefined,
|
||||
postalCode: postalCode || undefined,
|
||||
country: country || undefined,
|
||||
// Many registries print the ISO 3166-1 alpha-2 code directly
|
||||
countryCode: country && /^[A-Za-z]{2}$/.test(country) ? country.toUpperCase() : undefined,
|
||||
});
|
||||
contacts.push(
|
||||
finalizeContact({
|
||||
type: r.role,
|
||||
name: name || undefined,
|
||||
organization: org || undefined,
|
||||
email: email || undefined,
|
||||
phone: phone || undefined,
|
||||
fax: fax || undefined,
|
||||
street: street,
|
||||
city: city || undefined,
|
||||
state: state || undefined,
|
||||
postalCode: postalCode || undefined,
|
||||
country: country || undefined,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
return contacts.length ? contacts : undefined;
|
||||
|
||||
Reference in New Issue
Block a user