diff --git a/backend/web-bff/App/package-lock.json b/backend/web-bff/App/package-lock.json index 210260a2..db535811 100644 --- a/backend/web-bff/App/package-lock.json +++ b/backend/web-bff/App/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@azure/msal-node": "^2.6.4", "axios": "^1.6.8", + "busboy": "^1.6.0", "connect-mongo": "^5.1.0", "cookie-parser": "^1.4.6", "cookie-session": "^2.1.0", @@ -20,6 +21,7 @@ "express": "^4.19.1", "express-rate-limit": "^7.2.0", "express-session": "^1.18.0", + "form-data": "^4.0.0", "hbs": "^4.2.0", "helmet": "^7.1.0", "hpp": "^0.2.3", @@ -248,6 +250,17 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -1774,6 +1787,14 @@ "node": ">= 0.8" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/backend/web-bff/App/package.json b/backend/web-bff/App/package.json index 2808e361..0d047121 100644 --- a/backend/web-bff/App/package.json +++ b/backend/web-bff/App/package.json @@ -8,6 +8,7 @@ "dependencies": { "@azure/msal-node": "^2.6.4", "axios": "^1.6.8", + "busboy": "^1.6.0", "connect-mongo": "^5.1.0", "cookie-parser": "^1.4.6", "cookie-session": "^2.1.0", @@ -18,6 +19,7 @@ "express": "^4.19.1", "express-rate-limit": "^7.2.0", "express-session": "^1.18.0", + "form-data": "^4.0.0", "hbs": "^4.2.0", "helmet": "^7.1.0", "hpp": "^0.2.3", diff --git a/backend/web-bff/App/routes/api.js b/backend/web-bff/App/routes/api.js index b15647ae..63063889 100644 --- a/backend/web-bff/App/routes/api.js +++ b/backend/web-bff/App/routes/api.js @@ -5,8 +5,9 @@ const router = express.Router(); const fetch = require('../fetch'); -const { BACKEND_API_ENDPOINT, msalConfig, REDIRECT_URI} = require('../authConfig'); +const {BACKEND_API_ENDPOINT, msalConfig, REDIRECT_URI} = require('../authConfig'); const isAuthenticated = require('../util/isAuthenticated'); +const handleMultipart = require('../util/handleMultipart'); /** * Route that captures every method and route starting with /web/api. @@ -18,17 +19,22 @@ const isAuthenticated = require('../util/isAuthenticated'); router.all('/*', isAuthenticated("/web/auth/signin"), authProvider.acquireToken({ - scopes: [msalConfig.auth.clientId + "/.default"], - redirectUri: REDIRECT_URI + scopes: [msalConfig.auth.clientId + "/.default"], + redirectUri: REDIRECT_URI }), - async function(req, res, next) { - - try { - const response = await fetch( "api" + req.url , req.session.accessToken, req.method, req.body, req.headers) - res.status(response.code).send(response.data) - } catch(error) { - next(error); + async function (req, res, next) { + const contentType = req.headers['content-type']; + if (contentType && contentType.includes('multipart/form-data')) { + handleMultipart(req, res, next); + } else { + try { + const response = await fetch("api" + req.url, req.session.accessToken, req.method, req.body, req.headers) + res.status(response.code).send(response.data) + } catch (error) { + next(error); + } + } } - }) +) module.exports = router; \ No newline at end of file diff --git a/backend/web-bff/App/util/handleMultipart.js b/backend/web-bff/App/util/handleMultipart.js new file mode 100644 index 00000000..783cd402 --- /dev/null +++ b/backend/web-bff/App/util/handleMultipart.js @@ -0,0 +1,34 @@ +const busboy = require('busboy'); +const FormData = require('form-data'); +const fetch = require('../fetch'); + +function handleMultipart(req, res, next) { + console.log("multipart") + + const bb = busboy({headers: req.headers}); + const form = new FormData(); + + bb.on('file', (name, file, info) => { + const {filename, encoding, mimetype} = info; + file.on('data', (data) => { + form.append(name, data, {filename, contentType: mimetype}); + }); + }); + + bb.on('field', (fieldname, val) => { + form.append(fieldname, val); + }); + + bb.on('close', async () => { + try { + const response = await fetch("api" + req.url, req.session.accessToken, req.method, form, form.getHeaders()) + res.status(response.code).send(response.data); + } catch (error) { + next(error); + } + }); + + req.pipe(bb); +} + +module.exports = handleMultipart; \ No newline at end of file