Skip to content

Commit 05cc7d0

Browse files
committed
feat(auth): add linkIdentity method
1 parent 76233bb commit 05cc7d0

File tree

3 files changed

+89
-5
lines changed

3 files changed

+89
-5
lines changed

Examples/Examples/Profile/UserIdentityList.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,7 @@ struct UserIdentityList: View {
6262
Button(provider.rawValue) {
6363
Task {
6464
do {
65-
let response = try await supabase.auth.getLinkIdentityURL(provider: provider)
66-
openURL(response.url)
67-
debug("getLinkIdentityURL: \(response.url) opened for provider \(response.provider)")
65+
try await supabase.auth.linkIdentity(provider: provider)
6866
} catch {
6967
self.error = error
7068
}

Sources/Auth/AuthClient.swift

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -955,14 +955,67 @@ public final class AuthClient: Sendable {
955955
try await user().identities ?? []
956956
}
957957

958+
/// Links an OAuth identity to an existing user.
959+
///
960+
/// This method supports the PKCE flow.
961+
///
962+
/// - Parameters:
963+
/// - provider: The provider you want to link the user with.
964+
/// - scopes: A space-separated list of scopes granted to the OAuth application.
965+
/// - redirectTo: A URL to send the user to after they are confirmed.
966+
/// - queryParams: Additional query parameters to use.
967+
/// - launchURL: Custom launch URL logic.
968+
public func linkIdentity(
969+
provider: Provider,
970+
scopes: String? = nil,
971+
redirectTo: URL? = nil,
972+
queryParams: [(name: String, value: String?)] = [],
973+
launchURL: @MainActor (_ url: URL) -> Void
974+
) async throws {
975+
let response = try await getLinkIdentityURL(
976+
provider: provider,
977+
scopes: scopes,
978+
redirectTo: redirectTo,
979+
queryParams: queryParams
980+
)
981+
982+
await launchURL(response.url)
983+
}
984+
985+
/// Links an OAuth identity to an existing user.
986+
///
987+
/// This method supports the PKCE flow.
988+
///
989+
/// - Parameters:
990+
/// - provider: The provider you want to link the user with.
991+
/// - scopes: A space-separated list of scopes granted to the OAuth application.
992+
/// - redirectTo: A URL to send the user to after they are confirmed.
993+
/// - queryParams: Additional query parameters to use.
994+
///
995+
/// - Note: This method opens the URL using the default URL opening mechanism for the platform, if you with to provide your own URL opening logic use ``linkIdentity(provider:scopes:redirectTo:queryParams:launchURL:)``.
996+
public func linkIdentity(
997+
provider: Provider,
998+
scopes: String? = nil,
999+
redirectTo: URL? = nil,
1000+
queryParams: [(name: String, value: String?)] = []
1001+
) async throws {
1002+
try await linkIdentity(
1003+
provider: provider,
1004+
scopes: scopes,
1005+
redirectTo: redirectTo,
1006+
queryParams: queryParams,
1007+
launchURL: { URLOpener.open($0) }
1008+
)
1009+
}
1010+
9581011
/// Returns the URL to link the user's identity with an OAuth provider.
9591012
///
9601013
/// This method supports the PKCE flow.
9611014
///
9621015
/// - Parameters:
9631016
/// - provider: The provider you want to link the user with.
964-
/// - scopes: The scopes to request from the OAuth provider.
965-
/// - redirectTo: The redirect URL to use, specify a configured deep link.
1017+
/// - scopes: A space-separated list of scopes granted to the OAuth application.
1018+
/// - redirectTo: A URL to send the user to after they are confirmed.
9661019
/// - queryParams: Additional query parameters to use.
9671020
public func getLinkIdentityURL(
9681021
provider: Provider,

Sources/Auth/Internal/URLOpener.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// URLOpener.swift
3+
//
4+
//
5+
// Created by Guilherme Souza on 17/05/24.
6+
//
7+
8+
import Foundation
9+
10+
#if canImport(WatchKit)
11+
import WatchKit
12+
#endif
13+
14+
#if canImport(UIKit)
15+
import UIKit
16+
#endif
17+
18+
#if canImport(AppKit)
19+
import AppKit
20+
#endif
21+
22+
enum URLOpener {
23+
@MainActor
24+
static func open(_ url: URL) {
25+
#if os(macOS)
26+
NSWorkspace.shared.open(url)
27+
#elseif os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst)
28+
UIApplication.shared.open(url)
29+
#elseif os(watchOS)
30+
WKExtension.shared().openSystemURL(url)
31+
#endif
32+
}
33+
}

0 commit comments

Comments
 (0)