11import _Helpers
2+ import ConcurrencyExtras
23import Foundation
34
45#if canImport(AuthenticationServices)
@@ -9,81 +10,13 @@ import Foundation
910 import FoundationNetworking
1011#endif
1112
12- public final class AuthClient : @unchecked Sendable {
13- /// FetchHandler is a type alias for asynchronous network request handling.
14- public typealias FetchHandler = @Sendable (
15- _ request: URLRequest
16- ) async throws -> ( Data , URLResponse )
17-
18- /// Configuration struct represents the client configuration.
19- public struct Configuration : Sendable {
20- public let url : URL
21- public var headers : [ String : String ]
22- public let flowType : AuthFlowType
23- public let redirectToURL : URL ?
24- public let localStorage : any AuthLocalStorage
25- public let logger : ( any SupabaseLogger ) ?
26- public let encoder : JSONEncoder
27- public let decoder : JSONDecoder
28- public let fetch : FetchHandler
29-
30- /// Initializes a AuthClient Configuration with optional parameters.
31- ///
32- /// - Parameters:
33- /// - url: The base URL of the Auth server.
34- /// - headers: Custom headers to be included in requests.
35- /// - flowType: The authentication flow type.
36- /// - redirectToURL: Default URL to be used for redirect on the flows that requires it.
37- /// - localStorage: The storage mechanism for local data.
38- /// - logger: The logger to use.
39- /// - encoder: The JSON encoder to use for encoding requests.
40- /// - decoder: The JSON decoder to use for decoding responses.
41- /// - fetch: The asynchronous fetch handler for network requests.
42- public init (
43- url: URL ,
44- headers: [ String : String ] = [ : ] ,
45- flowType: AuthFlowType = Configuration . defaultFlowType,
46- redirectToURL: URL ? = nil ,
47- localStorage: any AuthLocalStorage ,
48- logger: ( any SupabaseLogger ) ? = nil ,
49- encoder: JSONEncoder = AuthClient . Configuration. jsonEncoder,
50- decoder: JSONDecoder = AuthClient . Configuration. jsonDecoder,
51- fetch: @escaping FetchHandler = { try await URLSession . shared. data ( for: $0) }
52- ) {
53- let headers = headers. merging ( Configuration . defaultHeaders) { l, _ in l }
54-
55- self . url = url
56- self . headers = headers
57- self . flowType = flowType
58- self . redirectToURL = redirectToURL
59- self . localStorage = localStorage
60- self . logger = logger
61- self . encoder = encoder
62- self . decoder = decoder
63- self . fetch = fetch
64- }
65- }
66-
67- @Dependency ( \. configuration)
68- private var configuration : Configuration
69-
70- @Dependency ( \. api)
71- private var api : APIClient
72-
73- @Dependency ( \. eventEmitter)
74- private var eventEmitter : EventEmitter
75-
76- @Dependency ( \. sessionManager)
77- private var sessionManager : SessionManager
78-
79- @Dependency ( \. codeVerifierStorage)
80- private var codeVerifierStorage : CodeVerifierStorage
81-
82- @Dependency ( \. currentDate)
83- private var currentDate : @Sendable ( ) -> Date
84-
85- @Dependency ( \. logger)
86- private var logger : ( any SupabaseLogger ) ?
13+ public final class AuthClient : Sendable {
14+ private var api : APIClient { Current . api }
15+ private var configuration : AuthClient . Configuration { Current . configuration }
16+ private var codeVerifierStorage : CodeVerifierStorage { Current . codeVerifierStorage }
17+ private var date : @Sendable ( ) -> Date { Current . date }
18+ private var sessionManager : SessionManager { Current . sessionManager }
19+ private var eventEmitter : AuthStateChangeEventEmitter { Current . eventEmitter }
8720
8821 /// Returns the session, refreshing it if necessary.
8922 ///
@@ -95,101 +28,22 @@ public final class AuthClient: @unchecked Sendable {
9528 }
9629
9730 /// Namespace for accessing multi-factor authentication API.
98- public let mfa : AuthMFA
99-
31+ public let mfa = AuthMFA ( )
10032 /// Namespace for the GoTrue admin methods.
10133 /// - Warning: This methods requires `service_role` key, be careful to never expose `service_role`
10234 /// key in the client.
103- public let admin : AuthAdmin
104-
105- /// Initializes a AuthClient with optional parameters.
106- ///
107- /// - Parameters:
108- /// - url: The base URL of the Auth server.
109- /// - headers: Custom headers to be included in requests.
110- /// - flowType: The authentication flow type..
111- /// - redirectToURL: Default URL to be used for redirect on the flows that requires it.
112- /// - localStorage: The storage mechanism for local data..
113- /// - logger: The logger to use.
114- /// - encoder: The JSON encoder to use for encoding requests.
115- /// - decoder: The JSON decoder to use for decoding responses.
116- /// - fetch: The asynchronous fetch handler for network requests.
117- public convenience init (
118- url: URL ,
119- headers: [ String : String ] = [ : ] ,
120- flowType: AuthFlowType = AuthClient . Configuration. defaultFlowType,
121- redirectToURL: URL ? = nil ,
122- localStorage: any AuthLocalStorage ,
123- logger: ( any SupabaseLogger ) ? = nil ,
124- encoder: JSONEncoder = AuthClient . Configuration. jsonEncoder,
125- decoder: JSONDecoder = AuthClient . Configuration. jsonDecoder,
126- fetch: @escaping FetchHandler = { try await URLSession . shared. data ( for: $0) }
127- ) {
128- self . init (
129- configuration: Configuration (
130- url: url,
131- headers: headers,
132- flowType: flowType,
133- redirectToURL: redirectToURL,
134- localStorage: localStorage,
135- logger: logger,
136- encoder: encoder,
137- decoder: decoder,
138- fetch: fetch
139- )
140- )
141- }
35+ public let admin = AuthAdmin ( )
14236
14337 /// Initializes a AuthClient with a specific configuration.
14438 ///
14539 /// - Parameters:
14640 /// - configuration: The client configuration.
147- public convenience init ( configuration: Configuration ) {
148- let api = APIClient . live (
149- configuration: configuration,
150- http: HTTPClient (
151- logger: configuration. logger,
152- fetchHandler: configuration. fetch
153- )
154- )
155-
156- self . init (
157- configuration: configuration,
158- sessionManager: . live,
159- codeVerifierStorage: . live,
160- api: api,
161- eventEmitter: . live,
162- sessionStorage: . live,
163- logger: configuration. logger
164- )
165- }
166-
167- /// This internal initializer is here only for easy injecting mock instances when testing.
168- init (
169- configuration: Configuration ,
170- sessionManager: SessionManager ,
171- codeVerifierStorage: CodeVerifierStorage ,
172- api: APIClient ,
173- eventEmitter: EventEmitter ,
174- sessionStorage: SessionStorage ,
175- logger: ( any SupabaseLogger ) ?
176- ) {
177- mfa = AuthMFA ( )
178- admin = AuthAdmin ( )
179-
41+ public init ( configuration: Configuration ) {
18042 Current = Dependencies (
18143 configuration: configuration,
182- sessionManager: sessionManager,
183- api: api,
184- eventEmitter: eventEmitter,
185- sessionStorage: sessionStorage,
186- sessionRefresher: SessionRefresher (
187- refreshSession: { [ weak self] in
188- try await self ? . refreshSession ( refreshToken: $0) ?? . empty
189- }
190- ) ,
191- codeVerifierStorage: codeVerifierStorage,
192- logger: logger
44+ sessionRefresher: SessionRefresher { [ weak self] in
45+ try await self ? . refreshSession ( refreshToken: $0) ?? . empty
46+ }
19347 )
19448 }
19549
@@ -204,7 +58,7 @@ public final class AuthClient: @unchecked Sendable {
20458 public func onAuthStateChange(
20559 _ listener: @escaping AuthStateChangeListener
20660 ) async -> some AuthStateChangeListenerRegistration {
207- let token = eventEmitter. attachListener ( listener)
61+ let token = eventEmitter. attach ( listener)
20862 await emitInitialSession ( forToken: token)
20963 return token
21064 }
@@ -782,7 +636,7 @@ public final class AuthClient: @unchecked Sendable {
782636 accessToken: accessToken,
783637 tokenType: tokenType,
784638 expiresIn: expiresIn,
785- expiresAt: expiresAt ?? currentDate ( ) . addingTimeInterval ( expiresIn) . timeIntervalSince1970,
639+ expiresAt: expiresAt ?? date ( ) . addingTimeInterval ( expiresIn) . timeIntervalSince1970,
786640 refreshToken: refreshToken,
787641 user: user
788642 )
@@ -808,7 +662,7 @@ public final class AuthClient: @unchecked Sendable {
808662 /// - Returns: A new valid session.
809663 @discardableResult
810664 public func setSession( accessToken: String , refreshToken: String ) async throws -> Session {
811- let now = currentDate ( )
665+ let now = date ( )
812666 var expiresAt = now
813667 var hasExpired = true
814668 var session : Session
@@ -1187,7 +1041,7 @@ public final class AuthClient: @unchecked Sendable {
11871041
11881042 private func emitInitialSession( forToken token: ObservationToken ) async {
11891043 let session = try ? await session
1190- eventEmitter. emit ( . initialSession, session, token)
1044+ eventEmitter. emit ( . initialSession, session: session , token : token)
11911045 }
11921046
11931047 private func prepareForPKCE( ) -> ( codeChallenge: String ? , codeChallengeMethod: String ? ) {
0 commit comments