Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 0 additions & 215 deletions [email protected]

This file was deleted.

10 changes: 5 additions & 5 deletions Sources/Auth/AuthClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1393,7 +1393,7 @@ public actor AuthClient {
}

private func emitInitialSession(forToken token: ObservationToken) async {
#if EmitLocalSessionAsInitialSession
if configuration.emitLocalSessionAsInitialSession {
guard let currentSession else {
eventEmitter.emit(.initialSession, session: nil, token: token)
return
Expand All @@ -1407,7 +1407,7 @@ public actor AuthClient {
// No need to emit `tokenRefreshed` nor `signOut` event since the `refreshSession` does it already.
}
}
#else
} else {
let session = try? await session
eventEmitter.emit(.initialSession, session: session, token: token)

Expand All @@ -1417,16 +1417,16 @@ public actor AuthClient {
reportIssue(
"""
Initial session emitted after attempting to refresh the local stored session.
This is incorrect behavior and will be fixed in the next major release since its a breaking change.
For now, if you want to opt-in to the new behavior, add the trait `EmitLocalSessionAsInitialSession` to your Package.swift file when importing the Supabase dependency.
This is incorrect behavior and will be fixed in the next major release since it's a breaking change.
To opt-in to the new behavior now, set `emitLocalSessionAsInitialSession: true` in your AuthClient configuration.
The new behavior ensures that the locally stored session is always emitted, regardless of its validity or expiration.
If you rely on the initial session to opt users in, you need to add an additional check for `session.isExpired` in the session.

Check https://github.com/supabase/supabase-swift/pull/822 for more information.
"""
)
}
#endif
}
}

nonisolated private func prepareForPKCE() -> (
Expand Down
22 changes: 19 additions & 3 deletions Sources/Auth/AuthClientConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ extension AuthClient {
/// Set to `true` if you want to automatically refresh the token before expiring.
public let autoRefreshToken: Bool

/// When `true`, emits the locally stored session immediately as the initial session,
/// regardless of its validity or expiration. When `false`, emits the initial session
/// after attempting to refresh the local stored session (legacy behavior).
///
/// Default is `false` for backward compatibility. This will change to `true` in the next major release.
///
/// - Note: If you rely on the initial session to opt users in, you need to add an additional
/// check for `session.isExpired` when this is set to `true`.
public let emitLocalSessionAsInitialSession: Bool

/// Initializes a AuthClient Configuration with optional parameters.
///
/// - Parameters:
Expand All @@ -60,6 +70,7 @@ extension AuthClient {
/// - decoder: The JSON decoder to use for decoding responses.
/// - fetch: The asynchronous fetch handler for network requests.
/// - autoRefreshToken: Set to `true` if you want to automatically refresh the token before expiring.
/// - emitLocalSessionAsInitialSession: When `true`, emits the locally stored session immediately as the initial session.
public init(
url: URL? = nil,
headers: [String: String] = [:],
Expand All @@ -71,7 +82,8 @@ extension AuthClient {
encoder: JSONEncoder = AuthClient.Configuration.jsonEncoder,
decoder: JSONDecoder = AuthClient.Configuration.jsonDecoder,
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) },
autoRefreshToken: Bool = AuthClient.Configuration.defaultAutoRefreshToken
autoRefreshToken: Bool = AuthClient.Configuration.defaultAutoRefreshToken,
emitLocalSessionAsInitialSession: Bool = false
) {
let headers = headers.merging(Configuration.defaultHeaders) { l, _ in l }

Expand All @@ -86,6 +98,7 @@ extension AuthClient {
self.decoder = decoder
self.fetch = fetch
self.autoRefreshToken = autoRefreshToken
self.emitLocalSessionAsInitialSession = emitLocalSessionAsInitialSession
}
}

Expand All @@ -103,6 +116,7 @@ extension AuthClient {
/// - decoder: The JSON decoder to use for decoding responses.
/// - fetch: The asynchronous fetch handler for network requests.
/// - autoRefreshToken: Set to `true` if you want to automatically refresh the token before expiring.
/// - emitLocalSessionAsInitialSession: When `true`, emits the locally stored session immediately as the initial session.
public init(
url: URL? = nil,
headers: [String: String] = [:],
Expand All @@ -114,7 +128,8 @@ extension AuthClient {
encoder: JSONEncoder = AuthClient.Configuration.jsonEncoder,
decoder: JSONDecoder = AuthClient.Configuration.jsonDecoder,
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) },
autoRefreshToken: Bool = AuthClient.Configuration.defaultAutoRefreshToken
autoRefreshToken: Bool = AuthClient.Configuration.defaultAutoRefreshToken,
emitLocalSessionAsInitialSession: Bool = false
) {
self.init(
configuration: Configuration(
Expand All @@ -128,7 +143,8 @@ extension AuthClient {
encoder: encoder,
decoder: decoder,
fetch: fetch,
autoRefreshToken: autoRefreshToken
autoRefreshToken: autoRefreshToken,
emitLocalSessionAsInitialSession: emitLocalSessionAsInitialSession
)
)
}
Expand Down
3 changes: 2 additions & 1 deletion Sources/Supabase/SupabaseClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ public final class SupabaseClient: Sendable {
// DON'T use `fetchWithAuth` method within the AuthClient as it may cause a deadlock.
try await options.global.session.data(for: $0)
},
autoRefreshToken: options.auth.autoRefreshToken
autoRefreshToken: options.auth.autoRefreshToken,
emitLocalSessionAsInitialSession: options.auth.emitLocalSessionAsInitialSession
)

_realtime = UncheckedSendable(
Expand Down
11 changes: 11 additions & 0 deletions Sources/Supabase/Types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ public struct SupabaseClientOptions: Sendable {
/// Set to `true` if you want to automatically refresh the token before expiring.
public let autoRefreshToken: Bool

/// When `true`, emits the locally stored session immediately as the initial session,
/// regardless of its validity or expiration. When `false`, emits the initial session
/// after attempting to refresh the local stored session (legacy behavior).
///
/// Default is `false` for backward compatibility. This will change to `true` in the next major release.
public let emitLocalSessionAsInitialSession: Bool

/// 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.
Expand All @@ -71,6 +78,7 @@ public struct SupabaseClientOptions: Sendable {
encoder: JSONEncoder = AuthClient.Configuration.jsonEncoder,
decoder: JSONDecoder = AuthClient.Configuration.jsonDecoder,
autoRefreshToken: Bool = AuthClient.Configuration.defaultAutoRefreshToken,
emitLocalSessionAsInitialSession: Bool = false,
accessToken: (@Sendable () async throws -> String?)? = nil
) {
self.storage = storage
Expand All @@ -80,6 +88,7 @@ public struct SupabaseClientOptions: Sendable {
self.encoder = encoder
self.decoder = decoder
self.autoRefreshToken = autoRefreshToken
self.emitLocalSessionAsInitialSession = emitLocalSessionAsInitialSession
self.accessToken = accessToken
}
}
Expand Down Expand Up @@ -173,6 +182,7 @@ extension SupabaseClientOptions.AuthOptions {
encoder: JSONEncoder = AuthClient.Configuration.jsonEncoder,
decoder: JSONDecoder = AuthClient.Configuration.jsonDecoder,
autoRefreshToken: Bool = AuthClient.Configuration.defaultAutoRefreshToken,
emitLocalSessionAsInitialSession: Bool = false,
accessToken: (@Sendable () async throws -> String?)? = nil
) {
self.init(
Expand All @@ -183,6 +193,7 @@ extension SupabaseClientOptions.AuthOptions {
encoder: encoder,
decoder: decoder,
autoRefreshToken: autoRefreshToken,
emitLocalSessionAsInitialSession: emitLocalSessionAsInitialSession,
accessToken: accessToken
)
}
Expand Down
Loading
Loading