@@ -66,7 +66,8 @@ self.testURL = function(url, type, serverType, context) {
66
66
} ;
67
67
68
68
/**
69
- * Invoked when the fetch has completed.
69
+ * Invoked when the fetch has completed. This tests an HTTP response (ie headers
70
+ * and body)
70
71
* @param {Response } response
71
72
*/
72
73
self . testResponse = function ( response ) {
@@ -118,6 +119,10 @@ self.testResponse = function(response) {
118
119
) ;
119
120
} ;
120
121
122
+ /**
123
+ * This is called by testResponse() and validates the JSON body of the response.
124
+ * @param json
125
+ */
121
126
self . validateResponse = function ( json ) {
122
127
123
128
self . path = [ "$" ] ;
@@ -607,8 +612,6 @@ self.validateJCard = function (jcard) {
607
612
self . validateJCardProperty
608
613
) ;
609
614
610
- self . popPath ( "[1]" ) ;
611
-
612
615
self . pushSpec ( "rfc6350" ) ;
613
616
614
617
for ( const prop of self . requiredJCardProperties ) {
@@ -633,6 +636,8 @@ self.validateJCard = function (jcard) {
633
636
self . popSpec ( "nro" ) ;
634
637
}
635
638
639
+ self . popPath ( "[1]" ) ;
640
+
636
641
self . popSpec ( "rfc6350" ) ;
637
642
} ;
638
643
@@ -689,6 +694,12 @@ self.validateJCardPropertyType = function(property) {
689
694
"section-3.3" ,
690
695
) ) return ;
691
696
697
+ self . add (
698
+ property [ 0 ] === property [ 0 ] . toLowerCase ( ) ,
699
+ `Property name '${ property [ 0 ] } ' MUST be in lowercase.` ,
700
+ "section-3.3" ,
701
+ ) ;
702
+
692
703
if ( "rir" == self . lastTestedServerType ) {
693
704
self . pushSpec ( "nro" ) ;
694
705
@@ -713,11 +724,17 @@ self.validateJCardPropertyType = function(property) {
713
724
* Validate a JCard property parameter object.
714
725
*/
715
726
self . validateJCardPropertyParameters = function ( property ) {
716
- self . add (
727
+ if ( self . add (
717
728
self . isObject ( property [ 1 ] ) ,
718
729
"Item #2 of a jCard property MUST be an object." ,
719
730
"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
+ }
721
738
} ;
722
739
723
740
/**
@@ -807,6 +824,31 @@ self.validateJCardPropertyValue = function(property) {
807
824
}
808
825
809
826
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
+
810
852
}
811
853
812
854
self . popSpec ( "rfc6350" ) ;
@@ -1870,6 +1912,18 @@ self.validateGTLDRegistrarDomain = function(domain, name) {
1870
1912
1871
1913
self . pushPath ( ".entities" ) ;
1872
1914
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
+
1873
1927
const rant = (
1874
1928
domain . hasOwnProperty ( "entities" ) && self . isArray ( domain . entities )
1875
1929
? domain . entities : [ ]
@@ -2308,7 +2362,7 @@ self.validateGTLDNameserver = function(nameserver, name) {
2308
2362
} ;
2309
2363
2310
2364
self . validateGTLDEntity = function ( rar ) {
2311
- self . msg ( "Validating gTLD registrar response ..." ) ;
2365
+ self . msg ( "Validating gTLD registrar entity ..." ) ;
2312
2366
2313
2367
if ( rar . hasOwnProperty ( "roles" ) && self . isArray ( rar . roles ) ) {
2314
2368
self . pushPath ( ".roles" ) ;
@@ -2329,25 +2383,26 @@ self.validateGTLDEntity = function(rar) {
2329
2383
self . pushPath ( ".vcardArray[1]" ) ;
2330
2384
2331
2385
let seen_types = { } ;
2386
+
2332
2387
self . iterate (
2333
2388
rar . vcardArray [ 1 ] ,
2334
2389
function ( p ) {
2335
- if ( self . isArray ( p ) && self . isString ( p [ 1 ] ) ) {
2390
+ if ( self . isArray ( p ) && self . isString ( p [ 0 ] ) ) {
2336
2391
seen_types [ p [ 0 ] . toUpperCase ( ) ] = 1 ;
2337
2392
2338
2393
if ( "ADR" == p [ 0 ] . toUpperCase ( ) ) {
2339
2394
self . pushPath ( "[1]" ) ;
2340
2395
2341
2396
if ( self . isObject ( p [ 1 ] ) ) {
2342
- const keys = Object . keys ( p [ 1 ] ) . map ( ( k ) => k . toUpperCase ( ) ) ;
2397
+ const keys = Object . keys ( p [ 1 ] ) ;
2343
2398
if ( self . add (
2344
- keys . includes ( "CC" ) ,
2399
+ keys . map ( ( k ) => k . toUpperCase ( ) ) . includes ( "CC" ) ,
2345
2400
"JCard 'adr' property MUST include a 'cc' parameter."
2346
2401
) ) {
2347
- const k = keys . filter ( ( k ) => "CC" == k . toUpperCase ( ) ) . shift ( ) ;
2402
+ const key = keys . filter ( ( key ) => "CC" == key . toUpperCase ( ) ) . shift ( ) ;
2348
2403
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."
2351
2406
) ;
2352
2407
}
2353
2408
@@ -2435,7 +2490,10 @@ self.validateRIRNameServer = function(nameserver) {
2435
2490
* Default options for calls to fetch().
2436
2491
*/
2437
2492
self . fetchOptions = {
2438
- headers : { accept : "application/rdap+json, application/json, */*" } ,
2493
+ headers : {
2494
+ accept : "application/rdap+json, application/json, */*" ,
2495
+ origin : "null" ,
2496
+ } ,
2439
2497
redirect : "follow" ,
2440
2498
} ;
2441
2499
@@ -2463,7 +2521,9 @@ self.isULabel = function(label) {
2463
2521
2464
2522
/**
2465
2523
* 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.
2467
2527
*/
2468
2528
self . path = [ ] ;
2469
2529
@@ -2489,7 +2549,9 @@ self.popPath = function(last) {
2489
2549
2490
2550
/**
2491
2551
* 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).
2493
2555
*/
2494
2556
self . specStack = [ ] ;
2495
2557
0 commit comments