From 9426645ee8b22a1b442e51e9cd604746b1993061 Mon Sep 17 00:00:00 2001 From: leor-gh Date: Sun, 25 Aug 2024 21:07:46 -0700 Subject: [PATCH] Add support for automatic persistent data migration when upgrading from MV2 to MV3 --- background.js | 40 ++++++++++++++++++++++++++++++++-------- doc/migration | 15 +++++++-------- javascripts/migration.js | 16 ++++++++++++++++ manifest.json | 3 ++- migration.html | 5 +++++ 5 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 javascripts/migration.js create mode 100644 migration.html diff --git a/background.js b/background.js index 119e774..a25f8bc 100644 --- a/background.js +++ b/background.js @@ -60,18 +60,25 @@ chrome.webRequest.onAuthRequired.addListener( {urls: [""]}, ['asyncBlocking'] ); -chrome.runtime.onMessage.addListener(async function(msg, sender, res) { +chrome.runtime.onMessage.addListener((msg, sender, res) => { if (msg.action != "authUpdate") return; - console.log("%s onMessage listener", new Date(Date.now()).toISOString()); - if (localStorage.proxySetting == undefined) - await getLocalStorage(); + (async () => { + console.log("%s receive authUpdate", new Date(Date.now()).toISOString()); + if (localStorage.proxySetting == undefined) + await getLocalStorage(); - var proxySetting = JSON.parse(localStorage.proxySetting); - proxySetting['auth'] = msg.data; - localStorage.proxySetting = JSON.stringify(proxySetting); - chrome.storage.local.set(localStorage); + var proxySetting = JSON.parse(localStorage.proxySetting); + proxySetting['auth'] = msg.data; + localStorage.proxySetting = JSON.stringify(proxySetting); + await chrome.storage.local.set(localStorage); + + console.log("%s sending authUpdate response", new Date(Date.now()).toISOString()); + res('done'); + })(); + + return true; }); var proxySetting = { @@ -116,6 +123,23 @@ chrome.runtime.onInstalled.addListener(async details => { if (store.proxySetting == undefined) { localStorage.proxySetting = JSON.stringify(proxySetting); await chrome.storage.local.set(localStorage); + + if (details.reason == "update") { + chrome.runtime.onMessage.addListener((msg, sender, res) => { + if (msg.action != "migrationDone") + return; + + console.log("%s data migration done", new Date(Date.now()).toISOString()); + chrome.offscreen.closeDocument(); + }); + + console.log("%s starting data migration", new Date(Date.now()).toISOString()); + chrome.offscreen.createDocument({ + url: 'migration.html', + reasons: ['LOCAL_STORAGE'], + justification: 'Migrate storage data for MV2 to MV3', + }); + } } if(details.reason == "install") { gotoPage('options.html'); diff --git a/doc/migration b/doc/migration index 67761c7..38d74de 100644 --- a/doc/migration +++ b/doc/migration @@ -73,15 +73,14 @@ During normal operation: - Service worker comes and goes, and credential information is lazy-loaded only when needed -After migration of installed MV2 extension to MV3, on the first run: +During update migration of installed MV2 extension to MV3: - localStorage is populated with valid data - chrome.storage is empty, and the service worker populates the template proxySetting into chrome.storage, but this does not have valid proxy authorization credentials - - proxy authorization will fail, and the browser presents a popup - dialog to prompt user to enter proxy credentials - - the option page still displays the correct credentials - - this migration issue can be fixed by deleting and re-entering the - credential information (both the username and password) in the - options page to force the service worker receive and persist the - correct data for its use + - the onInstall handler sees a reason of "update", which means this + is the MV2 to MV3 migration, and it kicks off the migration + offscreen page + - the offscreen page JS code checks localStorage to see if it has + non-empty credentials, and sends a message to the service worker + to update the credentials in chrome.storage diff --git a/javascripts/migration.js b/javascripts/migration.js new file mode 100644 index 0000000..1b3d91f --- /dev/null +++ b/javascripts/migration.js @@ -0,0 +1,16 @@ +(async () => { + console.log("%s data migration. localStorage =", + new Date(Date.now()).toISOString(), + JSON.parse(JSON.stringify(localStorage))); + + let resp; + if (localStorage.proxySetting != undefined) { + auth = JSON.parse(localStorage.proxySetting).auth; + if (auth.user != '' || auth.pass != '') { + resp = chrome.runtime.sendMessage({ action: 'authUpdate', data: auth }); + } + } + await resp; + + chrome.runtime.sendMessage({ action: 'migrationDone' }); +})(); diff --git a/manifest.json b/manifest.json index 35b28aa..5454b6c 100644 --- a/manifest.json +++ b/manifest.json @@ -14,7 +14,8 @@ "tabs", "storage", "webRequest", - "webRequestAuthProvider" + "webRequestAuthProvider", + "offscreen" ], "host_permissions": [ "*://*/*" diff --git a/migration.html b/migration.html new file mode 100644 index 0000000..f7f4b71 --- /dev/null +++ b/migration.html @@ -0,0 +1,5 @@ + + + + +