Skip to content

fix(storage): url-encode object key in CDN purge methods#2545

Merged
mandarini merged 1 commit into
masterfrom
fix/storage-cdn-purge-encode-path
Jul 21, 2026
Merged

fix(storage): url-encode object key in CDN purge methods#2545
mandarini merged 1 commit into
masterfrom
fix/storage-cdn-purge-encode-path

Conversation

@mandarini

Copy link
Copy Markdown
Contributor

purgeCache and purgeBucketCache interpolated the key into the URL raw, so a ? or # was parsed as a querystring/fragment start and purged the wrong cache key. Encode each path segment before the request.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7d558e3b-ff7c-46f4-8260-fb34ddedb1eb

📥 Commits

Reviewing files that changed from the base of the PR and between 04b76b3 and 1b41435.

📒 Files selected for processing (5)
  • packages/core/storage-js/src/lib/common/helpers.ts
  • packages/core/storage-js/src/packages/StorageBucketApi.ts
  • packages/core/storage-js/src/packages/StorageFileApi.ts
  • packages/core/storage-js/test/storageBucketApi.test.ts
  • packages/core/storage-js/test/storageFileApi.test.ts

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Fixed cache purge requests for buckets and files with special characters in their names.
    • Preserved folder separators while safely encoding characters such as ? and #.
    • Ensured transformation parameters remain correctly separated from encoded file paths.
  • Tests

    • Added coverage for encoded bucket names, object keys, and transformed file requests.

Walkthrough

Added encodeStoragePath to percent-encode each storage path segment while preserving / separators. Bucket and file CDN purge requests now use the helper when constructing DELETE URLs. Tests cover encoding ? and # in bucket identifiers and object keys, preserving separators, and appending transformation query parameters after the encoded path.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the storage-js Related to the storage-js library. label Jul 21, 2026
@mandarini
mandarini marked this pull request as ready for review July 21, 2026 15:09
@mandarini
mandarini requested review from a team as code owners July 21, 2026 15:09
@pkg-pr-new

pkg-pr-new Bot commented Jul 21, 2026

Copy link
Copy Markdown

Open in StackBlitz

@supabase/auth-js

npm i https://pkg.pr.new/@supabase/auth-js@2545

@supabase/functions-js

npm i https://pkg.pr.new/@supabase/functions-js@2545

@supabase/postgrest-js

npm i https://pkg.pr.new/@supabase/postgrest-js@2545

@supabase/realtime-js

npm i https://pkg.pr.new/@supabase/realtime-js@2545

@supabase/storage-js

npm i https://pkg.pr.new/@supabase/storage-js@2545

@supabase/supabase-js

npm i https://pkg.pr.new/@supabase/supabase-js@2545

commit: 1b41435

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Capability matrix drift detected

The following capabilities are marked implemented in javascript but have no registered symbols to verify:

  • auth.admin.create_provider (no symbols list — cannot confirm implementation exists)
  • auth.admin.create_user (no symbols list — cannot confirm implementation exists)
  • auth.admin.delete_mfa_factor (no symbols list — cannot confirm implementation exists)
  • auth.admin.delete_provider (no symbols list — cannot confirm implementation exists)
  • auth.admin.delete_user (no symbols list — cannot confirm implementation exists)
  • auth.admin.generate_link (no symbols list — cannot confirm implementation exists)
  • auth.admin.get_provider (no symbols list — cannot confirm implementation exists)
  • auth.admin.get_user (no symbols list — cannot confirm implementation exists)
  • auth.admin.invite_user (no symbols list — cannot confirm implementation exists)
  • auth.admin.list_mfa_factors (no symbols list — cannot confirm implementation exists)
  • auth.admin.list_providers (no symbols list — cannot confirm implementation exists)
  • auth.admin.list_users (no symbols list — cannot confirm implementation exists)
  • auth.admin.sign_out (no symbols list — cannot confirm implementation exists)
  • auth.admin.update_provider (no symbols list — cannot confirm implementation exists)
  • auth.admin.update_user (no symbols list — cannot confirm implementation exists)
  • auth.identities.link_identity (no symbols list — cannot confirm implementation exists)
  • auth.identities.list_identities (no symbols list — cannot confirm implementation exists)
  • auth.identities.unlink_identity (no symbols list — cannot confirm implementation exists)
  • auth.mfa.challenge (no symbols list — cannot confirm implementation exists)
  • auth.mfa.challenge_and_verify (no symbols list — cannot confirm implementation exists)
  • auth.mfa.enroll (no symbols list — cannot confirm implementation exists)
  • auth.mfa.get_authenticator_assurance_level (no symbols list — cannot confirm implementation exists)
  • auth.mfa.list_factors (no symbols list — cannot confirm implementation exists)
  • auth.mfa.unenroll (no symbols list — cannot confirm implementation exists)
  • auth.mfa.verify (no symbols list — cannot confirm implementation exists)
  • auth.oauth_admin.create_client (no symbols list — cannot confirm implementation exists)
  • auth.oauth_admin.delete_client (no symbols list — cannot confirm implementation exists)
  • auth.oauth_admin.get_client (no symbols list — cannot confirm implementation exists)
  • auth.oauth_admin.list_clients (no symbols list — cannot confirm implementation exists)
  • auth.oauth_admin.regenerate_client_secret (no symbols list — cannot confirm implementation exists)
  • auth.oauth_admin.update_client (no symbols list — cannot confirm implementation exists)
  • auth.oauth_server.approve_authorization (no symbols list — cannot confirm implementation exists)
  • auth.oauth_server.deny_authorization (no symbols list — cannot confirm implementation exists)
  • auth.oauth_server.get_authorization_details (no symbols list — cannot confirm implementation exists)
  • auth.oauth_server.list_grants (no symbols list — cannot confirm implementation exists)
  • auth.oauth_server.revoke_grant (no symbols list — cannot confirm implementation exists)
  • auth.passkey.register_passkey (no symbols list — cannot confirm implementation exists)
  • auth.passkey.sign_in_with_passkey (no symbols list — cannot confirm implementation exists)
  • auth.passkey_admin.delete_passkey (no symbols list — cannot confirm implementation exists)
  • auth.passkey_admin.list_passkeys (no symbols list — cannot confirm implementation exists)
  • auth.session.auto_refresh (no symbols list — cannot confirm implementation exists)
  • auth.session.get_claims (no symbols list — cannot confirm implementation exists)
  • auth.session.get_session (no symbols list — cannot confirm implementation exists)
  • auth.session.get_user (no symbols list — cannot confirm implementation exists)
  • auth.session.refresh_session (no symbols list — cannot confirm implementation exists)
  • auth.session.set_session (no symbols list — cannot confirm implementation exists)
  • auth.session.sign_out (no symbols list — cannot confirm implementation exists)
  • auth.session.subscribe_auth_events (no symbols list — cannot confirm implementation exists)
  • auth.session.update_user (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.exchange_code_for_session (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.reauthenticate (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.resend_confirmation (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.reset_password (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.sign_in_anonymously (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.sign_in_with_id_token (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.sign_in_with_oauth (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.sign_in_with_otp (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.sign_in_with_password (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.sign_in_with_sso (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.sign_in_with_web3 (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.sign_up (no symbols list — cannot confirm implementation exists)
  • auth.sign_in.verify_otp (no symbols list — cannot confirm implementation exists)
  • database.mutate.delete (no symbols list — cannot confirm implementation exists)
  • database.mutate.insert (no symbols list — cannot confirm implementation exists)
  • database.mutate.update (no symbols list — cannot confirm implementation exists)
  • database.mutate.upsert (no symbols list — cannot confirm implementation exists)
  • database.query.from_table (no symbols list — cannot confirm implementation exists)
  • database.query.rpc (no symbols list — cannot confirm implementation exists)
  • database.query.schema_selection (no symbols list — cannot confirm implementation exists)
  • database.query.select (no symbols list — cannot confirm implementation exists)
  • database.using_filters.contained_by (no symbols list — cannot confirm implementation exists)
  • database.using_filters.contains (no symbols list — cannot confirm implementation exists)
  • database.using_filters.eq (no symbols list — cannot confirm implementation exists)
  • database.using_filters.gt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.gte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.ilike (no symbols list — cannot confirm implementation exists)
  • database.using_filters.ilike_all (no symbols list — cannot confirm implementation exists)
  • database.using_filters.ilike_any (no symbols list — cannot confirm implementation exists)
  • database.using_filters.in (no symbols list — cannot confirm implementation exists)
  • database.using_filters.is (no symbols list — cannot confirm implementation exists)
  • database.using_filters.is_distinct (no symbols list — cannot confirm implementation exists)
  • database.using_filters.like (no symbols list — cannot confirm implementation exists)
  • database.using_filters.like_all (no symbols list — cannot confirm implementation exists)
  • database.using_filters.like_any (no symbols list — cannot confirm implementation exists)
  • database.using_filters.lt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.lte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.match (no symbols list — cannot confirm implementation exists)
  • database.using_filters.neq (no symbols list — cannot confirm implementation exists)
  • database.using_filters.not (no symbols list — cannot confirm implementation exists)
  • database.using_filters.not_in (no symbols list — cannot confirm implementation exists)
  • database.using_filters.or (no symbols list — cannot confirm implementation exists)
  • database.using_filters.overlaps (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_adjacent (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_gt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_gte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_lt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_lte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.raw (no symbols list — cannot confirm implementation exists)
  • database.using_filters.regex (no symbols list — cannot confirm implementation exists)
  • database.using_filters.regex_icase (no symbols list — cannot confirm implementation exists)
  • database.using_filters.text_search (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.dry_run (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.explain (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.format_csv (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.format_geojson (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.limit (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.max_affected_rows (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.maybe_single_row (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.order (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.range (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.single_row (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.access_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.copy (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.create_file_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.create_signed_upload_url (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.create_signed_url (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.create_signed_urls (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.delete_file_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.download (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.empty_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.file_exists (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.file_info (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.get_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.get_public_url (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.list_file_buckets (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.list_files (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.list_files_paginated (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.move (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.remove (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.update_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.update_file (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.upload (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.upload_with_signed_url (no symbols list — cannot confirm implementation exists)
  • storage.vector_buckets.access_vector_index (no symbols list — cannot confirm implementation exists)
  • storage.vector_buckets.create_index (no symbols list — cannot confirm implementation exists)
  • storage.vector_buckets.delete_index (no symbols list — cannot confirm implementation exists)
  • storage.vector_buckets.delete_vectors (no symbols list — cannot confirm implementation exists)
  • storage.vector_buckets.get_index (no symbols list — cannot confirm implementation exists)
  • storage.vector_buckets.get_vectors (no symbols list — cannot confirm implementation exists)
  • storage.vector_buckets.list_indexes (no symbols list — cannot confirm implementation exists)
  • storage.vector_buckets.list_vectors (no symbols list — cannot confirm implementation exists)
  • storage.vector_buckets.put_vectors (no symbols list — cannot confirm implementation exists)
  • storage.vector_buckets.query_vectors (no symbols list — cannot confirm implementation exists)
  • realtime.channel.broadcast_http (no symbols list — cannot confirm implementation exists)
  • realtime.channel.send (no symbols list — cannot confirm implementation exists)
  • realtime.channel.subscribe (no symbols list — cannot confirm implementation exists)
  • realtime.channel.unsubscribe (no symbols list — cannot confirm implementation exists)
  • realtime.client.channel (no symbols list — cannot confirm implementation exists)
  • realtime.client.connect (no symbols list — cannot confirm implementation exists)
  • realtime.client.connection_state (no symbols list — cannot confirm implementation exists)
  • realtime.client.disconnect (no symbols list — cannot confirm implementation exists)
  • realtime.client.get_channels (no symbols list — cannot confirm implementation exists)
  • realtime.client.listen_heartbeats (no symbols list — cannot confirm implementation exists)
  • realtime.client.remove_all_channels (no symbols list — cannot confirm implementation exists)
  • realtime.client.remove_channel (no symbols list — cannot confirm implementation exists)
  • realtime.client.set_auth_token (no symbols list — cannot confirm implementation exists)
  • realtime.presence.presence_state (no symbols list — cannot confirm implementation exists)
  • realtime.presence.track (no symbols list — cannot confirm implementation exists)
  • realtime.presence.untrack (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.broadcast (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.subscribe_presence (no symbols list — cannot confirm implementation exists)
  • functions.invocation.invoke (no symbols list — cannot confirm implementation exists)
  • functions.invocation.set_auth_token (no symbols list — cannot confirm implementation exists)

These may have been renamed, removed, or never registered. Please update the capability matrix.
See: https://github.com/supabase/sdk/blob/main/docs/capability-matrix.md

@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 89.43%. first build — fix/storage-cdn-purge-encode-path into master

@mandarini
mandarini merged commit 6b8ff73 into master Jul 21, 2026
31 of 33 checks passed
@mandarini
mandarini deleted the fix/storage-cdn-purge-encode-path branch July 21, 2026 15:24
mandarini pushed a commit to supabase/supabase that referenced this pull request Jul 22, 2026
This PR updates @supabase/*-js libraries to version 2.110.8.

**Source**: supabase-js-stable-release

**Changes**:
- Updated @supabase/supabase-js to 2.110.8
- Updated @supabase/auth-js to 2.110.8
- Updated @supabase/realtime-js to 2.110.8
- Updated @supabase/postgest-js to 2.110.8
- Refreshed pnpm-lock.yaml

---

## Release Notes

## v2.110.8

## 2.110.8 (2026-07-21)

### 🩹 Fixes

- **auth:** downgrade aborted/transient fetch failures from
console.error to warn
([#2544](supabase/supabase-js#2544))
- **functions:** clean up cross-signal abort listener on invoke() return
([#2487](supabase/supabase-js#2487))
- **functions:** match response Content-Type case-insensitively
([#2515](supabase/supabase-js#2515))
- **storage:** url-encode object key in CDN purge methods
([#2545](supabase/supabase-js#2545))
- **supabase:** skip Node warning in Deno
([#2541](supabase/supabase-js#2541))

### ❤️ Thank You

- Franco Kaddour @FrancoKaddour
- Katerina Skroumpelou @mandarini
- Pedro Henrique
- Vaibhav @7ttp
## v2.110.7

## 2.110.7 (2026-07-16)

### 🩹 Fixes

- **postgrest:** correct self-reference inference
([#2525](supabase/supabase-js#2525))
- **realtime:** trigger set auth on INITIAL_SESSION event
([#2531](supabase/supabase-js#2531))
- **realtime:** update phoenix to fix presence issue
([#2532](supabase/supabase-js#2532))

### ❤️ Thank You

- Eduardo Gurgel
- Filipe Cabaço @filipecabaco
- Vaibhav @7ttp

This PR was created automatically.

Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
mandarini pushed a commit to supabase/ssr that referenced this pull request Jul 22, 2026
This PR updates `@supabase/supabase-js` to v2.110.8.

**Source**: supabase-js-stable-release

---

## Release Notes

## v2.110.8

## 2.110.8 (2026-07-21)

### 🩹 Fixes

- **auth:** downgrade aborted/transient fetch failures from
console.error to warn
([#2544](supabase/supabase-js#2544))
- **functions:** clean up cross-signal abort listener on invoke() return
([#2487](supabase/supabase-js#2487))
- **functions:** match response Content-Type case-insensitively
([#2515](supabase/supabase-js#2515))
- **storage:** url-encode object key in CDN purge methods
([#2545](supabase/supabase-js#2545))
- **supabase:** skip Node warning in Deno
([#2541](supabase/supabase-js#2541))

### ❤️ Thank You

- Franco Kaddour @FrancoKaddour
- Katerina Skroumpelou @mandarini
- Pedro Henrique
- Vaibhav @7ttp

This PR was created automatically.

Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

storage-js Related to the storage-js library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants