fix(storage): Supabase signed URLs — prepend /storage/v1 (#2565)

SupabaseStorage.getSignedUrl built the download URL as `${projectUrl}${signedURL}`,
but Supabase's sign API returns `signedURL` relative to the Storage API root
(/object/sign/<bucket>/<path>?token=...), so the generated link dropped /storage/v1
and returned 404. Now prepends `${projectUrl}/storage/v1`, tolerating an
already-absolute URL or a value that already carries the prefix. `gbrain files
signed-url` links resolve again.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
FloridaStyle
2026-07-23 15:32:08 -07:00
committed by Garry Tan
co-authored by Claude Opus 4.8
parent ca47c054b8
commit ea9019e6bd
+8 -1
View File
@@ -195,7 +195,14 @@ export class SupabaseStorage implements StorageBackend {
throw new Error(`Supabase signed URL failed: ${res.status} ${body}`);
}
const result = await res.json() as { signedURL: string };
return `${this.projectUrl}${result.signedURL}`;
// Supabase returns `signedURL` relative to the Storage API root, e.g.
// "/object/sign/<bucket>/<path>?token=...". Prepend projectUrl + "/storage/v1"
// (not just projectUrl) or the link 404s. Tolerate an already-absolute URL or a
// value that already carries the /storage/v1 prefix.
const signed = result.signedURL;
if (/^https?:\/\//.test(signed)) return signed;
if (signed.startsWith('/storage/v1')) return `${this.projectUrl}${signed}`;
return `${this.projectUrl}/storage/v1${signed.startsWith('/') ? '' : '/'}${signed}`;
}
async getUrl(path: string): Promise<string> {