From 59bc03d6ab578ebdd258d388e88191c99ae4a800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Vay=C3=A1?= Date: Fri, 14 Feb 2020 22:08:15 +0100 Subject: [PATCH] [MM-22558] fix loginurls on subpath and server's with team in the url (#1192) * fix loginurls on subpath and server's with team in the url * remove console logs * support both subpath and teamurls * improve readability --- src/main.js | 22 ++++++++++++++++++---- src/utils/util.js | 33 ++++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/main.js b/src/main.js index 1020340e..16e86d72 100644 --- a/src/main.js +++ b/src/main.js @@ -448,11 +448,13 @@ function handleAppWebContentsCreated(dc, contents) { contents.on('will-navigate', (event, url) => { const contentID = event.sender.id; const parsedURL = Utils.parseURL(url); - const serverURL = Utils.getServer(parsedURL, config.teams); - if ((serverURL !== null && Utils.isTeamUrl(serverURL.url, parsedURL)) || isTrustedPopupWindow(event.sender)) { + const server = Utils.getServer(parsedURL, config.teams); + + if ((server !== null && Utils.isTeamUrl(server.url, parsedURL)) || isTrustedPopupWindow(event.sender)) { return; } - if (isCustomLoginURL(parsedURL)) { + + if (isCustomLoginURL(parsedURL, server)) { return; } if (parsedURL.protocol === 'mailto:') { @@ -976,7 +978,8 @@ function isTrustedPopupWindow(webContents) { return BrowserWindow.fromWebContents(webContents) === popupWindow; } -function isCustomLoginURL(url) { +function isCustomLoginURL(url, server) { + const subpath = (server === null || typeof server === 'undefined') ? '' : server.url.pathname; const parsedURL = Utils.parseURL(url); if (!parsedURL) { return false; @@ -985,6 +988,17 @@ function isCustomLoginURL(url) { return false; } const urlPath = parsedURL.pathname; + if ((subpath !== '' || subpath !== '/') && urlPath.startsWith(subpath)) { + const replacement = subpath.endsWith('/') ? '/' : ''; + const replacedPath = urlPath.replace(subpath, replacement); + for (const regexPath of customLoginRegexPaths) { + if (replacedPath.match(regexPath)) { + return true; + } + } + } + + // if there is no subpath, or we are adding the team and got redirected to the real server it'll be caught here for (const regexPath of customLoginRegexPaths) { if (urlPath.match(regexPath)) { return true; diff --git a/src/utils/util.js b/src/utils/util.js index 46795732..b3d4edce 100644 --- a/src/utils/util.js +++ b/src/utils/util.js @@ -63,14 +63,17 @@ function getServerInfo(serverUrl) { function isTeamUrl(serverUrl, inputUrl, withApi) { const parsedURL = parseURL(inputUrl); const server = getServerInfo(serverUrl); - if (!parsedURL || !server) { + if (!parsedURL || !server || (!equalUrlsIgnoringSubpath(server, parsedURL))) { return null; } + const nonTeamUrlPaths = ['plugins', 'signup', 'login', 'admin', 'channel', 'post', 'oauth', 'admin_console']; if (withApi) { nonTeamUrlPaths.push('api'); } - return !(nonTeamUrlPaths.some((testPath) => parsedURL.pathname.toLowerCase().startsWith(`${server.subpath}${testPath}/`))); + return !(nonTeamUrlPaths.some((testPath) => ( + parsedURL.pathname.toLowerCase().startsWith(`${server.subpath}${testPath}/`) || + parsedURL.pathname.toLowerCase().startsWith(`/${testPath}/`)))); } function isPluginUrl(serverUrl, inputURL) { @@ -79,7 +82,10 @@ function isPluginUrl(serverUrl, inputURL) { if (!parsedURL || !server) { return false; } - return server.origin === parsedURL.origin && parsedURL.pathname.toLowerCase().startsWith(`${server.subpath}plugins/`); + return ( + equalUrlsIgnoringSubpath(server, parsedURL) && + (parsedURL.pathname.toLowerCase().startsWith(`${server.subpath}plugins/`) || + parsedURL.pathname.toLowerCase().startsWith('/plugins/'))); } function getServer(inputURL, teams) { @@ -88,15 +94,23 @@ function getServer(inputURL, teams) { return null; } let parsedServerUrl; + let secondOption = null; for (let i = 0; i < teams.length; i++) { parsedServerUrl = parseURL(teams[i].url); // check server and subpath matches (without subpath pathname is \ so it always matches) - if (parsedServerUrl.origin === parsedURL.origin && parsedURL.pathname.startsWith(parsedServerUrl.pathname)) { + if (equalUrlsWithSubpath(parsedServerUrl, parsedURL)) { return {name: teams[i].name, url: parsedServerUrl, index: i}; } + if (equalUrlsIgnoringSubpath(parsedServerUrl, parsedURL)) { + // in case the user added something on the path that doesn't really belong to the server + // there might be more than one that matches, but we can't differentiate, so last one + // is as good as any other in case there is no better match (e.g.: two subpath servers with the same origin) + // e.g.: https://community.mattermost.com/core + secondOption = {name: teams[i].name, url: parsedServerUrl, index: i}; + } } - return null; + return secondOption; } function getDisplayBoundaries() { @@ -116,6 +130,15 @@ function getDisplayBoundaries() { }); } +// next two functions are defined to clarify intent +function equalUrlsWithSubpath(url1, url2) { + return url1.origin === url2.origin && url2.pathname.toLowerCase().startsWith(url1.pathname.toLowerCase()); +} + +function equalUrlsIgnoringSubpath(url1, url2) { + return url1.origin.toLowerCase() === url2.origin.toLowerCase(); +} + export default { getDomain, isValidURL,