Conversation
None of CommentAutomation's 8 write methods (Messenger, Instagram, Threads, TikTok create/update) validated that privateReply.value or publicReply.value pointed at a real flow when their reply type is "flow" — AutomatedResponse (Keywords) already does this via flowService.exists before saving. A stale or mistyped flowId saves silently and the automation looks active in the UI, but every trigger fails at delivery time with a bare "FlowVersion not found" (worker's detectFlowVersion, apps/worker/src/lib/db.ts) — never surfaced back to the user who configured it. detectFlowVersion scopes its lookup to the triggering conversation's own workspaceId in all cases, so a foreign flowId can never execute cross-tenant — this is a validation gap, not a tenant-isolation defect. Adds assertFlowReplyExists, mirroring the check Keywords already runs, wired into all 8 write methods for privateReply and (where the channel lets the caller set it) publicReply.
service.ts now calls flowService.exists() before saving a flow reply (previous commit). Importing the real flowService transitively pulls in botFieldService -> the full contact-filter query builder, which these two suites fully replace @chatbotx.io/database/partials and @chatbotx.io/database/schema without, so the real chain broke both with "No X export is defined on the mock". Neither suite is testing flow validation, so flowService.exists is stubbed to always resolve true instead of chasing the transitive mock surface deeper.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1228.
None of
CommentAutomation's 8 write methods (Messenger, Instagram, Threads, TikTok — create/update) validated thatprivateReply.valueorpublicReply.valuepointed at a real flow when the reply type is"flow".AutomatedResponse(Keywords) already does this viaflowService.existsbefore saving (automated-response/service.ts); this table never did, for either reply field or any of its write methods.A stale or mistyped
flowIdsaves silently and the automation looks active in the UI, but every trigger fails at delivery time with a bareFlowVersion not found(worker'sdetectFlowVersion,apps/worker/src/lib/db.ts) — that failure is never surfaced back to the person who configured the automation.Not a tenant-isolation issue
We checked this specifically before treating it as a normal bug:
detectFlowVersionscopes its lookup to the triggering conversation's ownworkspaceIdin every case, for bothprivateReply(private-reply.ts) andpublicReply(public-reply.ts). A foreignflowIdcan never execute cross-tenant — it just fails closed with "not found." That's why this is a validation gap, not a security report.Change
Adds a private
assertFlowReplyExists(workspaceId, field, reply, tx?)helper, mirroring the checkAutomatedResponsealready runs, and wires it into all 8 write methods:createMessenger/updateMessenger—privateReply+publicReplycreateInstagram/updateInstagram—privateReply+publicReplycreateThreadsAutomation/updateThreadsAutomation—publicReplyonlycreateTiktokAutomation/updateTiktokAutomation—publicReplyonly(Threads and TikTok fix
privateReplyto{type: "none"}and don't let the caller set it, so only theirpublicReplyneeds covering.)Verification
packages/business/__tests__/comment-automation-write-methods.test.ts, 7 new cases added to the existing suite:ultracite checkandcheck-typesare clean.