From f8b886210519cfd4972135f09e878e4fab9e924f Mon Sep 17 00:00:00 2001 From: mikeboe Date: Tue, 3 Nov 2026 15:36:44 +0000 Subject: [PATCH 1/2] fix(api): collect Office macro-enabled and template outputs The output allowlist (SUPPORTED_EXTENSIONS) had .xlsx/.docx/.pptx but no .xlsm/.docm/.pptm or the template formats, so a generated .xlsm was silently dropped and never reached LibreChat (companyGPT, innfactoryai, 2026-11-03). Add .docm .dotx .dotm .xlsm .xlsb .xltx .xltm .pptm .potx .potm .ppsx .ppsm .odg to the allowlist and the MIME map. Co-Authored-By: Claude Opus 5.5 --- api/src/job-helpers.test.ts | 24 ++++++++++++++++++++++++ api/src/job.ts | 18 +++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/api/src/job-helpers.test.ts b/api/src/job-helpers.test.ts index 460902da..6078308d 100644 --- a/api/src/job-helpers.test.ts +++ b/api/src/job-helpers.test.ts @@ -12,6 +12,7 @@ import { inputsLiveUnder, mapWithConcurrency, mimeTypeFor, + isSupportedOutputFilename, } from './job'; import type { Runtime } from './runtime'; import type { TFile } from './job'; @@ -84,6 +85,13 @@ describe('mimeTypeFor', () => { expect(mimeTypeFor('logs.tar.gz')).toBe('application/gzip'); }); + it('returns the registered MIME for Office macro and template formats', () => { + expect(mimeTypeFor('calc.xlsm')).toBe('application/vnd.ms-excel.sheet.macroEnabled.12'); + expect(mimeTypeFor('letter.docm')).toBe('application/vnd.ms-word.document.macroEnabled.12'); + expect(mimeTypeFor('deck.pptm')).toBe('application/vnd.ms-powerpoint.presentation.macroEnabled.12'); + expect(mimeTypeFor('master.potx')).toBe('application/vnd.openxmlformats-officedocument.presentationml.template'); + }); + it('falls back to application/octet-stream for unknown extensions', () => { expect(mimeTypeFor('mystery.qwerty')).toBe('application/octet-stream'); }); @@ -492,3 +500,19 @@ describe('ensureNodeModulesSymlink', () => { } }); }); + +describe('isSupportedOutputFilename', () => { + it('collects Office macro-enabled, binary and template outputs', () => { + for (const name of ['calc.xlsm', 'CALC.XLSM', 'big.xlsb', 'tpl.xltx', 'tpl.xltm', 'letter.docm', + 'tpl.dotx', 'tpl.dotm', 'deck.pptm', 'master.potx', 'master.potm', 'show.ppsx', 'show.ppsm', 'draw.odg']) { + expect(isSupportedOutputFilename(name)).toBe(true); + } + }); + + it('still collects the existing formats and skips unknown ones', () => { + expect(isSupportedOutputFilename('report.xlsx')).toBe(true); + expect(isSupportedOutputFilename('notes.txt')).toBe(true); + expect(isSupportedOutputFilename('vbaProject.bin')).toBe(false); + expect(isSupportedOutputFilename('mystery.qwerty')).toBe(false); + }); +}); diff --git a/api/src/job.ts b/api/src/job.ts index 88d3e5b4..a5dc82a5 100644 --- a/api/src/job.ts +++ b/api/src/job.ts @@ -283,6 +283,19 @@ const MIME_TYPE_BY_EXTENSION: ReadonlyMap = new Map([ ['.odt', 'application/vnd.oasis.opendocument.text'], ['.ods', 'application/vnd.oasis.opendocument.spreadsheet'], ['.odp', 'application/vnd.oasis.opendocument.presentation'], + ['.docm', 'application/vnd.ms-word.document.macroEnabled.12'], + ['.dotx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.template'], + ['.dotm', 'application/vnd.ms-word.template.macroEnabled.12'], + ['.xlsm', 'application/vnd.ms-excel.sheet.macroEnabled.12'], + ['.xlsb', 'application/vnd.ms-excel.sheet.binary.macroEnabled.12'], + ['.xltx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.template'], + ['.xltm', 'application/vnd.ms-excel.template.macroEnabled.12'], + ['.pptm', 'application/vnd.ms-powerpoint.presentation.macroEnabled.12'], + ['.potx', 'application/vnd.openxmlformats-officedocument.presentationml.template'], + ['.potm', 'application/vnd.ms-powerpoint.template.macroEnabled.12'], + ['.ppsx', 'application/vnd.openxmlformats-officedocument.presentationml.slideshow'], + ['.ppsm', 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12'], + ['.odg', 'application/vnd.oasis.opendocument.graphics'], // Text / structured text ['.txt', 'text/plain'], ['.log', 'text/plain'], @@ -543,6 +556,9 @@ const SUPPORTED_EXTENSIONS = new Set([ '.conf', '.env', '.gitignore', '.ini', '.properties', '.toml', '.doc', '.docx', '.pdf', '.ppt', '.pptx', '.xls', '.xlsx', '.odt', '.ods', '.odp', '.rtf', + /* Office macro-enabled, binary and template formats (innFactory): */ + '.docm', '.dotx', '.dotm', '.xlsm', '.xlsb', '.xltx', '.xltm', + '.pptm', '.potx', '.potm', '.ppsx', '.ppsm', '.odg', '.avif', '.bmp', '.gif', '.ico', '.jpeg', '.jpg', '.png', '.tif', '.tiff', '.webp', '.eot', '.ttf', '.woff', '.woff2', @@ -554,7 +570,7 @@ const SUPPORTED_EXTENSIONS = new Set([ '.bat', '.cmd', '.deb', '.log', '.rpm', '.vbs', ]); -function isSupportedOutputFilename(name: string): boolean { +export function isSupportedOutputFilename(name: string): boolean { const basename = path.basename(name); const ext = path.extname(basename).toLowerCase(); const dottedBasename = `.${basename}`; From ad6c62283197bc13738d6f920d844e4e0cac0c0f Mon Sep 17 00:00:00 2001 From: mikeboe Date: Tue, 3 Nov 2026 18:29:49 +0000 Subject: [PATCH 2/2] fix(egress-gateway): allow Office macro-enabled and template uploads The egress gateway has its own artifact allowlist (BRIDGE_ARTIFACT_EXTENSIONS); with only the sandbox list extended, a generated .xlsm was collected but its upload was rejected with 403 scope_mismatch. Add the same formats and media types there. Co-Authored-By: Claude Opus 5.5 --- packages/code/src/protocol.test.ts | 4 ++++ packages/code/src/protocol.ts | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/packages/code/src/protocol.test.ts b/packages/code/src/protocol.test.ts index 25c00cf3..5c0f5ab2 100644 --- a/packages/code/src/protocol.test.ts +++ b/packages/code/src/protocol.test.ts @@ -985,6 +985,10 @@ test('bridge artifact policy and media types match the hardened gateway contract assert.equal(isSupportedBridgeArtifactName('reports/result.json'), true); assert.equal(isSupportedBridgeArtifactName('preview.png'), true); assert.equal(isSupportedBridgeArtifactName('model.bin'), false); + assert.equal(isSupportedBridgeArtifactName('calc.xlsm'), true); + assert.equal(isSupportedBridgeArtifactName('out/LETTER.DOCM'), true); + assert.equal(isSupportedBridgeArtifactName('master.potx'), true); + assert.equal(bridgeArtifactMediaType('calc.xlsm'), 'application/vnd.ms-excel.sheet.macroEnabled.12'); assert.equal(bridgeArtifactMediaType('preview.png'), 'image/png'); assert.equal(bridgeArtifactMediaType('reports/result.json'), 'application/json'); assert.equal(bridgeArtifactMediaType('Dockerfile'), 'application/octet-stream'); diff --git a/packages/code/src/protocol.ts b/packages/code/src/protocol.ts index 0fcb6090..1acf7570 100644 --- a/packages/code/src/protocol.ts +++ b/packages/code/src/protocol.ts @@ -121,6 +121,20 @@ const BRIDGE_ARTIFACT_EXTENSIONS = new Set([ '.ods', '.odp', '.rtf', + /* Office macro-enabled, binary and template formats (innFactory): */ + '.docm', + '.dotx', + '.dotm', + '.xlsm', + '.xlsb', + '.xltx', + '.xltm', + '.pptm', + '.potx', + '.potm', + '.ppsx', + '.ppsm', + '.odg', '.avif', '.bmp', '.gif', @@ -222,6 +236,19 @@ const BRIDGE_ARTIFACT_MEDIA_TYPES: Readonly> = { '.odt': 'application/vnd.oasis.opendocument.text', '.ods': 'application/vnd.oasis.opendocument.spreadsheet', '.odp': 'application/vnd.oasis.opendocument.presentation', + '.docm': 'application/vnd.ms-word.document.macroEnabled.12', + '.dotx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + '.dotm': 'application/vnd.ms-word.template.macroEnabled.12', + '.xlsm': 'application/vnd.ms-excel.sheet.macroEnabled.12', + '.xlsb': 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', + '.xltx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + '.xltm': 'application/vnd.ms-excel.template.macroEnabled.12', + '.pptm': 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', + '.potx': 'application/vnd.openxmlformats-officedocument.presentationml.template', + '.potm': 'application/vnd.ms-powerpoint.template.macroEnabled.12', + '.ppsx': 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + '.ppsm': 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', + '.odg': 'application/vnd.oasis.opendocument.graphics', '.parquet': 'application/vnd.apache.parquet', '.pdf': 'application/pdf', '.png': 'image/png',