mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
ensure phishing-detection page preload works in MV3 (#16029)
* ensure phishing-detection page preload works in MV3 * remove stored flag for FireFox in MV3 solution
This commit is contained in:
parent
3b63ecff07
commit
fc38f11580
@ -172,7 +172,9 @@ async function initialize(remotePort) {
|
||||
const initState = await loadStateFromPersistence();
|
||||
const initLangCode = await getFirstPreferredLangCode();
|
||||
await setupController(initState, initLangCode, remotePort);
|
||||
if (!isManifestV3) {
|
||||
await loadPhishingWarningPage();
|
||||
}
|
||||
log.info('MetaMask initialization complete.');
|
||||
}
|
||||
|
||||
|
@ -15,20 +15,28 @@ import launchMetaMaskUi, { updateBackgroundConnection } from '../../ui';
|
||||
import {
|
||||
ENVIRONMENT_TYPE_FULLSCREEN,
|
||||
ENVIRONMENT_TYPE_POPUP,
|
||||
PLATFORM_FIREFOX,
|
||||
} from '../../shared/constants/app';
|
||||
import { isManifestV3 } from '../../shared/modules/mv3.utils';
|
||||
import { SUPPORT_LINK } from '../../shared/lib/ui-utils';
|
||||
import { getErrorHtml } from '../../shared/lib/error-utils';
|
||||
import ExtensionPlatform from './platforms/extension';
|
||||
import { setupMultiplex } from './lib/stream-utils';
|
||||
import { getEnvironmentType } from './lib/util';
|
||||
import { getEnvironmentType, getPlatform } from './lib/util';
|
||||
import metaRPCClientFactory from './lib/metaRPCClientFactory';
|
||||
|
||||
const container = document.getElementById('app-content');
|
||||
|
||||
const WORKER_KEEP_ALIVE_INTERVAL = 1000;
|
||||
const ONE_SECOND_IN_MILLISECONDS = 1_000;
|
||||
|
||||
const WORKER_KEEP_ALIVE_INTERVAL = ONE_SECOND_IN_MILLISECONDS;
|
||||
const WORKER_KEEP_ALIVE_MESSAGE = 'WORKER_KEEP_ALIVE_MESSAGE';
|
||||
|
||||
// Timeout for initializing phishing warning page.
|
||||
const PHISHING_WARNING_PAGE_TIMEOUT = ONE_SECOND_IN_MILLISECONDS;
|
||||
|
||||
const PHISHING_WARNING_SW_STORAGE_KEY = 'phishing-warning-sw-registered';
|
||||
|
||||
/*
|
||||
* As long as UI is open it will keep sending messages to service worker
|
||||
* In service worker as this message is received
|
||||
@ -58,6 +66,7 @@ async function start() {
|
||||
|
||||
const activeTab = await queryCurrentActiveTab(windowType);
|
||||
|
||||
let loadPhishingWarningPage;
|
||||
/**
|
||||
* In case of MV3 the issue of blank screen was very frequent, it is caused by UI initialising before background is ready to send state.
|
||||
* Code below ensures that UI is rendered only after background is ready.
|
||||
@ -68,7 +77,7 @@ async function start() {
|
||||
* Code below ensures that UI is rendered only after CONNECTION_READY message is received thus background is ready.
|
||||
* In case the UI is already rendered, only update the streams.
|
||||
*/
|
||||
const messageListener = (message) => {
|
||||
const messageListener = async (message) => {
|
||||
if (message?.name === 'CONNECTION_READY') {
|
||||
if (isUIInitialised) {
|
||||
// Currently when service worker is revived we create new streams
|
||||
@ -77,6 +86,98 @@ async function start() {
|
||||
} else {
|
||||
initializeUiWithTab(activeTab);
|
||||
}
|
||||
await loadPhishingWarningPage();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An error thrown if the phishing warning page takes too long to load.
|
||||
*/
|
||||
class PhishingWarningPageTimeoutError extends Error {
|
||||
constructor() {
|
||||
super('Timeout failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the phishing warning page temporarily to ensure the service
|
||||
* worker has been registered, so that the warning page works offline.
|
||||
*/
|
||||
loadPhishingWarningPage = async function () {
|
||||
const currentPlatform = getPlatform();
|
||||
|
||||
// Check session storage for whether we've already initalized the phishing warning
|
||||
// service worker this browser session and do not attempt to re-initialize if so.
|
||||
const phishingSWMemoryFetch = await browser.storage.session.get(
|
||||
PHISHING_WARNING_SW_STORAGE_KEY,
|
||||
);
|
||||
|
||||
if (phishingSWMemoryFetch[PHISHING_WARNING_SW_STORAGE_KEY]) {
|
||||
return;
|
||||
}
|
||||
|
||||
let iframe;
|
||||
try {
|
||||
const extensionStartupPhishingPageUrl = new URL(
|
||||
process.env.PHISHING_WARNING_PAGE_URL,
|
||||
);
|
||||
// The `extensionStartup` hash signals to the phishing warning page that it should not bother
|
||||
// setting up streams for user interaction. Otherwise this page load would cause a console
|
||||
// error.
|
||||
extensionStartupPhishingPageUrl.hash = '#extensionStartup';
|
||||
|
||||
iframe = window.document.createElement('iframe');
|
||||
iframe.setAttribute('src', extensionStartupPhishingPageUrl.href);
|
||||
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
|
||||
|
||||
// Create "deferred Promise" to allow passing resolve/reject to event handlers
|
||||
let deferredResolve;
|
||||
let deferredReject;
|
||||
const loadComplete = new Promise((resolve, reject) => {
|
||||
deferredResolve = resolve;
|
||||
deferredReject = reject;
|
||||
});
|
||||
|
||||
// The load event is emitted once loading has completed, even if the loading failed.
|
||||
// If loading failed we can't do anything about it, so we don't need to check.
|
||||
iframe.addEventListener('load', deferredResolve);
|
||||
|
||||
// This step initiates the page loading.
|
||||
window.document.body.appendChild(iframe);
|
||||
|
||||
// This timeout ensures that this iframe gets cleaned up in a reasonable
|
||||
// timeframe, and ensures that the "initialization complete" message
|
||||
// doesn't get delayed too long.
|
||||
setTimeout(
|
||||
() => deferredReject(new PhishingWarningPageTimeoutError()),
|
||||
PHISHING_WARNING_PAGE_TIMEOUT,
|
||||
);
|
||||
await loadComplete;
|
||||
// store a flag in sessions storage that we've already loaded the service worker
|
||||
// and don't need to try again
|
||||
if (currentPlatform === PLATFORM_FIREFOX) {
|
||||
// Firefox does not yet support the storage.session API introduced in MV3
|
||||
// Tracked here: https://bugzilla.mozilla.org/show_bug.cgi?id=1687778
|
||||
console.error(
|
||||
'Firefox does not support required MV3 APIs: Phishing warning page iframe and service worker will reload each page refresh',
|
||||
);
|
||||
} else {
|
||||
browser.storage.session.set({
|
||||
[PHISHING_WARNING_SW_STORAGE_KEY]: true,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof PhishingWarningPageTimeoutError) {
|
||||
console.warn(
|
||||
'Phishing warning page timeout; page not guaranteed to work offline.',
|
||||
);
|
||||
} else {
|
||||
console.error('Failed to initialize phishing warning page', error);
|
||||
}
|
||||
} finally {
|
||||
if (iframe) {
|
||||
iframe.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user