mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 13:10:43 +00:00
fix(cron): preserve untrusted awareness event labels (#68210)
* fix(cron): preserve untrusted awareness event labels Keep isolated cron awareness summaries untrusted when they are promoted into the main session, and forward explicit trust downgrades through the gateway cron wrapper. Add focused regression coverage for both paths. * changelog: note cron awareness untrusted-label preservation (#68210)
This commit is contained in:
@@ -324,6 +324,7 @@ describe("dispatchCronDelivery — double-announce guard", () => {
|
||||
expect(enqueueSystemEvent).toHaveBeenCalledWith("Morning briefing complete.", {
|
||||
sessionKey: "agent:main:main",
|
||||
contextKey: "cron-direct-delivery:v1:run-123:telegram::123456:",
|
||||
trusted: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -351,6 +351,7 @@ async function queueCronAwarenessSystemEvent(params: {
|
||||
agentId: params.agentId,
|
||||
}),
|
||||
contextKey: params.deliveryIdempotencyKey,
|
||||
trusted: false,
|
||||
});
|
||||
} catch (err) {
|
||||
await logCronDeliveryWarn(
|
||||
|
||||
@@ -62,7 +62,7 @@ export type CronServiceDeps = {
|
||||
maxMissedJobsPerRestart?: number;
|
||||
enqueueSystemEvent: (
|
||||
text: string,
|
||||
opts?: { agentId?: string; sessionKey?: string; contextKey?: string },
|
||||
opts?: { agentId?: string; sessionKey?: string; contextKey?: string; trusted?: boolean },
|
||||
) => void;
|
||||
requestHeartbeatNow: (opts?: { reason?: string; agentId?: string; sessionKey?: string }) => void;
|
||||
runHeartbeatOnce?: (opts?: {
|
||||
|
||||
@@ -140,6 +140,47 @@ describe("buildGatewayCronService", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("preserves trust downgrades when cron enqueues system events", () => {
|
||||
const cfg = createCronConfig("server-cron-untrusted");
|
||||
loadConfigMock.mockReturnValue(cfg);
|
||||
|
||||
const state = buildGatewayCronService({
|
||||
cfg,
|
||||
deps: {} as CliDeps,
|
||||
broadcast: () => {},
|
||||
});
|
||||
try {
|
||||
const cronDeps = (
|
||||
state.cron as unknown as {
|
||||
state?: {
|
||||
deps?: {
|
||||
enqueueSystemEvent?: (optsText: string, opts?: {
|
||||
agentId?: string;
|
||||
sessionKey?: string;
|
||||
contextKey?: string;
|
||||
trusted?: boolean;
|
||||
}) => void;
|
||||
};
|
||||
};
|
||||
}
|
||||
).state?.deps;
|
||||
|
||||
cronDeps?.enqueueSystemEvent?.("hello", {
|
||||
sessionKey: "discord:channel:ops",
|
||||
contextKey: "cron:test",
|
||||
trusted: false,
|
||||
});
|
||||
|
||||
expect(enqueueSystemEventMock).toHaveBeenCalledWith("hello", {
|
||||
sessionKey: "agent:main:discord:channel:ops",
|
||||
contextKey: "cron:test",
|
||||
trusted: false,
|
||||
});
|
||||
} finally {
|
||||
state.cron.stop();
|
||||
}
|
||||
});
|
||||
|
||||
it("blocks private webhook URLs via SSRF-guarded fetch", async () => {
|
||||
const cfg = createCronConfig("server-cron-ssrf");
|
||||
loadConfigMock.mockReturnValue(cfg);
|
||||
|
||||
@@ -285,7 +285,11 @@ export function buildGatewayCronService(params: {
|
||||
agentId,
|
||||
requestedSessionKey: opts?.sessionKey,
|
||||
});
|
||||
enqueueSystemEvent(text, { sessionKey, contextKey: opts?.contextKey });
|
||||
enqueueSystemEvent(text, {
|
||||
sessionKey,
|
||||
contextKey: opts?.contextKey,
|
||||
trusted: opts?.trusted,
|
||||
});
|
||||
},
|
||||
requestHeartbeatNow: (opts) => {
|
||||
const { agentId, sessionKey } = resolveCronWakeTarget(opts);
|
||||
|
||||
Reference in New Issue
Block a user