botbook/node_modules/@azure/static-web-apps-cli/dist/msha/handlers/dab.handler.js
Rodrigo Rodriguez 6ae15fe3e5 Updated.
2024-09-04 13:13:15 -03:00

87 lines
No EOL
3.8 KiB
JavaScript

import chalk from "chalk";
import httpProxy from "http-proxy";
import { registerProcessExit } from "../../core/utils/cli.js";
import { decodeCookie, validateCookie } from "../../core/utils/cookie.js";
import { logger, logRequest } from "../../core/utils/logger.js";
import { SWA_CLI_DATA_API_URI } from "../../core/constants.js";
import { onConnectionLost } from "../middlewares/request.middleware.js";
const proxyApi = httpProxy.createProxyServer({ autoRewrite: true });
registerProcessExit(() => {
logger.silly(`killing SWA CLI`);
proxyApi.close(() => logger.log("Data-Api proxy stopped."));
process.exit(0);
});
/**
* Gets response from the Data Api
* @param req http request url
* @param res http response after redirecting to Data api builder
*/
export function handleDataApiRequest(req, res) {
const target = SWA_CLI_DATA_API_URI();
proxyApi.web(req, res, {
target,
}, onConnectionLost(req, res, target, "↳"));
proxyApi.once("proxyReq", (proxyReq) => {
injectHeaders(proxyReq, target);
injectClientPrincipalCookies(proxyReq);
});
proxyApi.once("proxyRes", (proxyRes) => {
logger.silly(`getting response from remote host`);
logRequest(req, "", proxyRes.statusCode);
});
logRequest(req, target);
}
// exported for testing
export function injectHeaders(req, host) {
const X_MS_ORIGINAL_URL_HEADER = "x-ms-original-url";
const X_MS_REQUEST_ID_HEADER = "x-ms-request-id";
logger.silly(`injecting headers to Data-api request:`);
if (!req.getHeader(X_MS_ORIGINAL_URL_HEADER)) {
req.setHeader(X_MS_ORIGINAL_URL_HEADER, encodeURI(new URL(req.path, host).toString()));
logger.silly(` - x-ms-original-url: ${chalk.yellow(req.getHeader(X_MS_ORIGINAL_URL_HEADER))}`);
}
// generate a fake correlation ID
req.setHeader(X_MS_REQUEST_ID_HEADER, `SWA-CLI-${Math.random().toString(36).substring(2).toUpperCase()}`);
logger.silly(` - x-ms-request-id: ${chalk.yellow(req.getHeader(X_MS_REQUEST_ID_HEADER))}`);
}
/**
* Checks if the request is Data-api request or not
* @param req http request url
* @param rewritePath
* @returns true if the request is data-api Request else false
*/
export function isDataApiRequest(req, rewritePath) {
const path = rewritePath || req.url;
return Boolean(path?.toLowerCase().startsWith(`/data-api/`));
}
// exported for testing
export function injectClientPrincipalCookies(req) {
const X_MS_CLIENT_PRINCIPAL_HEADER = "X-MS-CLIENT-PRINCIPAL";
const AUTH_HEADER = "authorization";
const COOKIE_HEADER = "cookie";
const CLAIMS_HEADER = "claims";
logger.silly(`injecting client principal to Functions request:`);
const cookie = req.getHeader(COOKIE_HEADER);
if (cookie && validateCookie(cookie)) {
const user = decodeCookie(cookie);
// Remove claims from client principal to match SWA behaviour. See https://github.com/MicrosoftDocs/azure-docs/issues/86803.
// The following property deletion can be removed depending on outcome of the above issue.
if (user) {
delete user[CLAIMS_HEADER];
}
const buff = Buffer.from(JSON.stringify(user), "utf-8");
const token = buff.toString("base64");
req.setHeader(X_MS_CLIENT_PRINCIPAL_HEADER, token);
logger.silly(` - X-MS-CLIENT-PRINCIPAL: ${chalk.yellow(req.getHeader(X_MS_CLIENT_PRINCIPAL_HEADER))}`);
// locally, we set the JWT bearer token to be the same as the cookie value because we are not using the real auth flow.
// Note: on production, SWA uses a valid encrypted JWT token!
if (!req.getHeader(AUTH_HEADER)) {
req.setHeader(AUTH_HEADER, `Bearer ${token}`);
logger.silly(` - Authorization: ${chalk.yellow(req.getHeader(AUTH_HEADER))}`);
}
}
else {
logger.silly(` - no valid cookie found`);
}
}
//# sourceMappingURL=dab.handler.js.map