diff --git a/awx/ui/config/webpackDevServer.config.js b/awx/ui/config/webpackDevServer.config.js index 1350af23..63bfea94 100644 --- a/awx/ui/config/webpackDevServer.config.js +++ b/awx/ui/config/webpackDevServer.config.js @@ -13,7 +13,8 @@ const sockHost = process.env.WDS_SOCKET_HOST; const sockPath = process.env.WDS_SOCKET_PATH; // default: '/ws' const sockPort = process.env.WDS_SOCKET_PORT; -module.exports = function (proxy, allowedHost) { +module.exports = function (proxy, allowedHost, proxyOptions = {}) { + const { createProxyMiddleware } = proxyOptions; const disableFirewall = !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true'; return { @@ -111,7 +112,7 @@ module.exports = function (proxy, allowedHost) { if (fs.existsSync(paths.proxySetup)) { // This registers user provided middleware for proxy reasons - require(paths.proxySetup)(devServer.app); + require(paths.proxySetup)(devServer.app, createProxyMiddleware); } // Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match diff --git a/awx/ui/package-lock.json b/awx/ui/package-lock.json index c1be7973..d91c2afe 100644 --- a/awx/ui/package-lock.json +++ b/awx/ui/package-lock.json @@ -82,7 +82,7 @@ "file-loader": "^6.2.0", "fs-extra": "^11.3.5", "html-webpack-plugin": "^5.6.7", - "http-proxy-middleware": "3.0.5", + "http-proxy-middleware": "4.0.0", "inject-manifest-plugin": "^0.6.5", "jest": "^30.3.0", "jest-environment-jsdom": "^30.3.0", @@ -114,7 +114,7 @@ "webpack-manifest-plugin": "^6.0.1" }, "engines": { - "node": ">=20.19.0" + "node": ">=22.19.0" } }, "node_modules/@adobe/css-tools": { @@ -10511,9 +10511,9 @@ } }, "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -13855,21 +13855,33 @@ } }, "node_modules/http-proxy-middleware": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz", - "integrity": "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-4.0.0.tgz", + "integrity": "sha512-wuHwaUtmC0XzJNHqRp41zXtt5ojpHbusXGhq6781VvnjWUYPu7opmOF3eomGNujT07kEOnHWZyV9UZzKimVCKA==", "dev": true, "license": "MIT", "dependencies": { - "@types/http-proxy": "^1.17.15", - "debug": "^4.3.6", - "http-proxy": "^1.18.1", + "debug": "^4.4.3", + "httpxy": "^0.5.1", "is-glob": "^4.0.3", - "is-plain-object": "^5.0.0", + "is-plain-obj": "^4.1.0", "micromatch": "^4.0.8" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^22.15.0 || ^24.0.0 || >=26.0.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/https-proxy-agent": { @@ -13886,6 +13898,13 @@ "node": ">= 14" } }, + "node_modules/httpxy": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/httpxy/-/httpxy-0.5.3.tgz", + "integrity": "sha512-SMS9V6Sn7VWaS11lYhoAr0ceoaiolTWf4jYdJn0NJhCdKMu9R2H9Fh0LBDWBHQF6HRLI1PmaePYsjanSpE5PEw==", + "dev": true, + "license": "MIT" + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -14574,16 +14593,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", diff --git a/awx/ui/package.json b/awx/ui/package.json index 778f1661..205f82d0 100644 --- a/awx/ui/package.json +++ b/awx/ui/package.json @@ -3,7 +3,7 @@ "homepage": ".", "private": true, "engines": { - "node": ">=20.19.0" + "node": ">=22.19.0" }, "dependencies": { "@lingui/react": "^5.4.0", @@ -82,7 +82,7 @@ "file-loader": "^6.2.0", "fs-extra": "^11.3.5", "html-webpack-plugin": "^5.6.7", - "http-proxy-middleware": "3.0.5", + "http-proxy-middleware": "4.0.0", "inject-manifest-plugin": "^0.6.5", "jest": "^30.3.0", "jest-environment-jsdom": "^30.3.0", diff --git a/awx/ui/scripts/start.js b/awx/ui/scripts/start.js index 891125d6..0c64dbb5 100644 --- a/awx/ui/scripts/start.js +++ b/awx/ui/scripts/start.js @@ -68,12 +68,12 @@ if (process.env.HOST) { // browserslist defaults. const { checkBrowsers } = require('react-dev-utils/browsersHelper'); checkBrowsers(paths.appPath, isInteractive) - .then(() => { + .then(async () => { // We attempt to use the default port but if it is busy, we offer the user to // run on a different port. `choosePort()` Promise resolves to the next free port. return choosePort(HOST, DEFAULT_PORT); }) - .then(port => { + .then(async port => { if (port == null) { // We have not found a port. return; @@ -106,9 +106,12 @@ checkBrowsers(paths.appPath, isInteractive) paths.appPublic, paths.publicUrlOrPath ); + const { createProxyMiddleware } = await import('http-proxy-middleware'); // Serve webpack assets generated by the compiler over a web server. const serverConfig = { - ...createDevServerConfig(proxyConfig, urls.lanUrlForConfig), + ...createDevServerConfig(proxyConfig, urls.lanUrlForConfig, { + createProxyMiddleware, + }), host: HOST, port, }; diff --git a/awx/ui/src/setupProxy.js b/awx/ui/src/setupProxy.js index d017eccd..81fe187f 100644 --- a/awx/ui/src/setupProxy.js +++ b/awx/ui/src/setupProxy.js @@ -1,10 +1,13 @@ -const { legacyCreateProxyMiddleware } = require('http-proxy-middleware'); - const TARGET = process.env.TARGET || 'https://localhost:8043'; -module.exports = (app) => { +module.exports = (app, createProxyMiddleware) => { + if (typeof createProxyMiddleware !== 'function') { + throw new Error('createProxyMiddleware must be provided to setupProxy'); + } + app.use( - legacyCreateProxyMiddleware(['/api', '/websocket', '/sso'], { + createProxyMiddleware({ + pathFilter: ['/api', '/websocket', '/sso'], target: TARGET, secure: false, ws: true, diff --git a/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 b/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 index 53cc4807..03623a08 100644 --- a/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 +++ b/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 @@ -27,7 +27,7 @@ USER root RUN dnf -y update && dnf install -y 'dnf-command(config-manager)' && \ dnf config-manager --set-enabled crb && \ dnf module reset nodejs -y && \ - dnf module enable nodejs:20 -y && \ + dnf module enable nodejs:22 -y && \ dnf -y install \ iputils \ gcc \ @@ -40,6 +40,7 @@ RUN dnf -y update && dnf install -y 'dnf-command(config-manager)' && \ make \ {% if not headless|bool %} nodejs \ + npm \ {% endif %} nss \ openldap-devel \ @@ -149,7 +150,7 @@ RUN pip3.12 install --no-cache-dir -vv virtualenv supervisor dumb-init build && {% if (build_dev|bool) or (kube_dev|bool) %} # Install development/test requirements RUN dnf module reset nodejs -y && \ - dnf module enable nodejs:20 -y && \ + dnf module enable nodejs:22 -y && \ dnf -y install \ crun \ gdb \ @@ -167,6 +168,7 @@ RUN dnf module reset nodejs -y && \ libpq-devel \ nodejs \ nss \ + npm \ make \ patch \ socat \