mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-29 07:16:36 +01:00
7199d9c567
An externally hosted phishing warning page is now used rather than the built-in phishing warning page.The phishing page warning URL is set via configuration file or environment variable. The default URL is either the expected production URL or `http://localhost:9999/` for e2e testing environments. The new external phishing page includes a design change when it is loaded within an iframe. In that case it now shows a condensed message, and prompts the user to open the full warning page in a new tab to see more details or bypass the warning. This is to prevent a clickjacking attack from safelisting a site without user consent. The new external phishing page also includes a simple caching service worker to ensure it continues to work offline (or if our hosting goes offline), as long as the user has successfully loaded the page at least once. We also load the page temporarily during the extension startup process to trigger the service worker installation. The old phishing page and all related lines have been removed. The property `web_accessible_resources` has also been removed from the manifest. The only entry apart from the phishing page was `inpage.js`, and we don't need that to be web accessible anymore because we inject the script inline into each page rather than loading the file directly. New e2e tests have been added to cover more phishing warning page functionality, including the "safelist" action and the "iframe" case.
169 lines
4.3 KiB
JavaScript
169 lines
4.3 KiB
JavaScript
import browser from 'webextension-polyfill';
|
|
|
|
import { stripHexPrefix } from 'ethereumjs-util';
|
|
import BN from 'bn.js';
|
|
import { memoize } from 'lodash';
|
|
import {
|
|
MAINNET_CHAIN_ID,
|
|
TEST_CHAINS,
|
|
} from '../../../shared/constants/network';
|
|
|
|
import {
|
|
ENVIRONMENT_TYPE_POPUP,
|
|
ENVIRONMENT_TYPE_NOTIFICATION,
|
|
ENVIRONMENT_TYPE_FULLSCREEN,
|
|
ENVIRONMENT_TYPE_BACKGROUND,
|
|
PLATFORM_FIREFOX,
|
|
PLATFORM_OPERA,
|
|
PLATFORM_CHROME,
|
|
PLATFORM_EDGE,
|
|
PLATFORM_BRAVE,
|
|
} from '../../../shared/constants/app';
|
|
|
|
/**
|
|
* @see {@link getEnvironmentType}
|
|
*/
|
|
const getEnvironmentTypeMemo = memoize((url) => {
|
|
const parsedUrl = new URL(url);
|
|
if (parsedUrl.pathname === '/popup.html') {
|
|
return ENVIRONMENT_TYPE_POPUP;
|
|
} else if (['/home.html'].includes(parsedUrl.pathname)) {
|
|
return ENVIRONMENT_TYPE_FULLSCREEN;
|
|
} else if (parsedUrl.pathname === '/notification.html') {
|
|
return ENVIRONMENT_TYPE_NOTIFICATION;
|
|
}
|
|
return ENVIRONMENT_TYPE_BACKGROUND;
|
|
});
|
|
|
|
/**
|
|
* Returns the window type for the application
|
|
*
|
|
* - `popup` refers to the extension opened through the browser app icon (in top right corner in chrome and firefox)
|
|
* - `fullscreen` refers to the main browser window
|
|
* - `notification` refers to the popup that appears in its own window when taking action outside of metamask
|
|
* - `background` refers to the background page
|
|
*
|
|
* NOTE: This should only be called on internal URLs.
|
|
*
|
|
* @param {string} [url] - the URL of the window
|
|
* @returns {string} the environment ENUM
|
|
*/
|
|
const getEnvironmentType = (url = window.location.href) =>
|
|
getEnvironmentTypeMemo(url);
|
|
|
|
/**
|
|
* Returns the platform (browser) where the extension is running.
|
|
*
|
|
* @returns {string} the platform ENUM
|
|
*/
|
|
const getPlatform = () => {
|
|
const { navigator } = window;
|
|
const { userAgent } = navigator;
|
|
|
|
if (userAgent.includes('Firefox')) {
|
|
return PLATFORM_FIREFOX;
|
|
} else if ('brave' in navigator) {
|
|
return PLATFORM_BRAVE;
|
|
} else if (userAgent.includes('Edg/')) {
|
|
return PLATFORM_EDGE;
|
|
} else if (userAgent.includes('OPR')) {
|
|
return PLATFORM_OPERA;
|
|
}
|
|
return PLATFORM_CHROME;
|
|
};
|
|
|
|
/**
|
|
* Converts a hex string to a BN object
|
|
*
|
|
* @param {string} inputHex - A number represented as a hex string
|
|
* @returns {Object} A BN object
|
|
*/
|
|
function hexToBn(inputHex) {
|
|
return new BN(stripHexPrefix(inputHex), 16);
|
|
}
|
|
|
|
/**
|
|
* Used to multiply a BN by a fraction
|
|
*
|
|
* @param {BN} targetBN - The number to multiply by a fraction
|
|
* @param {number|string} numerator - The numerator of the fraction multiplier
|
|
* @param {number|string} denominator - The denominator of the fraction multiplier
|
|
* @returns {BN} The product of the multiplication
|
|
*/
|
|
function BnMultiplyByFraction(targetBN, numerator, denominator) {
|
|
const numBN = new BN(numerator);
|
|
const denomBN = new BN(denominator);
|
|
return targetBN.mul(numBN).div(denomBN);
|
|
}
|
|
|
|
/**
|
|
* Returns an Error if extension.runtime.lastError is present
|
|
* this is a workaround for the non-standard error object that's used
|
|
*
|
|
* @returns {Error|undefined}
|
|
*/
|
|
function checkForError() {
|
|
const { lastError } = browser.runtime;
|
|
if (!lastError) {
|
|
return undefined;
|
|
}
|
|
// if it quacks like an Error, its an Error
|
|
if (lastError.stack && lastError.message) {
|
|
return lastError;
|
|
}
|
|
// repair incomplete error object (eg chromium v77)
|
|
return new Error(lastError.message);
|
|
}
|
|
|
|
/**
|
|
* Prefixes a hex string with '0x' or '-0x' and returns it. Idempotent.
|
|
*
|
|
* @param {string} str - The string to prefix.
|
|
* @returns {string} The prefixed string.
|
|
*/
|
|
const addHexPrefix = (str) => {
|
|
if (typeof str !== 'string' || str.match(/^-?0x/u)) {
|
|
return str;
|
|
}
|
|
|
|
if (str.match(/^-?0X/u)) {
|
|
return str.replace('0X', '0x');
|
|
}
|
|
|
|
if (str.startsWith('-')) {
|
|
return str.replace('-', '-0x');
|
|
}
|
|
|
|
return `0x${str}`;
|
|
};
|
|
|
|
/**
|
|
* Converts a BN object to a hex string with a '0x' prefix
|
|
*
|
|
* @param {BN} inputBn - The BN to convert to a hex string
|
|
* @returns {string} A '0x' prefixed hex string
|
|
*/
|
|
function bnToHex(inputBn) {
|
|
return addHexPrefix(inputBn.toString(16));
|
|
}
|
|
|
|
function getChainType(chainId) {
|
|
if (chainId === MAINNET_CHAIN_ID) {
|
|
return 'mainnet';
|
|
} else if (TEST_CHAINS.includes(chainId)) {
|
|
return 'testnet';
|
|
}
|
|
return 'custom';
|
|
}
|
|
|
|
export {
|
|
getPlatform,
|
|
getEnvironmentType,
|
|
hexToBn,
|
|
BnMultiplyByFraction,
|
|
checkForError,
|
|
addHexPrefix,
|
|
bnToHex,
|
|
getChainType,
|
|
};
|