fix(canvas): consolidate platform-auth headers via shared helper (#178) #54
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "fix/178-canvas-shared-auth-headers"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
platformAuthHeaders()tocanvas/src/lib/api.tsas the single source of truth for the bearer-token + tenant-slug header pair every authenticated canvas fetch needs.request()itself,uploadChatFiles,downloadChatFile, and the 5Attachment*components (Image/Video/Audio/PDF/TextPreview).getTenantSlug()copies that inline-redefined what@/lib/tenantalready exports.AttachmentTextPreview(no bearer leakage to third-party URLs).Why
Pre-fix, the 7 callsites each read
NEXT_PUBLIC_ADMIN_TOKEN, manually attached the bearer, called a local-or-importedgetTenantSlug(), and attached the slug header. A new poller / raw-fetch added without going through this exact recipe silently 401s against workspace-server whenADMIN_TOKENis set on the server side. Closes the bug-shape gap called out in #178.Test plan
platform-auth-headers.test.ts— empty, bearer-only, slug-only, both, empty-string-as-unset, fresh-object-per-call.npx tsc --noEmitclean.npm run buildsucceeds.Hostile self-review
request()— the helper returns{}instead of{ "Content-Type": "application/json" }; we spread the helper's result over an explicitContent-Typeline so JSON requests still set it. FormData uploads (uploadChatFiles) deliberately do NOT set Content-Type so the browser writes the multipart boundary; comment added explaining this.AttachmentTextPreviewoff-platform branch — the original code only attached auth headers whenisPlatformAttachment()was true. The new code preserves this withisPlatformAttachment(uri) ? platformAuthHeaders() : {}. Without that branch, off-platform fetches would leak the admin token to third-party origins.uploads.tsimport surface change — removedimport { getTenantSlug } from "@/lib/tenant"because it's no longer referenced. If a future caller inuploads.tsadds a slug-dependent code path, they'll either re-import or (more likely) reach forplatformAuthHeaders()— the right path.Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
Closes the post-Task-#176 self-review gap: the bearer-token + tenant- slug header construction was duplicated across 7 raw-fetch callsites in the canvas (lib/api.ts request(), uploads.ts × 2, and 5 Attachment* components). Each callsite read NEXT_PUBLIC_ADMIN_TOKEN, attached Authorization: Bearer manually, computed getTenantSlug locally (three of them inline-redefined it from /lib/tenant!), and attached X-Molecule-Org-Slug. A new poller / raw-fetch added without going through this exact recipe silently 401s against workspace-server when ADMIN_TOKEN is set on the server side — the bug shape called out in the original task. Adds platformAuthHeaders() to lib/api.ts as the single source of truth and routes all 7 raw-fetch callsites through it. Removes 4 duplicate local getTenantSlug() copies (Image, Video, Audio, PDF, TextPreview) that were inline-redefining what /lib/tenant.ts already exports. Also preserves the AttachmentTextPreview off-platform branch — when isPlatformAttachment() is false, headers is {} (no bearer leakage to third-party URLs). Tests: - 6 unit tests in platform-auth-headers.test.ts covering: empty, bearer-only, slug-only, both, empty-string-as-unset, fresh-object- per-call. Mutation-tested: removing the bearer attach inside the helper fails 2 of 6 tests immediately. - All 1389 existing canvas vitest tests pass unchanged. - npx tsc --noEmit clean. - npm run build succeeds (canvas Next.js build). Per feedback_assert_exact_not_substring: tests use exact toEqual() equality, not substring/contains, so an extra-header bug also fails the assertion. Per feedback_oss_design_philosophy: this is the "plugin/abstract/modular/SSOT" move applied to the auth-header construction surface — one helper, six call sites, no duplication. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>