From 2b67d9214058f5d6e370c60fc20bb8b15d71d2b9 Mon Sep 17 00:00:00 2001 From: Thomas Rientjes <synzvato@protonmail.com> Date: Mon, 6 Nov 2017 00:04:30 -0300 Subject: [PATCH] Refactor existing codebase --- .eslintrc | 17 ++++---------- audit/.eslintrc | 7 ++++++ core/constants.js | 51 ++++++++++++++++++++++++++++++---------- core/interceptor.js | 12 +++++----- core/main.js | 3 ++- core/request-analyzer.js | 26 ++++++++++---------- core/state-manager.js | 20 ++++++++-------- pages/options/options.js | 22 ++++++++--------- pages/popup/popup.js | 14 +++++------ 9 files changed, 100 insertions(+), 72 deletions(-) diff --git a/.eslintrc b/.eslintrc index f898349..b703040 100644 --- a/.eslintrc +++ b/.eslintrc @@ -6,25 +6,18 @@ }, "extends": "eslint:recommended", "globals": { + "Address": true, "files": true, "helpers": true, - "HOST_PREFIX": true, - "HOST_SUFFIX": true, - "HTTP_EXPRESSION": true, "interceptor": true, - "MAPPING_FILE_EXPRESSION": true, "mappings": true, - "REQUEST_BLOCKING": true, - "REQUEST_HEADERS": true, "requestAnalyzer": true, + "Resource": true, "resources": true, + "Setting": true, "stateManager": true, - "VALUE_SEPARATOR": true, - "VERSION_EXPRESSION": true, - "VERSION_PLACEHOLDER": true, - "WEB_DOMAIN_EXPRESSION": true, - "WEB_PREFIX_LENGTH": true, - "WEB_PREFIX_VALUE": true + "WebRequest": true, + "Whitelist": true }, "overrides": { "files": [ diff --git a/audit/.eslintrc b/audit/.eslintrc index c5501dd..7a386a6 100644 --- a/audit/.eslintrc +++ b/audit/.eslintrc @@ -17,6 +17,13 @@ "unix" ], "no-console": "off", + "no-multiple-empty-lines": [ + "error", { + "max": 1, + "maxEOF": 1, + "maxBOF": 0 + } + ], "no-use-before-define": "error", "operator-assignment": "error", "prefer-template": "error", diff --git a/core/constants.js b/core/constants.js index e68440d..07ddd42 100644 --- a/core/constants.js +++ b/core/constants.js @@ -17,15 +17,42 @@ * Constants */ -const HOST_PREFIX = '*://'; -const HOST_SUFFIX = '/*'; -const HTTP_EXPRESSION = /^http?:\/\//; -const MAPPING_FILE_EXPRESSION = /\.map$/i; -const REQUEST_BLOCKING = 'blocking'; -const REQUEST_HEADERS = 'requestHeaders'; -const VALUE_SEPARATOR = ';'; -const VERSION_EXPRESSION = /(?:\d{1,2}\.){1,3}\d{1,2}/; -const VERSION_PLACEHOLDER = '{version}'; -const WEB_DOMAIN_EXPRESSION = /:\/\/(.[^/]+)(.*)/; -const WEB_PREFIX_LENGTH = 4; -const WEB_PREFIX_VALUE = 'www.'; +const Address = { + 'ANY': '*://*/*', + 'ANY_PATH': '/*', + 'ANY_PROTOCOL': '*://', + 'DOMAIN_EXPRESSION': /:\/\/(.[^/]+)(.*)/, + 'EXAMPLE': 'example.org', + 'HTTP_EXPRESSION': /^http?:\/\//, + 'HTTPS': 'https://', + 'WWW_PREFIX': 'www.', + 'WWW_PREFIX_LENGTH': 4 +}; + +const Resource = { + 'MAPPING_EXPRESSION': /\.map$/i, + 'VERSION_EXPRESSION': /(?:\d{1,2}\.){1,3}\d{1,2}/, + 'VERSION_PLACEHOLDER': '{version}' +}; + +const Setting = { + 'AMOUNT_INJECTED': 'amountInjected', + 'BLOCK_MISSING': 'blockMissing', + 'DISABLE_PREFETCH': 'disablePrefetch', + 'SHOW_ICON_BADGE': 'showIconBadge', + 'STRIP_METADATA': 'stripMetadata', + 'WHITELISTED_DOMAINS': 'whitelistedDomains' +}; + +const WebRequest = { + 'GET': 'GET', + 'BLOCKING': 'blocking', + 'HEADERS': 'requestHeaders', + 'ORIGIN_HEADER': 'Origin', + 'REFERER_HEADER': 'Referer' +}; + +const Whitelist = { + 'TRIM_EXPRESSION': /^;+|;+$/g, + 'VALUE_SEPARATOR': ';' +}; diff --git a/core/interceptor.js b/core/interceptor.js index bc125f6..e9b28ce 100644 --- a/core/interceptor.js +++ b/core/interceptor.js @@ -37,10 +37,10 @@ interceptor.handleRequest = function (requestDetails, tabIdentifier, tab) { } try { - tabDomain = tab.url.match(WEB_DOMAIN_EXPRESSION)[1]; + tabDomain = tab.url.match(Address.DOMAIN_EXPRESSION)[1]; tabDomain = requestAnalyzer._normalizeDomain(tabDomain); } catch (exception) { - tabDomain = 'example.org'; + tabDomain = Address.EXAMPLE; } // Temporary list of undetectable tainted domains. @@ -98,9 +98,9 @@ interceptor._handleMissingCandidate = function (requestUrl) { }; } - if (requestUrl.match(HTTP_EXPRESSION)) { + if (requestUrl.match(Address.HTTP_EXPRESSION)) { - let secureRequestUrl = requestUrl.replace(HTTP_EXPRESSION, 'https://'); + let secureRequestUrl = requestUrl.replace(Address.HTTP_EXPRESSION, Address.HTTPS); return { 'redirectUrl': secureRequestUrl @@ -116,7 +116,7 @@ interceptor._handleMissingCandidate = function (requestUrl) { interceptor._handleStorageChanged = function (changes) { - if ('blockMissing' in changes) { + if (Setting.BLOCK_MISSING in changes) { interceptor.blockMissing = changes.blockMissing.newValue; } }; @@ -128,7 +128,7 @@ interceptor._handleStorageChanged = function (changes) { interceptor.amountInjected = 0; interceptor.blockMissing = false; -chrome.storage.local.get(['amountInjected', 'blockMissing'], function (items) { +chrome.storage.local.get([Setting.AMOUNT_INJECTED, Setting.BLOCK_MISSING], function (items) { interceptor.amountInjected = items.amountInjected || 0; interceptor.blockMissing = items.blockMissing || false; diff --git a/core/main.js b/core/main.js index 9bfc787..55632cd 100644 --- a/core/main.js +++ b/core/main.js @@ -54,7 +54,8 @@ main._showReleaseNotes = function (details) { let location = chrome.extension.getURL('pages/welcome/welcome.html'); - if (details.reason === 'install' || details.reason === 'update') { + if (details.reason === chrome.runtime.OnInstalledReason.INSTALL || + details.reason === chrome.runtime.OnInstalledReason.UPDATE) { if (details.temporary !== true) { diff --git a/core/request-analyzer.js b/core/request-analyzer.js index 70b41cb..d84a327 100644 --- a/core/request-analyzer.js +++ b/core/request-analyzer.js @@ -28,9 +28,9 @@ requestAnalyzer.isValidCandidate = function (requestDetails, tabDetails) { let initiatorHost; try { - initiatorHost = tabDetails.url.match(WEB_DOMAIN_EXPRESSION)[1]; + initiatorHost = tabDetails.url.match(Address.DOMAIN_EXPRESSION)[1]; } catch (exception) { - initiatorHost = 'example.org'; + initiatorHost = Address.EXAMPLE; } if (initiatorHost && requestAnalyzer.whitelistedDomains[requestAnalyzer._normalizeDomain(initiatorHost)]) { @@ -38,21 +38,21 @@ requestAnalyzer.isValidCandidate = function (requestDetails, tabDetails) { } // Only requests of type GET can be valid candidates. - return requestDetails.method === 'GET'; + return requestDetails.method === WebRequest.GET; }; requestAnalyzer.getLocalTarget = function (requestDetails) { let destinationHost, destinationPath, hostMappings, basePath, resourceMappings; - destinationHost = requestDetails.url.match(WEB_DOMAIN_EXPRESSION)[1]; - destinationPath = requestDetails.url.match(WEB_DOMAIN_EXPRESSION)[2]; + destinationHost = requestDetails.url.match(Address.DOMAIN_EXPRESSION)[1]; + destinationPath = requestDetails.url.match(Address.DOMAIN_EXPRESSION)[2]; // Use the proper mappings for the targeted host. hostMappings = mappings[destinationHost]; // Resource mapping files are never locally available. - if (MAPPING_FILE_EXPRESSION.test(destinationPath)) { + if (Resource.MAPPING_EXPRESSION.test(destinationPath)) { return false; } @@ -89,8 +89,8 @@ requestAnalyzer._findLocalTarget = function (resourceMappings, basePath, channel resourcePath = channelPath.replace(basePath, ''); - versionNumber = resourcePath.match(VERSION_EXPRESSION); - resourcePattern = resourcePath.replace(versionNumber, VERSION_PLACEHOLDER); + versionNumber = resourcePath.match(Resource.VERSION_EXPRESSION); + resourcePattern = resourcePath.replace(versionNumber, Resource.VERSION_PLACEHOLDER); for (let resourceMold of Object.keys(resourceMappings)) { @@ -99,9 +99,9 @@ requestAnalyzer._findLocalTarget = function (resourceMappings, basePath, channel let targetPath, version; targetPath = resourceMappings[resourceMold].path; - targetPath = targetPath.replace(VERSION_PLACEHOLDER, versionNumber); + targetPath = targetPath.replace(Resource.VERSION_PLACEHOLDER, versionNumber); - version = versionNumber && versionNumber[0] || targetPath.match(VERSION_EXPRESSION); + version = versionNumber && versionNumber[0] || targetPath.match(Resource.VERSION_EXPRESSION); // Prepare and return a local target. return { @@ -117,7 +117,7 @@ requestAnalyzer._findLocalTarget = function (resourceMappings, basePath, channel requestAnalyzer._applyWhitelistedDomains = function () { - chrome.storage.local.get('whitelistedDomains', function (items) { + chrome.storage.local.get(Setting.WHITELISTED_DOMAINS, function (items) { requestAnalyzer.whitelistedDomains = items.whitelistedDomains || {}; }); }; @@ -126,8 +126,8 @@ requestAnalyzer._normalizeDomain = function (domain) { domain = domain.toLowerCase().trim(); - if (domain.startsWith(WEB_PREFIX_VALUE)) { - domain = domain.slice(WEB_PREFIX_LENGTH); + if (domain.startsWith(Address.WWW_PREFIX)) { + domain = domain.slice(Address.WWW_PREFIX_LENGTH); } return domain; diff --git a/core/state-manager.js b/core/state-manager.js index bfe475d..6a4c798 100644 --- a/core/state-manager.js +++ b/core/state-manager.js @@ -53,7 +53,7 @@ stateManager.registerInjection = function (tabIdentifier, injection) { if (isNaN(interceptor.amountInjected)) { - chrome.storage.local.get('amountInjected', function (items) { + chrome.storage.local.get(Setting.AMOUNT_INJECTED, function (items) { interceptor.amountInjected = items.amountInjected; @@ -121,7 +121,7 @@ stateManager._createTab = function (tab) { }); }); - }, requestFilters, [REQUEST_BLOCKING]); + }, requestFilters, [WebRequest.BLOCKING]); }; stateManager._removeTab = function (tabIdentifier) { @@ -156,9 +156,9 @@ stateManager._stripMetadata = function (requestDetails) { for (let i = 0; i < requestDetails.requestHeaders.length; ++i) { - if (requestDetails.requestHeaders[i].name === 'Origin') { + if (requestDetails.requestHeaders[i].name === WebRequest.ORIGIN_HEADER) { requestDetails.requestHeaders.splice(i--, 1); - } else if (requestDetails.requestHeaders[i].name === 'Referer') { + } else if (requestDetails.requestHeaders[i].name === WebRequest.REFERER_HEADER) { requestDetails.requestHeaders.splice(i--, 1); } } @@ -190,13 +190,13 @@ stateManager._handleStorageChanged = function (changes) { onBeforeSendHeaders.removeListener(stateManager._stripMetadata, { 'urls': stateManager.validHosts - }, [REQUEST_BLOCKING, REQUEST_HEADERS]); + }, [WebRequest.BLOCKING, WebRequest.HEADERS]); if (changes.stripMetadata.newValue !== false) { onBeforeSendHeaders.addListener(stateManager._stripMetadata, { 'urls': stateManager.validHosts - }, [REQUEST_BLOCKING, REQUEST_HEADERS]); + }, [WebRequest.BLOCKING, WebRequest.HEADERS]); } } }; @@ -219,7 +219,7 @@ stateManager.validHosts = []; for (let mapping in mappings) { - let supportedHost = HOST_PREFIX + mapping + HOST_SUFFIX; + let supportedHost = Address.ANY_PROTOCOL + mapping + Address.ANY_PATH; stateManager.validHosts.push(supportedHost); } @@ -248,7 +248,7 @@ chrome.webRequest.onErrorOccurred.addListener(function (requestDetails) { delete stateManager.requests[requestDetails.requestId]; } -}, {'urls': ['*://*/*']}); +}, {'urls': [Address.ANY]}); chrome.webRequest.onBeforeRedirect.addListener(function (requestDetails) { @@ -260,10 +260,10 @@ chrome.webRequest.onBeforeRedirect.addListener(function (requestDetails) { delete stateManager.requests[requestDetails.requestId]; } -}, {'urls': ['*://*/*']}); +}, {'urls': [Address.ANY]}); chrome.webRequest.onBeforeSendHeaders.addListener(stateManager._stripMetadata, { 'urls': stateManager.validHosts -}, [REQUEST_BLOCKING, REQUEST_HEADERS]); +}, [WebRequest.BLOCKING, WebRequest.HEADERS]); chrome.storage.onChanged.addListener(stateManager._handleStorageChanged); diff --git a/pages/options/options.js b/pages/options/options.js index d91d2cc..ed6e8e2 100644 --- a/pages/options/options.js +++ b/pages/options/options.js @@ -31,8 +31,8 @@ function _normalizeDomain (domain) { domain = domain.toLowerCase().trim(); - if (domain.startsWith(WEB_PREFIX_VALUE)) { - domain = domain.slice(WEB_PREFIX_LENGTH); + if (domain.startsWith(Address.WWW_PREFIX)) { + domain = domain.slice(Address.WWW_PREFIX_LENGTH); } return domain; @@ -60,11 +60,11 @@ document.addEventListener('DOMContentLoaded', function () { helpers.insertI18nContentIntoDocument(document); optionElements = { - 'showIconBadge': options._getOptionElement('showIconBadge'), - 'blockMissing': options._getOptionElement('blockMissing'), - 'disablePrefetch': options._getOptionElement('disablePrefetch'), - 'stripMetadata': options._getOptionElement('stripMetadata'), - 'whitelistedDomains': options._getOptionElement('whitelistedDomains') + 'showIconBadge': options._getOptionElement(Setting.SHOW_ICON_BADGE), + 'blockMissing': options._getOptionElement(Setting.BLOCK_MISSING), + 'disablePrefetch': options._getOptionElement(Setting.DISABLE_PREFETCH), + 'stripMetadata': options._getOptionElement(Setting.STRIP_METADATA), + 'whitelistedDomains': options._getOptionElement(Setting.WHITELISTED_DOMAINS) }; chrome.storage.local.get(Object.keys(optionElements), function (items) { @@ -79,7 +79,7 @@ document.addEventListener('DOMContentLoaded', function () { }); domainWhitelist = domainWhitelist.slice(0, -1); - domainWhitelist = domainWhitelist.replace(/^;+|;+$/g, ''); + domainWhitelist = domainWhitelist.replace(Whitelist.TRIM_EXPRESSION, ''); optionElements.showIconBadge.checked = items.showIconBadge; optionElements.blockMissing.checked = items.blockMissing; @@ -103,7 +103,7 @@ document.addEventListener('DOMContentLoaded', function () { optionValue = target.value; } - if (optionKey === 'disablePrefetch') { + if (optionKey === Setting.DISABLE_PREFETCH) { if (optionValue === false) { @@ -118,13 +118,13 @@ document.addEventListener('DOMContentLoaded', function () { } } - if (optionKey === 'whitelistedDomains') { + if (optionKey === Setting.WHITELISTED_DOMAINS) { let domainWhitelist = optionValue; optionValue = {}; - domainWhitelist.split(VALUE_SEPARATOR).forEach(function (domain) { + domainWhitelist.split(Whitelist.VALUE_SEPARATOR).forEach(function (domain) { optionValue[_normalizeDomain(domain)] = true; }); } diff --git a/pages/popup/popup.js b/pages/popup/popup.js index cda7eaf..73ddce6 100644 --- a/pages/popup/popup.js +++ b/pages/popup/popup.js @@ -51,7 +51,7 @@ document.addEventListener('DOMContentLoaded', function () { popup.backgroundPage = backgroundPage; - if (backgroundPage.main.operatingSystem === 'android') { + if (backgroundPage.main.operatingSystem === chrome.runtime.PlatformOs.ANDROID) { browser.tabs.getCurrent().then(function (tab) { @@ -67,7 +67,7 @@ document.addEventListener('DOMContentLoaded', function () { injectionOverview = {}; try { - domain = tabs[0].url.match(WEB_DOMAIN_EXPRESSION)[1]; + domain = tabs[0].url.match(Address.DOMAIN_EXPRESSION)[1]; } catch (exception) { domain = null; } @@ -80,8 +80,8 @@ document.addEventListener('DOMContentLoaded', function () { protectionToggleElement = document.getElementById('protection-toggle-button'); domainIndicatorElement = document.getElementById('domain-indicator'); - if (domain.startsWith(WEB_PREFIX_VALUE)) { - domain = domain.slice(WEB_PREFIX_LENGTH); + if (domain.startsWith(Address.WWW_PREFIX)) { + domain = domain.slice(Address.WWW_PREFIX_LENGTH); } domainIndicatorElement.innerText = domain; @@ -99,7 +99,7 @@ document.addEventListener('DOMContentLoaded', function () { chrome.tabs.reload(tabs[0].id); - if (backgroundPage.main.operatingSystem === 'android') { + if (backgroundPage.main.operatingSystem === chrome.runtime.PlatformOs.ANDROID) { return browser.tabs.getCurrent().then(function (tab) { browser.tabs.remove(tab.id); @@ -125,7 +125,7 @@ document.addEventListener('DOMContentLoaded', function () { chrome.tabs.reload(tabs[0].id); - if (backgroundPage.main.operatingSystem === 'android') { + if (backgroundPage.main.operatingSystem === chrome.runtime.PlatformOs.ANDROID) { return browser.tabs.getCurrent().then(function (tab) { browser.tabs.remove(tab.id); @@ -225,7 +225,7 @@ document.addEventListener('DOMContentLoaded', function () { optionsButtonElement.addEventListener('mouseup', function () { - if (popup.backgroundPage.main.operatingSystem === 'android') { + if (popup.backgroundPage.main.operatingSystem === chrome.runtime.PlatformOs.ANDROID) { return chrome.tabs.create({ 'url': chrome.extension.getURL('pages/options/options.html') -- GitLab