From fd9db853658f82d87aed8f151e278d645d536eac Mon Sep 17 00:00:00 2001 From: ygd58 Date: Fri, 4 Sep 2026 06:32:11 +0200 Subject: [PATCH] fix(agent-sdk): strip trailing colon from URL scheme in createRemoteAttachment Fixes #4034 createRemoteAttachment() stored url.protocol directly as the remote attachment scheme. URL.protocol includes the trailing colon (e.g. "https:"), but the rest of libxmtp's remote attachment tests and content type examples consistently use the scheme without it (e.g. "https") - bindings/node/test/RemoteAttachmentEncryption.test.ts, bindings/wasm/test/RemoteAttachmentEncryption.test.ts, bindings/wasm/test/EnrichedMessage.test.ts, and crates/xmtp_content_types/src/remote_attachment.rs. Strip the trailing colon with url.protocol.replace(/:$/, ""), matching the suggested fix in the issue. Added a regression test asserting the scheme for both https and http URLs. Verified it fails against the pre-fix code (expected 'https:' to be 'https') and passes against the fix, via a full native build (cargo build for bindings/node, then yarn build for node-sdk, since agent-sdk's test suite imports encryptAttachment from @xmtp/node-sdk which requires the compiled native binding). yarn vitest run src/util/AttachmentUtil.test.ts - 3/3 passing. yarn typecheck, eslint, and prettier clean on both changed files. --- .../agent-sdk/src/util/AttachmentUtil.test.ts | 30 +++++++++++++++++++ sdks/js/agent-sdk/src/util/AttachmentUtil.ts | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/sdks/js/agent-sdk/src/util/AttachmentUtil.test.ts b/sdks/js/agent-sdk/src/util/AttachmentUtil.test.ts index bdee9f7ec0..20bca407d6 100644 --- a/sdks/js/agent-sdk/src/util/AttachmentUtil.test.ts +++ b/sdks/js/agent-sdk/src/util/AttachmentUtil.test.ts @@ -78,6 +78,10 @@ describe("AttachmentUtil", () => { expect(remoteAttachment.url).toBe(testUrl); expect(remoteAttachment.filename).toBe(fileName); + // Issue #4034: scheme must not carry the trailing colon that + // URL.protocol includes (e.g. "https", not "https:"), matching the + // format used elsewhere in libxmtp's remote attachment tests/examples. + expect(remoteAttachment.scheme).toBe("https"); const receivedAttachment = await downloadRemoteAttachment(remoteAttachment); @@ -97,4 +101,30 @@ describe("AttachmentUtil", () => { expect(decryptedContent).toBe(fileContent); }); }); + + describe("createRemoteAttachment scheme normalization", () => { + it("strips the trailing colon from URL.protocol (issue #4034)", async () => { + const fileContent = "scheme normalization test"; + const unencryptedFile = new File([fileContent], "hello.txt", { + type: "text/plain", + }); + const arrayBuffer = await unencryptedFile.arrayBuffer(); + const encryptedAttachment = encryptAttachment({ + filename: unencryptedFile.name, + content: new Uint8Array(arrayBuffer), + mimeType: unencryptedFile.type, + }); + + for (const [fileUrl, expectedScheme] of [ + ["https://localhost/test_file", "https"], + ["http://localhost/test_file", "http"], + ] as const) { + const remoteAttachment = createRemoteAttachment( + encryptedAttachment, + fileUrl, + ); + expect(remoteAttachment.scheme).toBe(expectedScheme); + } + }); + }); }); diff --git a/sdks/js/agent-sdk/src/util/AttachmentUtil.ts b/sdks/js/agent-sdk/src/util/AttachmentUtil.ts index dca55d6612..6c5b73b978 100644 --- a/sdks/js/agent-sdk/src/util/AttachmentUtil.ts +++ b/sdks/js/agent-sdk/src/util/AttachmentUtil.ts @@ -49,7 +49,7 @@ export function createRemoteAttachment( filename: encryptedAttachment.filename, nonce: encryptedAttachment.nonce, salt: encryptedAttachment.salt, - scheme: url.protocol, + scheme: url.protocol.replace(/:$/, ""), secret: encryptedAttachment.secret, url: url.toString(), };