fix(dashboard): authenticate artifact media URLs (#2144)
## Summary - append the existing same-origin daemon token fallback to artifact media URLs used by image, video, and link navigation - preserve project scoping and artifact ID encoding - add a focused regression test and patch changeset ## Root cause Artifact metadata loads through authenticated `fetch`, but previews and links use raw browser navigation (`<img src>`, `<video src>`, and anchors), which cannot attach the dashboard bearer header. The media endpoint therefore returned `401 Valid bearer token required` even though the dashboard itself was authenticated. ## Verification - `pnpm --filter @fusion/dashboard exec vitest run --project dashboard-app-quality-foundation-api app/__tests__/api-artifacts.test.ts --reporter=dot` - `pnpm lint` - `pnpm --filter @fusion/dashboard typecheck` - `pnpm check:changesets --strict` - `pnpm build` - `FUSION_PG_TEST_URL_BASE=postgresql://plarson@127.0.0.1:55432 VITEST_MAX_WORKERS=1 nix shell nixpkgs#postgresql --command pnpm test:gate` The broader dashboard foundation API shard was also attempted but aborted in Node after repeated unmanaged-file-descriptor warnings; the focused regression and canonical merge gate both pass. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed protected artifact images and links so they load correctly in authenticated dashboards. * Added authentication tokens to generated artifact media URLs for reliable previews and navigation. * **Tests** * Added coverage verifying authenticated artifact media URLs include the expected token and parameters. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
7
.changeset/fix-artifact-media-auth.md
Normal file
7
.changeset/fix-artifact-media-auth.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@runfusion/fusion": patch
|
||||
---
|
||||
|
||||
summary: Fix protected image artifacts so previews and links load in authenticated dashboards.
|
||||
category: fix
|
||||
dev: Artifact media URLs now use the existing same-origin query-token fallback required by browser image and link navigation.
|
||||
21
packages/dashboard/app/__tests__/api-artifacts.test.ts
Normal file
21
packages/dashboard/app/__tests__/api-artifacts.test.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { artifactMediaUrl } from "../api";
|
||||
import { clearAuthToken, setAuthToken } from "../auth";
|
||||
|
||||
afterEach(() => {
|
||||
clearAuthToken();
|
||||
});
|
||||
|
||||
describe("artifactMediaUrl", () => {
|
||||
/*
|
||||
* FNXC:ArtifactMediaAuth 2026-07-15-14:24:
|
||||
* Browser-native image, video, and link requests cannot attach the dashboard's Authorization header. Keep this regression focused on the generated URL contract: encoded artifact id and project scope survive while the existing same-origin fn_token fallback is appended.
|
||||
*/
|
||||
it("appends the daemon token for image and link navigation", () => {
|
||||
setAuthToken("daemon-token");
|
||||
|
||||
expect(artifactMediaUrl("artifact/with spaces", "project-1")).toBe(
|
||||
"/api/artifacts/artifact%2Fwith%20spaces/media?projectId=project-1&fn_token=daemon-token",
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1738,7 +1738,11 @@ export async function fetchArtifacts(
|
||||
}
|
||||
|
||||
export function artifactMediaUrl(id: string, projectId?: string): string {
|
||||
return buildApiUrl(withProjectId(`/artifacts/${encodeURIComponent(id)}/media`, projectId));
|
||||
/*
|
||||
* FNXC:ArtifactMediaAuth 2026-07-15-14:24:
|
||||
* Artifact previews and links use browser-native navigation, which cannot send the bearer header used by fetch. Reuse appendTokenQuery so authenticated media loads while its dashboard-owned URL guard prevents leaking the daemon token cross-origin.
|
||||
*/
|
||||
return appendTokenQuery(buildApiUrl(withProjectId(`/artifacts/${encodeURIComponent(id)}/media`, projectId)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user