Update buildUrl to prepend webUrlPrefix#93
Conversation
|
Thanks for the PR! The intent behind this fix makes sense — attachment download links are missing the However, I have a concern with modifying The rest of the codebase handles this at the call site (e.g., lines 416, 510, 1356), explicitly passing // normalizeAttachment (line 2063)
downloadLink: this.toAbsoluteUrl(
raw._links?.download ? `${this.webUrlPrefix}${raw._links.download}` : null
)
// downloadAttachment (line 864)
downloadUrl = this.toAbsoluteUrl(
attachment._links?.download ? `${this.webUrlPrefix}${attachment._links.download}` : null
);This keeps the fix scoped to where it's needed and stays consistent with the existing patterns. What do you think? |
|
I think your option is better |
|
Independently hit this same bug and opened #99 before seeing this PR — apologies for the duplication. Closing #99 in favor of this one since it was opened first. Sharing my root cause analysis and tests here so they're useful for the review. Root causeThe REST API returns each attachment's On Atlassian Cloud the context root is The fix here is correct: prepend Verified by curl'ing the two URLs directly against a live Cloud instance with the same credentials:
End-to-end verificationChecked this branch out locally, ran The downloaded file is byte-identical to what you get by fetching Suggested tests (cherry-pick-able)I wrote three targeted tests while working on #99 that would pin this fix down. Happy to send them as a follow-up PR if you'd prefer, or you can copy them in here — they're small: test('toAbsoluteUrl prepends /wiki context path on Atlassian Cloud', () => {
const cloudClient = new ConfluenceClient({
domain: 'test.atlassian.net',
token: 'token',
apiPath: '/wiki/rest/api'
});
expect(cloudClient.toAbsoluteUrl('/download/attachments/123/file.png?version=1&modificationDate=1700000000000&cacheVersion=1&api=v2'))
.toBe('https://test.atlassian.net/wiki/download/attachments/123/file.png?version=1&modificationDate=1700000000000&cacheVersion=1&api=v2');
});
test('toAbsoluteUrl does not double-prepend /wiki when path already starts with it', () => {
const cloudClient = new ConfluenceClient({
domain: 'test.atlassian.net',
token: 'token',
apiPath: '/wiki/rest/api'
});
expect(cloudClient.toAbsoluteUrl('/wiki/download/attachments/123/file.png'))
.toBe('https://test.atlassian.net/wiki/download/attachments/123/file.png');
});
test('toAbsoluteUrl leaves Server/DC paths untouched (no webUrlPrefix)', () => {
const serverClient = new ConfluenceClient({
domain: 'confluence.example.com',
token: 'token',
apiPath: '/rest/api'
});
expect(serverClient.toAbsoluteUrl('/download/attachments/123/file.png'))
.toBe('https://confluence.example.com/download/attachments/123/file.png');
});One optional hardeningThe current one-liner has no guard against const prefix = this.webUrlPrefix || '';
const needsPrefix = prefix && !pathOrUrl.startsWith(`${prefix}/`);
return this.buildUrl(needsPrefix ? `${prefix}${pathOrUrl}` : pathOrUrl);But the existing one-liner is fine for today's API behavior and matches the style of how |
pchuri
left a comment
There was a problem hiding this comment.
Thanks for the fix! This correctly identifies the root cause — the missing webUrlPrefix (/wiki) in toAbsoluteUrl is what causes the 404 on Atlassian Cloud.
One concern: if pathOrUrl already starts with /wiki (e.g., some API responses may return paths that already include it), the current change would produce /wiki/wiki/..., resulting in another 404.
A safer approach would be to guard against duplicate prefixes:
toAbsoluteUrl(pathOrUrl) {
if (!pathOrUrl) {
return null;
}
if (pathOrUrl.startsWith('http://') || pathOrUrl.startsWith('https://')) {
return pathOrUrl;
}
const pathWithPrefix = this.webUrlPrefix && !pathOrUrl.startsWith(this.webUrlPrefix)
? `${this.webUrlPrefix}${pathOrUrl}`
: pathOrUrl;
return this.buildUrl(pathWithPrefix);
}This is consistent with the pattern already used elsewhere in the codebase (lines 416, 510, 1356, 1360) where webUrlPrefix is explicitly prepended.
Also, it would be great to add a test case verifying Cloud download URLs include the /wiki prefix — the current test suite doesn't cover this scenario.
Note: This also relates to #98 — the issue reporter attributed the 404 to missing query parameters (version, modificationDate, cacheVersion), but the actual root cause is the missing /wiki prefix. The query params are already preserved through buildUrl since _links.download includes them.
Pull Request Template
Description
Update buildUrl to prepend webUrlPrefix
Type of Change
Bug fix (non-breaking change which fixes an issue)