279 lines
12 KiB
JavaScript
279 lines
12 KiB
JavaScript
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
'use strict';
|
|
|
|
import urlUtils, {getFormattedPathName, isUrlType, equalUrlsIgnoringSubpath, equalUrlsWithSubpath} from 'common/utils/url';
|
|
|
|
jest.mock('common/tabs/TabView', () => ({
|
|
getServerView: (srv, tab) => {
|
|
return {
|
|
name: `${srv.name}_${tab.name}`,
|
|
url: `${srv.url}${srv.url.toString().endsWith('/') ? '' : '/'}${tab.name.split('-')[1] || ''}`,
|
|
};
|
|
},
|
|
}));
|
|
|
|
describe('common/utils/url', () => {
|
|
describe('isValidURL', () => {
|
|
it('should be true for a valid web url', () => {
|
|
const testURL = 'https://developers.mattermost.com/';
|
|
expect(urlUtils.isValidURL(testURL)).toBe(true);
|
|
});
|
|
it('should be true for a valid, non-https web url', () => {
|
|
const testURL = 'http://developers.mattermost.com/';
|
|
expect(urlUtils.isValidURL(testURL)).toBe(true);
|
|
});
|
|
it('should be true for an invalid, self-defined, top-level domain', () => {
|
|
const testURL = 'https://www.example.x';
|
|
expect(urlUtils.isValidURL(testURL)).toBe(true);
|
|
});
|
|
it('should be true for a file download url', () => {
|
|
const testURL = 'https://community.mattermost.com/api/v4/files/ka3xbfmb3ffnmgdmww8otkidfw?download=1';
|
|
expect(urlUtils.isValidURL(testURL)).toBe(true);
|
|
});
|
|
it('should be true for a permalink url', () => {
|
|
const testURL = 'https://community.mattermost.com/test-channel/pl/pdqowkij47rmbyk78m5hwc7r6r';
|
|
expect(urlUtils.isValidURL(testURL)).toBe(true);
|
|
});
|
|
it('should be true for a valid, internal domain', () => {
|
|
const testURL = 'https://mattermost.company-internal';
|
|
expect(urlUtils.isValidURL(testURL)).toBe(true);
|
|
});
|
|
it('should be true for a second, valid internal domain', () => {
|
|
const testURL = 'https://serverXY/mattermost';
|
|
expect(urlUtils.isValidURL(testURL)).toBe(true);
|
|
});
|
|
it('should be true for a valid, non-https internal domain', () => {
|
|
const testURL = 'http://mattermost.local';
|
|
expect(urlUtils.isValidURL(testURL)).toBe(true);
|
|
});
|
|
it('should be true for a valid, non-https, ip address with port number', () => {
|
|
const testURL = 'http://localhost:8065';
|
|
expect(urlUtils.isValidURL(testURL)).toBe(true);
|
|
});
|
|
});
|
|
describe('isValidURI', () => {
|
|
it('should be true for a deeplink url', () => {
|
|
const testURL = 'mattermost://community-release.mattermost.com/core/channels/developers';
|
|
expect(urlUtils.isValidURI(testURL)).toBe(true);
|
|
});
|
|
it('should be false for a malicious url', () => {
|
|
const testURL = String.raw`mattermost:///" --data-dir "\\deans-mbp\mattermost`;
|
|
expect(urlUtils.isValidURI(testURL)).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('getHost', () => {
|
|
it('should return the origin of a well formed url', () => {
|
|
const myurl = 'https://mattermost.com/download';
|
|
expect(urlUtils.getHost(myurl)).toBe('https://mattermost.com');
|
|
});
|
|
|
|
it('shoud raise an error on malformed urls', () => {
|
|
const myurl = 'http://example.com:-80/';
|
|
expect(() => {
|
|
urlUtils.getHost(myurl);
|
|
}).toThrow(SyntaxError);
|
|
});
|
|
});
|
|
|
|
describe('parseURL', () => {
|
|
it('should return the URL if it is already a URL', () => {
|
|
const url = new URL('http://mattermost.com');
|
|
expect(urlUtils.parseURL(url)).toBe(url);
|
|
});
|
|
|
|
it('should return undefined when a bad url is passed', () => {
|
|
const badURL = 'not-a-real-url-at-all';
|
|
expect(urlUtils.parseURL(badURL)).toBe(undefined);
|
|
});
|
|
|
|
it('should remove duplicate slashes in a URL when parsing', () => {
|
|
const urlWithExtraSlashes = 'https://mattermost.com//sub//path//example';
|
|
const parsedURL = urlUtils.parseURL(urlWithExtraSlashes);
|
|
|
|
expect(parsedURL.toString()).toBe('https://mattermost.com/sub/path/example');
|
|
});
|
|
});
|
|
|
|
describe('isInternalURL', () => {
|
|
it('should return false on different hosts', () => {
|
|
const baseURL = new URL('http://mattermost.com');
|
|
const externalURL = new URL('http://google.com');
|
|
|
|
expect(urlUtils.isInternalURL(externalURL, baseURL)).toBe(false);
|
|
});
|
|
|
|
it('should return false on different ports', () => {
|
|
const baseURL = new URL('http://mattermost.com:8080');
|
|
const externalURL = new URL('http://mattermost.com:9001');
|
|
|
|
expect(urlUtils.isInternalURL(externalURL, baseURL)).toBe(false);
|
|
});
|
|
|
|
it('should return false on different subpaths', () => {
|
|
const baseURL = new URL('http://mattermost.com/sub/path/');
|
|
const externalURL = new URL('http://mattermost.com/different/sub/path');
|
|
|
|
expect(urlUtils.isInternalURL(externalURL, baseURL)).toBe(false);
|
|
});
|
|
|
|
it('should return true if matching', () => {
|
|
const baseURL = new URL('http://mattermost.com/');
|
|
const externalURL = new URL('http://mattermost.com');
|
|
|
|
expect(urlUtils.isInternalURL(externalURL, baseURL)).toBe(true);
|
|
});
|
|
|
|
it('should return true if matching with subpath', () => {
|
|
const baseURL = new URL('http://mattermost.com/sub/path/');
|
|
const externalURL = new URL('http://mattermost.com/sub/path');
|
|
|
|
expect(urlUtils.isInternalURL(externalURL, baseURL)).toBe(true);
|
|
});
|
|
|
|
it('should return true if subpath of', () => {
|
|
const baseURL = new URL('http://mattermost.com/');
|
|
const externalURL = new URL('http://mattermost.com/sub/path');
|
|
|
|
expect(urlUtils.isInternalURL(externalURL, baseURL)).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('getFormattedPathName', () => {
|
|
it('should format all to lower case', () => {
|
|
const unformattedPathName = '/aAbBbB/cC/DdeR/';
|
|
expect(getFormattedPathName(unformattedPathName)).toBe('/aabbbb/cc/dder/');
|
|
});
|
|
|
|
it('should add trailing slash', () => {
|
|
const unformattedPathName = '/aAbBbB/cC/DdeR';
|
|
expect(getFormattedPathName(unformattedPathName)).toBe('/aabbbb/cc/dder/');
|
|
});
|
|
});
|
|
|
|
describe('isUrlType', () => {
|
|
const serverURL = new URL('http://mattermost.com');
|
|
const urlType = 'url-type';
|
|
|
|
it('should identify base url', () => {
|
|
const adminURL = new URL(`http://mattermost.com/${urlType}`);
|
|
expect(isUrlType('url-type', serverURL, adminURL)).toBe(true);
|
|
});
|
|
|
|
it('should identify url of correct type', () => {
|
|
const adminURL = new URL(`http://mattermost.com/${urlType}/some/path`);
|
|
expect(isUrlType('url-type', serverURL, adminURL)).toBe(true);
|
|
});
|
|
|
|
it('should not identify other url', () => {
|
|
const adminURL = new URL('http://mattermost.com/some/other/path');
|
|
expect(isUrlType('url-type', serverURL, adminURL)).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('equalUrls', () => {
|
|
it('base urls', () => {
|
|
const url1 = new URL('http://server-1.com');
|
|
const url2 = new URL('http://server-1.com');
|
|
expect(equalUrlsIgnoringSubpath(url1, url2)).toBe(true);
|
|
expect(equalUrlsWithSubpath(url1, url2)).toBe(true);
|
|
});
|
|
|
|
it('different urls', () => {
|
|
const url1 = new URL('http://server-1.com');
|
|
const url2 = new URL('http://server-2.com');
|
|
expect(equalUrlsIgnoringSubpath(url1, url2)).toBe(false);
|
|
expect(equalUrlsWithSubpath(url1, url2)).toBe(false);
|
|
});
|
|
|
|
it('same host, different subpath', () => {
|
|
const url1 = new URL('http://server-1.com/subpath');
|
|
const url2 = new URL('http://server-1.com');
|
|
expect(equalUrlsIgnoringSubpath(url1, url2)).toBe(true);
|
|
expect(equalUrlsWithSubpath(url1, url2)).toBe(false);
|
|
});
|
|
|
|
it('same host and subpath', () => {
|
|
const url1 = new URL('http://server-1.com/subpath');
|
|
const url2 = new URL('http://server-1.com/subpath');
|
|
expect(equalUrlsIgnoringSubpath(url1, url2)).toBe(true);
|
|
expect(equalUrlsWithSubpath(url1, url2)).toBe(true);
|
|
});
|
|
|
|
it('same host, different URL scheme', () => {
|
|
const url1 = new URL('http://server-1.com');
|
|
const url2 = new URL('mattermost://server-1.com');
|
|
expect(equalUrlsIgnoringSubpath(url1, url2)).toBe(false);
|
|
expect(equalUrlsWithSubpath(url1, url2)).toBe(false);
|
|
});
|
|
|
|
it('same host, different URL scheme, with ignore scheme', () => {
|
|
const url1 = new URL('http://server-1.com');
|
|
const url2 = new URL('mattermost://server-1.com');
|
|
expect(equalUrlsIgnoringSubpath(url1, url2, true)).toBe(true);
|
|
expect(equalUrlsWithSubpath(url1, url2, true)).toBe(true);
|
|
});
|
|
|
|
it('same host, different ports', () => {
|
|
const url1 = new URL('http://server-1.com:8080');
|
|
const url2 = new URL('http://server-1.com');
|
|
expect(equalUrlsIgnoringSubpath(url1, url2, true)).toBe(false);
|
|
expect(equalUrlsWithSubpath(url1, url2, true)).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('cleanPathName', () => {
|
|
it('should not clean path name if it occurs other than the beginning', () => {
|
|
expect(urlUtils.cleanPathName('/mattermost', '/home/channels/mattermost/test')).toBe('/home/channels/mattermost/test');
|
|
});
|
|
|
|
it('should clean path name if it occurs at the beginning', () => {
|
|
expect(urlUtils.cleanPathName('/mattermost', '/mattermost/channels/home/test')).toBe('/channels/home/test');
|
|
});
|
|
|
|
it('should do nothing if it doesnt occur', () => {
|
|
expect(urlUtils.cleanPathName('/mattermost', '/channels/home/test')).toBe('/channels/home/test');
|
|
});
|
|
});
|
|
|
|
describe('isCustomLoginURL', () => {
|
|
it('should match correct URL', () => {
|
|
expect(urlUtils.isCustomLoginURL(
|
|
'http://server.com/oauth/authorize',
|
|
'http://server.com',
|
|
)).toBe(true);
|
|
});
|
|
it('should not match incorrect URL', () => {
|
|
expect(urlUtils.isCustomLoginURL(
|
|
'http://server.com/oauth/notauthorize',
|
|
'http://server.com',
|
|
)).toBe(false);
|
|
});
|
|
it('should not match base URL', () => {
|
|
expect(urlUtils.isCustomLoginURL(
|
|
'http://server.com/',
|
|
'http://server.com',
|
|
)).toBe(false);
|
|
});
|
|
it('should match with subpath', () => {
|
|
expect(urlUtils.isCustomLoginURL(
|
|
'http://server.com/subpath/oauth/authorize',
|
|
'http://server.com/subpath',
|
|
)).toBe(true);
|
|
});
|
|
it('should not match with different subpath', () => {
|
|
expect(urlUtils.isCustomLoginURL(
|
|
'http://server.com/subpath/oauth/authorize',
|
|
'http://server.com/different/subpath',
|
|
)).toBe(false);
|
|
});
|
|
it('should not match with oauth subpath', () => {
|
|
expect(urlUtils.isCustomLoginURL(
|
|
'http://server.com/oauth/authorize',
|
|
'http://server.com/oauth/authorize',
|
|
)).toBe(false);
|
|
});
|
|
});
|
|
});
|