diff --git a/packages/gotrue/lib/src/gotrue_client.dart b/packages/gotrue/lib/src/gotrue_client.dart index 3baa3097..03df2bd3 100644 --- a/packages/gotrue/lib/src/gotrue_client.dart +++ b/packages/gotrue/lib/src/gotrue_client.dart @@ -29,9 +29,17 @@ part 'gotrue_mfa_api.dart'; /// /// [autoRefreshToken] whether to refresh the token automatically or not. Defaults to true. /// +/// [persistSession] whether to persist the session via [asyncStorage] or not. +/// Defaults to false. Session is only broadcasted via [BroadcastChannel] if +/// set to true. +/// /// [httpClient] custom http client. /// -/// [asyncStorage] local storage to store pkce code verifiers. Required when using the pkce flow. +/// [asyncStorage] local storage to store sessions and pkce code verifiers. +/// Required when using the pkce flow and persisting sessions. +/// +/// [storageKey] key to store the session with in [asyncStorage]. +/// The pkce code verifiers are suffixed with `-code-verifier` /// /// Set [flowType] to [AuthFlowType.implicit] to perform old implicit auth flow. /// {@endtemplate} diff --git a/packages/gotrue/lib/src/types/types.dart b/packages/gotrue/lib/src/types/types.dart index c1001433..abf300cc 100644 --- a/packages/gotrue/lib/src/types/types.dart +++ b/packages/gotrue/lib/src/types/types.dart @@ -1,3 +1,5 @@ +/// An interface to use [html.BroadcastChannel] on web to broadcast sessions to +/// other tabs. typedef BroadcastChannel = ({ Stream> onMessage, void Function(Map) postMessage, diff --git a/packages/supabase/lib/src/supabase_client.dart b/packages/supabase/lib/src/supabase_client.dart index 5382ec9e..6f2c7416 100644 --- a/packages/supabase/lib/src/supabase_client.dart +++ b/packages/supabase/lib/src/supabase_client.dart @@ -11,20 +11,19 @@ import 'auth_http_client.dart'; import 'counter.dart'; /// {@template supabase_client} +/// /// Creates a Supabase client to interact with your Supabase instance. /// /// [supabaseUrl] and [supabaseKey] can be found on your Supabase dashboard. /// -/// You can access none public schema by passing different [schema]. -/// /// Default headers can be overridden by specifying [headers]. /// /// Custom http client can be used by passing [httpClient] parameter. /// -/// [storageRetryAttempts] specifies how many retry attempts there should be to -/// upload a file to Supabase storage when failed due to network interruption. -/// -/// [realtimeClientOptions] specifies different options you can pass to `RealtimeClient`. +/// [realtimeClientOptions], [authOptions], [storageOptions], +/// [postgrestOptions] specify different options you can pass to +/// [RealtimeClient], [GoTrueClient], [SupabaseStorageClient], +/// [PostgrestClient]. /// /// [accessToken] Optional function for using a third-party authentication system with Supabase. /// The function should return an access token or ID token (JWT) by obtaining @@ -36,8 +35,6 @@ import 'counter.dart'; /// Pass an instance of `YAJsonIsolate` to [isolate] to use your own persisted /// isolate instance. A new instance will be created if [isolate] is omitted. /// -/// Pass an instance of [gotrueAsyncStorage] and set the [authFlowType] to -/// `AuthFlowType.pkce`in order to perform auth actions with pkce flow. /// {@endtemplate} class SupabaseClient { final String _supabaseKey; diff --git a/packages/supabase/lib/src/supabase_client_options.dart b/packages/supabase/lib/src/supabase_client_options.dart index fe326a4b..52b23db4 100644 --- a/packages/supabase/lib/src/supabase_client_options.dart +++ b/packages/supabase/lib/src/supabase_client_options.dart @@ -6,6 +6,28 @@ class PostgrestClientOptions { const PostgrestClientOptions({this.schema = 'public'}); } +/// {@template supabase_auth_client_options} +/// +/// Configuration for the auth client with appropriate default values when using +/// the `supabase` package. For usage via `supabase_flutter` use +/// [FlutterAuthClientOptions] instead +/// +/// [autoRefreshToken] whether to refresh the token automatically or not. Defaults to true. +/// +/// [asyncStorage] a storage interface to store sessions +/// (if [persistSession] is `true`) and pkce code verifiers +/// (if [authFlowType] is [AuthFlowType.pkce]), which is the default. +/// +/// [storageKey] key to store the session with in [asyncStorage]. +/// The pkce code verifiers are suffixed with `-code-verifier` +/// +/// [persistSession] whether to persist the session via [asyncStorage] or not. +/// Session is only broadcasted via [BroadcastChannel] if set to true. +/// +/// Set [authFlowType] to [AuthFlowType.implicit] to use the old implicit flow for authentication +/// involving deep links. +/// +/// {@endtemplate} class AuthClientOptions { final bool autoRefreshToken; @@ -13,22 +35,28 @@ class AuthClientOptions { "The storage for the session is now handled by the auth client itself and is combined with the storage for pkce, so please use [asyncStorage] insetad") final GotrueAsyncStorage? pkceAsyncStorage; final GotrueAsyncStorage? asyncStorage; + final AuthFlowType authFlowType; + final String? storageKey; - final bool? persistSession; + final bool persistSession; + /// {@macro supabase_auth_client_options} const AuthClientOptions({ this.autoRefreshToken = true, this.pkceAsyncStorage, this.asyncStorage, this.authFlowType = AuthFlowType.pkce, this.storageKey, - this.persistSession, + this.persistSession = false, }); } class StorageClientOptions { final int retryAttempts; + /// [retryAttempts] specifies how many retry attempts there should be + /// to upload a file to Supabase storage when failed due to network + /// interruption. const StorageClientOptions({this.retryAttempts = 0}); } diff --git a/packages/supabase_flutter/lib/src/flutter_go_true_client_options.dart b/packages/supabase_flutter/lib/src/flutter_go_true_client_options.dart index e82db799..72e29c3b 100644 --- a/packages/supabase_flutter/lib/src/flutter_go_true_client_options.dart +++ b/packages/supabase_flutter/lib/src/flutter_go_true_client_options.dart @@ -1,21 +1,44 @@ import 'package:supabase_flutter/supabase_flutter.dart'; +/// {@template supabase_flutter_auth_client_options} +/// +/// [autoRefreshToken] whether to refresh the token automatically or not. Defaults to true. +/// +/// [asyncStorage] a storage interface to store sessions +/// (if [persistSession] is `true`) and pkce code verifiers +/// (if [authFlowType] is [AuthFlowType.pkce]) +/// +/// [storageKey] key to store the session with in [asyncStorage]. +/// The pkce code verifiers are suffixed with `-code-verifier` +/// +/// [persistSession] whether to persist the session via [asyncStorage] or not. +/// Session is only broadcasted via [BroadcastChannel] if set to true. +/// +/// Set [authFlowType] to [AuthFlowType.implicit] to use the old implicit flow for authentication +/// involving deep links. +/// +/// [detectSessionInUri] If true, the client will start the deep link observer and obtain sessions +/// when a valid URI is detected. +/// +/// PKCE flow uses shared preferences for storing the code verifier by default. +/// Pass a custom storage to [asyncStorage] to override the behavior. +/// +/// {@endtemplate} class FlutterAuthClientOptions extends AuthClientOptions { @Deprecated( "The storage for the session is now handled by the auth client itself and is combined with the storage for pkce, so please use [asyncStorage] insetad") final LocalStorage? localStorage; - /// If true, the client will start the deep link observer and obtain sessions - /// when a valid URI is detected. final bool detectSessionInUri; + /// {@macro supabase_flutter_auth_client_options} const FlutterAuthClientOptions({ super.authFlowType, super.autoRefreshToken, super.pkceAsyncStorage, super.asyncStorage, super.storageKey, - super.persistSession, + super.persistSession = true, this.localStorage, this.detectSessionInUri = true, }); diff --git a/packages/supabase_flutter/lib/src/supabase.dart b/packages/supabase_flutter/lib/src/supabase.dart index 77e5d389..c7b58b96 100644 --- a/packages/supabase_flutter/lib/src/supabase.dart +++ b/packages/supabase_flutter/lib/src/supabase.dart @@ -48,28 +48,26 @@ class Supabase with WidgetsBindingObserver { /// Initialize the current supabase instance /// /// This must be called only once. If called more than once, an - /// [AssertionError] is thrown + /// [AssertionError] is thrown. + /// (after calling [dispose], [initialize] can be called again) /// /// [url] and [anonKey] can be found on your Supabase dashboard. /// - /// You can access none public schema by passing different [schema]. - /// /// Default headers can be overridden by specifying [headers]. /// - /// Pass [localStorage] to override the default local storage option used to - /// persist auth. - /// /// Custom http client can be used by passing [httpClient] parameter. /// - /// [storageRetryAttempts] specifies how many retry attempts there should be - /// to upload a file to Supabase storage when failed due to network - /// interruption. - /// - /// Set [authFlowType] to [AuthFlowType.implicit] to use the old implicit flow for authentication - /// involving deep links. + /// [realtimeClientOptions], [authOptions], [storageOptions], + /// [postgrestOptions] specify different options you can pass to + /// [RealtimeClient], [GoTrueClient], [SupabaseStorageClient], + /// [PostgrestClient]. /// - /// PKCE flow uses shared preferences for storing the code verifier by default. - /// Pass a custom storage to [pkceAsyncStorage] to override the behavior. + /// [accessToken] Optional function for using a third-party authentication system with Supabase. + /// The function should return an access token or ID token (JWT) by obtaining + /// it from the third-party auth client library. Note that this function may be + /// called concurrently and many times. Use memoization and locking techniques + /// if this is not supported by the client libraries. When set, the `auth` + /// namespace of the Supabase client cannot be used. /// /// If [debug] is set to `true`, debug logs will be printed in debug console. Default is `kDebugMode`. static Future initialize({ @@ -119,11 +117,6 @@ class Supabase with WidgetsBindingObserver { ), ); } - if (authOptions.persistSession == null) { - authOptions = authOptions.copyWith( - persistSession: true, - ); - } if (authOptions.asyncStorage == null) { authOptions = authOptions.copyWith(