feat(security): integrate secret detection into message dispatch
This commit is contained in:
parent
83bca1871b
commit
64be499d96
@ -11,6 +11,13 @@ import {
|
|||||||
type ReplyDispatcherOptions,
|
type ReplyDispatcherOptions,
|
||||||
type ReplyDispatcherWithTypingOptions,
|
type ReplyDispatcherWithTypingOptions,
|
||||||
} from "./reply/reply-dispatcher.js";
|
} from "./reply/reply-dispatcher.js";
|
||||||
|
import { processSecretsInMessage } from "../security/process-secrets.js";
|
||||||
|
import {
|
||||||
|
generatePromptKey,
|
||||||
|
hasPendingPrompt,
|
||||||
|
resolvePendingPrompt,
|
||||||
|
parsePromptResponse,
|
||||||
|
} from "../security/interactive-prompts.js";
|
||||||
|
|
||||||
export type DispatchInboundResult = DispatchFromConfigResult;
|
export type DispatchInboundResult = DispatchFromConfigResult;
|
||||||
|
|
||||||
@ -22,8 +29,52 @@ export async function dispatchInboundMessage(params: {
|
|||||||
replyResolver?: typeof import("./reply.js").getReplyFromConfig;
|
replyResolver?: typeof import("./reply.js").getReplyFromConfig;
|
||||||
}): Promise<DispatchInboundResult> {
|
}): Promise<DispatchInboundResult> {
|
||||||
const finalized = finalizeInboundContext(params.ctx);
|
const finalized = finalizeInboundContext(params.ctx);
|
||||||
|
|
||||||
|
// Check if this user has a pending security prompt
|
||||||
|
const channel = finalized.Provider || finalized.Surface || 'unknown';
|
||||||
|
const senderId = finalized.SenderId || 'unknown';
|
||||||
|
const promptKey = generatePromptKey(channel, senderId);
|
||||||
|
|
||||||
|
if (hasPendingPrompt(promptKey)) {
|
||||||
|
// This message is a response to a security prompt
|
||||||
|
const body = finalized.Body || '';
|
||||||
|
const parsedAction = parsePromptResponse(body);
|
||||||
|
|
||||||
|
if (parsedAction) {
|
||||||
|
// Valid response - resolve the pending prompt
|
||||||
|
resolvePendingPrompt(promptKey, parsedAction);
|
||||||
|
// Send confirmation
|
||||||
|
await params.dispatcher.sendText(`✓ Applying action: ${parsedAction}`);
|
||||||
|
} else {
|
||||||
|
// Invalid response - send help message and keep the prompt pending
|
||||||
|
await params.dispatcher.sendText(
|
||||||
|
`❌ Invalid response. Please reply with **1**, **2**, **3**, or **4**.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't process this message further
|
||||||
|
return {
|
||||||
|
handled: true,
|
||||||
|
replies: [],
|
||||||
|
errors: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process secrets before dispatching to agent
|
||||||
|
const secretProcessing = await processSecretsInMessage(finalized, params.cfg, params.dispatcher);
|
||||||
|
|
||||||
|
// If the message was blocked by the user (cancelled), don't proceed
|
||||||
|
if (secretProcessing.blocked) {
|
||||||
|
return {
|
||||||
|
handled: true,
|
||||||
|
replies: [],
|
||||||
|
errors: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the updated context (with redacted/replaced secrets if applicable)
|
||||||
return await dispatchReplyFromConfig({
|
return await dispatchReplyFromConfig({
|
||||||
ctx: finalized,
|
ctx: secretProcessing.ctx,
|
||||||
cfg: params.cfg,
|
cfg: params.cfg,
|
||||||
dispatcher: params.dispatcher,
|
dispatcher: params.dispatcher,
|
||||||
replyOptions: params.replyOptions,
|
replyOptions: params.replyOptions,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user