82 lines
2.9 KiB
JavaScript
82 lines
2.9 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.sanitizeUrl = void 0;
|
|
var constants_1 = require("./constants");
|
|
function isRelativeUrlWithoutProtocol(url) {
|
|
return constants_1.relativeFirstCharacters.indexOf(url[0]) > -1;
|
|
}
|
|
function decodeHtmlCharacters(str) {
|
|
var removedNullByte = str.replace(constants_1.ctrlCharactersRegex, "");
|
|
return removedNullByte.replace(constants_1.htmlEntitiesRegex, function (match, dec) {
|
|
return String.fromCharCode(dec);
|
|
});
|
|
}
|
|
function isValidUrl(url) {
|
|
return URL.canParse(url);
|
|
}
|
|
function decodeURI(uri) {
|
|
try {
|
|
return decodeURIComponent(uri);
|
|
}
|
|
catch (e) {
|
|
// Ignoring error
|
|
// It is possible that the URI contains a `%` not associated
|
|
// with URI/URL-encoding.
|
|
return uri;
|
|
}
|
|
}
|
|
function sanitizeUrl(url) {
|
|
if (!url) {
|
|
return constants_1.BLANK_URL;
|
|
}
|
|
var charsToDecode;
|
|
var decodedUrl = decodeURI(url.trim());
|
|
do {
|
|
decodedUrl = decodeHtmlCharacters(decodedUrl)
|
|
.replace(constants_1.htmlCtrlEntityRegex, "")
|
|
.replace(constants_1.ctrlCharactersRegex, "")
|
|
.replace(constants_1.whitespaceEscapeCharsRegex, "")
|
|
.trim();
|
|
decodedUrl = decodeURI(decodedUrl);
|
|
charsToDecode =
|
|
decodedUrl.match(constants_1.ctrlCharactersRegex) ||
|
|
decodedUrl.match(constants_1.htmlEntitiesRegex) ||
|
|
decodedUrl.match(constants_1.htmlCtrlEntityRegex) ||
|
|
decodedUrl.match(constants_1.whitespaceEscapeCharsRegex);
|
|
} while (charsToDecode && charsToDecode.length > 0);
|
|
var sanitizedUrl = decodedUrl;
|
|
if (!sanitizedUrl) {
|
|
return constants_1.BLANK_URL;
|
|
}
|
|
if (isRelativeUrlWithoutProtocol(sanitizedUrl)) {
|
|
return sanitizedUrl;
|
|
}
|
|
// Remove any leading whitespace before checking the URL scheme
|
|
var trimmedUrl = sanitizedUrl.trimStart();
|
|
var urlSchemeParseResults = trimmedUrl.match(constants_1.urlSchemeRegex);
|
|
if (!urlSchemeParseResults) {
|
|
return sanitizedUrl;
|
|
}
|
|
var urlScheme = urlSchemeParseResults[0].toLowerCase().trim();
|
|
if (constants_1.invalidProtocolRegex.test(urlScheme)) {
|
|
return constants_1.BLANK_URL;
|
|
}
|
|
var backSanitized = trimmedUrl.replace(/\\/g, "/");
|
|
// Handle special cases for mailto: and custom deep-link protocols
|
|
if (urlScheme === "mailto:" || urlScheme.includes("://")) {
|
|
return backSanitized;
|
|
}
|
|
// For http and https URLs, perform additional validation
|
|
if (urlScheme === "http:" || urlScheme === "https:") {
|
|
if (!isValidUrl(backSanitized)) {
|
|
return constants_1.BLANK_URL;
|
|
}
|
|
var url_1 = new URL(backSanitized);
|
|
url_1.protocol = url_1.protocol.toLowerCase();
|
|
url_1.hostname = url_1.hostname.toLowerCase();
|
|
return url_1.toString();
|
|
}
|
|
return backSanitized;
|
|
}
|
|
exports.sanitizeUrl = sanitizeUrl;
|