Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Auth): Moving HostedUI continuations to one place #3363

Merged
merged 3 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ class ShowHostedUISignIn: NSObject, Action {

let signingInData: HostedUISigningInState

var sessionAdapter: HostedUISessionBehavior?

init(signInData: HostedUISigningInState) {
self.signingInData = signInData
}
Expand Down Expand Up @@ -48,17 +46,13 @@ class ShowHostedUISignIn: NSObject, Action {
self.logVerbose("\(#fileID) Showing url \(url.absoluteString)", environment: environment)

do {
let queryItems = try await withCheckedThrowingContinuation {
(continuation: CheckedContinuation<[URLQueryItem], Error>) in
sessionAdapter = hostedUIEnvironment.hostedUISessionFactory()
sessionAdapter?.showHostedUI(
url: url,
callbackScheme: callbackURLScheme,
inPrivate: signingInData.options.preferPrivateSession,
presentationAnchor: signingInData.presentationAnchor) { result in
continuation.resume(with: result)
}
}
let sessionAdapter = hostedUIEnvironment.hostedUISessionFactory()
let queryItems = try await sessionAdapter.showHostedUI(
url: url,
callbackScheme: callbackURLScheme,
inPrivate: signingInData.options.preferPrivateSession,
presentationAnchor: signingInData.presentationAnchor)

guard let code = queryItems.first(where: { $0.name == "code" })?.value,
let state = queryItems.first(where: { $0.name == "state" })?.value,
self.signingInData.state == state else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ class ShowHostedUISignOut: NSObject, Action {
let signOutEvent: SignOutEventData
let signInData: SignedInData

var sessionAdapter: HostedUISessionBehavior?

init(signOutEvent: SignOutEventData, signInData: SignedInData) {
self.signInData = signInData
self.signOutEvent = signOutEvent
Expand All @@ -44,17 +42,12 @@ class ShowHostedUISignOut: NSObject, Action {

do {
let logoutURL = try HostedUIRequestHelper.createSignOutURL(configuration: hostedUIConfig)
_ = try await withCheckedThrowingContinuation {
(continuation: CheckedContinuation<[URLQueryItem], Error>) in
sessionAdapter = hostedUIEnvironment.hostedUISessionFactory()
sessionAdapter?.showHostedUI(url: logoutURL,
callbackScheme: callbackURLScheme,
inPrivate: false,
presentationAnchor: signOutEvent.presentationAnchor) {
result in
continuation.resume(with: result)
}
}
let sessionAdapter = hostedUIEnvironment.hostedUISessionFactory()
_ = try await sessionAdapter.showHostedUI(
url: logoutURL,
callbackScheme: callbackURLScheme,
inPrivate: false,
presentationAnchor: signOutEvent.presentationAnchor)

await sendEvent(with: nil, dispatcher: dispatcher, environment: environment)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,56 @@ class HostedUIASWebAuthenticationSession: NSObject, HostedUISessionBehavior {

weak var webPresentation: AuthUIPresentationAnchor?

func showHostedUI(url: URL,
callbackScheme: String,
inPrivate: Bool,
presentationAnchor: AuthUIPresentationAnchor?,
callback: @escaping (Result<[URLQueryItem], HostedUIError>) -> Void) {
func showHostedUI(
url: URL,
callbackScheme: String,
inPrivate: Bool,
presentationAnchor: AuthUIPresentationAnchor?) async throws -> [URLQueryItem] {

#if os(iOS) || os(macOS)
self.webPresentation = presentationAnchor
let aswebAuthenticationSession = createAuthenticationSession(
url: url,
callbackURLScheme: callbackScheme,
completionHandler: { url, error in
if let url = url {
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)
let queryItems = urlComponents?.queryItems ?? []

if let error = queryItems.first(where: { $0.name == "error" })?.value {
let errorDescription = queryItems.first(
where: { $0.name == "error_description" }
)?.value?.trim() ?? ""
let message = "\(error) \(errorDescription)"
callback(.failure(.serviceMessage(message)))
return
}
callback(.success(queryItems))
} else if let error = error {
callback(.failure(self.convertHostedUIError(error)))
return try await withCheckedThrowingContinuation {
(continuation: CheckedContinuation<[URLQueryItem], Error>) in

let aswebAuthenticationSession = createAuthenticationSession(
url: url,
callbackURLScheme: callbackScheme,
completionHandler: { url, error in

} else {
callback(.failure(.unknown))
}
})
aswebAuthenticationSession.presentationContextProvider = self
aswebAuthenticationSession.prefersEphemeralWebBrowserSession = inPrivate
if let url = url {
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)
let queryItems = urlComponents?.queryItems ?? []

DispatchQueue.main.async {
aswebAuthenticationSession.start()
// Validate if query items contains an error
if let error = queryItems.first(where: { $0.name == "error" })?.value {
let errorDescription = queryItems.first(
where: { $0.name == "error_description" }
)?.value?.trim() ?? ""
let message = "\(error) \(errorDescription)"
return continuation.resume(
throwing: HostedUIError.serviceMessage(message))
}
return continuation.resume(
returning: queryItems)
} else if let error = error {
return continuation.resume(
throwing: self.convertHostedUIError(error))
} else {
return continuation.resume(
throwing: HostedUIError.unknown)
}
})
aswebAuthenticationSession.presentationContextProvider = self
aswebAuthenticationSession.prefersEphemeralWebBrowserSession = inPrivate

DispatchQueue.main.async {
aswebAuthenticationSession.start()
}
}

#else
callback(.failure(.serviceMessage("HostedUI is only available in iOS and macOS")))
throw HostedUIError.serviceMessage("HostedUI is only available in iOS and macOS")
#endif
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import Amplify

protocol HostedUISessionBehavior {

func showHostedUI(url: URL,
callbackScheme: String,
inPrivate: Bool,
presentationAnchor: AuthUIPresentationAnchor?,
callback: @escaping (Result<[URLQueryItem], HostedUIError>) -> Void)
func showHostedUI(
url: URL,
callbackScheme: String,
inPrivate: Bool,
presentationAnchor: AuthUIPresentationAnchor?
) async throws -> [URLQueryItem]
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ class MockHostedUISession: HostedUISessionBehavior {
self.result = result
}

func showHostedUI(url: URL,
callbackScheme: String,
inPrivate: Bool,
presentationAnchor: AuthUIPresentationAnchor?,
callback: @escaping (Result<[URLQueryItem], HostedUIError>) -> Void) {
callback(result)
func showHostedUI(
url: URL,
callbackScheme: String,
inPrivate: Bool,
presentationAnchor: AuthUIPresentationAnchor?
) async throws -> [URLQueryItem] {
return try result.get()
}

}
Loading
Loading