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 initState = await loadStateFromPersistence();
|
||||||
const initLangCode = await getFirstPreferredLangCode();
|
const initLangCode = await getFirstPreferredLangCode();
|
||||||
await setupController(initState, initLangCode, remotePort);
|
await setupController(initState, initLangCode, remotePort);
|
||||||
await loadPhishingWarningPage();
|
if (!isManifestV3) {
|
||||||
|
await loadPhishingWarningPage();
|
||||||
|
}
|
||||||
log.info('MetaMask initialization complete.');
|
log.info('MetaMask initialization complete.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,20 +15,28 @@ import launchMetaMaskUi, { updateBackgroundConnection } from '../../ui';
|
|||||||
import {
|
import {
|
||||||
ENVIRONMENT_TYPE_FULLSCREEN,
|
ENVIRONMENT_TYPE_FULLSCREEN,
|
||||||
ENVIRONMENT_TYPE_POPUP,
|
ENVIRONMENT_TYPE_POPUP,
|
||||||
|
PLATFORM_FIREFOX,
|
||||||
} from '../../shared/constants/app';
|
} from '../../shared/constants/app';
|
||||||
import { isManifestV3 } from '../../shared/modules/mv3.utils';
|
import { isManifestV3 } from '../../shared/modules/mv3.utils';
|
||||||
import { SUPPORT_LINK } from '../../shared/lib/ui-utils';
|
import { SUPPORT_LINK } from '../../shared/lib/ui-utils';
|
||||||
import { getErrorHtml } from '../../shared/lib/error-utils';
|
import { getErrorHtml } from '../../shared/lib/error-utils';
|
||||||
import ExtensionPlatform from './platforms/extension';
|
import ExtensionPlatform from './platforms/extension';
|
||||||
import { setupMultiplex } from './lib/stream-utils';
|
import { setupMultiplex } from './lib/stream-utils';
|
||||||
import { getEnvironmentType } from './lib/util';
|
import { getEnvironmentType, getPlatform } from './lib/util';
|
||||||
import metaRPCClientFactory from './lib/metaRPCClientFactory';
|
import metaRPCClientFactory from './lib/metaRPCClientFactory';
|
||||||
|
|
||||||
const container = document.getElementById('app-content');
|
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';
|
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
|
* As long as UI is open it will keep sending messages to service worker
|
||||||
* In service worker as this message is received
|
* In service worker as this message is received
|
||||||
@ -58,6 +66,7 @@ async function start() {
|
|||||||
|
|
||||||
const activeTab = await queryCurrentActiveTab(windowType);
|
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.
|
* 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.
|
* 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.
|
* 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.
|
* In case the UI is already rendered, only update the streams.
|
||||||
*/
|
*/
|
||||||
const messageListener = (message) => {
|
const messageListener = async (message) => {
|
||||||
if (message?.name === 'CONNECTION_READY') {
|
if (message?.name === 'CONNECTION_READY') {
|
||||||
if (isUIInitialised) {
|
if (isUIInitialised) {
|
||||||
// Currently when service worker is revived we create new streams
|
// Currently when service worker is revived we create new streams
|
||||||
@ -77,6 +86,98 @@ async function start() {
|
|||||||
} else {
|
} else {
|
||||||
initializeUiWithTab(activeTab);
|
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