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
148 changes: 83 additions & 65 deletions Sources/Auth/AuthClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
import WatchKit
#endif

#if canImport(ObjectiveC) && canImport(Combine)
import Combine
#endif

typealias AuthClientID = Int

struct AuthClientLoggerDecorator: SupabaseLogger {
Expand All @@ -27,21 +31,28 @@
}
}

public final class AuthClient: Sendable {
static let globalClientID = LockIsolated(0)
let clientID: AuthClientID
public actor AuthClient {
static var globalClientID = 0
nonisolated let clientID: AuthClientID

private var api: APIClient { Dependencies[clientID].api }
var configuration: AuthClient.Configuration { Dependencies[clientID].configuration }
private var codeVerifierStorage: CodeVerifierStorage {
nonisolated private var api: APIClient { Dependencies[clientID].api }

nonisolated var configuration: AuthClient.Configuration { Dependencies[clientID].configuration }

nonisolated private var codeVerifierStorage: CodeVerifierStorage {
Dependencies[clientID].codeVerifierStorage
}
private var date: @Sendable () -> Date { Dependencies[clientID].date }
private var sessionManager: SessionManager { Dependencies[clientID].sessionManager }
private var eventEmitter: AuthStateChangeEventEmitter { Dependencies[clientID].eventEmitter }
private var logger: (any SupabaseLogger)? { Dependencies[clientID].configuration.logger }
private var sessionStorage: SessionStorage { Dependencies[clientID].sessionStorage }
private var pkce: PKCE { Dependencies[clientID].pkce }

nonisolated private var date: @Sendable () -> Date { Dependencies[clientID].date }
nonisolated private var sessionManager: SessionManager { Dependencies[clientID].sessionManager }
nonisolated private var eventEmitter: AuthStateChangeEventEmitter {
Dependencies[clientID].eventEmitter
}
nonisolated private var logger: (any SupabaseLogger)? {
Dependencies[clientID].configuration.logger
}
nonisolated private var sessionStorage: SessionStorage { Dependencies[clientID].sessionStorage }
nonisolated private var pkce: PKCE { Dependencies[clientID].pkce }

/// Returns the session, refreshing it if necessary.
///
Expand All @@ -55,26 +66,26 @@
/// Returns the current session, if any.
///
/// The session returned by this property may be expired. Use ``session`` for a session that is guaranteed to be valid.
public var currentSession: Session? {
nonisolated public var currentSession: Session? {
sessionStorage.get()
}

/// Returns the current user, if any.
///
/// The user returned by this property may be outdated. Use ``user(jwt:)`` method to get an up-to-date user instance.
public var currentUser: User? {
nonisolated public var currentUser: User? {
currentSession?.user
}

/// Namespace for accessing multi-factor authentication API.
public var mfa: AuthMFA {
nonisolated public var mfa: AuthMFA {
AuthMFA(clientID: clientID)
}

/// Namespace for the GoTrue admin methods.
/// - Warning: This methods requires `service_role` key, be careful to never expose `service_role`
/// key in the client.
public var admin: AuthAdmin {
nonisolated public var admin: AuthAdmin {
AuthAdmin(clientID: clientID)
}

Expand All @@ -83,10 +94,8 @@
/// - Parameters:
/// - configuration: The client configuration.
public init(configuration: Configuration) {
clientID = AuthClient.globalClientID.withValue {
$0 += 1
return $0
}
AuthClient.globalClientID += 1

Check warning on line 97 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, TVOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 97 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, TVOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 97 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, VISIONOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 97 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, VISIONOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 97 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MACOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 97 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MACOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 97 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, IOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 97 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MAC_CATALYST, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 97 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, IOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 97 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MAC_CATALYST, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6
clientID = AuthClient.globalClientID

Check warning on line 98 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, TVOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 98 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, TVOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 98 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, VISIONOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 98 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, VISIONOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 98 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MACOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 98 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MACOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 98 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, IOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 98 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MAC_CATALYST, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 98 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, IOS, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Check warning on line 98 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MAC_CATALYST, 15.4)

reference to static property 'globalClientID' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6

Dependencies[clientID] = Dependencies(
configuration: configuration,
Expand All @@ -96,70 +105,76 @@
sessionStorage: .live(clientID: clientID),
sessionManager: .live(clientID: clientID),
logger: configuration.logger.map {
AuthClientLoggerDecorator(clientID: clientID, decoratee: $0)

Check warning on line 108 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, TVOS, 15.4)

nonisolated property 'clientID' can not be referenced from a non-isolated context; this is an error in Swift 6

Check warning on line 108 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, TVOS, 15.4)

nonisolated property 'clientID' can not be referenced from a non-isolated context; this is an error in Swift 6

Check warning on line 108 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, VISIONOS, 15.4)

nonisolated property 'clientID' can not be referenced from a non-isolated context; this is an error in Swift 6

Check warning on line 108 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, VISIONOS, 15.4)

nonisolated property 'clientID' can not be referenced from a non-isolated context; this is an error in Swift 6

Check warning on line 108 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MACOS, 15.4)

nonisolated property 'clientID' can not be referenced from a non-isolated context; this is an error in Swift 6

Check warning on line 108 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MACOS, 15.4)

nonisolated property 'clientID' can not be referenced from a non-isolated context; this is an error in Swift 6

Check warning on line 108 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, IOS, 15.4)

nonisolated property 'clientID' can not be referenced from a non-isolated context; this is an error in Swift 6

Check warning on line 108 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MAC_CATALYST, 15.4)

nonisolated property 'clientID' can not be referenced from a non-isolated context; this is an error in Swift 6

Check warning on line 108 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, IOS, 15.4)

nonisolated property 'clientID' can not be referenced from a non-isolated context; this is an error in Swift 6

Check warning on line 108 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MAC_CATALYST, 15.4)

nonisolated property 'clientID' can not be referenced from a non-isolated context; this is an error in Swift 6
}
)

Task { @MainActor in observeAppLifecycleChanges() }
}

#if canImport(ObjectiveC)
#if canImport(ObjectiveC) && canImport(Combine)
@MainActor
private func observeAppLifecycleChanges() {
var didBecomeActiveNotification: NSNotification.Name?
var willResignActiveNotification: NSNotification.Name?

#if canImport(UIKit)
#if canImport(WatchKit)
if #available(watchOS 7.0, *) {
NotificationCenter.default.addObserver(
self,
selector: #selector(handleDidBecomeActive),
name: WKExtension.applicationDidBecomeActiveNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleWillResignActive),
name: WKExtension.applicationWillResignActiveNotification,
object: nil
)
didBecomeActiveNotification = WKExtension.applicationDidBecomeActiveNotification
willResignActiveNotification = WKExtension.applicationWillResignActiveNotification
}
#else
NotificationCenter.default.addObserver(
self,
selector: #selector(handleDidBecomeActive),
name: UIApplication.didBecomeActiveNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleWillResignActive),
name: UIApplication.willResignActiveNotification,
object: nil
)
didBecomeActiveNotification = UIApplication.didBecomeActiveNotification
willResignActiveNotification = UIApplication.willResignActiveNotification
#endif
#elseif canImport(AppKit)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleDidBecomeActive),
name: NSApplication.didBecomeActiveNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleWillResignActive),
name: NSApplication.willResignActiveNotification,
object: nil
)
didBecomeActiveNotification = NSApplication.didBecomeActiveNotification
willResignActiveNotification = NSApplication.willResignActiveNotification
#endif

if let didBecomeActiveNotification, let willResignActiveNotification {
var cancellables = Set<AnyCancellable>()

NotificationCenter.default
.publisher(for: didBecomeActiveNotification)
.sink(
receiveCompletion: { _ in
// hold ref to cancellable until it completes
_ = cancellables
},
receiveValue: { [weak self] _ in
Task {
await self?.handleDidBecomeActive()
}
}
)
.store(in: &cancellables)

NotificationCenter.default
.publisher(for: willResignActiveNotification)
.sink(
receiveCompletion: { _ in
// hold ref to cancellable until it completes
_ = cancellables
},
receiveValue: { [weak self] _ in
Task {
await self?.handleWillResignActive()
}
}
)
.store(in: &cancellables)
}

}

@objc
private func handleDidBecomeActive() {
if configuration.autoRefreshToken {
startAutoRefresh()
}
}

@objc
private func handleWillResignActive() {
if configuration.autoRefreshToken {
stopAutoRefresh()
Expand All @@ -170,6 +185,7 @@
// no-op
}
#endif

/// Listen for auth state changes.
/// - Parameter listener: Block that executes when a new event is emitted.
/// - Returns: A handle that can be used to manually unsubscribe.
Expand All @@ -189,7 +205,7 @@
/// Listen for auth state changes.
///
/// An `.initialSession` is always emitted when this method is called.
public var authStateChanges:
nonisolated public var authStateChanges:
AsyncStream<
(
event: AuthChangeEvent,
Expand Down Expand Up @@ -323,7 +339,7 @@
method: .post,
query: [URLQueryItem(name: "grant_type", value: "password")],
body: configuration.encoder.encode(
UserCredentials(

Check warning on line 342 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, TVOS, 15.4)

'UserCredentials' is deprecated: Access to UserCredentials will be removed on the next major release.
email: email,
password: password,
gotrueMetaSecurity: captchaToken.map(AuthMetaSecurity.init(captchaToken:))
Expand All @@ -350,7 +366,7 @@
method: .post,
query: [URLQueryItem(name: "grant_type", value: "password")],
body: configuration.encoder.encode(
UserCredentials(

Check warning on line 369 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, TVOS, 15.4)

'UserCredentials' is deprecated: Access to UserCredentials will be removed on the next major release.
password: password,
phone: phone,
gotrueMetaSecurity: captchaToken.map(AuthMetaSecurity.init(captchaToken:))
Expand Down Expand Up @@ -597,7 +613,7 @@
/// If that isn't the case, you should consider using
/// ``signInWithOAuth(provider:redirectTo:scopes:queryParams:launchFlow:)`` or
/// ``signInWithOAuth(provider:redirectTo:scopes:queryParams:configure:)``.
public func getOAuthSignInURL(
nonisolated public func getOAuthSignInURL(
provider: Provider,
scopes: String? = nil,
redirectTo: URL? = nil,
Expand Down Expand Up @@ -672,7 +688,7 @@
scopes: scopes,
queryParams: queryParams
) { @MainActor url in
try await withCheckedThrowingContinuation { continuation in
try await withCheckedThrowingContinuation { [configuration] continuation in
guard let callbackScheme = (configuration.redirectToURL ?? redirectTo)?.scheme else {
preconditionFailure(
"Please, provide a valid redirect URL, either thorugh `redirectTo` param, or globally thorugh `AuthClient.Configuration.redirectToURL`."
Expand Down Expand Up @@ -767,7 +783,7 @@
/// supabase.auth.handle(url)
/// }
/// ```
public func handle(_ url: URL) {
nonisolated public func handle(_ url: URL) {
Task {
do {
try await session(from: url)
Expand Down Expand Up @@ -1326,7 +1342,9 @@
eventEmitter.emit(.initialSession, session: session, token: token)
}

private func prepareForPKCE() -> (codeChallenge: String?, codeChallengeMethod: String?) {
nonisolated private func prepareForPKCE() -> (
codeChallenge: String?, codeChallengeMethod: String?
) {
guard configuration.flowType == .pkce else {
return (nil, nil)
}
Expand All @@ -1350,7 +1368,7 @@
|| params["error_code"] != nil && currentCodeVerifier != nil
}

private func getURLForProvider(
nonisolated private func getURLForProvider(
url: URL,
provider: Provider,
scopes: String? = nil,
Expand Down Expand Up @@ -1424,7 +1442,7 @@
final class DefaultPresentationContextProvider: NSObject,
ASWebAuthenticationPresentationContextProviding
{
func presentationAnchor(for _: ASWebAuthenticationSession) -> ASPresentationAnchor {

Check warning on line 1445 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, VISIONOS, 15.4)

main actor-isolated instance method 'presentationAnchor(for:)' cannot be used to satisfy nonisolated protocol requirement

Check warning on line 1445 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, VISIONOS, 15.4)

main actor-isolated instance method 'presentationAnchor(for:)' cannot be used to satisfy nonisolated protocol requirement

Check warning on line 1445 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MACOS, 15.4)

main actor-isolated instance method 'presentationAnchor(for:)' cannot be used to satisfy nonisolated protocol requirement

Check warning on line 1445 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MACOS, 15.4)

main actor-isolated instance method 'presentationAnchor(for:)' cannot be used to satisfy nonisolated protocol requirement

Check warning on line 1445 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, IOS, 15.4)

main actor-isolated instance method 'presentationAnchor(for:)' cannot be used to satisfy nonisolated protocol requirement

Check warning on line 1445 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MAC_CATALYST, 15.4)

main actor-isolated instance method 'presentationAnchor(for:)' cannot be used to satisfy nonisolated protocol requirement

Check warning on line 1445 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, IOS, 15.4)

main actor-isolated instance method 'presentationAnchor(for:)' cannot be used to satisfy nonisolated protocol requirement

Check warning on line 1445 in Sources/Auth/AuthClient.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15) (test, MAC_CATALYST, 15.4)

main actor-isolated instance method 'presentationAnchor(for:)' cannot be used to satisfy nonisolated protocol requirement
ASPresentationAnchor()
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Auth/AuthClientConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,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.
public convenience init(
public init(
url: URL? = nil,
headers: [String: String] = [:],
flowType: AuthFlowType = AuthClient.Configuration.defaultFlowType,
Expand Down
2 changes: 1 addition & 1 deletion Sources/Auth/Deprecated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ extension AuthClient {
deprecated,
message: "Replace usages of this initializer with new init(url:headers:flowType:localStorage:logger:encoder:decoder:fetch)"
)
public convenience init(
public init(
url: URL,
headers: [String: String] = [:],
flowType: AuthFlowType = Configuration.defaultFlowType,
Expand Down
Loading