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)}`
}