Skip to content

fix(gotrue)!: assert asyncStorage is provided for PKCE flow in the constructor - #1489

Open
gourabsingha1 wants to merge 7 commits into
supabase:mainfrom
gourabsingha1:fix/assert-async-storage-constructor-1446
Open

fix(gotrue)!: assert asyncStorage is provided for PKCE flow in the constructor#1489
gourabsingha1 wants to merge 7 commits into
supabase:mainfrom
gourabsingha1:fix/assert-async-storage-constructor-1446

Conversation

@gourabsingha1

@gourabsingha1 gourabsingha1 commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Root cause
When flowType is AuthFlowType.pkce (the default) and no asyncStorage is provided, calling getOAuthSignInUrl() or getLinkIdentityUrl() fails late at call time. To provide a better developer experience and fail fast, the misconfiguration should be validated up front in the constructor.

Fix
Added an assert in the GoTrueClient constructor to validate that asyncStorage != null if flowType == AuthFlowType.pkce.

Tests

  • Added a unit test in gotrue/test/client_test.dart to verify that GoTrueClient throws an AssertionError if asyncStorage is missing when using PKCE flow.
  • Updated all test suites in gotrue and supabase packages to pass a mock storage or specify implicit flow type where no storage was configured.

Fixes #1446

Summary by CodeRabbit

  • New Features

    • Added in-memory storage for PKCE code verifiers.
    • Supabase clients now automatically use in-memory storage when PKCE is enabled without custom storage.
    • Added guidance for configuring persistent storage when verifiers must survive application restarts.
  • Bug Fixes

    • PKCE initialization now reports a descriptive error when required storage is unavailable.
  • Tests

    • Expanded coverage for PKCE flows, storage behavior, OAuth authentication, and client initialization.

@gourabsingha1
gourabsingha1 requested a review from a team as a code owner June 28, 2026 08:29
@Vinzent03

Copy link
Copy Markdown
Collaborator

As stated in your linked issue this is considered as a breaking change so won't plan this for main yet but later for v3 when we start actively working on it.

@spydon spydon changed the title fix(gotrue): assert asyncStorage is provided for PKCE flow in the constructor fix(gotrue)!: assert asyncStorage is provided for PKCE flow in the constructor Jun 29, 2026
@spydon
spydon changed the base branch from main to v3 June 29, 2026 14:12
@spydon spydon added the v3 label Jun 29, 2026
@spydon
spydon deleted the branch supabase:main July 7, 2026 07:42
@spydon spydon closed this Jul 7, 2026
@spydon spydon reopened this Jul 7, 2026
gourabsingha1 and others added 2 commits August 5, 2026 16:50
The constructor assertion trips every GoTrueClient and SupabaseClient built
without a pkce storage, including the suites main gained while this branch sat
on the old v3 base.
@spydon
spydon changed the base branch from v3 to main August 5, 2026 14:56
@spydon
spydon force-pushed the fix/assert-async-storage-constructor-1446 branch from 68a6a36 to 5297960 Compare August 5, 2026 15:00
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3b25c209-b51e-4432-8375-ea722c5f1f8f

📥 Commits

Reviewing files that changed from the base of the PR and between 41dcbfb and f5b6b3f.

📒 Files selected for processing (10)
  • packages/gotrue/lib/src/gotrue_client.dart
  • packages/gotrue/test/admin_list_users_test.dart
  • packages/gotrue/test/admin_test.dart
  • packages/gotrue/test/client_test.dart
  • packages/gotrue/test/src/gotrue_mfa_api_test.dart
  • packages/gotrue/test/utils.dart
  • packages/supabase/lib/src/supabase_client.dart
  • packages/supabase/lib/src/supabase_client_options.dart
  • packages/supabase/test/client_test.dart
  • sdk-compliance.yaml
🚧 Files skipped from review as they are similar to previous changes (8)
  • packages/gotrue/test/admin_test.dart
  • packages/gotrue/test/src/gotrue_mfa_api_test.dart
  • packages/supabase/test/client_test.dart
  • packages/gotrue/test/utils.dart
  • packages/supabase/lib/src/supabase_client.dart
  • packages/supabase/lib/src/supabase_client_options.dart
  • sdk-compliance.yaml
  • packages/gotrue/lib/src/gotrue_client.dart

📝 Walkthrough

Walkthrough

Changes

The change adds MemoryGotrueAsyncStorage, validates PKCE storage in GoTrueClient, updates GoTrue test fixtures, and makes Supabase create in-memory storage for default PKCE flows.

PKCE async storage

Layer / File(s) Summary
Memory-backed storage implementation
packages/gotrue/lib/src/types/gotrue_async_storage.dart, packages/gotrue/test/memory_async_storage_test.dart, packages/gotrue/test/utils.dart, packages/gotrue/example/main.dart, sdk-compliance.yaml
Adds memory-backed PKCE storage and tests read, write, removal, overwrite, and instance isolation behavior.
GoTrue constructor validation and fixtures
packages/gotrue/lib/src/gotrue_client.dart, packages/gotrue/test/client_test.dart, packages/gotrue/test/*, packages/gotrue/test/src/*
Requires storage for PKCE flow, permits storage-free implicit flow construction, and updates GoTrue test clients to use TestAsyncStorage.
Supabase PKCE fallback integration
packages/supabase/lib/src/supabase_client.dart, packages/supabase/lib/src/supabase_client_options.dart, packages/supabase/test/client_test.dart
Creates memory storage when PKCE has no configured storage and verifies that OAuth URLs include a PKCE code challenge.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SupabaseClient
  participant GoTrueClient
  participant MemoryGotrueAsyncStorage
  SupabaseClient->>MemoryGotrueAsyncStorage: Create fallback storage for PKCE
  SupabaseClient->>GoTrueClient: Initialize with PKCE and storage
  GoTrueClient->>MemoryGotrueAsyncStorage: Store PKCE verifier
  GoTrueClient-->>SupabaseClient: Return OAuth sign-in URL with code challenge
Loading

Possibly related PRs

Suggested labels: auth

Suggested reviewers: vinzent03, tr00d

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the constructor assertion for PKCE storage, which is the primary change.
Linked Issues check ✅ Passed The changes implement the constructor assertion, update storage defaults, and add tests for issue [#1446].
Out of Scope Changes check ✅ Passed The storage implementation, documentation, compatibility updates, and tests directly support the linked issue objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/gotrue/lib/src/gotrue_client.dart`:
- Around line 156-159: Replace the constructor assert in
packages/gotrue/lib/src/gotrue_client.dart:156-159 with runtime validation
enforcing that PKCE requires non-null asyncStorage, failing during construction.
Update the corresponding constructor test in
packages/gotrue/test/client_test.dart:869-894 to expect the runtime failure
rather than AssertionError.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 25a0956e-2ada-4718-8e25-8c26c6a81ebe

📥 Commits

Reviewing files that changed from the base of the PR and between 1862f74 and 5297960.

📒 Files selected for processing (18)
  • packages/gotrue/lib/src/gotrue_client.dart
  • packages/gotrue/test/admin_delete_user_test.dart
  • packages/gotrue/test/admin_test.dart
  • packages/gotrue/test/client_test.dart
  • packages/gotrue/test/header_isolation_test.dart
  • packages/gotrue/test/mfa_enroll_test.dart
  • packages/gotrue/test/src/gotrue_admin_custom_providers_api_test.dart
  • packages/gotrue/test/src/gotrue_admin_mfa_api_test.dart
  • packages/gotrue/test/src/gotrue_admin_oauth_api_test.dart
  • packages/gotrue/test/src/gotrue_mfa_api_test.dart
  • packages/gotrue/test/src/gotrue_oauth_api_test.dart
  • packages/supabase/test/client_test.dart
  • packages/supabase/test/mock_test.dart
  • packages/supabase/test/realtime_test.dart
  • packages/supabase/test/stream_filter_test.dart
  • packages/supabase/test/stream_integration_test.dart
  • packages/supabase/test/trace_propagation_test.dart
  • packages/supabase/test/utils.dart

Comment thread packages/gotrue/lib/src/gotrue_client.dart
The constructor assert makes asyncStorage mandatory for the pkce flow,
which is the default. Without a storage of its own the supabase package
would have made every SupabaseClient throw, so ship a
MemoryGotrueAsyncStorage in gotrue and use it when no storage is passed.
The gotrue tests keep the pkce flow and pass a storage instead of
switching to the implicit flow.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/gotrue/test/client_test.dart`:
- Around line 869-881: Replace the PKCE storage requirement assertion in the
GoTrueClient constructor with unconditional runtime validation that throws an
ArgumentError or StateError when PKCE is configured without asyncStorage. Update
the “Constructing a client without an asyncStorage” test to expect that runtime
exception while preserving the existing message assertion.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b273ef0f-b007-4cea-a877-831595787079

📥 Commits

Reviewing files that changed from the base of the PR and between 5297960 and 41dcbfb.

📒 Files selected for processing (11)
  • packages/gotrue/example/main.dart
  • packages/gotrue/lib/src/gotrue_client.dart
  • packages/gotrue/lib/src/types/gotrue_async_storage.dart
  • packages/gotrue/test/client_test.dart
  • packages/gotrue/test/header_isolation_test.dart
  • packages/gotrue/test/memory_async_storage_test.dart
  • packages/gotrue/test/utils.dart
  • packages/supabase/lib/src/supabase_client.dart
  • packages/supabase/lib/src/supabase_client_options.dart
  • packages/supabase/test/client_test.dart
  • sdk-compliance.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/gotrue/test/header_isolation_test.dart
  • packages/gotrue/lib/src/gotrue_client.dart

Comment thread packages/gotrue/test/client_test.dart
spydon added 2 commits August 5, 2026 17:41
isNotNull on a freshly constructed client can never fail, which DCM
flags as a misused test matcher.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves PKCE developer ergonomics in the Supabase Flutter SDK monorepo by validating (and/or supplying) the async storage required to persist PKCE code verifiers. It adds an in-memory GotrueAsyncStorage implementation and updates clients/tests to use it where appropriate.

Changes:

  • Added a GoTrueClient constructor assert for missing asyncStorage when flowType is PKCE, plus guidance in docs/examples.
  • Introduced MemoryGotrueAsyncStorage (in-memory PKCE verifier storage) and used it as a fallback in SupabaseClient when PKCE is enabled without a custom storage.
  • Updated/added tests to cover the new storage and to ensure PKCE flows work (or fail fast) under the new configuration rules.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
sdk-compliance.yaml Registers the new public MemoryGotrueAsyncStorage API symbols for compliance tracking.
packages/supabase/test/client_test.dart Adds a test asserting PKCE works without explicitly passing pkceAsyncStorage to SupabaseClient.
packages/supabase/lib/src/supabase_client.dart Falls back to MemoryGotrueAsyncStorage() when PKCE is used and no storage is provided.
packages/supabase/lib/src/supabase_client_options.dart Documents PKCE verifier storage behavior for AuthClientOptions.pkceAsyncStorage.
packages/gotrue/test/utils.dart Reworks TestAsyncStorage to reuse MemoryGotrueAsyncStorage.
packages/gotrue/test/src/gotrue_oauth_api_test.dart Supplies asyncStorage in OAuth API tests to satisfy PKCE requirements.
packages/gotrue/test/src/gotrue_mfa_api_test.dart Supplies asyncStorage in MFA API tests to satisfy PKCE requirements.
packages/gotrue/test/src/gotrue_admin_oauth_api_test.dart Supplies asyncStorage in admin OAuth API tests.
packages/gotrue/test/src/gotrue_admin_mfa_api_test.dart Supplies asyncStorage in admin MFA API tests.
packages/gotrue/test/src/gotrue_admin_custom_providers_api_test.dart Supplies asyncStorage in admin custom provider tests.
packages/gotrue/test/mfa_enroll_test.dart Supplies asyncStorage in MFA enroll test.
packages/gotrue/test/memory_async_storage_test.dart New unit tests covering MemoryGotrueAsyncStorage behavior.
packages/gotrue/test/header_isolation_test.dart Supplies asyncStorage in header isolation test.
packages/gotrue/test/client_test.dart Updates client tests for PKCE storage requirements and adds constructor-assert test.
packages/gotrue/test/admin_test.dart Supplies asyncStorage in admin test setup.
packages/gotrue/test/admin_delete_user_test.dart Supplies asyncStorage in delete-user admin test.
packages/gotrue/lib/src/types/gotrue_async_storage.dart Adds MemoryGotrueAsyncStorage implementation.
packages/gotrue/lib/src/gotrue_client.dart Adds constructor assert requiring asyncStorage for PKCE, with guidance in docs.
packages/gotrue/example/main.dart Updates example to pass MemoryGotrueAsyncStorage for PKCE flow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/gotrue/lib/src/gotrue_client.dart
Comment thread packages/supabase/lib/src/supabase_client_options.dart Outdated
@spydon
spydon requested a review from Vinzent03 August 6, 2026 08:45
spydon and others added 2 commits August 10, 2026 14:32
…age-constructor-1446

# Conflicts:
#	packages/gotrue/lib/src/gotrue_client.dart
#	packages/supabase/lib/src/supabase_client.dart
#	sdk-compliance.yaml
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@Vinzent03

Copy link
Copy Markdown
Collaborator

I'm not entirely sure we want to set a memory only storage option by default for the supabase package. I think this may hide issues developers may face of missing pkce values after a program restart or creating a new client. I would favor having no default, but still include the memory storage for the user to specify manually. This ensures they are more aware of that restriction. It also makes the new assert in the constructor basically redundant as it would only occur for users of the gotrue package only. I'm curious what you @spydon think of this.

If we keep it as the default it think it would make more sense to set the memory storage as the storage option in the gotrue package itself rather than in the supabase package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Assert asyncStorage is provided for PKCE flow in the GoTrue client constructor

4 participants