Skip to content

Commit 39768de

Browse files
authored
Merge pull request #1013 from ItzNotABug/feat-signin
Feat: In-App OAuth2 Sign-in
2 parents a852aba + c8a11fb commit 39768de

File tree

2 files changed

+54
-14
lines changed

2 files changed

+54
-14
lines changed

templates/apple/base/requests/oauth.twig

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
let callbackScheme = "appwrite-callback-\(client.config["project"] ?? "")"
44

55
_ = try await withCheckedThrowingContinuation { continuation in
6-
WebAuthComponent.authenticate(url: url, callbackScheme: callbackScheme) { result in
7-
continuation.resume(with: result)
6+
/// main thread for PresentationContextProvider
7+
DispatchQueue.main.async {
8+
WebAuthComponent.authenticate(url: url, callbackScheme: callbackScheme) { result in
9+
continuation.resume(with: result)
10+
}
811
}
912
}
10-
11-
return true
13+
14+
return true

templates/swift/Sources/OAuth/WebAuthComponent.swift.twig

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import AsyncHTTPClient
22
import Foundation
33
import NIO
44

5-
#if canImport(SwiftUI)
6-
import SwiftUI
5+
#if canImport(AuthenticationServices)
6+
import AuthenticationServices
77
#endif
88

99
///
@@ -13,12 +13,10 @@ import SwiftUI
1313
@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, visionOS 1.0, *)
1414
public class WebAuthComponent {
1515

16-
#if canImport(SwiftUI)
17-
@Environment(\.openURL)
18-
private static var openURL
19-
#endif
20-
2116
private static var callbacks = [String: (Result<String, {{ spec.title | caseUcfirst}}Error>) -> Void]()
17+
#if canImport(AuthenticationServices)
18+
private static var currentAuthSession: ASWebAuthenticationSession?
19+
#endif
2220

2321
///
2422
/// Authenticate Session with OAuth2
@@ -41,9 +39,29 @@ public class WebAuthComponent {
4139
) {
4240
callbacks[callbackScheme] = onComplete
4341

44-
#if canImport(SwiftUI)
45-
openURL(url)
46-
#endif
42+
#if canImport(AuthenticationServices)
43+
currentAuthSession = ASWebAuthenticationSession(
44+
url: url,
45+
callbackURLScheme: callbackScheme
46+
) { callbackURL, error in
47+
if let error = error {
48+
cleanUp()
49+
} else if let callbackURL = callbackURL {
50+
// handle cookies here itself!
51+
WebAuthComponent.handleIncomingCookie(from: callbackURL)
52+
cleanUp()
53+
}
54+
}
55+
56+
if let session = currentAuthSession {
57+
/// Indicates that the session should be a private session.
58+
session.prefersEphemeralWebBrowserSession = true
59+
session.presentationContextProvider = PresentationContextProvider.shared
60+
session.start()
61+
} else {
62+
print("Failed to create ASWebAuthenticationSession")
63+
}
64+
#endif
4765
}
4866

4967
///
@@ -130,5 +148,24 @@ public class WebAuthComponent {
130148
callbacks.forEach { (_, callback) in
131149
callback(.failure({{ spec.title | caseUcfirst}}Error(message: "User cancelled login.")))
132150
}
151+
152+
#if canImport(AuthenticationServices)
153+
currentAuthSession = nil
154+
#endif
155+
}
156+
}
157+
158+
#if canImport(AuthenticationServices)
159+
/// Presentation context for the ASWebAuthenticationSession.
160+
class PresentationContextProvider: NSObject, ASWebAuthenticationPresentationContextProviding {
161+
static let shared = PresentationContextProvider()
162+
163+
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
164+
if let mainWindow = OSApplication.shared.windows.first { $0.isKeyWindow } {
165+
return mainWindow
166+
}
167+
168+
return ASPresentationAnchor()
133169
}
134170
}
171+
#endif

0 commit comments

Comments
 (0)