diff --git a/.github/workflows/pull-kyma-integration-tests.yml b/.github/workflows/pull-kyma-integration-tests.yml index c363b2913f..ed66465939 100644 --- a/.github/workflows/pull-kyma-integration-tests.yml +++ b/.github/workflows/pull-kyma-integration-tests.yml @@ -61,12 +61,17 @@ jobs: name: cypress-${{ github.job }} path: tests/integration/cypress retention-days: 90 + - name: Fetch busola k3d logs + if: ${{ always() }} + run: | + kubectl logs deployments/busola > busola-deploy.log - name: Upload Kyma Dashboard logs uses: actions/upload-artifact@v4 if: ${{ always() }} with: name: kyma-dashboard-logs-${{ github.job }} path: | + busola-deploy.log kyma-alpha-deploy.log kyma-provision.log busola-build.log diff --git a/backend/common.js b/backend/common.js index b851a7d2f8..7a9026762d 100644 --- a/backend/common.js +++ b/backend/common.js @@ -102,7 +102,7 @@ export const makeHandleRequest = () => { (k8sResponse.headers['Content-Type']?.includes('\\') || k8sResponse.headers['content-encoding']?.includes('\\')) ) - return throwInternalServerError( + return respondWithInternalError( 'Response headers are potentially dangerous', ); @@ -123,16 +123,16 @@ export const makeHandleRequest = () => { }); k8sResponse.pipe(res); }); - k8sRequest.on('error', throwInternalServerError); // no need to sanitize the error here as the http.request() will never throw a vulnerable error - + k8sRequest.on('error', respondWithInternalError); // no need to sanitize the error here as the http.request() will never throw a vulnerable error if (Buffer.isBuffer(req.body)) { - k8sRequest.end(req.body); + console.log('Got buffer requests'); + // If body is buffer it means it's not a json. + respondWithBadContent(res, req.id); } else { - // If there's no body, pipe the request (for streaming) - req.pipe(k8sRequest); + k8sRequest.end(JSON.stringify(req.body)); } - function throwInternalServerError(originalError) { + function respondWithInternalError(originalError) { req.log.warn(originalError); res.contentType('text/plain; charset=utf-8'); res @@ -142,6 +142,13 @@ export const makeHandleRequest = () => { }; }; +function respondWithBadContent(res, id) { + res.contentType('text/plain; charset=utf-8'); + res + .status(415) + .send('Bad request. Invalid content type. Request ID: ' + escape(id)); +} + export const serveStaticApp = (app, requestPath, directoryPath) => { app.use(requestPath, express.static(path.join(__dirname, directoryPath))); app.get(requestPath + '*', (_, res) => diff --git a/backend/index.js b/backend/index.js index 5f6c600e2f..7633e1f44c 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,4 +1,4 @@ -import { makeHandleRequest, serveStaticApp, serveMonaco } from './common'; +import { makeHandleRequest, serveMonaco, serveStaticApp } from './common'; import { handleTracking } from './tracking.js'; import jsyaml from 'js-yaml'; import { proxyHandler, proxyRateLimiter } from './proxy.js'; @@ -34,6 +34,12 @@ try { const app = express(); app.disable('x-powered-by'); +app.use( + express.json({ + type: ['application/json-patch+json', 'application/json'], + limit: '100mb', + }), +); app.use(express.raw({ type: '*/*', limit: '100mb' })); const gzipEnabled = global.config.features?.GZIP?.isEnabled; diff --git a/src/components/KymaCompanion/api/getFollowUpQuestions.ts b/src/components/KymaCompanion/api/getFollowUpQuestions.ts index eb96999f67..423d215bd4 100644 --- a/src/components/KymaCompanion/api/getFollowUpQuestions.ts +++ b/src/components/KymaCompanion/api/getFollowUpQuestions.ts @@ -25,7 +25,7 @@ export default async function getFollowUpQuestions({ const response = await fetch(url, { headers: { accept: 'application/json', - 'content-type': 'application/json', + 'Content-Type': 'application/json', 'X-Cluster-Certificate-Authority-Data': certificateAuthorityData, 'X-Cluster-Url': clusterUrl, 'X-K8s-Authorization': k8sAuthorization,