mirror of https://github.com/openclaw/openclaw.git
61 lines
1.7 KiB
TypeScript
61 lines
1.7 KiB
TypeScript
import {
|
|
PROTECTED_PLUGIN_ROUTE_PREFIXES,
|
|
canonicalizePathForSecurity,
|
|
} from "../../security-path.js";
|
|
|
|
export type PluginRoutePathContext = {
|
|
pathname: string;
|
|
canonicalPath: string;
|
|
candidates: string[];
|
|
malformedEncoding: boolean;
|
|
decodePassLimitReached: boolean;
|
|
rawNormalizedPath: string;
|
|
};
|
|
|
|
function normalizeProtectedPrefix(prefix: string): string {
|
|
const collapsed = prefix.toLowerCase().replace(/\/{2,}/g, "/");
|
|
if (collapsed.length <= 1) {
|
|
return collapsed || "/";
|
|
}
|
|
return collapsed.replace(/\/+$/, "");
|
|
}
|
|
|
|
export function prefixMatchPath(pathname: string, prefix: string): boolean {
|
|
return (
|
|
pathname === prefix || pathname.startsWith(`${prefix}/`) || pathname.startsWith(`${prefix}%`)
|
|
);
|
|
}
|
|
|
|
const NORMALIZED_PROTECTED_PLUGIN_ROUTE_PREFIXES =
|
|
PROTECTED_PLUGIN_ROUTE_PREFIXES.map(normalizeProtectedPrefix);
|
|
|
|
export function isProtectedPluginRoutePathFromContext(context: PluginRoutePathContext): boolean {
|
|
if (
|
|
context.candidates.some((candidate) =>
|
|
NORMALIZED_PROTECTED_PLUGIN_ROUTE_PREFIXES.some((prefix) =>
|
|
prefixMatchPath(candidate, prefix),
|
|
),
|
|
)
|
|
) {
|
|
return true;
|
|
}
|
|
if (!context.malformedEncoding) {
|
|
return false;
|
|
}
|
|
return NORMALIZED_PROTECTED_PLUGIN_ROUTE_PREFIXES.some((prefix) =>
|
|
prefixMatchPath(context.rawNormalizedPath, prefix),
|
|
);
|
|
}
|
|
|
|
export function resolvePluginRoutePathContext(pathname: string): PluginRoutePathContext {
|
|
const canonical = canonicalizePathForSecurity(pathname);
|
|
return {
|
|
pathname,
|
|
canonicalPath: canonical.canonicalPath,
|
|
candidates: canonical.candidates,
|
|
malformedEncoding: canonical.malformedEncoding,
|
|
decodePassLimitReached: canonical.decodePassLimitReached,
|
|
rawNormalizedPath: canonical.rawNormalizedPath,
|
|
};
|
|
}
|