mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:00: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:
@@ -32,6 +32,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Models status/OAuth health: align OAuth health reporting with the same effective credential view runtime uses, so expired refreshable sessions stop showing healthy by default and fresher imported Codex CLI credentials surface correctly in `models status`, doctor, and gateway auth status. Thanks @vincentkoc.
|
||||
- Twitch/setup: load Twitch through the bundled setup-entry discovery path and keep setup/status account detection aligned with runtime config. (#68008) Thanks @gumadeiras.
|
||||
- Feishu/card actions: resolve card-action chat type from the Feishu chat API when stored context is missing, preferring `chat_mode` over `chat_type`, so DM-originated card actions no longer bypass `dmPolicy` by falling through to the group handling path. (#68201)
|
||||
- Cron/isolated-agent: preserve `trusted: false` on isolated cron awareness events mirrored into the main session, and forward the optional `trusted` flag through the gateway cron wrapper so explicit trust downgrades survive session-key scoping. (#68210)
|
||||
|
||||
## 2026.4.15
|
||||
|
||||
|
||||
@@ -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