mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +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.
222 lines
5.1 KiB
JavaScript
222 lines
5.1 KiB
JavaScript
const path = require('path');
|
|
const fs = require('fs-extra');
|
|
const watch = require('gulp-watch');
|
|
const glob = require('fast-glob');
|
|
|
|
const locales = require('../../app/_locales/index.json');
|
|
const { BuildType } = require('../lib/build-type');
|
|
|
|
const { createTask, composeSeries } = require('./task');
|
|
|
|
const EMPTY_JS_FILE = './development/empty.js';
|
|
|
|
module.exports = function createStaticAssetTasks({
|
|
livereload,
|
|
browserPlatforms,
|
|
shouldIncludeLockdown = true,
|
|
buildType,
|
|
}) {
|
|
const [copyTargetsProd, copyTargetsDev] = getCopyTargets(
|
|
shouldIncludeLockdown,
|
|
);
|
|
|
|
const additionalBuildTargets = {
|
|
[BuildType.beta]: [
|
|
{
|
|
src: './app/build-types/beta/images/',
|
|
dest: `images`,
|
|
},
|
|
],
|
|
[BuildType.flask]: [
|
|
{
|
|
src: './app/build-types/flask/images/',
|
|
dest: `images`,
|
|
},
|
|
],
|
|
};
|
|
|
|
if (Object.keys(additionalBuildTargets).includes(buildType)) {
|
|
copyTargetsProd.push(...additionalBuildTargets[buildType]);
|
|
copyTargetsDev.push(...additionalBuildTargets[buildType]);
|
|
}
|
|
|
|
const prod = createTask(
|
|
'static:prod',
|
|
composeSeries(
|
|
...copyTargetsProd.map((target) => {
|
|
return async function copyStaticAssets() {
|
|
await performCopy(target);
|
|
};
|
|
}),
|
|
),
|
|
);
|
|
const dev = createTask(
|
|
'static:dev',
|
|
composeSeries(
|
|
...copyTargetsDev.map((target) => {
|
|
return async function copyStaticAssets() {
|
|
await setupLiveCopy(target);
|
|
};
|
|
}),
|
|
),
|
|
);
|
|
|
|
return { dev, prod };
|
|
|
|
async function setupLiveCopy(target) {
|
|
const pattern = target.pattern || '/**/*';
|
|
watch(target.src + pattern, (event) => {
|
|
livereload.changed(event.path);
|
|
performCopy(target);
|
|
});
|
|
await performCopy(target);
|
|
}
|
|
|
|
async function performCopy(target) {
|
|
await Promise.all(
|
|
browserPlatforms.map(async (platform) => {
|
|
if (target.pattern) {
|
|
await copyGlob(
|
|
target.src,
|
|
`${target.src}${target.pattern}`,
|
|
`./dist/${platform}/${target.dest}`,
|
|
);
|
|
} else {
|
|
await copyGlob(
|
|
target.src,
|
|
`${target.src}`,
|
|
`./dist/${platform}/${target.dest}`,
|
|
);
|
|
}
|
|
}),
|
|
);
|
|
}
|
|
|
|
async function copyGlob(baseDir, srcGlob, dest) {
|
|
const sources = await glob(srcGlob, { onlyFiles: false });
|
|
await Promise.all(
|
|
sources.map(async (src) => {
|
|
const relativePath = path.relative(baseDir, src);
|
|
await fs.copy(src, `${dest}${relativePath}`);
|
|
}),
|
|
);
|
|
}
|
|
};
|
|
|
|
function getCopyTargets(shouldIncludeLockdown) {
|
|
const allCopyTargets = [
|
|
{
|
|
src: `./app/_locales/`,
|
|
dest: `_locales`,
|
|
},
|
|
{
|
|
src: `./app/images/`,
|
|
dest: `images`,
|
|
},
|
|
{
|
|
src: `./node_modules/@metamask/contract-metadata/images/`,
|
|
dest: `images/contract`,
|
|
},
|
|
{
|
|
src: `./app/fonts/`,
|
|
dest: `fonts`,
|
|
},
|
|
{
|
|
src: `./app/vendor/`,
|
|
dest: `vendor`,
|
|
},
|
|
{
|
|
src: `./node_modules/@fortawesome/fontawesome-free/webfonts/`,
|
|
dest: `fonts/fontawesome`,
|
|
},
|
|
{
|
|
src: `./node_modules/react-responsive-carousel/lib/styles`,
|
|
dest: 'react-gallery/',
|
|
},
|
|
{
|
|
src: `./ui/css/output/`,
|
|
pattern: `*.css`,
|
|
dest: ``,
|
|
},
|
|
{
|
|
src: `./app/loading.html`,
|
|
dest: `loading.html`,
|
|
},
|
|
{
|
|
src: `./node_modules/globalthis/dist/browser.js`,
|
|
dest: `globalthis.js`,
|
|
},
|
|
{
|
|
src: shouldIncludeLockdown
|
|
? `./node_modules/ses/dist/lockdown.umd.min.js`
|
|
: EMPTY_JS_FILE,
|
|
dest: `lockdown-install.js`,
|
|
},
|
|
{
|
|
src: shouldIncludeLockdown
|
|
? `./app/scripts/lockdown-run.js`
|
|
: EMPTY_JS_FILE,
|
|
dest: `lockdown-run.js`,
|
|
},
|
|
{
|
|
src: shouldIncludeLockdown
|
|
? `./app/scripts/lockdown-more.js`
|
|
: EMPTY_JS_FILE,
|
|
dest: `lockdown-more.js`,
|
|
},
|
|
{
|
|
// eslint-disable-next-line node/no-extraneous-require
|
|
src: require.resolve('@lavamoat/lavapack/src/runtime-cjs.js'),
|
|
dest: `runtime-cjs.js`,
|
|
},
|
|
{
|
|
// eslint-disable-next-line node/no-extraneous-require
|
|
src: require.resolve('@lavamoat/lavapack/src/runtime.js'),
|
|
dest: `runtime-lavamoat.js`,
|
|
},
|
|
];
|
|
|
|
const languageTags = new Set();
|
|
for (const locale of locales) {
|
|
const { code } = locale;
|
|
const tag = code.split('_')[0];
|
|
languageTags.add(tag);
|
|
}
|
|
|
|
for (const tag of languageTags) {
|
|
allCopyTargets.push({
|
|
src: `./node_modules/@formatjs/intl-relativetimeformat/dist/locale-data/${tag}.json`,
|
|
dest: `intl/${tag}/relative-time-format-data.json`,
|
|
});
|
|
}
|
|
|
|
const copyTargetsDev = [
|
|
...allCopyTargets,
|
|
{
|
|
src: './development',
|
|
pattern: '/chromereload.js',
|
|
dest: ``,
|
|
},
|
|
// empty files to suppress missing file errors
|
|
{
|
|
src: EMPTY_JS_FILE,
|
|
dest: `bg-libs.js`,
|
|
},
|
|
{
|
|
src: EMPTY_JS_FILE,
|
|
dest: `ui-libs.js`,
|
|
},
|
|
];
|
|
|
|
const copyTargetsProd = [
|
|
...allCopyTargets,
|
|
// empty files to suppress missing file errors
|
|
{
|
|
src: EMPTY_JS_FILE,
|
|
dest: `chromereload.js`,
|
|
},
|
|
];
|
|
|
|
return [copyTargetsProd, copyTargetsDev];
|
|
}
|