118 lines
No EOL
6.3 KiB
JavaScript
118 lines
No EOL
6.3 KiB
JavaScript
import chalk from "chalk";
|
|
import { logger } from "../../core/utils/logger.js";
|
|
import { globToRegExp, isValidGlobExpression } from "../../core/utils/glob.js";
|
|
import { AUTH_STATUS, CUSTOM_URL_SCHEME, SWA_CLI_APP_PROTOCOL } from "../../core/constants.js";
|
|
import { getIndexHtml } from "./rules/routes.js";
|
|
export function doesRequestPathMatchRoute(requestPath, routeRule, requestMethod, methods, authStatus) {
|
|
logger.silly(`check if request match route`);
|
|
const route = routeRule?.route;
|
|
const hasRouteRuleHasWildcard = route?.includes("*");
|
|
logger.silly(` - route: ${chalk.yellow(route)}`);
|
|
logger.silly(` - wildcard: ${chalk.yellow(hasRouteRuleHasWildcard)}`);
|
|
// Do not match auth requests besides /.auth/login/<idp>
|
|
// /.auth/login/<idp> must match a non wildcard rule
|
|
// no allowed role can be listed for a rule with route /.auth/login/<idp>
|
|
if ((authStatus != AUTH_STATUS.NoAuth && authStatus != AUTH_STATUS.HostNameAuthLogin) ||
|
|
(authStatus == AUTH_STATUS.HostNameAuthLogin && (hasRouteRuleHasWildcard || routeRule?.allowedRoles?.length))) {
|
|
logger.silly(` - authStatus: ${chalk.yellow(authStatus)}`);
|
|
logger.silly(` - allowedRoles: ${chalk.yellow(routeRule?.allowedRoles)}`);
|
|
logger.silly(` - match: ${chalk.yellow(false)}`);
|
|
return false;
|
|
}
|
|
// request method must match allowed methods if listed
|
|
if (methods != null && !methods.includes(requestMethod)) {
|
|
logger.silly(` - methods: ${chalk.yellow(methods)}`);
|
|
logger.silly(` - requestMethod: ${chalk.yellow(requestMethod)}`);
|
|
logger.silly(` - match: ${chalk.yellow(false)}`);
|
|
return false;
|
|
}
|
|
if (route === requestPath || (hasRouteRuleHasWildcard && doesRequestPathMatchWildcardRoute(requestPath, route))) {
|
|
logger.silly(` - doesRequestPathMatchWildcardRoute: ${chalk.yellow(true)}`);
|
|
return true;
|
|
}
|
|
// Since this is a file request, return now, since we are trying to get a match by appending /index.html doesn't apply here
|
|
if (!route) {
|
|
logger.silly(` - route: ${chalk.yellow(route || "<empty>")}`);
|
|
logger.silly(` - match: ${chalk.yellow(false)}`);
|
|
return false;
|
|
}
|
|
// If the request hasn't already matched the route, and the request is a non-file path,
|
|
// try adding /index.html to the path to see if it then matches. This is especially handy
|
|
// to match a request to the /{customPath}/* route
|
|
const alternateRequestPath = getIndexHtml(requestPath);
|
|
logger.silly(` - alternateRequestPath: ${chalk.yellow(alternateRequestPath)}`);
|
|
return (routeRule?.route === alternateRequestPath ||
|
|
(hasRouteRuleHasWildcard && doesRequestPathMatchWildcardRoute(alternateRequestPath, routeRule?.route)));
|
|
}
|
|
export function doesRequestPathMatchLegacyRoute(requestPath, routeRule, isAuthRequest, isFileRequest) {
|
|
const hasWildcard = routeRule?.route.includes("*");
|
|
if (routeRule?.route === requestPath || (!isAuthRequest && hasWildcard)) {
|
|
return true;
|
|
}
|
|
// since this is a file request, don't perform the wildcard matching check
|
|
if (isFileRequest) {
|
|
return false;
|
|
}
|
|
// if the request hasn't already matched the route, and the request is a non-file path,
|
|
// try adding /index.html to the path to see if it then matches. This is especially handy
|
|
// to match a request to the /{customPath}/* route
|
|
const alternateRequestPath = getIndexHtml(requestPath);
|
|
return routeRule?.route === alternateRequestPath || (!isAuthRequest && hasWildcard);
|
|
}
|
|
function doesRequestPathMatchWildcardRoute(requestPath, requestPathFileWithWildcard) {
|
|
logger.silly(`checking wildcard route`);
|
|
logger.silly(` - glob: ${chalk.yellow(requestPathFileWithWildcard)}`);
|
|
const pathBeforeWildcard = requestPathFileWithWildcard?.substr(0, requestPathFileWithWildcard?.indexOf("*"));
|
|
logger.silly(` - pathBeforeWildcard: ${chalk.yellow(pathBeforeWildcard || "<empty>")}`);
|
|
// before processing regexp which might be expensive
|
|
// let's check first if both path and rule start with the same substring
|
|
if (pathBeforeWildcard && requestPath.startsWith(pathBeforeWildcard) === false) {
|
|
logger.silly(` - base path doesn't match. Exit`);
|
|
return false;
|
|
}
|
|
// also, let's check if the route rule doesn't contains a wildcard in the middle of the path
|
|
if (isValidGlobExpression(requestPathFileWithWildcard) === false) {
|
|
logger.silly(` - route rule contains a wildcard in the middle of the path. Exit`);
|
|
return false;
|
|
}
|
|
try {
|
|
logger.silly(` - route regexp: ${chalk.yellow(requestPathFileWithWildcard)}`);
|
|
// we don't support full globs in the config file.
|
|
// add this little utility to convert a wildcard into a valid glob pattern
|
|
const regexp = new RegExp(`^${globToRegExp(requestPathFileWithWildcard)}$`);
|
|
logger.silly(` - regexp: ${chalk.yellow(regexp)}`);
|
|
const isMatch = regexp.test(requestPath);
|
|
logger.silly(` - isMatch: ${chalk.yellow(isMatch)}`);
|
|
return isMatch;
|
|
}
|
|
catch (error) {
|
|
logger.silly(` - ERROR: IGNORING REGEXP!!!`);
|
|
logger.silly(` - read: ${chalk.yellow("https://learn.microsoft.com/en-us/azure/static-web-apps/configuration#wildcards")}`);
|
|
logger.silly(` - error: ${chalk.yellow(error)}`);
|
|
return false;
|
|
}
|
|
}
|
|
export function isCustomUrl(req) {
|
|
return !!req.url?.startsWith(CUSTOM_URL_SCHEME);
|
|
}
|
|
export function parseQueryParams(req, matchingRouteRule) {
|
|
const urlPathnameWithQueryParams = matchingRouteRule?.rewrite || req.url;
|
|
const url = new URL(urlPathnameWithQueryParams, `${SWA_CLI_APP_PROTOCOL}://${req?.headers?.host}`);
|
|
const urlQueryString = url.searchParams.toString();
|
|
const urlPathnameWithoutQueryParams = url.pathname;
|
|
if (urlQueryString !== "") {
|
|
logger.silly(` - url: ${chalk.yellow(url)}`);
|
|
logger.silly(` - urlQueryString: ${chalk.yellow(urlQueryString)}`);
|
|
url.searchParams.forEach((value, key) => {
|
|
logger.silly(` - ${key}: ${chalk.yellow(value || "<undefined>")}`);
|
|
});
|
|
logger.silly(` - urlPathnameWithQueryParams: ${chalk.yellow(urlPathnameWithQueryParams)}`);
|
|
logger.silly(` - urlPathnameWithoutQueryParams: ${chalk.yellow(urlPathnameWithoutQueryParams)}`);
|
|
}
|
|
return {
|
|
url,
|
|
urlPathnameWithoutQueryParams,
|
|
urlPathnameWithQueryParams,
|
|
};
|
|
}
|
|
//# sourceMappingURL=route-processor.js.map
|