From f05cc7bae94537f521feeb79eecec1b2aada0cf9 Mon Sep 17 00:00:00 2001 From: Phuc H Date: Sun, 27 Oct 2024 16:04:24 +0700 Subject: [PATCH 1/3] feat(v3): blocking feature works --- frontend/js/background.js | 168 +++++++++++++++++++++++-------------- frontend/js/features.js | 15 ++-- frontend/js/psl-wrapper.js | 5 ++ frontend/manifest.json | 22 +++-- 4 files changed, 135 insertions(+), 75 deletions(-) create mode 100644 frontend/js/psl-wrapper.js diff --git a/frontend/js/background.js b/frontend/js/background.js index 512ad0b..a37e2af 100644 --- a/frontend/js/background.js +++ b/frontend/js/background.js @@ -1,11 +1,12 @@ /* global chrome*/ /* global psl*/ // global variables, accessed in plugin_ui.js via chrome.extension.getBackgroundPage() -window.isWhiteList = {}; -window.isBlocked = {}; -window.results = {}; -window.isPhish = {}; -window.legitimatePercents = {}; +import psl from './psl-wrapper.js'; +let isWhiteList = {}; +let isBlocked = {}; +let results = {}; +let isPhish = {}; +let legitimatePercents = {}; // File level variables @@ -87,13 +88,12 @@ const fetchCLF = (callback) => { const classify = (tabId, result, url) => { - /** * If this site is on whitelist, we don't need to classify it anymore * I return it here because don't know where to disable the ML event, should not trigger this * event later */ - if (window.isWhiteList[tabId] == url) { + if (isWhiteList[tabId] == url) { return; } @@ -111,19 +111,19 @@ const classify = (tabId, result, url) => { legitimateCount++; } } - window.legitimatePercents[tabId] = ( + legitimatePercents[tabId] = ( legitimateCount / (phishingCount + suspiciousCount + legitimateCount) * 100); if (result.length) { const X = [result.map((row) => parseInt(row))]; fetchCLF(function(clf) { const rf = randomForest(clf); - window.isPhish[tabId] = rf.predict(X)[0][0]; + isPhish[tabId] = rf.predict(X)[0][0]; //TODO: correction - if (window.isPhish[tabId] && window.legitimatePercents[tabId] > 60) { - window.isPhish[tabId] = false; + if (isPhish[tabId] && legitimatePercents[tabId] > 60) { + isPhish[tabId] = false; } - updateBadge(window.isPhish[tabId], window.legitimatePercents[tabId], tabId); + updateBadge(isPhish[tabId], legitimatePercents[tabId], tabId); }); } }; @@ -164,20 +164,24 @@ const blockingFunction = (url, blackSite, tabId) => { lenient: inputBlockLenient, favicon: `https://www.google.com/s2/favicons?domain=${url}`, }; - window.isBlocked[tabId] = url; + isBlocked[tabId] = url; - // TODO: This still not work, must find another way to change icon to red - chrome.browserAction.setIcon({ + chrome.action.setIcon({ path: '../assets/cldvn_red.png', tabId }); - const redirectUrl = `${browser.runtime.getURL('blocking.html')}#${JSON.stringify(message)}`; - return { - redirectUrl: redirectUrl - }; -}; + const redirectUrl = `${chrome.runtime.getURL('blocking.html')}#${JSON.stringify(message)}`; + + // Redirect the tab to the blocking page + chrome.tabs.update(tabId, { url: redirectUrl }, () => { + if (chrome.runtime.lastError) { + console.error('Error redirecting tab:', chrome.runtime.lastError); + } + }); + // We no longer return a redirectUrl object, as we're handling the redirect directly +}; const createUrlObject = (url) => { try { @@ -192,9 +196,10 @@ const createUrlObject = (url) => { * @param {Object} details of onBeforeRequest event * @docs https://developer.chrome.com/docs/extensions/reference/webRequest/#event-onBeforeRequest */ -const safeCheck = ({url, tabId, initiator}) => { +const safeCheck = async ({ url, tabId, initiator }) => { + console.log('safeCheck', { url, tabId, initiator }); // Invalid url - if (!url || url.indexOf('chrome://') === 0 || url.indexOf(browser.runtime.getURL('/')) === 0) { + if (!url || url.indexOf('chrome://') === 0 || url.indexOf(chrome.runtime.getURL('/')) === 0) { return; } @@ -204,8 +209,10 @@ const safeCheck = ({url, tabId, initiator}) => { } // In case user decided to not blocking this site, we let them in - if (localStorage.getItem('whiteList')) { - return localStorage.removeItem('whiteList'); + const whiteList = await getStorageData('whiteList'); + if (whiteList) { + await setStorageData('whiteList', null); + return; } const sites = blackListing; @@ -256,7 +263,7 @@ const safeCheck = ({url, tabId, initiator}) => { // If not blocklisted, then just check the domain of the initiator instead of sub frame url const domain = getDomain(initiator || url); if (whiteListing.find((row) => row.includes(domain))) { - window.isWhiteList[tabId] = domain; + isWhiteList[tabId] = domain; return; } @@ -265,24 +272,23 @@ const safeCheck = ({url, tabId, initiator}) => { const sendCurrentUrl = (tab = null) => { if (tab && tab.tabId) { - return updateBadge(window.isPhish[tab.tabId], window.legitimatePercents[tab.tabId], tab.tabId); + return updateBadge(isPhish[tab.tabId], legitimatePercents[tab.tabId], tab.tabId); } chrome.tabs.query({active: true, currentWindow: true}, ([tab]) => { - updateBadge(window.isPhish[tab.id], window.legitimatePercents[tab.id], tab.id); + updateBadge(isPhish[tab.id], legitimatePercents[tab.id], tab.id); }); }; const updateBadge = (isPhishing, legitimatePercent, tabId) => { - chrome.browserAction.setTitle({title: `P:${isPhishing} per: ${legitimatePercent}`}); + chrome.action.setTitle({title: `P:${isPhishing} per: ${legitimatePercent}`, tabId}); if (isPhishing) { - return chrome.browserAction.setIcon({ + return chrome.action.setIcon({ path: '../assets/cldvn_red.png', tabId }); } - //else(!isPhishing && parseInt(legitimatePercent) < 50) - chrome.browserAction.setIcon({ + chrome.action.setIcon({ path: '../assets/cldvn128.png', tabId }); @@ -304,7 +310,7 @@ chrome.runtime.onInstalled.addListener(() => { startup(); chrome.notifications.create({ type: 'basic', - iconUrl: browser.runtime.getURL('assets/logo.png'), + iconUrl: chrome.runtime.getURL('assets/logo.png'), title: 'Cài đặt thành công!', message: 'Khởi động lại trình duyệt của bạn để có thể bắt đầu sử dụng ChongLuaDao. Xin cảm ơn!' }); @@ -312,50 +318,88 @@ chrome.runtime.onInstalled.addListener(() => { chrome.tabs.onActivated.addListener(sendCurrentUrl); -chrome.tabs.onUpdated.addListener((tabId, changeinfo, tab) => { - if (tab.status == 'complete') { - chrome.tabs.sendMessage(tab.id, tab); +chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { + if (changeInfo.status === 'complete') { + chrome.tabs.sendMessage(tabId, { type: 'TAB_UPDATED', tab }) + .catch((error) => console.log('Error sending message to tab:', error)); } }); -chrome.runtime.onConnect.addListener((port) => { - switch (port.name) { - case REDIRECT_PORT_NAME: - port.onMessage.addListener((msg) => { - chrome.tabs.query({currentWindow: true, active: true}, ([tab,]) => { - chrome.tabs.update(tab.id, {url: msg.redirect}); +chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + console.log('onMessage', message); + switch (message.type) { + case REDIRECT_PORT_NAME: + chrome.tabs.update(message.tabId, { url: message.redirect }, () => { + if (chrome.runtime.lastError) { + console.error('Error updating tab:', chrome.runtime.lastError); + sendResponse({ error: 'Error updating tab' }); + } else { + sendResponse({ success: true }); + } }); - }); - break; - case CLOSE_TAB_PORT_NAME: - port.onMessage.addListener((msg) => { - if (msg.close_tab) { - chrome.tabs.query({currentWindow: true, active: true}, ([tab,]) => { - chrome.tabs.remove(tab.id); + return true; // Indicates that the response is sent asynchronously + + case CLOSE_TAB_PORT_NAME: + if (message.close_tab) { + chrome.tabs.remove(message.tabId, () => { + if (chrome.runtime.lastError) { + console.error('Error closing tab:', chrome.runtime.lastError); + sendResponse({ error: 'Error closing tab' }); + } else { + sendResponse({ success: true }); + } }); + } else { + sendResponse({ success: false, reason: 'close_tab flag not set' }); } - }); - break; - case ML_PORT_NAME: - port.onMessage.addListener((msg) => { - const {request} = msg; + return true; // Indicates that the response is sent asynchronously + + case ML_PORT_NAME: + const { request, tabId } = message; if (request.input_block_list !== undefined) { blackListing = request.input_block_list; inputBlockLenient = request.input_block_lenient; } - chrome.tabs.query({currentWindow: true, active: true}, ([tab,]) => { - window.results[tab.id] = request; - classify(tab.id, request, tab.url); + results[tabId] = request; + + // Get the tab URL using chrome.tabs API + chrome.tabs.get(tabId, (tab) => { + if (chrome.runtime.lastError) { + console.error('Error getting tab:', chrome.runtime.lastError); + sendResponse({ error: 'Error getting tab information' }); + return; + } + classify(tabId, request, tab.url); + sendResponse({ success: true }); }); - }); - break; - default: - ML_PORT_NAME; - break; + return true; // Indicates that the response is sent asynchronously + + default: + console.warn('Unknown message type:', message.type); + sendResponse({ error: 'Unknown message type' }); } }); chrome.webRequest.onBeforeRequest.addListener(safeCheck, { urls: ['*://*/*'], types: ['main_frame', 'sub_frame'] -}, ['blocking']); +}); + + +// Export variables and functions that need to be accessed from other parts of your extension +export { isWhiteList, isBlocked, results, isPhish, legitimatePercents, classify, sendCurrentUrl, updateBadge }; + +// Replace localStorage with chrome.storage.local +const getStorageData = (key) => { + return new Promise((resolve) => { + chrome.storage.local.get(key, (result) => { + resolve(result[key]); + }); + }); +}; + +const setStorageData = (key, value) => { + return new Promise((resolve) => { + chrome.storage.local.set({ [key]: value }, resolve); + }); +}; diff --git a/frontend/js/features.js b/frontend/js/features.js index af4ec56..1dc96e5 100644 --- a/frontend/js/features.js +++ b/frontend/js/features.js @@ -291,10 +291,15 @@ if (iframes.length == 0) { } //---------------------- Sending the result ---------------------- -const mlPort = chrome.runtime.connect({name: ML_PORT_NAME}); -mlPort.postMessage({request: result}); -chrome.runtime.onMessage.addListener((tab) => { - result['tab'] = tab; - mlPort.postMessage({request: result}); +chrome.runtime.sendMessage({ + type: ML_PORT_NAME, + request: result, + tabId: chrome.runtime.id // This will be the ID of the current tab +}, (response) => { + if (chrome.runtime.lastError) { + console.error('Error sending message:', chrome.runtime.lastError); + return; + } + console.log('Message sent successfully', response); }); diff --git a/frontend/js/psl-wrapper.js b/frontend/js/psl-wrapper.js new file mode 100644 index 0000000..d293f0a --- /dev/null +++ b/frontend/js/psl-wrapper.js @@ -0,0 +1,5 @@ +import './psl.min.js'; + +const psl = self.psl || {}; + +export default psl; \ No newline at end of file diff --git a/frontend/manifest.json b/frontend/manifest.json index d040ff6..f9982c4 100644 --- a/frontend/manifest.json +++ b/frontend/manifest.json @@ -6,16 +6,17 @@ "permissions": [ "tabs", "storage", - "webRequestBlocking", "webRequest", - "notifications", + "notifications" + ], + "host_permissions": [ "*://*/*" ], "background": { - "scripts": ["js/psl.min.js", "js/background.js"], - "persistent": true + "service_worker": "js/background.js", + "type": "module" }, - "browser_action": { + "action": { "default_popup": "plugin_ui.html" }, "content_scripts": [ @@ -24,7 +25,10 @@ "js": ["js/features.js"] } ], - "web_accessible_resources": ["js/blocking.js", "blocking.html"], + "web_accessible_resources": [{ + "resources": ["js/blocking.js", "blocking.html"], + "matches": [""] + }], "incognito": "split", "icons": { "16": "assets/cldvn16.png", @@ -32,6 +36,8 @@ "48": "assets/cldvn48.png", "128": "assets/cldvn128.png" }, - "manifest_version": 2, - "content_security_policy": "script-src 'self' https://cdnjs.cloudflare.com; object-src 'self'" + "manifest_version": 3, + "content_security_policy": { + "extension_pages": "script-src 'self'; object-src 'self'" + } } From f26109aeda25de0c9f0245a422cfb2061359b003 Mon Sep 17 00:00:00 2001 From: Phuc H Date: Sun, 27 Oct 2024 17:35:45 +0700 Subject: [PATCH 2/3] feat(v3): popup ui that works --- frontend/js/background.js | 44 ++++++++------- frontend/js/features.js | 5 +- frontend/js/plugin_ui.js | 110 +++++++++++++++++++++----------------- 3 files changed, 88 insertions(+), 71 deletions(-) diff --git a/frontend/js/background.js b/frontend/js/background.js index a37e2af..eac6bee 100644 --- a/frontend/js/background.js +++ b/frontend/js/background.js @@ -156,7 +156,6 @@ const startup = () => { * @return Redirect */ const blockingFunction = (url, blackSite, tabId) => { - console.log('blockingFunction'); const message = { site: url, match: blackSite, @@ -197,7 +196,6 @@ const createUrlObject = (url) => { * @docs https://developer.chrome.com/docs/extensions/reference/webRequest/#event-onBeforeRequest */ const safeCheck = async ({ url, tabId, initiator }) => { - console.log('safeCheck', { url, tabId, initiator }); // Invalid url if (!url || url.indexOf('chrome://') === 0 || url.indexOf(chrome.runtime.getURL('/')) === 0) { return; @@ -326,8 +324,9 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { }); chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { - console.log('onMessage', message); - switch (message.type) { + const { type } = message; + + switch (type) { case REDIRECT_PORT_NAME: chrome.tabs.update(message.tabId, { url: message.redirect }, () => { if (chrome.runtime.lastError) { @@ -355,27 +354,35 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { return true; // Indicates that the response is sent asynchronously case ML_PORT_NAME: - const { request, tabId } = message; - if (request.input_block_list !== undefined) { - blackListing = request.input_block_list; - inputBlockLenient = request.input_block_lenient; + const senderId = sender.tab ? sender.tab.id : null; + if (message.input_block_list !== undefined) { + blackListing = message.input_block_list; + inputBlockLenient = message.input_block_lenient; } - results[tabId] = request; + results[senderId] = message.request; - // Get the tab URL using chrome.tabs API - chrome.tabs.get(tabId, (tab) => { - if (chrome.runtime.lastError) { - console.error('Error getting tab:', chrome.runtime.lastError); - sendResponse({ error: 'Error getting tab information' }); - return; - } - classify(tabId, request, tab.url); + // Use sender.tab instead of chrome.tabs.get + if (sender.tab && sender.tab.url) { + classify(senderId, message.request, sender.tab.url); sendResponse({ success: true }); + } else { + sendResponse({ error: 'Unable to get tab information' }); + } + return true; + + case 'GET_TAB_DATA': + const { tabId } = message; + sendResponse({ + isWhiteList: isWhiteList[tabId], + isBlocked: isBlocked[tabId], + results: results[tabId], + isPhish: isPhish[tabId], + legitimatePercents: legitimatePercents[tabId] }); return true; // Indicates that the response is sent asynchronously default: - console.warn('Unknown message type:', message.type); + console.warn('Unknown message type:', type); sendResponse({ error: 'Unknown message type' }); } }); @@ -403,3 +410,4 @@ const setStorageData = (key, value) => { chrome.storage.local.set({ [key]: value }, resolve); }); }; + diff --git a/frontend/js/features.js b/frontend/js/features.js index 1dc96e5..2fc107f 100644 --- a/frontend/js/features.js +++ b/frontend/js/features.js @@ -3,7 +3,6 @@ // const REDIRECT_PORT_NAME = 'REDIRECT_PORT_NAME'; // const CLOSE_TAB_PORT_NAME = 'CLOSE_TAB_PORT_NAME'; const ML_PORT_NAME = 'ML_PORT_NAME'; - /* $('a').click(function(){ alert("You are about to go to "+$(this).attr('href')); @@ -294,12 +293,10 @@ if (iframes.length == 0) { chrome.runtime.sendMessage({ type: ML_PORT_NAME, - request: result, - tabId: chrome.runtime.id // This will be the ID of the current tab + request: result }, (response) => { if (chrome.runtime.lastError) { console.error('Error sending message:', chrome.runtime.lastError); return; } - console.log('Message sent successfully', response); }); diff --git a/frontend/js/plugin_ui.js b/frontend/js/plugin_ui.js index d64923b..a956006 100644 --- a/frontend/js/plugin_ui.js +++ b/frontend/js/plugin_ui.js @@ -1,6 +1,5 @@ /*global chrome*/ /*global $*/ -const background = chrome.extension.getBackgroundPage(); const colors = { '-1': '#28a745', '0': '#ffeb3c', @@ -19,69 +18,82 @@ const colors = { }); }); -chrome.tabs.query({currentWindow: true, active: true}, ([tab,]) => { +chrome.tabs.query({active: true, currentWindow: true}, ([tab]) => { + if (!tab) { + console.error('No active tab found'); + return; + } + const tabId = tab.id; const url = new URL(tab.url); const domain = url.hostname; - // Display nothing if protocol is neither http or https + + // Display nothing if protocol is neither http nor https if (!['https:', 'http:'].includes(url.protocol)) { $('#pluginBody').hide(); $('#domain_url').text(domain); return; } - if (background.isWhiteList[tab.id] == domain) { - $('#pluginBody').hide(); - $('#isSafe').show(); - $('#isSafe .site-url').text(domain); + // Request data from the background script + chrome.runtime.sendMessage({type: 'GET_TAB_DATA', tabId}, (response) => { + if (chrome.runtime.lastError) { + console.error('Error getting tab data:', chrome.runtime.lastError); + return; + } - chrome.browserAction.setIcon({ - path: '../assets/cldvn128.png', - tabId - }); + if (response.isWhiteList === domain) { + $('#pluginBody').hide(); + $('#isSafe').show(); + $('#isSafe .site-url').text(domain); - } else if(background.isBlocked[tab.id] == domain){ - $('#pluginBody').hide(); - $('#isPhishing').show(); - $('#isPhishing .site-url').text(background.isBlocked[tab.id]); + chrome.action.setIcon({ + path: '../assets/cldvn128.png', + tabId + }); + } else if (response.isBlocked === domain) { + $('#pluginBody').hide(); + $('#isPhishing').show(); + $('#isPhishing .site-url').text(response.isBlocked); - chrome.browserAction.setIcon({ - path: '../assets/cldvn_red.png', - tabId - }); - } else { - const result = background.results[tab.id]; - const isPhish = background.isPhish[tab.id]; - const legitimatePercent = background.legitimatePercents[tab.id]; + chrome.action.setIcon({ + path: '../assets/cldvn_red.png', + tabId + }); + } else { + const result = response.results; + const isPhish = response.isPhish; + const legitimatePercent = response.legitimatePercents; - for (const key in result) { - const newFeature = document.createElement('li'); - newFeature.textContent = key; - newFeature.style.backgroundColor = colors[result[key]]; - const featureList = document.getElementById('features'); - featureList.appendChild(newFeature); - } + for (const key in result) { + const newFeature = document.createElement('li'); + newFeature.textContent = key; + newFeature.style.backgroundColor = colors[result[key]]; + const featureList = document.getElementById('features'); + featureList.appendChild(newFeature); + } - const phishingMessage = isPhish ? 'Website này có thể không an toàn.' : 'Website này có thể an toàn.'; + const phishingMessage = isPhish ? 'Website này có thể không an toàn.' : 'Website này có thể an toàn.'; - const site_score = document.getElementById('site_score'); - const percentage_content = document.getElementById('percentage_content'); - const site_msg = document.getElementById('site_msg'); - percentage_content.classList.add(`p${parseInt(legitimatePercent)}`); + const site_score = document.getElementById('site_score'); + const percentage_content = document.getElementById('percentage_content'); + const site_msg = document.getElementById('site_msg'); + percentage_content.classList.add(`p${parseInt(legitimatePercent)}`); - if (isPhish) { - percentage_content.classList.add('orange'); - site_score.classList.add('warning'); - site_msg.classList.add('warning'); - } - else { - site_score.classList.add('safe'); - site_msg.classList.add('safe'); - } + if (isPhish) { + percentage_content.classList.add('orange'); + site_score.classList.add('warning'); + site_msg.classList.add('warning'); + } + else { + site_score.classList.add('safe'); + site_msg.classList.add('safe'); + } - const percentage = parseInt(legitimatePercent); - $('#site_msg').text(isNaN(percentage) ? '...' : phishingMessage); - $('#site_score').text(isNaN(percentage) ? '...' : `${parseInt(legitimatePercent) - 1}%`); - $('#domain_url').text(domain); - } + const percentage = parseInt(legitimatePercent); + $('#site_msg').text(isNaN(percentage) ? '...' : phishingMessage); + $('#site_score').text(isNaN(percentage) ? '...' : `${parseInt(legitimatePercent) - 1}%`); + $('#domain_url').text(domain); + } + }); }); From 4eb5cf2d3f30d6ec8e58c3ff83d1e53cc2b69faf Mon Sep 17 00:00:00 2001 From: Phuc H Date: Mon, 28 Oct 2024 10:27:30 +0700 Subject: [PATCH 3/3] fix(v3): add build version --- frontend/js/psl-wrapper.js | 6 +- package-lock.json | 164 ++++++++++++++++++++++++++++++++++++- package.json | 2 +- webpack.config.js | 19 +++-- 4 files changed, 181 insertions(+), 10 deletions(-) diff --git a/frontend/js/psl-wrapper.js b/frontend/js/psl-wrapper.js index d293f0a..49209c3 100644 --- a/frontend/js/psl-wrapper.js +++ b/frontend/js/psl-wrapper.js @@ -1,5 +1,7 @@ -import './psl.min.js'; +import psl from './psl.min.js'; -const psl = self.psl || {}; +// change to this for pre-build version: +// import './psl.min.js'; +// const psl = self.psl || {}; export default psl; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index fd7aadb..383ce9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,12 +5,17 @@ "requires": true, "packages": { "": { + "name": "chongluadao-extension", "version": "1.0.0", "license": "ISC", + "dependencies": { + "browserslist": "^4.17.0", + "glob-to-regexp": "^0.4.1" + }, "devDependencies": { "dotenv": "^8.2.0", "eslint": "^7.23.0", - "gulp": "4.0.2", + "gulp": "^4.0.2", "gulp-append-prepend": "1.0.8", "webpack": "^4.0.0", "webpack-cli": "^3.3.12", @@ -1138,6 +1143,37 @@ "pako": "~1.0.5" } }, + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/buffer": { "version": "4.9.2", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", @@ -1292,6 +1328,25 @@ "node": ">=0.10.0" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001673", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001673.tgz", + "integrity": "sha512-WTrjUCSMp3LYX0nE12ECkV0a+e6LC85E0Auz75555/qr78Oc8YWhEPNfDd6SHdtlCMSzqtuXY0uyEMNRcsKpKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, "node_modules/chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -2095,6 +2150,11 @@ "node": ">=0.10.0" } }, + "node_modules/electron-to-chromium": { + "version": "1.5.47", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.47.tgz", + "integrity": "sha512-zS5Yer0MOYw4rtK2iq43cJagHZ8sXN0jDHDKzB+86gSBSAI4v07S97mcq+Gs2vclAxSh1j7vOAHxSVgduiiuVQ==" + }, "node_modules/elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -2244,6 +2304,14 @@ "es6-symbol": "^3.1.1" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -3041,6 +3109,11 @@ "node": ">=0.10.0" } }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, "node_modules/glob-watcher": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", @@ -4587,6 +4660,11 @@ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -5107,6 +5185,11 @@ "node": ">=0.12" } }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, "node_modules/picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -6957,6 +7040,35 @@ "yarn": "*" } }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -8963,6 +9075,17 @@ "pako": "~1.0.5" } }, + "browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "requires": { + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + } + }, "buffer": { "version": "4.9.2", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", @@ -9098,6 +9221,11 @@ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true }, + "caniuse-lite": { + "version": "1.0.30001673", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001673.tgz", + "integrity": "sha512-WTrjUCSMp3LYX0nE12ECkV0a+e6LC85E0Auz75555/qr78Oc8YWhEPNfDd6SHdtlCMSzqtuXY0uyEMNRcsKpKw==" + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -9793,6 +9921,11 @@ } } }, + "electron-to-chromium": { + "version": "1.5.47", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.47.tgz", + "integrity": "sha512-zS5Yer0MOYw4rtK2iq43cJagHZ8sXN0jDHDKzB+86gSBSAI4v07S97mcq+Gs2vclAxSh1j7vOAHxSVgduiiuVQ==" + }, "elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -9931,6 +10064,11 @@ "es6-symbol": "^3.1.1" } }, + "escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -10585,6 +10723,11 @@ } } }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, "glob-watcher": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", @@ -11825,6 +11968,11 @@ } } }, + "node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -12234,6 +12382,11 @@ "sha.js": "^2.4.8" } }, + "picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -13759,6 +13912,15 @@ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true }, + "update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "requires": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + } + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/package.json b/package.json index 78cc9e7..e96f6d8 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "description": "chongluadao", "scripts": { - "build": "rm -rf ./build/* && cp -r ./frontend/* ./build/ && webpack --config webpack.config.js && gulp licenses", + "build": "export NODE_OPTIONS=--openssl-legacy-provider && rm -rf ./build/* && cp -r ./frontend/* ./build/ && webpack --config webpack.config.js && gulp licenses", "build-firefox": "rm -rf ./build-firefox/* && cp -r ./frontend/* ./build-firefox/ && webpack --config webpack.firefox-config.js && gulp licenses --firefox" }, "repository": { diff --git a/webpack.config.js b/webpack.config.js index 07da884..ac4d89c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,14 +3,21 @@ const path = require('path'); module.exports = { mode: 'production', entry: { - background: './build/js/background.js', - blocking: './build/js/blocking.js', - features: './build/js/features.js', - plugin_ui: './build/js/plugin_ui.js', - rating: './build/js/rating.js', + 'background': './build/js/background.js', + 'blocking': './build/js/blocking.js', + 'features': './build/js/features.js', + 'plugin_ui': './build/js/plugin_ui.js', + 'rating': './build/js/rating.js', }, output: { filename: '[name].js', - path: path.resolve(__dirname, 'build/js/') + path: path.resolve(__dirname, 'build/js/'), + globalObject: 'this' + }, + optimization: { + splitChunks: { + chunks: 'all', + name: 'vendors' + } } };