Skip to content

Commit 036c03d

Browse files
authored
feat: prepare for v2 release (#187)
* feat: use nil as default value for configuration params * feat: rename GoTrue to Auth * Deprecate access to default JSONEncoder and JSONDecoder * Refactor default initialization values * Bump version to 2.0.0 * Fix tests
1 parent e5f1e4b commit 036c03d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+379
-264
lines changed

Package.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ let package = Package(
1515
],
1616
products: [
1717
.library(name: "Functions", targets: ["Functions"]),
18-
.library(name: "GoTrue", targets: ["GoTrue"]),
18+
.library(name: "Auth", targets: ["Auth"]),
1919
.library(name: "PostgREST", targets: ["PostgREST"]),
2020
.library(name: "Realtime", targets: ["Realtime"]),
2121
.library(name: "Storage", targets: ["Storage"]),
2222
.library(
2323
name: "Supabase",
24-
targets: ["Supabase", "Functions", "PostgREST", "GoTrue", "Realtime", "Storage"]
24+
targets: ["Supabase", "Functions", "PostgREST", "Auth", "Realtime", "Storage"]
2525
),
2626
],
2727
dependencies: [
@@ -46,20 +46,23 @@ let package = Package(
4646
]
4747
),
4848
.target(
49-
name: "GoTrue",
49+
name: "Auth",
5050
dependencies: [
5151
"_Helpers",
5252
.product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"),
5353
.product(name: "KeychainAccess", package: "KeychainAccess"),
5454
]
5555
),
5656
.testTarget(
57-
name: "GoTrueTests",
57+
name: "AuthTests",
5858
dependencies: [
59-
"GoTrue",
59+
"Auth",
6060
.product(name: "SnapshotTesting", package: "swift-snapshot-testing"),
6161
.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
6262
],
63+
exclude: [
64+
"__Snapshots__",
65+
],
6366
resources: [.process("Resources")]
6467
),
6568
.target(
@@ -93,7 +96,7 @@ let package = Package(
9396
name: "Supabase",
9497
dependencies: [
9598
.product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"),
96-
"GoTrue",
99+
"Auth",
97100
"Storage",
98101
"Realtime",
99102
"PostgREST",

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ let package = Package(
3131

3232
If you're using Xcode, [use this guide](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app) to add `supabase-swift` to your project. Use `https://github.com/supabase-community/supabase-swift.git` for the url when Xcode asks.
3333

34-
If you don't want the full Supabase environment, you can also add individual packages, such as `Functions`, `GoTrue`, `Realtime`, `Storage`, or `PostgREST`.
34+
If you don't want the full Supabase environment, you can also add individual packages, such as `Functions`, `Auth`, `Realtime`, `Storage`, or `PostgREST`.
3535

3636
Then you're able to import the package and establish the connection with the database.
3737

Sources/GoTrue/GoTrueClient.swift renamed to Sources/Auth/AuthClient.swift

Lines changed: 52 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Foundation
55
import FoundationNetworking
66
#endif
77

8-
public actor GoTrueClient {
8+
public actor AuthClient {
99
/// FetchHandler is a type alias for asynchronous network request handling.
1010
public typealias FetchHandler =
1111
@Sendable (_ request: URLRequest) async throws -> (Data, URLResponse)
@@ -15,45 +15,36 @@ public actor GoTrueClient {
1515
public let url: URL
1616
public var headers: [String: String]
1717
public let flowType: AuthFlowType
18-
public let localStorage: GoTrueLocalStorage
18+
public let localStorage: AuthLocalStorage
1919
public let encoder: JSONEncoder
2020
public let decoder: JSONDecoder
2121
public let fetch: FetchHandler
2222

23-
/// Initializes a GoTrueClient Configuration with optional parameters.
23+
/// Initializes a AuthClient Configuration with optional parameters.
2424
///
2525
/// - Parameters:
26-
/// - url: The base URL of the GoTrue server.
27-
/// - headers: (Optional) Custom headers to be included in requests.
28-
/// - flowType: (Optional) The authentication flow type. Default is `.implicit`.
29-
/// - localStorage: (Optional) The storage mechanism for local data. Default is a
30-
/// KeychainLocalStorage.
31-
/// - encoder: (Optional) The JSON encoder to use for encoding requests.
32-
/// - decoder: (Optional) The JSON decoder to use for decoding responses.
33-
/// - fetch: (Optional) The asynchronous fetch handler for network requests.
26+
/// - url: The base URL of the Auth server.
27+
/// - headers: Custom headers to be included in requests.
28+
/// - flowType: The authentication flow type.
29+
/// - localStorage: The storage mechanism for local data.
30+
/// - encoder: The JSON encoder to use for encoding requests.
31+
/// - decoder: The JSON decoder to use for decoding responses.
32+
/// - fetch: The asynchronous fetch handler for network requests.
3433
public init(
3534
url: URL,
3635
headers: [String: String] = [:],
37-
flowType: AuthFlowType = .implicit,
38-
localStorage: GoTrueLocalStorage? = nil,
39-
encoder: JSONEncoder = .goTrue,
40-
decoder: JSONDecoder = .goTrue,
36+
flowType: AuthFlowType = Configuration.defaultFlowType,
37+
localStorage: AuthLocalStorage = Configuration.defaultLocalStorage,
38+
encoder: JSONEncoder = AuthClient.Configuration.jsonEncoder,
39+
decoder: JSONDecoder = AuthClient.Configuration.jsonDecoder,
4140
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) }
4241
) {
43-
var headers = headers
44-
if headers["X-Client-Info"] == nil {
45-
headers["X-Client-Info"] = "gotrue-swift/\(version)"
46-
}
42+
let headers = headers.merging(Configuration.defaultHeaders) { l, _ in l }
4743

4844
self.url = url
4945
self.headers = headers
5046
self.flowType = flowType
51-
self.localStorage =
52-
localStorage
53-
?? KeychainLocalStorage(
54-
service: "supabase.gotrue.swift",
55-
accessGroup: nil
56-
)
47+
self.localStorage = localStorage
5748
self.encoder = encoder
5849
self.decoder = decoder
5950
self.fetch = fetch
@@ -82,34 +73,33 @@ public actor GoTrueClient {
8273

8374
/// Returns the session, refreshing it if necessary.
8475
///
85-
/// If no session can be found, a ``GoTrueError/sessionNotFound`` error is thrown.
76+
/// If no session can be found, a ``AuthError/sessionNotFound`` error is thrown.
8677
public var session: Session {
8778
get async throws {
8879
try await sessionManager.session()
8980
}
9081
}
9182

9283
/// Namespace for accessing multi-factor authentication API.
93-
public let mfa: GoTrueMFA
84+
public let mfa: AuthMFA
9485

95-
/// Initializes a GoTrueClient with optional parameters.
86+
/// Initializes a AuthClient with optional parameters.
9687
///
9788
/// - Parameters:
98-
/// - url: The base URL of the GoTrue server.
99-
/// - headers: (Optional) Custom headers to be included in requests.
100-
/// - flowType: (Optional) The authentication flow type. Default is `.implicit`.
101-
/// - localStorage: (Optional) The storage mechanism for local data. Default is a
102-
/// KeychainLocalStorage.
103-
/// - encoder: (Optional) The JSON encoder to use for encoding requests.
104-
/// - decoder: (Optional) The JSON decoder to use for decoding responses.
105-
/// - fetch: (Optional) The asynchronous fetch handler for network requests.
89+
/// - url: The base URL of the Auth server.
90+
/// - headers: Custom headers to be included in requests.
91+
/// - flowType: The authentication flow type..
92+
/// - localStorage: The storage mechanism for local data..
93+
/// - encoder: The JSON encoder to use for encoding requests.
94+
/// - decoder: The JSON decoder to use for decoding responses.
95+
/// - fetch: The asynchronous fetch handler for network requests.
10696
public init(
10797
url: URL,
10898
headers: [String: String] = [:],
109-
flowType: AuthFlowType = .implicit,
110-
localStorage: GoTrueLocalStorage? = nil,
111-
encoder: JSONEncoder = .goTrue,
112-
decoder: JSONDecoder = .goTrue,
99+
flowType: AuthFlowType = AuthClient.Configuration.defaultFlowType,
100+
localStorage: AuthLocalStorage = AuthClient.Configuration.defaultLocalStorage,
101+
encoder: JSONEncoder = AuthClient.Configuration.jsonEncoder,
102+
decoder: JSONDecoder = AuthClient.Configuration.jsonDecoder,
113103
fetch: @escaping FetchHandler = { try await URLSession.shared.data(for: $0) }
114104
) {
115105
self.init(
@@ -125,7 +115,7 @@ public actor GoTrueClient {
125115
)
126116
}
127117

128-
/// Initializes a GoTrueClient with a specific configuration.
118+
/// Initializes a AuthClient with a specific configuration.
129119
///
130120
/// - Parameters:
131121
/// - configuration: The client configuration.
@@ -151,7 +141,7 @@ public actor GoTrueClient {
151141
eventEmitter: EventEmitter,
152142
sessionStorage: SessionStorage
153143
) {
154-
mfa = GoTrueMFA()
144+
mfa = AuthMFA()
155145

156146
Dependencies.current.setValue(
157147
Dependencies(
@@ -213,7 +203,7 @@ public actor GoTrueClient {
213203
email: email,
214204
password: password,
215205
data: data,
216-
gotrueMetaSecurity: captchaToken.map(GoTrueMetaSecurity.init(captchaToken:)),
206+
gotrueMetaSecurity: captchaToken.map(AuthMetaSecurity.init(captchaToken:)),
217207
codeChallenge: codeChallenge,
218208
codeChallengeMethod: codeChallengeMethod
219209
)
@@ -243,7 +233,7 @@ public actor GoTrueClient {
243233
password: password,
244234
phone: phone,
245235
data: data,
246-
gotrueMetaSecurity: captchaToken.map(GoTrueMetaSecurity.init(captchaToken:))
236+
gotrueMetaSecurity: captchaToken.map(AuthMetaSecurity.init(captchaToken:))
247237
)
248238
)
249239
)
@@ -359,7 +349,7 @@ public actor GoTrueClient {
359349
email: email,
360350
createUser: shouldCreateUser,
361351
data: data,
362-
gotrueMetaSecurity: captchaToken.map(GoTrueMetaSecurity.init(captchaToken:)),
352+
gotrueMetaSecurity: captchaToken.map(AuthMetaSecurity.init(captchaToken:)),
363353
codeChallenge: codeChallenge,
364354
codeChallengeMethod: codeChallengeMethod
365355
)
@@ -391,7 +381,7 @@ public actor GoTrueClient {
391381
phone: phone,
392382
createUser: shouldCreateUser,
393383
data: data,
394-
gotrueMetaSecurity: captchaToken.map(GoTrueMetaSecurity.init(captchaToken:))
384+
gotrueMetaSecurity: captchaToken.map(AuthMetaSecurity.init(captchaToken:))
395385
)
396386
)
397387
)
@@ -401,7 +391,7 @@ public actor GoTrueClient {
401391
/// Log in an existing user by exchanging an Auth Code issued during the PKCE flow.
402392
public func exchangeCodeForSession(authCode: String) async throws -> Session {
403393
guard let codeVerifier = try codeVerifierStorage.getCodeVerifier() else {
404-
throw GoTrueError.pkce(.codeVerifierNotFound)
394+
throw AuthError.pkce(.codeVerifierNotFound)
405395
}
406396
do {
407397
let session: Session = try await api.execute(
@@ -482,26 +472,26 @@ public actor GoTrueClient {
482472
@discardableResult
483473
public func session(from url: URL) async throws -> Session {
484474
if configuration.flowType == .implicit, !isImplicitGrantFlow(url: url) {
485-
throw GoTrueError.invalidImplicitGrantFlowURL
475+
throw AuthError.invalidImplicitGrantFlowURL
486476
}
487477

488478
if configuration.flowType == .pkce, !isPKCEFlow(url: url) {
489-
throw GoTrueError.pkce(.invalidPKCEFlowURL)
479+
throw AuthError.pkce(.invalidPKCEFlowURL)
490480
}
491481

492482
let params = extractParams(from: url)
493483

494484
if isPKCEFlow(url: url) {
495485
guard let code = params.first(where: { $0.name == "code" })?.value else {
496-
throw GoTrueError.pkce(.codeVerifierNotFound)
486+
throw AuthError.pkce(.codeVerifierNotFound)
497487
}
498488

499489
let session = try await exchangeCodeForSession(authCode: code)
500490
return session
501491
}
502492

503493
if let errorDescription = params.first(where: { $0.name == "error_description" })?.value {
504-
throw GoTrueError.api(.init(errorDescription: errorDescription))
494+
throw AuthError.api(.init(errorDescription: errorDescription))
505495
}
506496

507497
guard
@@ -565,7 +555,7 @@ public actor GoTrueClient {
565555
expiresAt = Date(timeIntervalSince1970: exp)
566556
hasExpired = expiresAt <= now
567557
} else {
568-
throw GoTrueError.missingExpClaim
558+
throw AuthError.missingExpClaim
569559
}
570560

571561
if hasExpired {
@@ -607,7 +597,7 @@ public actor GoTrueClient {
607597
// ignore 401s since an invalid or expired JWT should sign out the current session
608598
let ignoredCodes = Set([404, 401])
609599

610-
if case let GoTrueError.api(apiError) = error, let code = apiError.code,
600+
if case let AuthError.api(apiError) = error, let code = apiError.code,
611601
!ignoredCodes.contains(code)
612602
{
613603
throw error
@@ -642,7 +632,7 @@ public actor GoTrueClient {
642632
email: email,
643633
token: token,
644634
type: type,
645-
gotrueMetaSecurity: captchaToken.map(GoTrueMetaSecurity.init(captchaToken:))
635+
gotrueMetaSecurity: captchaToken.map(AuthMetaSecurity.init(captchaToken:))
646636
)
647637
)
648638
)
@@ -669,7 +659,7 @@ public actor GoTrueClient {
669659
phone: phone,
670660
token: token,
671661
type: type,
672-
gotrueMetaSecurity: captchaToken.map(GoTrueMetaSecurity.init(captchaToken:))
662+
gotrueMetaSecurity: captchaToken.map(AuthMetaSecurity.init(captchaToken:))
673663
)
674664
)
675665
)
@@ -755,7 +745,7 @@ public actor GoTrueClient {
755745
body: configuration.encoder.encode(
756746
RecoverParams(
757747
email: email,
758-
gotrueMetaSecurity: captchaToken.map(GoTrueMetaSecurity.init(captchaToken:)),
748+
gotrueMetaSecurity: captchaToken.map(AuthMetaSecurity.init(captchaToken:)),
759749
codeChallenge: codeChallenge,
760750
codeChallengeMethod: codeChallengeMethod
761751
)
@@ -841,17 +831,17 @@ public actor GoTrueClient {
841831
}
842832
}
843833

844-
extension GoTrueClient {
834+
extension AuthClient {
845835
/// Notification posted when an auth state event is triggered.
846836
public static let didChangeAuthStateNotification = Notification.Name(
847-
"GoTrueClient.didChangeAuthStateNotification"
837+
"AuthClient.didChangeAuthStateNotification"
848838
)
849839

850840
/// A user info key to retrieve the ``AuthChangeEvent`` value for a
851-
/// ``GoTrueClient/didChangeAuthStateNotification`` notification.
852-
public static let authChangeEventInfoKey = "GoTrueClient.authChangeEvent"
841+
/// ``AuthClient/didChangeAuthStateNotification`` notification.
842+
public static let authChangeEventInfoKey = "AuthClient.authChangeEvent"
853843

854844
/// A user info key to retrieve the ``Session`` value for a
855-
/// ``GoTrueClient/didChangeAuthStateNotification`` notification.
856-
public static let authChangeSessionInfoKey = "GoTrueClient.authChangeSession"
845+
/// ``AuthClient/didChangeAuthStateNotification`` notification.
846+
public static let authChangeSessionInfoKey = "AuthClient.authChangeSession"
857847
}

Sources/GoTrue/GoTrueError.swift renamed to Sources/Auth/AuthError.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Foundation
22

3-
public enum GoTrueError: LocalizedError, Sendable {
3+
public enum AuthError: LocalizedError, Sendable {
44
case missingExpClaim
55
case malformedJWT
66
case sessionNotFound

Sources/GoTrue/GoTrueLocalStorage.swift renamed to Sources/Auth/AuthLocalStorage.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import Foundation
22
@preconcurrency import KeychainAccess
33

4-
public protocol GoTrueLocalStorage: Sendable {
4+
public protocol AuthLocalStorage: Sendable {
55
func store(key: String, value: Data) throws
66
func retrieve(key: String) throws -> Data?
77
func remove(key: String) throws
88
}
99

10-
struct KeychainLocalStorage: GoTrueLocalStorage {
10+
struct KeychainLocalStorage: AuthLocalStorage {
1111
private let keychain: Keychain
1212

1313
init(service: String, accessGroup: String?) {

Sources/GoTrue/GoTrueMFA.swift renamed to Sources/Auth/AuthMFA.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Foundation
22
@_spi(Internal) import _Helpers
33

44
/// Contains the full multi-factor authentication API.
5-
public actor GoTrueMFA {
5+
public actor AuthMFA {
66
private var api: APIClient {
77
Dependencies.current.value!.api
88
}
@@ -11,7 +11,7 @@ public actor GoTrueMFA {
1111
Dependencies.current.value!.sessionManager
1212
}
1313

14-
private var configuration: GoTrueClient.Configuration {
14+
private var configuration: AuthClient.Configuration {
1515
Dependencies.current.value!.configuration
1616
}
1717

@@ -148,7 +148,7 @@ public actor GoTrueMFA {
148148
nextLevel: nextLevel,
149149
currentAuthenticationMethods: currentAuthenticationMethods
150150
)
151-
} catch GoTrueError.sessionNotFound {
151+
} catch AuthError.sessionNotFound {
152152
return AuthMFAGetAuthenticatorAssuranceLevelResponse(
153153
currentLevel: nil,
154154
nextLevel: nil,

0 commit comments

Comments
 (0)