11import Ajv from 'ajv/dist/jtd.js'
2-
3- const ajv = new Ajv ( )
2+ import { isCanonicalUrl } from '../../lib/shared/urlHelper.js'
43
54/** @typedef {import('ajv/dist/jtd.js').JTDDataType<typeof inputSchema> } InputSchema */
65
@@ -10,6 +9,8 @@ const ajv = new Ajv()
109
1110/** @typedef {NonNullable<Metric['content']> } MetricContent */
1211
12+ /** @typedef {{url?: string, category?: string} } Reference */
13+
1314const jtdAjv = new Ajv ( )
1415
1516const inputSchema = /** @type {const } */ ( {
@@ -21,7 +22,7 @@ const inputSchema = /** @type {const} */ ({
2122 references : {
2223 elements : {
2324 additionalProperties : true ,
24- properties : {
25+ optionalProperties : {
2526 category : { type : 'string' } ,
2627 url : { type : 'string' } ,
2728 } ,
@@ -64,41 +65,24 @@ const inputSchema = /** @type {const} */ ({
6465 } ,
6566} )
6667
67- /** @typedef {{ url: string; category: string} } Reference */
68-
69- const referenceSchema = /** @type {const } */ ( {
70- additionalProperties : true ,
71- properties : {
72- category : { type : 'string' } ,
73- url : { type : 'string' } ,
74- } ,
75- } )
76-
77- const validate = jtdAjv . compile ( inputSchema )
78- const validateReference = ajv . compile ( referenceSchema )
68+ const validateInput = jtdAjv . compile ( inputSchema )
7969
8070/**
8171 * Get the canonical url from the document
8272 * @return {string } canonical url or empty when no canonical url exists
83- * @param {Array<Reference> | undefined } references
84- * @param {string | undefined } trackingId
73+ * @param {Array<{url?: string, category?: string}>| undefined } references
74+ * @param {string| undefined } trackingId
8575 */
8676function getCanonicalUrl ( references , trackingId ) {
8777 if ( references && trackingId ) {
8878 // Find the reference that matches our criteria
8979 /** @type {Reference| undefined } */
90- const canonicalUrlReference = references . find (
91- ( reference ) =>
92- validateReference ( reference ) &&
93- reference . category === 'self' &&
94- reference . url . startsWith ( 'https://' ) &&
95- reference . url . endsWith (
96- trackingId . toLowerCase ( ) . replace ( / [ ^ + \- a - z 0 - 9 ] + / g, '_' ) + '.json'
97- )
80+ const canonicalUrlReference = references . find ( ( reference ) =>
81+ isCanonicalUrl ( reference , trackingId )
9882 )
9983
10084 // When we find a matching reference, we know it has the url property
101- // because validateReference ensures it matches the Reference schema
85+ // because isCanonicalUrl ensures it matches the Reference schema
10286 return canonicalUrlReference ?. url ?? ''
10387 } else {
10488 return ''
@@ -112,7 +96,7 @@ function getCanonicalUrl(references, trackingId) {
11296 * @param {string } canonicalURL
11397 * @return {boolean }
11498 */
115- function hasServerRatingAndNoSource ( metric , canonicalURL ) {
99+ function hasSeverityRatingAndNoSource ( metric , canonicalURL ) {
116100 return (
117101 ( ! metric . source || metric . source === canonicalURL ) &&
118102 ! ! metric ?. content ?. qualitative_severity_rating
@@ -129,18 +113,18 @@ function hasServerRatingAndNoSource(metric, canonicalURL) {
129113 * @param {any } doc
130114 */
131115export function recommendedTest_6_2_47 ( doc ) {
132- /** @type { Array<{ message: string; instancePath: string }> } */
133- const warnings = [ ]
134- const context = { warnings }
135-
136- if ( ! validate ( doc ) ) {
137- return context
116+ const ctx = {
117+ warnings :
118+ /** @type { Array<{ instancePath: string; message: string }> } */ ( [ ] ) ,
119+ }
120+ if ( ! validateInput ( doc ) ) {
121+ return ctx
138122 }
139123
140124 /** @type {Array<Vulnerability> } */
141125 const vulnerabilities = doc . vulnerabilities
142126 const canonicalURL = getCanonicalUrl (
143- doc . document . references ,
127+ doc . document ? .references ,
144128 doc . document ?. tracking ?. id
145129 )
146130
@@ -150,23 +134,23 @@ export function recommendedTest_6_2_47(doc) {
150134 /** @type {Array<String> | undefined } */
151135 const invalidPaths = metrics
152136 ?. map ( ( metric , metricIndex ) =>
153- hasServerRatingAndNoSource ( metric , canonicalURL )
137+ hasSeverityRatingAndNoSource ( metric , canonicalURL )
154138 ? `/vulnerabilities/${ vulnerabilityIndex } /metrics/${ metricIndex } /content/qualitative_severity_rating`
155139 : null
156140 )
157141 . filter ( ( path ) => path !== null )
158142
159143 if ( ! ! invalidPaths ) {
160144 invalidPaths . forEach ( ( path ) => {
161- context . warnings . push ( {
145+ ctx . warnings . push ( {
162146 message :
163- 'the metric has a qualitative severity rating and no source property ' +
164- ' or a source property that ist equal to the canonical URL' ,
147+ 'a qualitative severity rating is used by the issuing party (as no " source" is given ' +
148+ ' or the source property equals to the canonical URL) ' ,
165149 instancePath : path ,
166150 } )
167151 } )
168152 }
169153 } )
170154
171- return context
155+ return ctx
172156}
0 commit comments