openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
137 lines (136 loc) • 6.58 kB
JavaScript
import { n as GATEWAY_CLIENT_IDS, r as GATEWAY_CLIENT_MODES } from "./client-info-CcqJJIan.js";
import "./version-51ymduTn.js";
import { n as withPluginRuntimeGatewayRequestScope } from "./gateway-request-scope-BAEdAUQ6.js";
import "./src-oj0IwW6K.js";
import { a as resolvePluginRoutePathContext, i as isProtectedPluginRoutePathFromContext, n as findRegisteredPluginHttpRoute, r as isRegisteredPluginHttpRoutePath, t as findMatchingPluginHttpRoutes } from "./route-match-DlTv7M6i.js";
import { n as shouldEnforceGatewayAuthForPluginPath, t as matchedPluginRoutesRequireGatewayAuth } from "./route-auth-CuhIaW7_.js";
import { t as resolvePluginRouteRuntimeOperatorScopes } from "./plugin-route-runtime-scopes-DpEVg7d_.js";
//#region src/gateway/server/plugins-http.ts
function resolvePluginRoutePathContextForRequest(req, providedPathContext) {
if (providedPathContext) return providedPathContext;
return resolvePluginRoutePathContext(new URL(req.url ?? "/", "http://localhost").pathname);
}
function createPluginRouteRuntimeClient(scopes) {
return { connect: {
minProtocol: 4,
maxProtocol: 4,
client: {
id: GATEWAY_CLIENT_IDS.GATEWAY_CLIENT,
version: "internal",
platform: "node",
mode: GATEWAY_CLIENT_MODES.BACKEND
},
role: "operator",
scopes: [...scopes]
} };
}
function writeUpgradeUnauthorized(socket) {
socket.write("HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n");
socket.destroy();
}
function getMissingPluginRouteRuntimeContext(route, context) {
if (route.auth !== "gateway") return;
if (route.gatewayRuntimeScopeSurface === "trusted-operator") return context.gatewayRequestAuth ? void 0 : "caller auth context";
return context.gatewayRequestOperatorScopes === void 0 ? "caller scope context" : void 0;
}
function createPluginRouteRuntimeScope(params) {
const runtimeClient = createPluginRouteRuntimeClient(params.route.auth !== "gateway" ? [] : params.route.gatewayRuntimeScopeSurface === "trusted-operator" ? resolvePluginRouteRuntimeOperatorScopes(params.req, params.gatewayRequestAuth, "trusted-operator") : params.gatewayRequestOperatorScopes);
return {
...params.gatewayRequestContext ? { context: params.gatewayRequestContext } : {},
client: runtimeClient,
isWebchatConnect: () => false,
...params.route.pluginId ? { pluginId: params.route.pluginId } : {},
...params.route.source ? { pluginSource: params.route.source } : {},
...params.route.gatewayMethodDispatchAllowed === true ? { gatewayMethodDispatchAllowed: true } : {}
};
}
function createGatewayPluginRequestHandler(params) {
const { log } = params;
return async (req, res, providedPathContext, dispatchContext) => {
const registry = params.getRouteRegistry?.() ?? params.registry;
const gatewayRequestContext = params.getGatewayRequestContext?.();
if ((registry.httpRoutes ?? []).length === 0) return false;
const pathContext = resolvePluginRoutePathContextForRequest(req, providedPathContext);
const matchedRoutes = findMatchingPluginHttpRoutes(registry, pathContext);
if (matchedRoutes.length === 0) return false;
if (matchedPluginRoutesRequireGatewayAuth(matchedRoutes) && dispatchContext?.gatewayAuthSatisfied !== true) {
log.warn(`plugin http route blocked without gateway auth (${pathContext.canonicalPath})`);
return false;
}
const gatewayRequestAuth = dispatchContext?.gatewayRequestAuth;
const gatewayRequestOperatorScopes = dispatchContext?.gatewayRequestOperatorScopes;
for (const route of matchedRoutes) {
const missingRuntimeContext = getMissingPluginRouteRuntimeContext(route, {
gatewayRequestAuth,
gatewayRequestOperatorScopes
});
if (missingRuntimeContext) {
log.warn(`plugin http route blocked without ${missingRuntimeContext} (${pathContext.canonicalPath})`);
return false;
}
}
for (const route of matchedRoutes) try {
if (await withPluginRuntimeGatewayRequestScope(createPluginRouteRuntimeScope({
route,
req,
gatewayRequestContext,
gatewayRequestAuth,
gatewayRequestOperatorScopes
}), async () => route.handler(req, res)) !== false) return true;
} catch (err) {
log.warn(`plugin http route failed (${route.pluginId ?? "unknown"}): ${String(err)}`);
if (!res.headersSent) {
res.statusCode = 500;
res.setHeader("Content-Type", "text/plain; charset=utf-8");
res.end("Internal Server Error");
}
return true;
}
return false;
};
}
function createGatewayPluginUpgradeHandler(params) {
const { log } = params;
return async (req, socket, head, providedPathContext, dispatchContext) => {
const registry = params.getRouteRegistry?.() ?? params.registry;
const gatewayRequestContext = params.getGatewayRequestContext?.();
if ((registry.httpRoutes ?? []).length === 0) return false;
const pathContext = resolvePluginRoutePathContextForRequest(req, providedPathContext);
const matchedRoutes = findMatchingPluginHttpRoutes(registry, pathContext).filter((route) => typeof route.handleUpgrade === "function");
if (matchedRoutes.length === 0) return false;
if (matchedPluginRoutesRequireGatewayAuth(matchedRoutes) && dispatchContext?.gatewayAuthSatisfied !== true) {
log.warn(`plugin http upgrade blocked without gateway auth (${pathContext.canonicalPath})`);
writeUpgradeUnauthorized(socket);
return true;
}
const gatewayRequestAuth = dispatchContext?.gatewayRequestAuth;
const gatewayRequestOperatorScopes = dispatchContext?.gatewayRequestOperatorScopes;
for (const route of matchedRoutes) {
const missingRuntimeContext = getMissingPluginRouteRuntimeContext(route, {
gatewayRequestAuth,
gatewayRequestOperatorScopes
});
if (missingRuntimeContext) {
log.warn(`plugin http upgrade blocked without ${missingRuntimeContext} (${pathContext.canonicalPath})`);
writeUpgradeUnauthorized(socket);
return true;
}
}
for (const route of matchedRoutes) try {
if (await withPluginRuntimeGatewayRequestScope(createPluginRouteRuntimeScope({
route,
req,
gatewayRequestContext,
gatewayRequestAuth,
gatewayRequestOperatorScopes
}), async () => route.handleUpgrade?.(req, socket, head)) !== false) return true;
} catch (err) {
log.warn(`plugin http upgrade failed (${route.pluginId ?? "unknown"}): ${String(err)}`);
socket.destroy();
return true;
}
return false;
};
}
//#endregion
export { createGatewayPluginRequestHandler, createGatewayPluginUpgradeHandler, findRegisteredPluginHttpRoute, isProtectedPluginRoutePathFromContext, isRegisteredPluginHttpRoutePath, resolvePluginRoutePathContext, shouldEnforceGatewayAuthForPluginPath };