Box inbound: defensive loop guard on parent folder

Reject inbound events whose Box file isn't a direct child of the
configured BOX_WATCH_FOLDER_ID, and explicitly skip any file whose
parent IS BOX_OUT_FOLDER_ID. Box webhooks are folder-scoped already
so a normal subscription won't fire on our own outbound writes —
this is defence in depth in case a future webhook is mis-subscribed
or the two folder ids ever drift into the same value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
DJP 2026-05-12 21:45:19 -04:00
parent 545b0eef05
commit bb9c7aa02d

View file

@ -6,10 +6,42 @@ import { ingestInboundFile, type IngestResult } from "@/lib/services/inbound-ing
* the file's name from Box (so the matcher has something to parse) and
* delegates everything else regex resolution, project/deliverable
* matching, holding-pen vs active branching, notifications.
*
* Loop guard: only accepts events whose file's parent folder matches
* BOX_WATCH_FOLDER_ID. Box webhooks are already folder-scoped on
* subscription, but a misconfigured subscription on the outbound folder
* would otherwise ingest our own uploads. Defence in depth.
*/
export async function ingestBoxUpload(fileId: string): Promise<IngestResult> {
try {
const meta = await getBoxFileMetadata(fileId);
const watchFolderId = process.env.BOX_WATCH_FOLDER_ID;
const outFolderId = process.env.BOX_OUT_FOLDER_ID;
const parentId = meta.parent?.id;
// Reject anything from the outbound folder — that's our own writes.
if (outFolderId && parentId === outFolderId) {
return {
ok: true,
status: "UNMATCHED",
error: `Ignoring event from outbound folder ${outFolderId} (loop guard).`,
};
}
// When the watch folder is configured, require the file to be a direct
// child of it. (We don't walk up the parent chain — files dropped
// into nested sub-folders won't fire matching webhooks anyway because
// Box only fires on the subscribed folder's direct contents unless
// the subscription includes descendants.)
if (watchFolderId && parentId !== watchFolderId) {
return {
ok: true,
status: "UNMATCHED",
error: `File parent ${parentId} is not the watch folder ${watchFolderId}.`,
};
}
return ingestInboundFile({
source: "BOX",
fileName: meta.name,