"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = getDomain; /** * Check if `vhost` is a valid suffix of `hostname` (top-domain) * * It means that `vhost` needs to be a suffix of `hostname` and we then need to * make sure that: either they are equal, or the character preceding `vhost` in * `hostname` is a '.' (it should not be a partial label). * * * hostname = 'not.evil.com' and vhost = 'vil.com' => not ok * * hostname = 'not.evil.com' and vhost = 'evil.com' => ok * * hostname = 'not.evil.com' and vhost = 'not.evil.com' => ok */ function shareSameDomainSuffix(hostname, vhost) { if (hostname.endsWith(vhost)) { return (hostname.length === vhost.length || hostname[hostname.length - vhost.length - 1] === '.'); } return false; } /** * Given a hostname and its public suffix, extract the general domain. */ function extractDomainWithSuffix(hostname, publicSuffix) { // Locate the index of the last '.' in the part of the `hostname` preceding // the public suffix. // // examples: // 1. not.evil.co.uk => evil.co.uk // ^ ^ // | | start of public suffix // | index of the last dot // // 2. example.co.uk => example.co.uk // ^ ^ // | | start of public suffix // | // | (-1) no dot found before the public suffix const publicSuffixIndex = hostname.length - publicSuffix.length - 2; const lastDotBeforeSuffixIndex = hostname.lastIndexOf('.', publicSuffixIndex); // No '.' found, then `hostname` is the general domain (no sub-domain) if (lastDotBeforeSuffixIndex === -1) { return hostname; } // Extract the part between the last '.' return hostname.slice(lastDotBeforeSuffixIndex + 1); } /** * Detects the domain based on rules and upon and a host string */ function getDomain(suffix, hostname, options) { // Check if `hostname` ends with a member of `validHosts`. if (options.validHosts !== null) { const validHosts = options.validHosts; for (const vhost of validHosts) { if ( /*@__INLINE__*/shareSameDomainSuffix(hostname, vhost)) { return vhost; } } } let numberOfLeadingDots = 0; if (hostname.startsWith('.')) { while (numberOfLeadingDots < hostname.length && hostname[numberOfLeadingDots] === '.') { numberOfLeadingDots += 1; } } // If `hostname` is a valid public suffix, then there is no domain to return. // Since we already know that `getPublicSuffix` returns a suffix of `hostname` // there is no need to perform a string comparison and we only compare the // size. if (suffix.length === hostname.length - numberOfLeadingDots) { return null; } // To extract the general domain, we start by identifying the public suffix // (if any), then consider the domain to be the public suffix with one added // level of depth. (e.g.: if hostname is `not.evil.co.uk` and public suffix: // `co.uk`, then we take one more level: `evil`, giving the final result: // `evil.co.uk`). return /*@__INLINE__*/ extractDomainWithSuffix(hostname, suffix); } //# sourceMappingURL=domain.js.map