diff --git a/.changeset/brown-pens-confess.md b/.changeset/brown-pens-confess.md new file mode 100644 index 00000000000..038b177796e --- /dev/null +++ b/.changeset/brown-pens-confess.md @@ -0,0 +1,6 @@ +--- +"@firebase/storage": patch +"@firebase/util": patch +--- + +Fixed issue where Storage on Firebase Studio throws CORS errors. diff --git a/common/api-review/util.api.md b/common/api-review/util.api.md index f263f450da3..4ac51fda550 100644 --- a/common/api-review/util.api.md +++ b/common/api-review/util.api.md @@ -270,7 +270,7 @@ export function isBrowserExtension(): boolean; export function isCloudflareWorker(): boolean; // @public -export function isCloudWorkstation(host: string): boolean; +export function isCloudWorkstation(url: string): boolean; // Warning: (ae-missing-release-tag) "isElectron" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // diff --git a/packages/storage/test/browser/connection.test.ts b/packages/storage/test/browser/connection.test.ts index 2a0320d0c02..4cb4d4cb919 100644 --- a/packages/storage/test/browser/connection.test.ts +++ b/packages/storage/test/browser/connection.test.ts @@ -35,7 +35,7 @@ describe('Connections', () => { const fakeXHR = useFakeXMLHttpRequest(); const connection = new XhrBytesConnection(); const sendPromise = connection.send( - 'https://abc.cloudworkstations.dev', + 'https://abc.cloudworkstations.dev/test', 'GET', true ); diff --git a/packages/util/src/url.ts b/packages/util/src/url.ts index e41d26594c2..6de92584979 100644 --- a/packages/util/src/url.ts +++ b/packages/util/src/url.ts @@ -19,8 +19,20 @@ * Checks whether host is a cloud workstation or not. * @public */ -export function isCloudWorkstation(host: string): boolean { - return host.endsWith('.cloudworkstations.dev'); +export function isCloudWorkstation(url: string): boolean { + // `isCloudWorkstation` is called without protocol in certain connect*Emulator functions + // In HTTP request builders, it's called with the protocol. + // If called with protocol prefix, it's a valid URL, so we extract the hostname + // If called without, we assume the string is the hostname. + try { + const host = + url.startsWith('http://') || url.startsWith('https://') + ? new URL(url).hostname + : url; + return host.endsWith('.cloudworkstations.dev'); + } catch { + return false; + } } /**