12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- 'use strict';
- const { parse } = require('url');
- const Cache = require('./cache');
- const cache = new Cache();
- /**
- * Check whether the link is external
- * @param {String} input The url to check
- * @param {String} input The hostname / url of website
- * @param {Array} input Exclude hostnames. Specific subdomain is required when applicable, including www.
- * @returns {Boolean} True if the link doesn't have protocol or link has same host with config.url
- */
- function isExternalLink(input, sitehost, exclude) {
- return cache.apply(`${input}-${sitehost}-${exclude}`, () => {
- // Return false early for internal link
- if (!/^(\/\/|http(s)?:)/.test(input)) return false;
- sitehost = parse(sitehost).hostname || sitehost;
- if (!sitehost) return false;
- // handle relative url and invalid url
- let data;
- try {
- data = new URL(input, `http://${sitehost}`);
- } catch (e) { }
- // if input is invalid url, data should be undefined
- if (typeof data !== 'object') return false;
- // handle mailto: javascript: vbscript: and so on
- if (data.origin === 'null') return false;
- const host = data.hostname;
- if (exclude) {
- exclude = Array.isArray(exclude) ? exclude : [exclude];
- if (exclude && exclude.length) {
- for (const i of exclude) {
- if (host === i) return false;
- }
- }
- }
- if (host !== sitehost) return true;
- return false;
- });
- }
- module.exports = isExternalLink;
|