fileoverview import { debug as d } from '@hint/utils-debug' ; import { includedHeaders , isDataURI } from '@hint/utils-network' ; import { mergeIgnoreIncludeArrays } from '@hint/utils-string' ; import { HintContext } from 'hint/dist/src/lib/hint-context' ; import { FetchEnd , Response , IHint } from 'hint/dist/src/lib/types' ; import { Severity } from '@hint/utils-types' ; import meta from './meta' ; import { getMessage } from './i18n.import' ; const debug = d ( __filename ) ; export default class NoHtmlOnlyHeadersHint implements IHint { public static readonly meta = meta ; public constructor ( context ) { let unneededHeaders = [ 'content-security-policy' , 'feature-policy' , 'x-content-security-policy' , 'x-ua-compatible' , 'x-webkit-csp' , 'x-xss-protection' ] ; const exceptionHeaders = [ 'content-security-policy' , 'x-content-security-policy' , 'x-webkit-csp' ] ; const exceptionMediaTypes = [ 'application/pdf' , 'image/svg+xml' , 'text/javascript' ] ; const loadHintConfigs = ( ) => { const includeHeaders = ( context . hintOptions && context . hintOptions . include ) || [ ] ; const ignoreHeaders = ( context . hintOptions && context . hintOptions . ignore ) || [ ] ; unneededHeaders = mergeIgnoreIncludeArrays ( unneededHeaders , ignoreHeaders , includeHeaders ) ; } ; const willBeTreatedAsHTML = ( response ) : boolean => { const contentTypeHeader = response . headers [ 'content-type' ] ; const mediaType = contentTypeHeader ? contentTypeHeader . split ( ';' ) [ 0 ] . trim ( ) : '' ; if ( [ 'text/html' , 'text/xml' , 'application/xhtml+xml' ] . includes ( mediaType ) ) { return true ; } if ( mediaType . indexOf ( '/' ) > 0 ) { return false ; } return false ; } ; const validate = ( { element , resource , response } ) => { if ( isDataURI ( resource ) ) { debug ( `Check does not apply for data URI: ${ resource }` ) ; return ; } if ( ! willBeTreatedAsHTML ( response ) ) { let headersToValidate = unneededHeaders ; if ( exceptionMediaTypes . includes ( response . mediaType ) ) { headersToValidate = mergeIgnoreIncludeArrays ( headersToValidate , exceptionHeaders , [ ] ) ; } const headers = includedHeaders ( response . headers , headersToValidate ) ; const numberOfHeaders = headers . length ; if ( numberOfHeaders > 0 ) { const message = getMessage ( 'unneededHeaders' , context . language , headers . join ( ', ' ) ) ; context . report ( resource , message , { element , severity : Severity . warning } ) ; } } } ; loadHintConfigs ( ) ; context . on ( 'fetch::end::*' , validate ) ; } }