Skip to content

Commit

Permalink
Move request executor to APIClient actor
Browse files Browse the repository at this point in the history
  • Loading branch information
grdsdev committed Oct 26, 2023
1 parent 8ba922a commit d60e8f2
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 42 deletions.
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.9
// swift-tools-version:5.8
// The swift-tools-version declares the minimum version of Swift required to build this package.

import Foundation
Expand Down
55 changes: 14 additions & 41 deletions Sources/GoTrue/GoTrueClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public actor GoTrueClient {
}

private let configuration: Configuration
private let api: APIClient
private let sessionManager: SessionManager
private let codeVerifierStorage: CodeVerifierStorage

Expand Down Expand Up @@ -114,6 +115,7 @@ public actor GoTrueClient {
var configuration = configuration
configuration.headers["X-Client-Info"] = "gotrue-swift/\(version)"
self.configuration = configuration
self.api = APIClient(configuration: configuration, sessionManager: sessionManager)
self.sessionManager = sessionManager
self.codeVerifierStorage = codeVerifierStorage
}
Expand Down Expand Up @@ -238,7 +240,7 @@ public actor GoTrueClient {

private func _signUp(request: Request) async throws -> AuthResponse {
await sessionManager.remove()
let response = try await execute(request).decoded(
let response = try await api.execute(request).decoded(
as: AuthResponse.self,
decoder: configuration.decoder
)
Expand Down Expand Up @@ -298,7 +300,7 @@ public actor GoTrueClient {
private func _signIn(request: Request) async throws -> Session {
await sessionManager.remove()

let session = try await execute(request).decoded(
let session = try await api.execute(request).decoded(
as: Session.self,
decoder: configuration.decoder
)
Expand Down Expand Up @@ -333,7 +335,7 @@ public actor GoTrueClient {

let (codeChallenge, codeChallengeMethod) = prepareForPKCE()

try await execute(
try await api.execute(
.init(
path: "/otp",
method: "POST",
Expand Down Expand Up @@ -368,7 +370,7 @@ public actor GoTrueClient {
captchaToken: String? = nil
) async throws {
await sessionManager.remove()
try await execute(
try await api.execute(
.init(
path: "/otp",
method: "POST",
Expand All @@ -390,7 +392,7 @@ public actor GoTrueClient {
throw GoTrueError.pkce(.codeVerifierNotFound)
}
do {
let session: Session = try await execute(
let session: Session = try await api.execute(
.init(
path: "/token",
method: "POST",
Expand Down Expand Up @@ -492,7 +494,7 @@ public actor GoTrueClient {
let providerToken = params.first(where: { $0.name == "provider_token" })?.value
let providerRefreshToken = params.first(where: { $0.name == "provider_refresh_token" })?.value

let user = try await execute(
let user = try await api.execute(
.init(
path: "/user",
method: "GET",
Expand Down Expand Up @@ -547,7 +549,7 @@ public actor GoTrueClient {
if hasExpired {
session = try await refreshSession(refreshToken: refreshToken)
} else {
let user = try await authorizedExecute(.init(path: "/user", method: "GET"))
let user = try await api.authorizedExecute(.init(path: "/user", method: "GET"))
.decoded(as: User.self, decoder: configuration.decoder)
session = Session(
accessToken: accessToken,
Expand All @@ -571,7 +573,7 @@ public actor GoTrueClient {
public func signOut() async throws {
do {
_ = try await sessionManager.session()
try await authorizedExecute(
try await api.authorizedExecute(
.init(
path: "/logout",
method: "POST"
Expand Down Expand Up @@ -640,7 +642,7 @@ public actor GoTrueClient {
private func _verifyOTP(request: Request) async throws -> AuthResponse {
await sessionManager.remove()

let response = try await execute(request).decoded(
let response = try await api.execute(request).decoded(
as: AuthResponse.self,
decoder: configuration.decoder
)
Expand All @@ -665,7 +667,7 @@ public actor GoTrueClient {
}

var session = try await sessionManager.session()
let updatedUser = try await authorizedExecute(
let updatedUser = try await api.authorizedExecute(
.init(path: "/user", method: "PUT", body: configuration.encoder.encode(user))
).decoded(as: User.self, decoder: configuration.decoder)
session.user = updatedUser
Expand All @@ -680,7 +682,7 @@ public actor GoTrueClient {
redirectTo: URL? = nil,
captchaToken: String? = nil
) async throws {
try await execute(
try await api.execute(
.init(
path: "/recover",
method: "POST",
Expand All @@ -697,35 +699,6 @@ public actor GoTrueClient {
)
}

@discardableResult
private func authorizedExecute(_ request: Request) async throws -> Response {
let session = try await sessionManager.session()

var request = request
request.headers["Authorization"] = "Bearer \(session.accessToken)"

return try await execute(request)
}

@discardableResult
private func execute(_ request: Request) async throws -> Response {
var request = request
request.headers.merge(configuration.headers) { r, _ in r }
let urlRequest = try request.urlRequest(withBaseURL: configuration.url)

let (data, response) = try await configuration.fetch(urlRequest)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}

guard (200..<300).contains(httpResponse.statusCode) else {
let apiError = try configuration.decoder.decode(GoTrueError.APIError.self, from: data)
throw GoTrueError.api(apiError)
}

return Response(data: data, response: httpResponse)
}

private func emitAuthChangeEvent(_ event: AuthChangeEvent) async {
_debug("start")
defer { _debug("end") }
Expand Down Expand Up @@ -775,7 +748,7 @@ extension GoTrueClient: SessionRefresher {
@discardableResult
public func refreshSession(refreshToken: String) async throws -> Session {
do {
let session = try await execute(
let session = try await api.execute(
.init(
path: "/token",
method: "POST",
Expand Down
42 changes: 42 additions & 0 deletions Sources/GoTrue/Internal/APIClient.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Foundation
@_spi(Internal) import _Helpers

actor APIClient {

private let configuration: GoTrueClient.Configuration
private let sessionManager: SessionManager

init(configuration: GoTrueClient.Configuration, sessionManager: SessionManager) {
self.configuration = configuration
self.sessionManager = sessionManager
}

@discardableResult
func authorizedExecute(_ request: Request) async throws -> Response {
let session = try await sessionManager.session()

var request = request
request.headers["Authorization"] = "Bearer \(session.accessToken)"

return try await execute(request)
}

@discardableResult
func execute(_ request: Request) async throws -> Response {
var request = request
request.headers.merge(configuration.headers) { r, _ in r }
let urlRequest = try request.urlRequest(withBaseURL: configuration.url)

let (data, response) = try await configuration.fetch(urlRequest)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}

guard (200..<300).contains(httpResponse.statusCode) else {
let apiError = try configuration.decoder.decode(GoTrueError.APIError.self, from: data)
throw GoTrueError.api(apiError)
}

return Response(data: data, response: httpResponse)
}
}

0 comments on commit d60e8f2

Please sign in to comment.