1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var FILE_URI_MATCH = /\/\/\//;
|
4 | var INVALID_RELATIVE_URL = /[/\\][/\\]/;
|
5 | var VALID_PROTOCOLS = ['https:', 'http:'];
|
6 | var DUMMY_HOSTNAME = 'http://test.com';
|
7 | function isSafe(redirectUrl, _a) {
|
8 | var _b = _a === void 0 ? {} : _a, _c = _b.whitelist, whitelist = _c === void 0 ? [] : _c, _d = _b.subdomains, subdomains = _d === void 0 ? [] : _d, matchPath = _b.matchPath, requireAbsolute = _b.requireAbsolute, requireSSL = _b.requireSSL;
|
9 | if (FILE_URI_MATCH.test(redirectUrl)) {
|
10 | return false;
|
11 | }
|
12 | if (redirectUrl.startsWith('/')) {
|
13 | if (whitelist.length > 0 || subdomains.length > 0 || requireAbsolute || requireSSL) {
|
14 | return false;
|
15 | }
|
16 | if (matchPath) {
|
17 |
|
18 | return pathMatches(new URL(redirectUrl, DUMMY_HOSTNAME), redirectUrl, matchPath);
|
19 | }
|
20 | return !INVALID_RELATIVE_URL.test(redirectUrl);
|
21 | }
|
22 | var url;
|
23 | try {
|
24 | url = new URL(redirectUrl);
|
25 | }
|
26 | catch (error) {
|
27 | return false;
|
28 | }
|
29 | if (!VALID_PROTOCOLS.includes(url.protocol)) {
|
30 | return false;
|
31 | }
|
32 | if (requireSSL && url.protocol !== 'https:') {
|
33 | return false;
|
34 | }
|
35 | if (url.username || url.password) {
|
36 | return false;
|
37 | }
|
38 | if (matchPath && !pathMatches(url, redirectUrl, matchPath)) {
|
39 | return false;
|
40 | }
|
41 | if (!hostIsValid(url, whitelist, subdomains)) {
|
42 | return false;
|
43 | }
|
44 | return true;
|
45 | }
|
46 | exports.isSafe = isSafe;
|
47 | function hostIsValid(url, whitelist, subdomains) {
|
48 | if (!subdomains.every(function (subdomain) { return subdomain.startsWith('.'); })) {
|
49 | throw new TypeError('Subdomains must begin with .');
|
50 | }
|
51 | var hostname = url.hostname;
|
52 | return ((whitelist.length === 0 && subdomains.length === 0) ||
|
53 | whitelist.includes(hostname) ||
|
54 | subdomains.some(function (subdomain) { return hostname.endsWith(subdomain); }));
|
55 | }
|
56 | function pathMatches(url, originalUrl, matcher) {
|
57 | var pathname = url.pathname;
|
58 |
|
59 | var originalPathname = originalUrl.replace(url.origin, '').split('?')[0];
|
60 | return typeof matcher === 'string'
|
61 | ? pathname === matcher && originalPathname === matcher
|
62 | : matcher.test(pathname) && matcher.test(originalPathname);
|
63 | }
|
64 | function makeSafe(url, fallback, options) {
|
65 | return isSafe(url, options) ? encodeURI(url) : fallback;
|
66 | }
|
67 | exports.makeSafe = makeSafe;
|