From 7cd929126138da7a7efcaabf2130bbb254f150a1 Mon Sep 17 00:00:00 2001 From: Martin Hradil Date: Wed, 18 Dec 2024 20:03:13 +0000 Subject: [PATCH] Change to API_PROXY=http://localhost:5001 instead of API_PROXY_HOST & API_PROXY_PORT to allow running against https backends and ignore self-signed https certificates, and spoof the Origin, Host & Referer headers correctly --- README.md | 4 ++- config/community.dev.webpack.config.js | 42 +++++++++++------------- config/community.prod.webpack.config.js | 2 +- config/insights.dev.webpack.config.js | 8 ++--- config/insights.prod.webpack.config.js | 2 +- config/standalone.dev.webpack.config.js | 42 +++++++++++------------- config/standalone.prod.webpack.config.js | 2 +- config/webpack.base.config.js | 40 +++++++++++++++++----- package.json | 2 +- 9 files changed, 82 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index d09d02491f..f03d8a6524 100644 --- a/README.md +++ b/README.md @@ -54,9 +54,11 @@ Run: ``` cd ansible-hub-ui -API_PROXY_PORT=5001 npm run start-standalone +API_PROXY=http://localhost:5001 npm run start-standalone ``` +(Or run `API_PROXY=https://my-server.example.com npm run start-standalone` to run with external backend.) + This app can be developed in standalone, community, or insights mode. Insights mode compiles the app to be run on the Red Hat cloud services platform (insights). Standalone mode only requires a running instance of the galaxy API for the UI to connect to. Community mode is similar to standalone, with github login and roles. diff --git a/config/community.dev.webpack.config.js b/config/community.dev.webpack.config.js index 40d2a8f3f3..180059b461 100644 --- a/config/community.dev.webpack.config.js +++ b/config/community.dev.webpack.config.js @@ -1,11 +1,11 @@ -const webpackBase = require('./webpack.base.config'); +const { webpackBase, proxy, fake } = require('./webpack.base.config'); const collectionRatings = require('../static/scores/collection.json'); const roleRatings = require('../static/scores/role.json'); // Used for getting the correct host when running in a container -const proxyHost = process.env.API_PROXY_HOST || 'localhost'; -const proxyPort = process.env.API_PROXY_PORT || '5001'; +const proxyTarget = process.env.API_PROXY || 'http://localhost:5001'; + const apiBasePath = process.env.API_BASE_PATH || '/api/'; const uiExternalLoginURI = process.env.UI_EXTERNAL_LOGIN_URI || '/login/github/'; @@ -44,23 +44,21 @@ module.exports = webpackBase({ // Value for webpack.devServer.proxy // https://webpack.js.org/configuration/dev-server/#devserverproxy // used to get around CORS requirements when running in dev mode - WEBPACK_PROXY: { - '/api/': `http://${proxyHost}:${proxyPort}`, - '/complete/': `http://${proxyHost}:${proxyPort}`, - '/login/': `http://${proxyHost}:${proxyPort}`, - '/pulp/api/': `http://${proxyHost}:${proxyPort}`, - '/static/rest_framework/': `http://${proxyHost}:${proxyPort}`, - '/static/scores/': { - bypass: function (req, res) { - if (req.url === '/static/scores/collection.json') { - res.send(collectionRatings); - return false; - } - if (req.url === '/static/scores/role.json') { - res.send(roleRatings); - return false; - } - }, - }, - }, + WEBPACK_PROXY: [ + proxy('/api/', proxyTarget), + proxy('/pulp/api/', proxyTarget), + proxy('/complete/', proxyTarget), + proxy('/login/', proxyTarget), + proxy('/static/rest_framework/', proxyTarget), + fake('/static/scores/', (req, res) => { + if (req.url === '/static/scores/collection.json') { + res.send(collectionRatings); + return false; + } + if (req.url === '/static/scores/role.json') { + res.send(roleRatings); + return false; + } + }), + ], }); diff --git a/config/community.prod.webpack.config.js b/config/community.prod.webpack.config.js index 66726de71d..d2a00752a7 100644 --- a/config/community.prod.webpack.config.js +++ b/config/community.prod.webpack.config.js @@ -1,4 +1,4 @@ -const webpackBase = require('./webpack.base.config'); +const { webpackBase } = require('./webpack.base.config'); // Compile configuration for stnadalone mode module.exports = webpackBase({ diff --git a/config/insights.dev.webpack.config.js b/config/insights.dev.webpack.config.js index a29bbbd816..aa5eddd048 100644 --- a/config/insights.dev.webpack.config.js +++ b/config/insights.dev.webpack.config.js @@ -1,7 +1,7 @@ -const webpackBase = require('./webpack.base.config'); +const { webpackBase } = require('./webpack.base.config'); -const proxyHost = process.env.API_PROXY_HOST || 'localhost'; -const proxyPort = process.env.API_PROXY_PORT || '55001'; +// Used for getting the correct host when running in a container +const proxyTarget = process.env.API_PROXY || 'http://localhost:55001'; const cloudBeta = process.env.HUB_CLOUD_BETA; // "true" | "false" | undefined (=default) @@ -13,7 +13,7 @@ module.exports = webpackBase({ API_BASE_PATH: '/api/automation-hub/', // Value for standalone.api.target - API_PROXY_TARGET: `http://${proxyHost}:${proxyPort}`, + API_PROXY: proxyTarget, // Path on the host where the UI is found. EX: /apps/automation-hub UI_BASE_PATH: diff --git a/config/insights.prod.webpack.config.js b/config/insights.prod.webpack.config.js index 9c9b0a321c..64439cae9d 100644 --- a/config/insights.prod.webpack.config.js +++ b/config/insights.prod.webpack.config.js @@ -1,4 +1,4 @@ -const webpackBase = require('./webpack.base.config'); +const { webpackBase } = require('./webpack.base.config'); const cloudBeta = process.env.HUB_CLOUD_BETA; // "true" | "false" | undefined (=default) // Compile configuration for deploying to insights diff --git a/config/standalone.dev.webpack.config.js b/config/standalone.dev.webpack.config.js index 47eb30b833..ee578f7853 100644 --- a/config/standalone.dev.webpack.config.js +++ b/config/standalone.dev.webpack.config.js @@ -1,11 +1,11 @@ -const webpackBase = require('./webpack.base.config'); +const { webpackBase, proxy, fake } = require('./webpack.base.config'); const collectionRatings = require('../static/scores/collection.json'); const roleRatings = require('../static/scores/role.json'); // Used for getting the correct host when running in a container -const proxyHost = process.env.API_PROXY_HOST || 'localhost'; -const proxyPort = process.env.API_PROXY_PORT || '55001'; +const proxyTarget = process.env.API_PROXY || 'http://localhost:55001'; + const apiBasePath = process.env.API_BASE_PATH || '/api/galaxy/'; const uiExternalLoginURI = process.env.UI_EXTERNAL_LOGIN_URI || '/login'; @@ -37,23 +37,21 @@ module.exports = webpackBase({ // Value for webpack.devServer.proxy // https://webpack.js.org/configuration/dev-server/#devserverproxy // used to get around CORS requirements when running in dev mode - WEBPACK_PROXY: { - '/api/': `http://${proxyHost}:${proxyPort}`, - '/pulp/api/': `http://${proxyHost}:${proxyPort}`, - '/v2/': `http://${proxyHost}:${proxyPort}`, - '/extensions/v2/': `http://${proxyHost}:${proxyPort}`, - '/static/rest_framework/': `http://${proxyHost}:${proxyPort}`, - '/static/scores/': { - bypass: function (req, res) { - if (req.url === '/static/scores/collection.json') { - res.send(collectionRatings); - return false; - } - if (req.url === '/static/scores/role.json') { - res.send(roleRatings); - return false; - } - }, - }, - }, + WEBPACK_PROXY: [ + proxy('/api/', proxyTarget), + proxy('/pulp/api/', proxyTarget), + proxy('/v2/', proxyTarget), + proxy('/extensions/v2/', proxyTarget), + proxy('/static/rest_framework/', proxyTarget), + fake('/static/scores/', (req, res) => { + if (req.url === '/static/scores/collection.json') { + res.send(collectionRatings); + return false; + } + if (req.url === '/static/scores/role.json') { + res.send(roleRatings); + return false; + } + }), + ], }); diff --git a/config/standalone.prod.webpack.config.js b/config/standalone.prod.webpack.config.js index d194bde8ab..4e51dcf0ca 100644 --- a/config/standalone.prod.webpack.config.js +++ b/config/standalone.prod.webpack.config.js @@ -1,4 +1,4 @@ -const webpackBase = require('./webpack.base.config'); +const { webpackBase } = require('./webpack.base.config'); // Compile configuration for stnadalone mode module.exports = webpackBase({ diff --git a/config/webpack.base.config.js b/config/webpack.base.config.js index a3777ed6c6..5a6186eaa2 100644 --- a/config/webpack.base.config.js +++ b/config/webpack.base.config.js @@ -39,7 +39,7 @@ const defaultConfigs = [ { name: 'UI_EXTERNAL_LOGIN_URI', default: '/login', scope: 'global' }, // Webpack scope: only available in customConfigs here, not exposed to the UI - { name: 'API_PROXY_TARGET', default: undefined, scope: 'webpack' }, + { name: 'API_PROXY', default: undefined, scope: 'webpack' }, { name: 'UI_DEBUG', default: false, scope: 'webpack' }, { name: 'UI_PORT', default: 8002, scope: 'webpack' }, { name: 'UI_USE_HTTPS', default: false, scope: 'webpack' }, @@ -47,7 +47,28 @@ const defaultConfigs = [ { name: 'WEBPACK_PUBLIC_PATH', default: undefined, scope: 'webpack' }, ]; -module.exports = (inputConfigs) => { +const proxy = (route, target) => { + const u = new URL(target); + return { + context: [route], + target, + secure: false, + router: (req) => { + req.headers.host = u.host; + req.headers.origin = u.origin; + req.headers.referer = u.href; + }, + }; +}; + +const fake = (route, bypass) => ({ + context: [route], + target: { + bypass, + }, +}); + +const webpackBase = (inputConfigs) => { const customConfigs = {}; const globals = {}; @@ -105,7 +126,7 @@ module.exports = (inputConfigs) => { standalone: { api: { context: [customConfigs.API_BASE_PATH], - target: customConfigs.API_PROXY_TARGET, + target: customConfigs.API_PROXY, }, rbac, ...defaultServices, @@ -173,12 +194,7 @@ module.exports = (inputConfigs) => { if (customConfigs.WEBPACK_PROXY) { // array since webpack-dev-server 5 - newWebpackConfig.devServer.proxy = Object.entries( - customConfigs.WEBPACK_PROXY, - ).map(([k, v]) => ({ - context: [k], - target: v, - })); + newWebpackConfig.devServer.proxy = customConfigs.WEBPACK_PROXY; } if (customConfigs.WEBPACK_PUBLIC_PATH) { @@ -235,3 +251,9 @@ module.exports = (inputConfigs) => { plugins, }; }; + +module.exports = { + fake, + proxy, + webpackBase, +}; diff --git a/package.json b/package.json index bd48d4b0c1..66182417aa 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "sort-exports": "perl -i -pe 's/^export/import/' src/**/index.ts ; npm run prettier ; perl -i -pe 's/^import/export/' src/**/index.ts", "start-community": "NODE_ENV=development webpack serve --host 0.0.0.0 --config config/community.dev.webpack.config.js", "start-insights": "NODE_ENV=development webpack serve --host 0.0.0.0 --config config/insights.dev.webpack.config.js", - "start-pulp": "NODE_ENV=development API_PROXY_PORT=8080 webpack serve --host 0.0.0.0 --config config/standalone.dev.webpack.config.js", + "start-pulp": "NODE_ENV=development API_PROXY=http://localhost:8080 webpack serve --host 0.0.0.0 --config config/standalone.dev.webpack.config.js", "start-standalone": "NODE_ENV=development webpack serve --host 0.0.0.0 --config config/standalone.dev.webpack.config.js" }, "insights": {