From 5a3524fa7416a10332cf63448783ee51f461e8c5 Mon Sep 17 00:00:00 2001 From: Empowerful <45366397+Empowerful@users.noreply.github.com> Date: Fri, 25 Oct 2019 15:40:17 -0400 Subject: [PATCH] Ready to deploy. --- package.json | 3 + packages/main-process/webpack.config.dev.js | 4 + packages/main-process/webpack.debug.js | 177 +++++----- packages/root-process/package.json | 12 +- packages/root-process/webpack.ci.js | 90 +++++ .../webpack.ci.process.js} | 63 +++- packages/root-process/webpack.config.ci.js | 48 --- packages/root-process/webpack.debug.js | 307 +++++++++--------- .../root-process/webpack.local.process.js | 228 +++++++++++++ .../security-process/webpack.config.ci.js | 79 ----- packages/security-process/webpack.debug.js | 177 +++++----- webpack.config.ci.js | 73 ----- yarn.lock | 75 ++++- 13 files changed, 805 insertions(+), 531 deletions(-) create mode 100644 packages/root-process/webpack.ci.js rename packages/{main-process/webpack.config.ci.js => root-process/webpack.ci.process.js} (60%) delete mode 100644 packages/root-process/webpack.config.ci.js create mode 100644 packages/root-process/webpack.local.process.js delete mode 100644 packages/security-process/webpack.config.ci.js delete mode 100644 webpack.config.ci.js diff --git a/package.json b/package.json index 3d6306c5ec7..792c089c105 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,9 @@ "coverage:core": "yarn workspace blockchain-wallet-v4 coverage", "coverage:main": "yarn workspace main-process coverage", "coverage:security": "yarn workspace security-process coverage", + "debug:dev": "yarn workspace root-process debug:dev", "debug:prod": "yarn workspace root-process debug:prod", + "debug:staging": "yarn workspace root-process debug:staging", "fix": "cross-env yarn prettier && yarn lint:fix && yarn test:components:update && yarn test:frontend:update", "link:resolved:paths": "yarn wsrun link:resolved:paths --exclude-missing", "lint": "eslint --cache './packages/*/src/**/*.js'", @@ -178,6 +180,7 @@ "file-loader": "3.0.1", "generate-changelog": "1.7.1", "html-webpack-plugin": "3.2.0", + "http-proxy": "1.18.0", "husky": "2.3.0", "identity-obj-proxy": "3.0.0", "istanbul": "github:Xesenix/istanbul", diff --git a/packages/main-process/webpack.config.dev.js b/packages/main-process/webpack.config.dev.js index f6784153fe7..603098d27c4 100644 --- a/packages/main-process/webpack.config.dev.js +++ b/packages/main-process/webpack.config.dev.js @@ -1,3 +1,7 @@ +/* eslint no-console: "off" */ + +'use strict' + const CleanWebpackPlugin = require('clean-webpack-plugin') const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') diff --git a/packages/main-process/webpack.debug.js b/packages/main-process/webpack.debug.js index b25f027f716..ffc1092a326 100644 --- a/packages/main-process/webpack.debug.js +++ b/packages/main-process/webpack.debug.js @@ -1,3 +1,7 @@ +/* eslint no-console: "off" */ + +'use strict' + const CleanWebpackPlugin = require('clean-webpack-plugin') const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') @@ -8,35 +12,110 @@ const fs = require('fs') const babelConfig = require(`./babel.config.js`) -const src = path.join(__dirname, `src`) +const ContentSecurityPolicy = ({ + api, + bitpay, + coinify, + coinifyPaymentDomain, + comWalletApp, + horizon, + i_sign_this_domain, + ledger, + ledgerSocket, + localhostUrl, + root, + sfox_kyc_url, + sfox_quote_url, + sfox_url, + shapeshift_url, + veriff, + walletHelper, + webpackHttp, + webpackWebSocket, + webSocket +}) => ({ + 'child-src': [ + coinifyPaymentDomain, + i_sign_this_domain, + root, + veriff, + walletHelper + ], + 'connect-src': [ + api, + bitpay, + coinify, + horizon, + ledgerSocket, + ledger, + localhostUrl, + root, + sfox_kyc_url, + sfox_quote_url, + sfox_url, + shapeshift_url, + webpackHttp, + webpackWebSocket, + webSocket, + 'https://horizon.stellar.org', + 'https://www.unocoin.com' + ], + 'default-src': [localhostUrl], + 'font-src': [localhostUrl], + 'form-action': [localhostUrl], + 'frame-ancestors': [comWalletApp], + 'frame-src': [ + coinifyPaymentDomain, + i_sign_this_domain, + root, + veriff, + walletHelper + ], + 'img-src': [ + localhostUrl, + root, + 'android-webview-video-poster:', + 'blob:', + 'data:' + ], + 'media-src': [ + localhostUrl, + 'blob:', + 'data:', + 'https://storage.googleapis.com/bc_public_assets/', + 'mediastream:' + ], + 'object-src': ["'none'"], + 'script-src': [localhostUrl, "'unsafe-eval'"], + 'style-src': ["'unsafe-inline'", localhostUrl], + 'worker-src': ['blob:;'] +}) const cspToString = policy => Object.entries(policy) .map(([key, value]) => `${key} ${value.join(' ')}`) .join(`; `) +const src = path.join(__dirname, `src`) + module.exports = ({ - envConfig, + domains, localhostUrl, manifestCacheBust, PATHS, - port, - rootProcessUrl, sslEnabled }) => { - const webSocketProtocol = sslEnabled ? `wss` : `ws` - const webSocketUrl = `${webSocketProtocol}://localhost:${port}` + const webpackHttpProtocol = sslEnabled ? `https` : `http` + const webpackUrlProtocol = sslEnabled ? `wss` : `ws` return { mode: 'production', node: { fs: 'empty' }, - entry: { - app: ['@babel/polyfill', src + '/index.js'] - }, + entry: ['@babel/polyfill', src + '/index.js'], output: { - path: PATHS.ciBuild, + path: path.join(PATHS.ciBuild, `main`), chunkFilename: '[name].[chunkhash:10].js', publicPath: '/', crossOriginLoading: 'anonymous' @@ -90,8 +169,7 @@ module.exports = ({ new CleanWebpackPlugin(), new CaseSensitivePathsPlugin(), new Webpack.DefinePlugin({ - APP_VERSION: JSON.stringify(require(PATHS.pkgJson).version), - NETWORK_TYPE: JSON.stringify(envConfig.NETWORK_TYPE) + APP_VERSION: JSON.stringify(require(PATHS.pkgJson).version) }), new HtmlWebpackPlugin({ template: src + '/index.html', @@ -131,86 +209,33 @@ module.exports = ({ : '', contentBase: src, disableHostCheck: true, - host: 'localhost', https: sslEnabled, key: sslEnabled ? fs.readFileSync(PATHS.sslConfig + '/key.pem', 'utf8') : '', + liveReload: false, hot: false, historyApiFallback: true, proxy: { '/ledger': { - target: envConfig.LEDGER_URL, + target: domains.ledger, secure: false, changeOrigin: true, pathRewrite: { '^/ledger': '' } } }, - overlay: { - warnings: true, - errors: true - }, headers: { 'Access-Control-Allow-Origin': '*', - 'Content-Security-Policy': cspToString({ - 'base-uri': [localhostUrl], - 'connect-src': [ - localhostUrl, - webSocketUrl, - envConfig.COINIFY_URL, - envConfig.WEB_SOCKET_URL, - envConfig.WALLET_HELPER_DOMAIN, - envConfig.LEDGER_URL, - envConfig.LEDGER_SOCKET_URL, - envConfig.HORIZON_URL, - envConfig.VERIFF_URL, - 'https://app-api.sandbox.coinify.com', - 'https://api.sfox.com', - 'https://api.staging.sfox.com', - 'https://api.testnet.blockchain.info', - `https://bitpay.com`, - 'https://friendbot.stellar.org', - `https://horizon.blockchain.info`, - 'https://quotes.sfox.com', - `https://quotes.staging.sfox.com`, - 'https://sfox-kyc.s3.amazonaws.com', - 'https://sfox-kyctest.s3.amazonaws.com', - 'https://shapeshift.io', - 'https://testnet5.blockchain.info', - `https://www.unocoin.com`, - `wss://api.ledgerwallet.com`, - `wss://ws.testnet.blockchain.info/inv` - ], - 'default-src': [localhostUrl], - 'form-action': [localhostUrl], - 'frame-ancestors': [rootProcessUrl], - 'frame-src': [ - envConfig.COINIFY_PAYMENT_DOMAIN, - envConfig.WALLET_HELPER_DOMAIN, - envConfig.ROOT_URL, - envConfig.VERIFF_URL, - `https://verify.isignthis.com/` - ], - 'img-src': [ - localhostUrl, - `https://blockchain.info/`, - `data:`, - `blob:`, - `android-webview-video-poster:` - ], - 'media-src': [ + 'Content-Security-Policy': cspToString( + ContentSecurityPolicy({ + ...domains, localhostUrl, - `blob:`, - `data:`, - `mediastream:`, - `https://storage.googleapis.com/bc_public_assets/` - ], - 'object-src': [`'none'`], - 'script-src': [localhostUrl, `'unsafe-eval'`], - 'style-src': [localhostUrl, `'unsafe-inline'`], - 'worker-src': [`blob:`] - }) - } + webpackHttp: `${webpackHttpProtocol}://localhost:8080`, + webpackWebSocket: `${webpackUrlProtocol}://localhost:8080` + }) + ) + }, + writeToDisk: true } } } diff --git a/packages/root-process/package.json b/packages/root-process/package.json index 05409aac768..b29b7ca1470 100644 --- a/packages/root-process/package.json +++ b/packages/root-process/package.json @@ -4,11 +4,13 @@ "main": "index.js", "license": "MIT", "scripts": { - "debug:prod": "cross-env-shell NODE_ENV=production webpack-dev-server --config webpack.debug.js --progress --colors", - "start:dev": "cross-env-shell NODE_ENV=development webpack-dev-server --config webpack.config.dev.js --progress --colors --watch --devtool cheap-module-source-map", - "start:prod": "cross-env-shell DISABLE_SSL=true NODE_ENV=production webpack-dev-server --config webpack.config.dev.js --progress --colors --watch --devtool cheap-module-source-map", - "start:staging": "cross-env-shell NODE_ENV=staging webpack-dev-server --config webpack.config.dev.js --progress --colors --watch --devtool cheap-module-source-map", - "start:testnet": "cross-env-shell NODE_ENV=testnet webpack-dev-server --config webpack.config.dev.js --progress --colors --watch --devtool cheap-module-source-map", + "debug:dev": "cross-env-shell BACKEND_ENV=development NODE_ENV=production webpack-dev-server --config webpack.debug.js --progress --colors", + "debug:prod": "cross-env-shell BACKEND_ENV=production NODE_ENV=production webpack-dev-server --config webpack.debug.js --progress --colors", + "debug:staging": "cross-env-shell BACKEND_ENV=staging NODE_ENV=production webpack-dev-server --config webpack.debug.js --progress --colors", + "start:dev": "cross-env-shell NODE_ENV=development NODE_OPTIONS=--max-old-space-size=8192 webpack-dev-server --config webpack.config.dev.js --progress --colors --watch --devtool cheap-module-source-map", + "start:prod": "cross-env-shell DISABLE_SSL=true NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 webpack-dev-server --config webpack.config.dev.js --progress --colors --watch --devtool cheap-module-source-map", + "start:staging": "cross-env-shell NODE_ENV=staging NODE_OPTIONS=--max-old-space-size=8192 webpack-dev-server --config webpack.config.dev.js --progress --colors --watch --devtool cheap-module-source-map", + "start:testnet": "cross-env-shell NODE_ENV=testnet NODE_OPTIONS=--max-old-space-size=8192 webpack-dev-server --config webpack.config.dev.js --progress --colors --watch --devtool cheap-module-source-map", "test": "echo 'No tests to execute.'", "test:build": "echo 'No precomplilation required for tests to execute.'" }, diff --git a/packages/root-process/webpack.ci.js b/packages/root-process/webpack.ci.js new file mode 100644 index 00000000000..4bd219c4375 --- /dev/null +++ b/packages/root-process/webpack.ci.js @@ -0,0 +1,90 @@ +/* eslint no-console: "off" */ + +'use strict' + +const CleanWebpackPlugin = require('clean-webpack-plugin') +const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const path = require('path') +const UglifyJSPlugin = require('uglifyjs-webpack-plugin') + +const babelConfig = require(`./babel.config`) +const PATHS = require('../../config/paths') +const ProcessConfiguration = require(`./webpack.ci.process`) + +let manifestCacheBust = new Date().getTime() +const src = path.join(__dirname, `src`) + +const rootProcess = { + mode: 'production', + name: `root`, + node: { + fs: 'empty' + }, + entry: ['@babel/polyfill', src + '/index.js'], + output: { + path: path.join(PATHS.ciBuild, `root`), + chunkFilename: '[name].[chunkhash:10].js', + publicPath: '/', + crossOriginLoading: 'anonymous' + }, + module: { + rules: [ + { + test: /\.js$/, + use: [ + { loader: 'thread-loader', options: { workerParallelJobs: 50 } }, + { loader: 'babel-loader', options: babelConfig } + ] + }, + { + test: /\.(png|jpg|gif|svg|ico|webmanifest|xml)$/, + use: { + loader: 'file-loader', + options: { + name: 'img/[name].[ext]' + } + } + } + ] + }, + performance: { + hints: false + }, + plugins: [ + new CleanWebpackPlugin(), + new CaseSensitivePathsPlugin(), + new HtmlWebpackPlugin({ + template: src + '/index.html', + filename: 'index.html' + }) + ], + optimization: { + namedModules: true, + minimizer: [ + new UglifyJSPlugin({ + uglifyOptions: { + warnings: false, + compress: { + keep_fnames: true + }, + mangle: { + keep_fnames: true + } + }, + parallel: true, + cache: false + }) + ], + concatenateModules: true, + runtimeChunk: { + name: `manifest.${manifestCacheBust}` + } + } +} + +module.exports = () => [ + rootProcess, + ProcessConfiguration({ manifestCacheBust, PATHS }, `main`), + ProcessConfiguration({ manifestCacheBust, PATHS }, `security`) +] diff --git a/packages/main-process/webpack.config.ci.js b/packages/root-process/webpack.ci.process.js similarity index 60% rename from packages/main-process/webpack.config.ci.js rename to packages/root-process/webpack.ci.process.js index f17d73a0d8b..0b2638d5d2f 100644 --- a/packages/main-process/webpack.config.ci.js +++ b/packages/root-process/webpack.ci.process.js @@ -1,21 +1,29 @@ -/* eslint-disable */ -const babelConfig = require(`./babel.config.js`) -const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') - .BundleAnalyzerPlugin +/* eslint no-console: "off" */ + +'use strict' + const CleanWebpackPlugin = require('clean-webpack-plugin') +const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') -const path = require(`path`) +const UglifyJSPlugin = require('uglifyjs-webpack-plugin') const Webpack = require('webpack') +const path = require('path') + +const babelConfig = require(`./babel.config.js`) -const runBundleAnalyzer = process.env.ANALYZE const src = path.join(__dirname, `src`) -module.exports = ({ envConfig, PATHS }) => ({ - name: `main`, - entry: ['@babel/polyfill', path.join(src, 'index.js')], +module.exports = ({ manifestCacheBust, PATHS }, name) => ({ + mode: 'production', + name, + node: { + fs: 'empty' + }, + entry: ['@babel/polyfill', src + '/index.js'], output: { - path: PATHS.ciBuild, + path: path.join(PATHS.ciBuild, name), chunkFilename: '[name].[chunkhash:10].js', + publicPath: '/', crossOriginLoading: 'anonymous' }, module: { @@ -60,20 +68,45 @@ module.exports = ({ envConfig, PATHS }) => ({ } ] }, + performance: { + hints: false + }, plugins: [ new CleanWebpackPlugin(), + new CaseSensitivePathsPlugin(), new Webpack.DefinePlugin({ - APP_VERSION: JSON.stringify(require(PATHS.pkgJson).version), - NETWORK_TYPE: JSON.stringify(envConfig.NETWORK_TYPE) + APP_VERSION: JSON.stringify(require(PATHS.pkgJson).version) }), new HtmlWebpackPlugin({ - template: path.join(src, 'index.html'), + template: src + '/index.html', filename: 'index.html' }), new Webpack.IgnorePlugin({ resourceRegExp: /^\.\/locale$/, contextRegExp: /moment$/ }), - ...(runBundleAnalyzer ? [new BundleAnalyzerPlugin({})] : []) - ] + new Webpack.ProgressPlugin() + ], + optimization: { + namedModules: true, + minimizer: [ + new UglifyJSPlugin({ + uglifyOptions: { + warnings: false, + compress: { + keep_fnames: true + }, + mangle: { + keep_fnames: true + } + }, + parallel: true, + cache: false + }) + ], + concatenateModules: true, + runtimeChunk: { + name: `manifest.${manifestCacheBust}` + } + } }) diff --git a/packages/root-process/webpack.config.ci.js b/packages/root-process/webpack.config.ci.js deleted file mode 100644 index 4e5cebf67b2..00000000000 --- a/packages/root-process/webpack.config.ci.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict' -const babelConfig = require(`./babel.config.js`) -const CleanWebpackPlugin = require('clean-webpack-plugin') -const HtmlWebpackPlugin = require('html-webpack-plugin') -const path = require(`path`) -const Webpack = require('webpack') - -const src = path.join(__dirname, `src`) - -module.exports = ({ PATHS }) => ({ - name: `root`, - entry: ['@babel/polyfill', path.join(src, 'index.js')], - module: { - rules: [ - { - test: /\.js$/, - use: [ - { loader: 'thread-loader', options: { workerParallelJobs: 50 } }, - { loader: 'babel-loader', options: babelConfig } - ] - }, - { - test: /\.(png|jpg|gif|svg|ico|webmanifest|xml)$/, - use: { - loader: 'file-loader', - options: { - name: 'img/[name].[ext]' - } - } - } - ] - }, - output: { - filename: `index.js`, - path: PATHS.ciBuild - }, - plugins: [ - new CleanWebpackPlugin(), - new HtmlWebpackPlugin({ - template: path.join(src, 'index.html'), - filename: 'index.html' - }), - new Webpack.DefinePlugin({ - MAIN_DOMAIN: `"https://wallet-main-dev.blockchain.com/"`, - SECURITY_DOMAIN: `"https://wallet-security-dev.blockchain.com/"` - }) - ] -}) diff --git a/packages/root-process/webpack.debug.js b/packages/root-process/webpack.debug.js index 4e598ba95a0..2b68c28e913 100644 --- a/packages/root-process/webpack.debug.js +++ b/packages/root-process/webpack.debug.js @@ -1,21 +1,49 @@ /* eslint no-console: "off" */ +'use strict' + const chalk = require('chalk') const CleanWebpackPlugin = require('clean-webpack-plugin') const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') +const httpProxy = require(`http-proxy`) +const fetch = require('node-fetch') const net = require(`net`) const UglifyJSPlugin = require('uglifyjs-webpack-plugin') +const R = require(`ramda`) +const util = require(`util`) const Webpack = require('webpack') const webpackDevServer = require(`webpack-dev-server`) const path = require('path') const fs = require('fs') + +const babelConfig = require(`./babel.config.js`) const PATHS = require('../../config/paths') -const mockWalletOptions = require('../../config/mocks/wallet-options-v4.json') const MainProcessWebpackConfiguration = require(`main-process/webpack.debug.js`) const SecurityProcessWebpackConfiguration = require(`security-process/webpack.debug.js`) +const ContentSecurityPolicy = ({ + api, + comWalletApp, + mainProcess, + root, + securityProcess, + webpack, + webSocket +}) => ({ + 'base-uri': [comWalletApp], + 'connect-src': [api, comWalletApp, root, webpack, webSocket], + 'default-src': [`'none'`], + 'form-action': [`'none'`], + 'frame-src': [mainProcess, securityProcess], + 'img-src': [comWalletApp], + 'manifest-src': [comWalletApp], + 'object-src': [`'none'`], + 'script-src': [comWalletApp, `'unsafe-eval'`], + 'style-src': [`'unsafe-inline'`] +}) + const cspToString = policy => Object.entries(policy) .map(([key, value]) => `${key} ${value.join(' ')}`) @@ -36,59 +64,73 @@ const getAvailablePort = () => }) }) +const src = path.join(__dirname, `src`) + module.exports = async () => { - let envConfig = {} + const subdomains = { + development: `dev`, + staging: `staging`, + production: `prod`, + testnet: `prod` + } + + const { + BACKEND_ENV, + MAIN_PROCESS_URL, + NODE_ENV, + SECURITY_PROCESS_URL + } = process.env + + const subdomain = subdomains[BACKEND_ENV || NODE_ENV] + const walletOptionsUrl = `https://wallet-frontend-v4.${subdomain}.blockchain.info/Resources/wallet-options-v4.json` + const originalWalletOptions = await (await fetch(walletOptionsUrl)).json() + let manifestCacheBust = new Date().getTime() + let localOverrides = {} + + try { + localOverrides = require(PATHS.envConfig + + `/${process.env.NODE_ENV}` + + '.js') + } catch {} + let sslEnabled = process.env.DISABLE_SSL ? false : fs.existsSync(PATHS.sslConfig + '/key.pem') && fs.existsSync(PATHS.sslConfig + '/cert.pem') const port = 8080 - const protocol = sslEnabled ? `https` : `http` - const rootProcessUrl = `${protocol}://localhost:${port}` - const webSocketProtocol = sslEnabled ? `wss` : `ws` - const webSocketUrl = `${webSocketProtocol}://localhost:${port}` + const comWalletAppProtocol = sslEnabled ? `https` : `http` + const webPackProtocol = sslEnabled ? `wss` : `ws` - try { - envConfig = require(PATHS.envConfig + `/${process.env.NODE_ENV}` + '.js') - } catch (e) { - console.log( - chalk.red('\u{1F6A8} WARNING \u{1F6A8} ') + - chalk.yellow( - `Failed to load ${ - process.env.NODE_ENV - }.js config file! Using the production config instead.\n` - ) - ) - envConfig = require(PATHS.envConfig + '/production.js') - } finally { - console.log(chalk.blue('\u{1F6A7} CONFIGURATION \u{1F6A7}')) - console.log(chalk.cyan('Root URL') + `: ${envConfig.ROOT_URL}`) - console.log(chalk.cyan('API Domain') + `: ${envConfig.API_DOMAIN}`) - console.log( - chalk.cyan('Wallet Helper Domain') + - ': ' + - chalk.blue(envConfig.WALLET_HELPER_DOMAIN) - ) - console.log( - chalk.cyan('Web Socket URL') + ': ' + chalk.blue(envConfig.WEB_SOCKET_URL) - ) - console.log(chalk.cyan('SSL Enabled: ') + chalk.blue(sslEnabled)) + const serverOverrides = { + domains: { + comWalletApp: `${comWalletAppProtocol}://localhost:${port}`, + webpack: `${webPackProtocol}://localhost:${port}`, + ...(MAIN_PROCESS_URL ? { mainProcess: MAIN_PROCESS_URL } : {}), + ...(SECURITY_PROCESS_URL ? { securityProcess: SECURITY_PROCESS_URL } : {}) + } } - const startServer = async WebpackConfiguration => { + const walletOptions = [ + originalWalletOptions, + localOverrides, + serverOverrides + ].reduce(R.mergeDeepRight) + + const { domains } = walletOptions + + const startServer = async (WebpackConfiguration, domain) => { const port = await getAvailablePort() - const protocol = sslEnabled ? `https` : `http` - const localhostUrl = `${protocol}://localhost:${port}` + const localhostProtocol = sslEnabled ? `https` : `http` + const localhostUrl = `${localhostProtocol}://localhost:${port}` const configuration = WebpackConfiguration({ - envConfig, - localhostUrl, + domains: walletOptions.domains, + localhostUrl: domain, manifestCacheBust, PATHS, port, - rootProcessUrl, sslEnabled }) @@ -99,20 +141,83 @@ module.exports = async () => { } const [mainProcessUrl, securityProcessUrl] = await Promise.all([ - startServer(MainProcessWebpackConfiguration), - startServer(SecurityProcessWebpackConfiguration) + startServer(MainProcessWebpackConfiguration, domains.mainProcess), + startServer(SecurityProcessWebpackConfiguration, domains.securityProcess) ]) + console.log(chalk.blue('\u{1F6A7} CONFIGURATION \u{1F6A7}')) + + console.log( + util.inspect( + R.pick( + [ + `api`, + `mainProcess`, + `root`, + `securityProcess`, + `walletHelper`, + `webSocket` + ], + domains + ), + { colors: true } + ) + ) + + console.log(chalk.cyan('SSL Enabled: ') + chalk.blue(sslEnabled)) + + const vhost = (url, middleware) => (request, response, next) => { + const { hostname } = new URL(url) + + if (request.hostname === hostname) { + middleware(request, response, next) + } else { + next() + } + } + + const before = app => { + if (domains.mainProcess && domains.securityProcess) { + const proxy = httpProxy.createProxyServer() + + app.use( + vhost(domains.mainProcess, (request, response) => { + proxy.web(request, response, { target: mainProcessUrl }) + }) + ) + + app.use( + vhost(domains.securityProcess, (request, response) => { + proxy.web(request, response, { target: securityProcessUrl }) + }) + ) + } + + app.get('/Resources/wallet-options-v4.json', function (req, res) { + res.json(walletOptions) + }) + + // TODO: DEPRECATE + // This is to locally test transferring cookies from transfer_stored_values.html + app.get('/Resources/transfer_stored_values.html', function (req, res) { + res.sendFile( + path.join(__dirname, '/../../config/mocks/transfer_stored_values.html') + ) + }) + + app.get('/Resources/wallet-options.json', function (req, res) { + res.json(walletOptions) + }) + } + return { mode: 'production', node: { fs: 'empty' }, - entry: { - app: ['@babel/polyfill', PATHS.src + '/index.js'] - }, + entry: ['@babel/polyfill', src + '/index.js'], output: { - path: PATHS.ciBuild, + path: path.join(PATHS.ciBuild, `root`), chunkFilename: '[name].[chunkhash:10].js', publicPath: '/', crossOriginLoading: 'anonymous' @@ -123,18 +228,9 @@ module.exports = async () => { test: /\.js$/, use: [ { loader: 'thread-loader', options: { workerParallelJobs: 50 } }, - 'babel-loader' + { loader: 'babel-loader', options: babelConfig } ] }, - { - test: /\.(eot|ttf|otf|woff|woff2)$/, - use: { - loader: 'file-loader', - options: { - name: 'fonts/[name]-[hash].[ext]' - } - } - }, { test: /\.(png|jpg|gif|svg|ico|webmanifest|xml)$/, use: { @@ -143,19 +239,6 @@ module.exports = async () => { name: 'img/[name].[ext]' } } - }, - { - test: /\.(pdf)$/, - use: { - loader: 'file-loader', - options: { - name: 'resources/[name]-[hash].[ext]' - } - } - }, - { - test: /\.css$/, - use: [{ loader: 'style-loader' }, { loader: 'css-loader' }] } ] }, @@ -165,21 +248,14 @@ module.exports = async () => { plugins: [ new CleanWebpackPlugin(), new CaseSensitivePathsPlugin(), - new Webpack.DefinePlugin({ - APP_VERSION: JSON.stringify(require(PATHS.pkgJson).version), - NETWORK_TYPE: JSON.stringify(envConfig.NETWORK_TYPE) - }), new HtmlWebpackPlugin({ - template: PATHS.src + '/index.html', + template: src + '/index.html', filename: 'index.html' }), new Webpack.DefinePlugin({ - MAIN_PROCESS_URL: `"${mainProcessUrl}"`, - SECURITY_PROCESS_URL: `"${securityProcessUrl}"` - }), - new Webpack.IgnorePlugin({ - resourceRegExp: /^\.\/locale$/, - contextRegExp: /moment$/ + MAIN_PROCESS_URL: `"${domains.mainProcess || mainProcessUrl}"`, + SECURITY_PROCESS_URL: `"${domains.securityProcess || + securityProcessUrl}"` }) ], optimization: { @@ -205,96 +281,33 @@ module.exports = async () => { } }, devServer: { + before, cert: sslEnabled ? fs.readFileSync(PATHS.sslConfig + '/cert.pem', 'utf8') : '', - contentBase: PATHS.src, + contentBase: src, disableHostCheck: true, - host: 'localhost', https: sslEnabled, key: sslEnabled ? fs.readFileSync(PATHS.sslConfig + '/key.pem', 'utf8') : '', + liveReload: false, port, hot: false, historyApiFallback: true, - before (app) { - app.get('/Resources/wallet-options-v4.json', function (req, res) { - // combine wallet options base with custom environment config - mockWalletOptions.domains = { - api: envConfig.API_DOMAIN, - coinify: envConfig.COINIFY_URL, - coinifyPaymentDomain: envConfig.COINIFY_PAYMENT_DOMAIN, - comRoot: envConfig.COM_ROOT, - comWalletApp: envConfig.COM_WALLET_APP, - horizon: envConfig.HORIZON_URL, - ledger: rootProcessUrl + '/ledger', // will trigger reverse proxy - ledgerSocket: envConfig.LEDGER_SOCKET_URL, - root: envConfig.ROOT_URL, - thePit: envConfig.THE_PIT_URL, - veriff: envConfig.VERIFF_URL, - walletHelper: envConfig.WALLET_HELPER_DOMAIN, - webSocket: envConfig.WEB_SOCKET_URL - } - - if (process.env.NODE_ENV === 'testnet') { - mockWalletOptions.platforms.web.coins.BTC.config.network = 'testnet' - mockWalletOptions.platforms.web.coinify.config.partnerId = 35 - mockWalletOptions.platforms.web.sfox.config.apiKey = - '6fbfb80536564af8bbedb7e3be4ec439' - } - - res.json(mockWalletOptions) - }) - - // TODO: DEPRECATE - // This is to locally test transferring cookies from transfer_stored_values.html - app.get('/Resources/transfer_stored_values.html', function (req, res) { - res.sendFile( - path.join( - __dirname, - '/../../config/mocks/transfer_stored_values.html' - ) - ) - }) - - app.get('/Resources/wallet-options.json', function (req, res) { - mockWalletOptions.domains = { comWalletApp: rootProcessUrl } - res.json(mockWalletOptions) - }) - }, proxy: { '/ledger': { - target: envConfig.LEDGER_URL, + target: domains.ledger, secure: false, changeOrigin: true, pathRewrite: { '^/ledger': '' } } }, - overlay: { - warnings: true, - errors: true - }, headers: { 'Access-Control-Allow-Origin': '*', - 'Content-Security-Policy': cspToString({ - 'base-uri': [rootProcessUrl], - 'connect-src': [ - rootProcessUrl, - webSocketUrl, - envConfig.API_DOMAIN, - envConfig.ROOT_URL - ], - 'default-src': [`'none'`], - 'form-action': [`'none'`], - 'frame-src': [mainProcessUrl, securityProcessUrl], - 'img-src': [rootProcessUrl], - 'manifest-src': [rootProcessUrl], - 'object-src': [`'none'`], - 'script-src': [rootProcessUrl, `'unsafe-eval'`], - 'style-src': [`'unsafe-inline'`] - }) - } + 'Content-Security-Policy': cspToString(ContentSecurityPolicy(domains)) + }, + writeToDisk: true } } } diff --git a/packages/root-process/webpack.local.process.js b/packages/root-process/webpack.local.process.js new file mode 100644 index 00000000000..81628f346ec --- /dev/null +++ b/packages/root-process/webpack.local.process.js @@ -0,0 +1,228 @@ +/* eslint no-console: "off" */ + +'use strict' + +const CleanWebpackPlugin = require('clean-webpack-plugin') +const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const fs = require('fs') +const path = require(`path`) +const Webpack = require('webpack') + +const babelConfig = require(`./babel.config.js`) + +const ContentSecurityPolicy = ({ + api, + bitpay, + coinify, + coinifyPaymentDomain, + comWalletApp, + horizon, + i_sign_this_domain, + ledger, + ledgerSocket, + localhostUrl, + root, + sfox_kyc_url, + sfox_quote_url, + sfox_url, + shapeshift_url, + veriff, + walletHelper, + webpack, + webSocket +}) => ({ + 'child-src': [ + coinifyPaymentDomain, + i_sign_this_domain, + root, + veriff, + walletHelper + ], + 'connect-src': [ + api, + bitpay, + coinify, + horizon, + ledgerSocket, + ledger, + localhostUrl, + root, + sfox_kyc_url, + sfox_quote_url, + sfox_url, + shapeshift_url, + webpack, + webSocket, + 'https://horizon.stellar.org', + 'https://www.unocoin.com' + ], + 'default-src': [localhostUrl], + 'font-src': [localhostUrl], + 'form-action': [localhostUrl], + 'frame-ancestors': [comWalletApp], + 'frame-src': [ + coinifyPaymentDomain, + i_sign_this_domain, + root, + veriff, + walletHelper + ], + 'img-src': [ + localhostUrl, + root, + 'android-webview-video-poster:', + 'blob:', + 'data:' + ], + 'media-src': [ + localhostUrl, + 'blob:', + 'data:', + 'https://storage.googleapis.com/bc_public_assets/', + 'mediastream:' + ], + 'object-src': ["'none'"], + 'script-src': [localhostUrl, "'unsafe-eval'"], + 'style-src': ["'unsafe-inline'", localhostUrl], + 'worker-src': ['blob:;'] +}) + +const cspToString = policy => + Object.entries(policy) + .map(([key, value]) => `${key} ${value.join(' ')}`) + .join(`; `) + +const src = path.join(__dirname, `src`) + +module.exports = ( + { domains, localhostUrl, manifestCacheBust, PATHS, port, sslEnabled }, + name +) => { + const webpackProtocol = sslEnabled ? `wss` : `ws` + const webpackUrl = `${webpackProtocol}://localhost:${port}` + + return { + mode: 'development', + name, + node: { + fs: 'empty' + }, + entry: [ + '@babel/polyfill', + 'react-hot-loader/patch', + `webpack-dev-server/client?${localhostUrl}`, + 'webpack/hot/only-dev-server', + src + '/index.js' + ], + output: { + path: path.join(PATHS.appBuild, name), + chunkFilename: '[name].[chunkhash:10].js', + publicPath: '/', + crossOriginLoading: 'anonymous' + }, + module: { + rules: [ + { + test: /\.js$/, + include: /src|blockchain-info-components.src|blockchain-wallet-v4.src/, + use: [ + { loader: 'thread-loader', options: { workerParallelJobs: 50 } }, + { loader: 'babel-loader', options: babelConfig } + ] + }, + { + test: /\.(eot|ttf|otf|woff|woff2)$/, + use: { + loader: 'file-loader', + options: { + name: 'fonts/[name]-[hash].[ext]' + } + } + }, + { + test: /\.(png|jpg|gif|svg|ico|webmanifest|xml)$/, + use: { + loader: 'file-loader', + options: { + name: 'img/[name].[ext]' + } + } + }, + { + test: /\.(pdf)$/, + use: { + loader: 'file-loader', + options: { + name: 'resources/[name]-[hash].[ext]' + } + } + }, + { + test: /\.css$/, + use: [{ loader: 'style-loader' }, { loader: 'css-loader' }] + } + ] + }, + plugins: [ + new CleanWebpackPlugin(), + new CaseSensitivePathsPlugin(), + new Webpack.DefinePlugin({ + APP_VERSION: JSON.stringify(require(PATHS.pkgJson).version) + }), + new HtmlWebpackPlugin({ + template: src + '/index.html', + filename: 'index.html' + }), + new Webpack.IgnorePlugin({ + resourceRegExp: /^\.\/locale$/, + contextRegExp: /moment$/ + }), + new Webpack.HotModuleReplacementPlugin(), + new Webpack.ProgressPlugin() + ], + optimization: { + namedModules: true, + concatenateModules: false, + runtimeChunk: { + name: `manifest.${manifestCacheBust}` + } + }, + devServer: { + cert: sslEnabled + ? fs.readFileSync(PATHS.sslConfig + '/cert.pem', 'utf8') + : '', + contentBase: src, + disableHostCheck: true, + host: 'localhost', + https: sslEnabled, + key: sslEnabled + ? fs.readFileSync(PATHS.sslConfig + '/key.pem', 'utf8') + : '', + hot: true, + historyApiFallback: true, + proxy: { + '/ledger': { + target: domains.ledger, + secure: false, + changeOrigin: true, + pathRewrite: { '^/ledger': '' } + } + }, + overlay: { + warnings: true, + errors: true + }, + headers: { + 'Access-Control-Allow-Origin': '*', + 'Content-Security-Policy': cspToString( + ContentSecurityPolicy({ + ...domains, + localhostUrl, + webpack: webpackUrl + }) + ) + } + } + } +} diff --git a/packages/security-process/webpack.config.ci.js b/packages/security-process/webpack.config.ci.js deleted file mode 100644 index e9918349623..00000000000 --- a/packages/security-process/webpack.config.ci.js +++ /dev/null @@ -1,79 +0,0 @@ -/* eslint-disable */ -const babelConfig = require(`./babel.config.js`) -const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') - .BundleAnalyzerPlugin -const CleanWebpackPlugin = require('clean-webpack-plugin') -const HtmlWebpackPlugin = require('html-webpack-plugin') -const path = require(`path`) -const Webpack = require('webpack') - -const runBundleAnalyzer = process.env.ANALYZE -const src = path.join(__dirname, `src`) - -module.exports = ({ envConfig, PATHS }) => ({ - name: `security`, - entry: ['@babel/polyfill', path.join(src, 'index.js')], - output: { - path: PATHS.ciBuild, - chunkFilename: '[name].[chunkhash:10].js', - crossOriginLoading: 'anonymous' - }, - module: { - rules: [ - { - test: /\.js$/, - use: [ - { loader: 'thread-loader', options: { workerParallelJobs: 50 } }, - { loader: 'babel-loader', options: babelConfig } - ] - }, - { - test: /\.(eot|ttf|otf|woff|woff2)$/, - use: { - loader: 'file-loader', - options: { - name: 'fonts/[name]-[hash].[ext]' - } - } - }, - { - test: /\.(png|jpg|gif|svg|ico|webmanifest|xml)$/, - use: { - loader: 'file-loader', - options: { - name: 'img/[name].[ext]' - } - } - }, - { - test: /\.(pdf)$/, - use: { - loader: 'file-loader', - options: { - name: 'resources/[name]-[hash].[ext]' - } - } - }, - { - test: /\.css$/, - use: [{ loader: 'style-loader' }, { loader: 'css-loader' }] - } - ] - }, - plugins: [ - new CleanWebpackPlugin(), - new Webpack.DefinePlugin({ - APP_VERSION: JSON.stringify(require(PATHS.pkgJson).version), - NETWORK_TYPE: JSON.stringify(envConfig.NETWORK_TYPE) - }), - new HtmlWebpackPlugin({ - template: path.join(src, 'index.html'), - filename: 'index.html' - }), - new Webpack.IgnorePlugin({ - resourceRegExp: /^\.\/locale$/, - contextRegExp: /moment$/ - }), - ...(runBundleAnalyzer ? [new BundleAnalyzerPlugin({})] : []) - ] -}) diff --git a/packages/security-process/webpack.debug.js b/packages/security-process/webpack.debug.js index b25f027f716..3f90695d03b 100644 --- a/packages/security-process/webpack.debug.js +++ b/packages/security-process/webpack.debug.js @@ -1,3 +1,7 @@ +/* eslint no-console: "off" */ + +'use strict' + const CleanWebpackPlugin = require('clean-webpack-plugin') const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') @@ -8,35 +12,110 @@ const fs = require('fs') const babelConfig = require(`./babel.config.js`) -const src = path.join(__dirname, `src`) +const ContentSecurityPolicy = ({ + api, + bitpay, + coinify, + coinifyPaymentDomain, + comWalletApp, + horizon, + i_sign_this_domain, + ledger, + ledgerSocket, + localhostUrl, + root, + sfox_kyc_url, + sfox_quote_url, + sfox_url, + shapeshift_url, + veriff, + walletHelper, + webpackHttp, + webpackWebSocket, + webSocket +}) => ({ + 'child-src': [ + coinifyPaymentDomain, + i_sign_this_domain, + root, + veriff, + walletHelper + ], + 'connect-src': [ + api, + bitpay, + coinify, + horizon, + ledgerSocket, + ledger, + localhostUrl, + root, + sfox_kyc_url, + sfox_quote_url, + sfox_url, + shapeshift_url, + webpackHttp, + webpackWebSocket, + webSocket, + 'https://horizon.stellar.org', + 'https://www.unocoin.com' + ], + 'default-src': [localhostUrl], + 'font-src': [localhostUrl], + 'form-action': [localhostUrl], + 'frame-ancestors': [comWalletApp], + 'frame-src': [ + coinifyPaymentDomain, + i_sign_this_domain, + root, + veriff, + walletHelper + ], + 'img-src': [ + localhostUrl, + root, + 'android-webview-video-poster:', + 'blob:', + 'data:' + ], + 'media-src': [ + localhostUrl, + 'blob:', + 'data:', + 'https://storage.googleapis.com/bc_public_assets/', + 'mediastream:' + ], + 'object-src': ["'none'"], + 'script-src': [localhostUrl, "'unsafe-eval'"], + 'style-src': ["'unsafe-inline'", localhostUrl], + 'worker-src': ['blob:;'] +}) const cspToString = policy => Object.entries(policy) .map(([key, value]) => `${key} ${value.join(' ')}`) .join(`; `) +const src = path.join(__dirname, `src`) + module.exports = ({ - envConfig, + domains, localhostUrl, manifestCacheBust, PATHS, - port, - rootProcessUrl, sslEnabled }) => { - const webSocketProtocol = sslEnabled ? `wss` : `ws` - const webSocketUrl = `${webSocketProtocol}://localhost:${port}` + const webpackHttpProtocol = sslEnabled ? `https` : `http` + const webpackUrlProtocol = sslEnabled ? `wss` : `ws` return { mode: 'production', node: { fs: 'empty' }, - entry: { - app: ['@babel/polyfill', src + '/index.js'] - }, + entry: ['@babel/polyfill', src + '/index.js'], output: { - path: PATHS.ciBuild, + path: path.join(PATHS.ciBuild, `security`), chunkFilename: '[name].[chunkhash:10].js', publicPath: '/', crossOriginLoading: 'anonymous' @@ -90,8 +169,7 @@ module.exports = ({ new CleanWebpackPlugin(), new CaseSensitivePathsPlugin(), new Webpack.DefinePlugin({ - APP_VERSION: JSON.stringify(require(PATHS.pkgJson).version), - NETWORK_TYPE: JSON.stringify(envConfig.NETWORK_TYPE) + APP_VERSION: JSON.stringify(require(PATHS.pkgJson).version) }), new HtmlWebpackPlugin({ template: src + '/index.html', @@ -131,86 +209,33 @@ module.exports = ({ : '', contentBase: src, disableHostCheck: true, - host: 'localhost', https: sslEnabled, key: sslEnabled ? fs.readFileSync(PATHS.sslConfig + '/key.pem', 'utf8') : '', + liveReload: false, hot: false, historyApiFallback: true, proxy: { '/ledger': { - target: envConfig.LEDGER_URL, + target: domains.ledger, secure: false, changeOrigin: true, pathRewrite: { '^/ledger': '' } } }, - overlay: { - warnings: true, - errors: true - }, headers: { 'Access-Control-Allow-Origin': '*', - 'Content-Security-Policy': cspToString({ - 'base-uri': [localhostUrl], - 'connect-src': [ - localhostUrl, - webSocketUrl, - envConfig.COINIFY_URL, - envConfig.WEB_SOCKET_URL, - envConfig.WALLET_HELPER_DOMAIN, - envConfig.LEDGER_URL, - envConfig.LEDGER_SOCKET_URL, - envConfig.HORIZON_URL, - envConfig.VERIFF_URL, - 'https://app-api.sandbox.coinify.com', - 'https://api.sfox.com', - 'https://api.staging.sfox.com', - 'https://api.testnet.blockchain.info', - `https://bitpay.com`, - 'https://friendbot.stellar.org', - `https://horizon.blockchain.info`, - 'https://quotes.sfox.com', - `https://quotes.staging.sfox.com`, - 'https://sfox-kyc.s3.amazonaws.com', - 'https://sfox-kyctest.s3.amazonaws.com', - 'https://shapeshift.io', - 'https://testnet5.blockchain.info', - `https://www.unocoin.com`, - `wss://api.ledgerwallet.com`, - `wss://ws.testnet.blockchain.info/inv` - ], - 'default-src': [localhostUrl], - 'form-action': [localhostUrl], - 'frame-ancestors': [rootProcessUrl], - 'frame-src': [ - envConfig.COINIFY_PAYMENT_DOMAIN, - envConfig.WALLET_HELPER_DOMAIN, - envConfig.ROOT_URL, - envConfig.VERIFF_URL, - `https://verify.isignthis.com/` - ], - 'img-src': [ - localhostUrl, - `https://blockchain.info/`, - `data:`, - `blob:`, - `android-webview-video-poster:` - ], - 'media-src': [ + 'Content-Security-Policy': cspToString( + ContentSecurityPolicy({ + ...domains, localhostUrl, - `blob:`, - `data:`, - `mediastream:`, - `https://storage.googleapis.com/bc_public_assets/` - ], - 'object-src': [`'none'`], - 'script-src': [localhostUrl, `'unsafe-eval'`], - 'style-src': [localhostUrl, `'unsafe-inline'`], - 'worker-src': [`blob:`] - }) - } + webpackHttp: `${webpackHttpProtocol}://localhost:8080`, + webpackWebSocket: `${webpackUrlProtocol}://localhost:8080` + }) + ) + }, + writeToDisk: true } } } diff --git a/webpack.config.ci.js b/webpack.config.ci.js deleted file mode 100644 index 543e85c7f8a..00000000000 --- a/webpack.config.ci.js +++ /dev/null @@ -1,73 +0,0 @@ -/* eslint-disable */ -const path = require(`path`) -const PATHS = require('./config/paths') -const UglifyJSPlugin = require('uglifyjs-webpack-plugin') - -const mainProcess = require(`./packages/main-process/webpack.config.ci`) -const rootProcess = require(`./packages/root-process/webpack.config.ci`) -const securityProcess = require(`./packages/security-process/webpack.config.ci`) - -let envConfig = {} -let manifestCacheBust = new Date().getTime() - -const common = { - mode: 'production', - node: { - fs: 'empty' - }, - stats: 'verbose', - optimization: { - namedModules: true, - minimizer: [ - new UglifyJSPlugin({ - uglifyOptions: { - warnings: false, - compress: { - keep_fnames: true - }, - mangle: { - keep_fnames: true - } - }, - parallel: true, - cache: false - }) - ], - concatenateModules: true, - runtimeChunk: { - name: `manifest.${manifestCacheBust}` - } - } -} - -module.exports = [ - { - ...common, - ...rootProcess({ - PATHS: { - ...PATHS, - ciBuild: path.join(PATHS.ciBuild, `root`) - } - }) - }, - { - ...common, - ...mainProcess({ - envConfig, - PATHS: { - ...PATHS, - ciBuild: path.join(PATHS.ciBuild, `main`) - } - }) - }, - { - ...common, - ...securityProcess({ - envConfig, - PATHS: { - ...PATHS, - ciBuild: path.join(PATHS.ciBuild, `security`) - } - }) - } -] diff --git a/yarn.lock b/yarn.lock index 369af7c5ece..100ab4efbdc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5003,6 +5003,11 @@ bluebird@^3.5.3: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== +bluebird@^3.5.5: + version "3.7.1" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.1.tgz#df70e302b471d7473489acf26a93d63b53f874de" + integrity sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg== + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.0, bn.js@^4.11.3, bn.js@^4.11.8, bn.js@^4.4.0, bn.js@^4.8.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" @@ -5371,7 +5376,7 @@ cacache@^10.0.4: unique-filename "^1.1.0" y18n "^4.0.0" -cacache@^11.0.2, cacache@^11.3.2: +cacache@^11.0.2: version "11.3.2" resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa" integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg== @@ -5391,6 +5396,26 @@ cacache@^11.0.2, cacache@^11.3.2: unique-filename "^1.1.1" y18n "^4.0.0" +cacache@^11.3.2: + version "11.3.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.3.tgz#8bd29df8c6a718a6ebd2d010da4d7972ae3bbadc" + integrity sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -6024,10 +6049,10 @@ commander@~2.13.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA== -commander@~2.20.0: - version "2.20.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" - integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== +commander@~2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commitizen@3.1.1: version "3.1.1" @@ -8050,6 +8075,11 @@ eventemitter3@^3.0.0, eventemitter3@^3.1.0: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== +eventemitter3@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" + integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg== + events@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -9104,6 +9134,18 @@ glob@7.1.3, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glo once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.4: + version "7.1.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0" + integrity sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-dirs@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" @@ -9788,6 +9830,15 @@ http-proxy-middleware@^0.19.1: lodash "^4.17.11" micromatch "^3.1.10" +http-proxy@1.18.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a" + integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + http-proxy@^1.17.0: version "1.17.0" resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" @@ -16062,9 +16113,9 @@ serialize-javascript@^1.4.0: integrity sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ== serialize-javascript@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65" - integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA== + version "1.9.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.9.1.tgz#cfc200aef77b600c47da9bb8149c943e798c2fdb" + integrity sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A== serve-favicon@^2.5.0: version "2.5.0" @@ -17583,11 +17634,11 @@ uglify-js@3.4.x, uglify-js@^3.1.4: source-map "~0.6.1" uglify-js@^3.5.12: - version "3.5.12" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.5.12.tgz#6b759cabc08c3e91fe82323d6387019f0c5864cd" - integrity sha512-KeQesOpPiZNgVwJj8Ge3P4JYbQHUdZzpx6Fahy6eKAYRSV4zhVmLXoC+JtOeYxcHCHTve8RG1ZGdTvpeOUM26Q== + version "3.6.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.4.tgz#88cc880c6ed5cf9868fdfa0760654e7bed463f1d" + integrity sha512-9Yc2i881pF4BPGhjteCXQNaXx1DCwm3dtOyBaG2hitHjLWOczw/ki8vD1bqyT3u6K0Ms/FpCShkmfg+FtlOfYA== dependencies: - commander "~2.20.0" + commander "~2.20.3" source-map "~0.6.1" uglifyjs-webpack-plugin@2.1.3: