diff --git a/.changeset/fix-cid-attachment-url.md b/.changeset/fix-cid-attachment-url.md index 4a525f0..aec7c6f 100644 --- a/.changeset/fix-cid-attachment-url.md +++ b/.changeset/fix-cid-attachment-url.md @@ -7,4 +7,5 @@ Fix the URL that `replaceCidReferences` rewrites inline (CID) attachments to. It built `/email/:id/attachment/:file`, which matches no route: the attachment is served from `/api/email/:id/attachment/:file`, under the configured base path. The URL is now root-relative and includes both parts, so it resolves at the root -and under a subpath such as `/mail`. +and under a subpath such as `/mail`. A base path that resolves to the root (`/`) +adds no prefix, so it can no longer produce a protocol-relative `//api/email/...`. diff --git a/packages/smtp/src/__tests__/sanitize.test.ts b/packages/smtp/src/__tests__/sanitize.test.ts index 52a4d98..015f580 100644 --- a/packages/smtp/src/__tests__/sanitize.test.ts +++ b/packages/smtp/src/__tests__/sanitize.test.ts @@ -122,6 +122,20 @@ describe('replaceCidReferences', () => { } }) + it('should treat basePath "/" as no prefix', () => { + const html = '' + const attachments = [{ contentId: 'image123', generatedFileName: 'abc.png' }] + const result = replaceCidReferences(html, 'email1', attachments, undefined, '/') + expect(result).toContain('src="/api/email/email1/attachment/abc.png"') + }) + + it('should combine baseUrl and basePath', () => { + const html = '' + const attachments = [{ contentId: 'image123', generatedFileName: 'abc.png' }] + const result = replaceCidReferences(html, 'email1', attachments, 'example.com', '/mail') + expect(result).toContain('src="//example.com/mail/api/email/email1/attachment/abc.png"') + }) + it('should replace multiple cid references', () => { const html = '' const attachments = [ diff --git a/packages/smtp/src/sanitize.ts b/packages/smtp/src/sanitize.ts index 16ae54a..a50db3a 100644 --- a/packages/smtp/src/sanitize.ts +++ b/packages/smtp/src/sanitize.ts @@ -94,7 +94,8 @@ function buildAttachmentUrl( basePath?: string ): string { const base = baseUrl ? `//${baseUrl}` : '' - const prefix = basePath ? `/${basePath.replace(/^\/|\/$/g, '')}` : '' + const segments = basePath ? basePath.replace(/^\/+|\/+$/g, '') : '' + const prefix = segments ? `/${segments}` : '' return `${base}${prefix}/api/email/${emailId}/attachment/${encodeURIComponent(filename)}` }