diff --git a/.changeset/fix-artifact-media-auth.md b/.changeset/fix-artifact-media-auth.md new file mode 100644 index 0000000000..a129a3a072 --- /dev/null +++ b/.changeset/fix-artifact-media-auth.md @@ -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. diff --git a/packages/dashboard/app/__tests__/api-artifacts.test.ts b/packages/dashboard/app/__tests__/api-artifacts.test.ts new file mode 100644 index 0000000000..e7731c00b4 --- /dev/null +++ b/packages/dashboard/app/__tests__/api-artifacts.test.ts @@ -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", + ); + }); +}); diff --git a/packages/dashboard/app/api/legacy.ts b/packages/dashboard/app/api/legacy.ts index 7dd0dcb134..297dc98a34 100644 --- a/packages/dashboard/app/api/legacy.ts +++ b/packages/dashboard/app/api/legacy.ts @@ -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))); } /*