mirror of
https://github.com/openclaw/clawhub.git
synced 2026-08-14 00:47:57 +00:00
fix: resolve production skills sync environment (#3333)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { getVercelOidcToken } from "@vercel/oidc";
|
||||
import { defineEventHandler, getHeader, readBody } from "h3";
|
||||
import { resolveConvexProxyEnv } from "../../../convexProxy";
|
||||
import {
|
||||
buildSkillsShMirrorProofSnapshotId,
|
||||
fetchSkillsShMirrorBatch,
|
||||
@@ -191,7 +192,7 @@ export function createSkillsShMirrorRoute(target: keyof typeof ROUTE_CONFIG) {
|
||||
return defineEventHandler(async (event) => {
|
||||
const policy =
|
||||
target === "production"
|
||||
? getSkillsShCatalogProductionSourcePolicy(process.env)
|
||||
? getSkillsShCatalogProductionSourcePolicy(resolveConvexProxyEnv(process.env))
|
||||
: getSkillsShCatalogTestSourcePolicy(process.env);
|
||||
if (!policy.allowed) return jsonResponse({ error: "not_found" }, 404);
|
||||
const authorization = getHeader(event, "authorization")?.trim() ?? "";
|
||||
|
||||
@@ -9,6 +9,7 @@ const buildProofSnapshotIdMock = vi.fn();
|
||||
const measureProofSourceMock = vi.fn();
|
||||
const parseProofSnapshotIdMock = vi.fn();
|
||||
const productionPolicyMock = vi.fn();
|
||||
const resolveConvexProxyEnvMock = vi.fn();
|
||||
|
||||
vi.mock("h3", () => ({
|
||||
defineEventHandler: (handler: unknown) => handler,
|
||||
@@ -20,6 +21,10 @@ vi.mock("@vercel/oidc", () => ({
|
||||
getVercelOidcToken: (...args: unknown[]) => getVercelOidcTokenMock(...args),
|
||||
}));
|
||||
|
||||
vi.mock("./convexProxy", () => ({
|
||||
resolveConvexProxyEnv: (...args: unknown[]) => resolveConvexProxyEnvMock(...args),
|
||||
}));
|
||||
|
||||
vi.mock("./skillsShCatalogSource", () => ({
|
||||
buildSkillsShMirrorProofSnapshotId: (...args: unknown[]) => buildProofSnapshotIdMock(...args),
|
||||
fetchSkillsShMirrorBatch: vi.fn(),
|
||||
@@ -47,6 +52,8 @@ describe("skills.sh production mirror route", () => {
|
||||
measureProofSourceMock.mockReset();
|
||||
parseProofSnapshotIdMock.mockReset();
|
||||
productionPolicyMock.mockReset();
|
||||
resolveConvexProxyEnvMock.mockReset();
|
||||
resolveConvexProxyEnvMock.mockImplementation((env) => env);
|
||||
productionPolicyMock.mockReturnValue({ allowed: true, environment: "production" });
|
||||
getHeaderMock.mockReturnValue("Bearer github-actions-oidc");
|
||||
getVercelOidcTokenMock.mockResolvedValue("vercel-production-oidc");
|
||||
@@ -81,6 +88,27 @@ describe("skills.sh production mirror route", () => {
|
||||
expect(convexFetch).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("validates production source policy against bundled frontend identity", async () => {
|
||||
const resolvedEnv = {
|
||||
VERCEL_ENV: "production",
|
||||
VITE_CLAWHUB_DEPLOY_ENV: "production",
|
||||
VITE_CONVEX_URL: "https://wry-manatee-359.convex.cloud",
|
||||
};
|
||||
resolveConvexProxyEnvMock.mockReturnValue(resolvedEnv);
|
||||
readBodyMock.mockResolvedValue({ operation: "status" });
|
||||
vi.stubGlobal(
|
||||
"fetch",
|
||||
vi.fn(async () => new Response(JSON.stringify({ control: null, runs: [] }))),
|
||||
);
|
||||
|
||||
const handler = (await import("./routes/ops/skills-sh/mirror.post")).default;
|
||||
const response = (await handler({} as never)) as Response;
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(resolveConvexProxyEnvMock).toHaveBeenCalledWith(process.env);
|
||||
expect(productionPolicyMock).toHaveBeenCalledWith(resolvedEnv);
|
||||
});
|
||||
|
||||
it("fails closed before the operator call when the production source policy is not exact", async () => {
|
||||
productionPolicyMock.mockReturnValue({
|
||||
allowed: false,
|
||||
|
||||
Reference in New Issue
Block a user