Skip to content

Commit 08fefdc

Browse files
committed
Merge remote-tracking branch 'origin/main'
2 parents 0c27de0 + 935d9cd commit 08fefdc

File tree

1 file changed

+77
-15
lines changed

1 file changed

+77
-15
lines changed

lib/rdap-validator.js

Lines changed: 77 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ self.testURL = function(url, type, serverType, context) {
6666
};
6767

6868
/**
69-
* Invoked when the fetch has completed.
69+
* Invoked when the fetch has completed. This tests an HTTP response (ie headers
70+
* and body)
7071
* @param {Response} response
7172
*/
7273
self.testResponse = function(response) {
@@ -118,6 +119,10 @@ self.testResponse = function(response) {
118119
);
119120
};
120121

122+
/**
123+
* This is called by testResponse() and validates the JSON body of the response.
124+
* @param json
125+
*/
121126
self.validateResponse = function(json) {
122127

123128
self.path = ["$"];
@@ -607,8 +612,6 @@ self.validateJCard = function (jcard) {
607612
self.validateJCardProperty
608613
);
609614

610-
self.popPath("[1]");
611-
612615
self.pushSpec("rfc6350");
613616

614617
for (const prop of self.requiredJCardProperties) {
@@ -633,6 +636,8 @@ self.validateJCard = function (jcard) {
633636
self.popSpec("nro");
634637
}
635638

639+
self.popPath("[1]");
640+
636641
self.popSpec("rfc6350");
637642
};
638643

@@ -689,6 +694,12 @@ self.validateJCardPropertyType = function(property) {
689694
"section-3.3",
690695
)) return;
691696

697+
self.add(
698+
property[0] === property[0].toLowerCase(),
699+
`Property name '${property[0]}' MUST be in lowercase.`,
700+
"section-3.3",
701+
);
702+
692703
if ("rir" == self.lastTestedServerType) {
693704
self.pushSpec("nro");
694705

@@ -713,11 +724,17 @@ self.validateJCardPropertyType = function(property) {
713724
* Validate a JCard property parameter object.
714725
*/
715726
self.validateJCardPropertyParameters = function(property) {
716-
self.add(
727+
if (self.add(
717728
self.isObject(property[1]),
718729
"Item #2 of a jCard property MUST be an object.",
719730
"section-3.3",
720-
);
731+
)) {
732+
self.add(
733+
Object.keys(property[1]).length == Object.keys(property[1]).filter(n => n === n.toLowerCase()).length,
734+
"jCard parameter names MUST be lowercase.",
735+
"section-3.4"
736+
)
737+
}
721738
};
722739

723740
/**
@@ -807,6 +824,31 @@ self.validateJCardPropertyValue = function(property) {
807824
}
808825

809826
self.popSpec("rfc8605");
827+
828+
} else if (self.isString(property[0]) && "TEL" === property[0].toUpperCase() && self.isString(property[2]) && "uri" == property[2]) {
829+
830+
let url, valid;
831+
try {
832+
url = new URL(property[3]);
833+
valid = true;
834+
835+
} catch (e) {
836+
valid = false;
837+
838+
}
839+
840+
if (self.add(
841+
valid,
842+
"Value of a TEL property of the 'uri' type MUST be a valid URL.",
843+
"section-2.1",
844+
)) {
845+
self.add(
846+
"tel:" === url.protocol,
847+
"URI MUST have the tel: scheme.",
848+
"section-2.1",
849+
);
850+
}
851+
810852
}
811853

812854
self.popSpec("rfc6350");
@@ -1870,6 +1912,18 @@ self.validateGTLDRegistrarDomain = function(domain, name) {
18701912

18711913
self.pushPath(".entities");
18721914

1915+
if (domain.hasOwnProperty("entities") && self.isArray(domain.entities)) {
1916+
self.iterate(
1917+
domain.entities,
1918+
function (e) {
1919+
["handle", "roles", "vcardArray"].forEach(p => self.add(
1920+
e.hasOwnProperty(p),
1921+
`Entity MUST have the '${p}' property.`,
1922+
));
1923+
}
1924+
);
1925+
}
1926+
18731927
const rant = (
18741928
domain.hasOwnProperty("entities") && self.isArray(domain.entities)
18751929
? domain.entities : []
@@ -2308,7 +2362,7 @@ self.validateGTLDNameserver = function(nameserver, name) {
23082362
};
23092363

23102364
self.validateGTLDEntity = function(rar) {
2311-
self.msg("Validating gTLD registrar response...");
2365+
self.msg("Validating gTLD registrar entity...");
23122366

23132367
if (rar.hasOwnProperty("roles") && self.isArray(rar.roles)) {
23142368
self.pushPath(".roles");
@@ -2329,25 +2383,26 @@ self.validateGTLDEntity = function(rar) {
23292383
self.pushPath(".vcardArray[1]");
23302384

23312385
let seen_types = {};
2386+
23322387
self.iterate(
23332388
rar.vcardArray[1],
23342389
function (p) {
2335-
if (self.isArray(p) && self.isString(p[1])) {
2390+
if (self.isArray(p) && self.isString(p[0])) {
23362391
seen_types[p[0].toUpperCase()] = 1;
23372392

23382393
if ("ADR" == p[0].toUpperCase()) {
23392394
self.pushPath("[1]");
23402395

23412396
if (self.isObject(p[1])) {
2342-
const keys = Object.keys(p[1]).map((k) => k.toUpperCase());
2397+
const keys = Object.keys(p[1]);
23432398
if (self.add(
2344-
keys.includes("CC"),
2399+
keys.map((k) => k.toUpperCase()).includes("CC"),
23452400
"JCard 'adr' property MUST include a 'cc' parameter."
23462401
)) {
2347-
const k = keys.filter((k) => "CC" == k.toUpperCase()).shift();
2402+
const key = keys.filter((key) => "CC" == key.toUpperCase()).shift();
23482403
self.add(
2349-
self.countryCodes.includes(p[1][k]),
2350-
"JCard 'adr' 'cc' parameter MUST be a valid ISO-3166-alpha2 code."
2404+
self.countryCodes.includes(p[1][key]),
2405+
"JCard 'adr' 'cc' parameter (value '" + p[1][key] + "') MUST be a valid ISO-3166-alpha2 code."
23512406
);
23522407
}
23532408

@@ -2435,7 +2490,10 @@ self.validateRIRNameServer = function(nameserver) {
24352490
* Default options for calls to fetch().
24362491
*/
24372492
self.fetchOptions = {
2438-
headers: {accept: "application/rdap+json, application/json, */*"},
2493+
headers: {
2494+
accept: "application/rdap+json, application/json, */*",
2495+
origin: "null",
2496+
},
24392497
redirect: "follow",
24402498
};
24412499

@@ -2463,7 +2521,9 @@ self.isULabel = function(label) {
24632521

24642522
/**
24652523
* This stores the JSONPath query that identifies the value in the response that
2466-
* is currently being validated.
2524+
* is currently being validated. When add() is called, the a JSON Path
2525+
* expression is generated using this stack, so the specific component of the
2526+
* JSON response can be associated with the message.
24672527
*/
24682528
self.path = [];
24692529

@@ -2489,7 +2549,9 @@ self.popPath = function(last) {
24892549

24902550
/**
24912551
* This keeps track of the specification document that the response is being
2492-
* validated against.
2552+
* validated against. when add() is called, the topmost entry in the stack is
2553+
* copied into the message, so the message can be associated with a particular
2554+
* specification (RFC, etc).
24932555
*/
24942556
self.specStack = [];
24952557

0 commit comments

Comments
 (0)