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

feat: added support for webview as a provider for webauth #875

Merged
merged 17 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 2 additions & 0 deletions App/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ class ViewController: UIViewController {
@IBAction func login(_ sender: Any) {
Auth0
.webAuth()
.useWebViewProvider()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest adding a new static func to the WebAuthentication struct like https://github.com/auth0/Auth0.swift/blob/master/Auth0/SafariProvider.swift#L37, as that:

  • Follows the existing pattern in use for web providers
  • Avoids adding new useX() methods that have the disadvantage of being mutually exclusive (e.g. these can be chained and it's not clear which one will end up being used)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, changed accordingly

.logging(enabled: true)
.start(onAuth)
}

@IBAction func logout(_ sender: Any) {
Auth0
.webAuth()
.useWebViewProvider()
.logging(enabled: true)
.clearSession(federated: false) { result in
switch result {
Expand Down
8 changes: 8 additions & 0 deletions Auth0.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@
A7DDDF6D2BC9A81E0077B067 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = A7DDDF6B2BC9A81E0077B067 /* PrivacyInfo.xcprivacy */; };
A7DDDF6E2BC9A81E0077B067 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = A7DDDF6B2BC9A81E0077B067 /* PrivacyInfo.xcprivacy */; };
A7DDDF702BC9A93F0077B067 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = A7DDDF6B2BC9A81E0077B067 /* PrivacyInfo.xcprivacy */; };
C107B51D2C9AC4D8006B6BEA /* WebViewProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = C107B51B2C9AC4D3006B6BEA /* WebViewProvider.swift */; };
C107B5222CA27F7C006B6BEA /* WebViewProviderSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = C107B5202CA27F76006B6BEA /* WebViewProviderSpec.swift */; };
C12BFE432C352DD400D1CC00 /* NetworkStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = C177D76F2C2BDFE40094C657 /* NetworkStub.swift */; };
C12BFE442C352DD700D1CC00 /* StubURLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C177D7742C2BE00D0094C657 /* StubURLProtocol.swift */; };
C177D6C32C2ADDEB0094C657 /* Auth0.plist in Resources */ = {isa = PBXBuildFile; fileRef = C177D6C22C2ADDEB0094C657 /* Auth0.plist */; };
Expand Down Expand Up @@ -746,6 +748,8 @@
5FF465BB1CE2AC4500F7ED8C /* Management.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Management.swift; path = Auth0/Management.swift; sourceTree = SOURCE_ROOT; };
970BC36A25C27095007A7745 /* Challenge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Challenge.swift; sourceTree = "<group>"; };
A7DDDF6B2BC9A81E0077B067 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
C107B51B2C9AC4D3006B6BEA /* WebViewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewProvider.swift; sourceTree = "<group>"; };
C107B5202CA27F76006B6BEA /* WebViewProviderSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewProviderSpec.swift; sourceTree = "<group>"; };
C177D6C22C2ADDEB0094C657 /* Auth0.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Auth0.plist; sourceTree = "<group>"; };
C177D76F2C2BDFE40094C657 /* NetworkStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkStub.swift; sourceTree = "<group>"; };
C177D7742C2BE00D0094C657 /* StubURLProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StubURLProtocol.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -928,6 +932,7 @@
5C0AF09828330CA000162044 /* Providers */ = {
isa = PBXGroup;
children = (
C107B51B2C9AC4D3006B6BEA /* WebViewProvider.swift */,
5B16D88C1F7141A0009476A5 /* ASProvider.swift */,
5C0AF09928330CBA00162044 /* SafariProvider.swift */,
);
Expand Down Expand Up @@ -977,6 +982,7 @@
5CF539222836DC360073F623 /* Providers */ = {
isa = PBXGroup;
children = (
C107B5202CA27F76006B6BEA /* WebViewProviderSpec.swift */,
5CF5392A283835460073F623 /* ASProviderSpec.swift */,
5CF539232836DCC10073F623 /* SafariProviderSpec.swift */,
);
Expand Down Expand Up @@ -2046,6 +2052,7 @@
5F3965C21CF67CF000CDE7C0 /* WebAuth.swift in Sources */,
5FCAB1761D0900CF00331C84 /* TransactionStore.swift in Sources */,
5FDE87471D8A422300EA27DC /* Telemetry.swift in Sources */,
C107B51D2C9AC4D8006B6BEA /* WebViewProvider.swift in Sources */,
5FAE9C911D8878D400A871CE /* Auth0WebAuth.swift in Sources */,
5B5E93F91EC45C22002A37F9 /* CredentialsManagerError.swift in Sources */,
5CA541CD2B1A81A700E4284D /* Documentation.docc in Sources */,
Expand Down Expand Up @@ -2151,6 +2158,7 @@
5FADB6091CED500900D4BB50 /* ManagementSpec.swift in Sources */,
5FCAB16D1D07AC3500331C84 /* WebAuthSpec.swift in Sources */,
5F28B4671D8300D50000EB23 /* LoggerSpec.swift in Sources */,
C107B5222CA27F7C006B6BEA /* WebViewProviderSpec.swift in Sources */,
5FBBF0431CCA90300024D2AF /* AuthenticationSpec.swift in Sources */,
5B2860D61EEF210A00C75D54 /* UserInfoSpec.swift in Sources */,
5C809D9A275FA3EF00F15A67 /* ManagementErrorSpec.swift in Sources */,
Expand Down
6 changes: 5 additions & 1 deletion Auth0.xcodeproj/xcshareddata/xcschemes/Auth0.iOS.xcscheme
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1400"
version = "1.3">
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
Expand Down Expand Up @@ -47,6 +47,10 @@
BlueprintName = "Auth0Tests.iOS"
ReferencedContainer = "container:Auth0.xcodeproj">
</BuildableReference>
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
</TestableReference>
</Testables>
</TestAction>
Expand Down
28 changes: 26 additions & 2 deletions Auth0/Auth0WebAuth.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#if WEB_AUTH_PLATFORM
import Foundation
import Combine
#if os(iOS)
import UIKit
#endif

final class Auth0WebAuth: WebAuth {

Expand Down Expand Up @@ -33,6 +36,11 @@
private(set) var overrideAuthorizeURL: URL?
private(set) var provider: WebAuthProvider?
private(set) var onCloseCallback: (() -> Void)?

Check warning on line 39 in Auth0/Auth0WebAuth.swift

View workflow job for this annotation

GitHub Actions / Lint code with SwiftLint

Lines should not have trailing whitespace (trailing_whitespace)
#if os(iOS)
private(set) var useWebViewProvider = false
private(set) var webViewProviderPresentationStyle: UIModalPresentationStyle = .fullScreen
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a func like https://github.com/auth0/Auth0.swift/blob/master/Auth0/SafariProvider.swift#L37 also has the advantage of being on its own (gated) file, so there's no need to have these conditionals here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed accordingly


var state: String {
return self.parameters["state"] ?? self.generateDefaultState()
Expand Down Expand Up @@ -144,6 +152,14 @@
self.ephemeralSession = true
return self
}

Check warning on line 155 in Auth0/Auth0WebAuth.swift

View workflow job for this annotation

GitHub Actions / Lint code with SwiftLint

Lines should not have trailing whitespace (trailing_whitespace)
#if os(iOS)
func useWebViewProvider(style: UIModalPresentationStyle = .fullScreen) -> Self {
self.useWebViewProvider = true
self.webViewProviderPresentationStyle = style
return self

Check warning on line 160 in Auth0/Auth0WebAuth.swift

View check run for this annotation

Codecov / codecov/patch

Auth0/Auth0WebAuth.swift#L158-L160

Added lines #L158 - L160 were not covered by tests
}
#endif

func invitationURL(_ invitationURL: URL) -> Self {
self.invitationURL = invitationURL
Expand Down Expand Up @@ -196,8 +212,12 @@
state: state,
organization: organization,
invitation: invitation)
let provider = self.provider ?? WebAuthentication.asProvider(redirectURL: redirectURL,
ephemeralSession: ephemeralSession)

Check warning on line 215 in Auth0/Auth0WebAuth.swift

View workflow job for this annotation

GitHub Actions / Lint code with SwiftLint

Lines should not have trailing whitespace (trailing_whitespace)
#if os(iOS)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed accordingly

let provider = useWebViewProvider ? WebAuthentication.webViewProvider(redirectionURL: redirectURL, style: webViewProviderPresentationStyle) : (self.provider ?? WebAuthentication.asProvider(redirectURL: redirectURL, ephemeralSession: ephemeralSession))
#else
let provider = self.provider ?? WebAuthentication.asProvider(redirectURL: redirectURL, ephemeralSession: ephemeralSession)
#endif
let userAgent = provider(authorizeURL) { [storage, onCloseCallback] result in
storage.clear()

Expand Down Expand Up @@ -238,7 +258,11 @@
return callback(.failure(WebAuthError(code: .noBundleIdentifier)))
}

#if os(iOS)
let provider = useWebViewProvider ? WebAuthentication.webViewProvider(redirectionURL: redirectURL, style: webViewProviderPresentationStyle) : (self.provider ?? WebAuthentication.asProvider(redirectURL: redirectURL))
#else
let provider = self.provider ?? WebAuthentication.asProvider(redirectURL: redirectURL)
#endif
let userAgent = provider(logoutURL) { [storage] result in
storage.clear()
callback(result)
Expand Down
1 change: 0 additions & 1 deletion Auth0/SafariProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ extension SafariUserAgent: SFSafariViewControllerDelegate {
// If you are developing a custom Web Auth provider, call WebAuthentication.cancel() instead
// TransactionStore is internal
TransactionStore.shared.cancel()

}

}
Expand Down
15 changes: 14 additions & 1 deletion Auth0/WebAuth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import Foundation
import Combine

#if os(iOS)
import UIKit
#endif

/// Callback invoked by the ``WebAuthUserAgent`` when the web-based operation concludes.
public typealias WebAuthProviderCallback = (WebAuthResult<Void>) -> Void

Expand Down Expand Up @@ -164,6 +168,10 @@
/// - [FAQ](https://github.com/auth0/Auth0.swift/blob/master/FAQ.md)
/// - [prefersEphemeralWebBrowserSession](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession/3237231-prefersephemeralwebbrowsersessio)
func useEphemeralSession() -> Self

Check warning on line 171 in Auth0/WebAuth.swift

View workflow job for this annotation

GitHub Actions / Lint code with SwiftLint

Lines should not have trailing whitespace (trailing_whitespace)
#if os(iOS)
func useWebViewProvider(style: UIModalPresentationStyle) -> Self
#endif

/// Specify an invitation URL to join an organization.
///
Expand Down Expand Up @@ -413,6 +421,11 @@
return try await self.clearSession(federated: federated)
}
#endif


#if os(iOS)
func useWebViewProvider(style: UIModalPresentationStyle = .fullScreen) -> Self {
return self.useWebViewProvider(style: style)

Check warning on line 427 in Auth0/WebAuth.swift

View check run for this annotation

Codecov / codecov/patch

Auth0/WebAuth.swift#L427

Added line #L427 was not covered by tests
}
#endif
}
#endif
8 changes: 8 additions & 0 deletions Auth0/WebAuthError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
public struct WebAuthError: Auth0Error {

enum Code: Equatable {
case webViewNavigationFailed
case webViewProvisionalNavigationFailed
case webViewContentProcessTerminated
case webViewResourceLoadingStopped
case noBundleIdentifier
case transactionActiveAlready
case invalidInvitationURL(String)
Expand Down Expand Up @@ -39,7 +43,7 @@
/// build a valid URL.
/// This error does not include a ``Auth0Error/cause-9wuyi``.
public static let noBundleIdentifier: WebAuthError = .init(code: .noBundleIdentifier)

Check warning on line 46 in Auth0/WebAuthError.swift

View workflow job for this annotation

GitHub Actions / Lint code with SwiftLint

Lines should not have trailing whitespace (trailing_whitespace)
/// There is already an active transaction at the moment; therefore, this newly initiated transaction is canceled.
/// This error does not include a ``Auth0Error/cause-9wuyi``.
public static let transactionActiveAlready: WebAuthError = .init(code: .transactionActiveAlready)
Expand Down Expand Up @@ -82,6 +86,10 @@

var message: String {
switch self.code {
case .webViewNavigationFailed: return "An error occured during a committed main frame navigation of WebView"
case .webViewProvisionalNavigationFailed: return "An error occured while starting to load data for the main frame of WebView"
case .webViewContentProcessTerminated: return "WebView's content process is terminated."
case .webViewResourceLoadingStopped: return "WebView's resource loading has been stopped"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
case .webViewNavigationFailed: return "An error occured during a committed main frame navigation of WebView"
case .webViewProvisionalNavigationFailed: return "An error occured while starting to load data for the main frame of WebView"
case .webViewContentProcessTerminated: return "WebView's content process is terminated."
case .webViewResourceLoadingStopped: return "WebView's resource loading has been stopped"
case .webViewNavigationFailed: return "An error occurred during a committed main frame navigation of the WebView."
case .webViewProvisionalNavigationFailed: return "An error occurred while starting to load data for the main frame of the WebView."
case .webViewContentProcessTerminated: return "The WebView's content process was terminated."
case .webViewResourceLoadingStopped: return "The WebView's resource loading was stopped."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated accordingly

case .noBundleIdentifier: return "Unable to retrieve the bundle identifier from Bundle.main.bundleIdentifier,"
+ " or it could not be used to build a valid URL."
case .transactionActiveAlready: return "Failed to start this transaction, as there is an active transaction at the"
Expand Down
163 changes: 163 additions & 0 deletions Auth0/WebViewProvider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
//
// WebViewProvider.swift
// Auth0
//
// Created by Desu Sai Venkat on 18/09/24.
// Copyright © 2024 Auth0. All rights reserved.
//

#if os(iOS)

@preconcurrency import WebKit


extension WebAuthentication {
static func webViewProvider(redirectionURL: URL, style: UIModalPresentationStyle = .fullScreen) -> WebAuthProvider {
return { url, callback in
WebViewUserAgent(authorizeURL: url, redirectURL: redirectionURL, modalPresentationStyle: style, callback: callback)
}
}
}

extension WebViewUserAgent {
var topViewController: UIViewController? {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have this logic here: https://github.com/auth0/Auth0.swift/blob/master/Auth0/SafariProvider.swift#L50-L77
Maybe we can put it in some kind of shared helper (e.g. an internal static var added to UIWindow –analogous to rootViewController)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, moved this to a shared helper

guard let root = UIApplication.shared()?.windows.last(where: \.isKeyWindow)?.rootViewController else {
return nil
}
return self.findTopViewController(from: root)
}

private func findTopViewController(from root: UIViewController) -> UIViewController? {
if let presented = root.presentedViewController { return self.findTopViewController(from: presented) }

switch root {
case let split as UISplitViewController:
guard let last = split.viewControllers.last else { return split }
return self.findTopViewController(from: last)
case let navigation as UINavigationController:
guard let top = navigation.topViewController else { return navigation }
return self.findTopViewController(from: top)
case let tab as UITabBarController:
guard let selected = tab.selectedViewController else { return tab }
return self.findTopViewController(from: selected)
default:
return root
}
}
}

class WebViewUserAgent: NSObject, WebAuthUserAgent {

static let customSchemeRedirectionSuccessMessage = "com.auth0.webview.redirection_success"
static let customSchemeRedirectionFailureMessage = "com.auth0.webview.redirection_failure"
let defaultSchemesSupportedByWKWebview = ["http", "https"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest checking with somebody from the security team if we should be supporting http schemes here (vs https only), e.g. when using an authorize URL override that proxies to Auth0.


let request: URLRequest
var webview: WKWebView!
let viewController: UIViewController
let redirectURL: URL
let callback: WebAuthProviderCallback


init(authorizeURL: URL, redirectURL: URL, viewController: UIViewController = UIViewController(), modalPresentationStyle: UIModalPresentationStyle = .fullScreen, callback: @escaping WebAuthProviderCallback) {
self.request = URLRequest(url: authorizeURL)
self.redirectURL = redirectURL
self.callback = callback
self.viewController = viewController
self.viewController.modalPresentationStyle = modalPresentationStyle

super.init()
if !defaultSchemesSupportedByWKWebview.contains(redirectURL.scheme!) {
self.setupWebViewWithCustomScheme()
} else {
self.setupWebViewWithHTTPS()
}
}

private func setupWebViewWithCustomScheme() {
let configuration = WKWebViewConfiguration()
configuration.setURLSchemeHandler(self, forURLScheme: redirectURL.scheme!)
self.webview = WKWebView(frame: .zero, configuration: configuration)
self.viewController.view = webview
webview.navigationDelegate = self
}

private func setupWebViewWithHTTPS() {
self.webview = WKWebView(frame: .zero)
self.viewController.view = webview
webview.navigationDelegate = self
}

func start() {
self.webview.load(self.request)
self.topViewController?.present(self.viewController, animated: true)
}

func finish(with result: WebAuthResult<Void>) {
DispatchQueue.main.async { [weak webview, weak viewController, callback] in
webview?.removeFromSuperview()
guard let presenting = viewController?.presentingViewController else {
let error = WebAuthError(code: .unknown("Cannot dismiss WKWebView"))
return callback(.failure(error))
}
presenting.dismiss(animated: true) {
callback(result)
}
}
}

public override var description: String {
return String(describing: WKWebView.self)
}
}

/// Handling Custom Scheme Callbacks
extension WebViewUserAgent: WKURLSchemeHandler {
func webView(_ webView: WKWebView, start urlSchemeTask: any WKURLSchemeTask) {
_ = TransactionStore.shared.resume(urlSchemeTask.request.url!)
let error = NSError(domain: WebViewUserAgent.customSchemeRedirectionSuccessMessage, code: 200, userInfo: [
NSLocalizedDescriptionKey: "WebViewProvider: WKURLSchemeHandler: Succesfully redirected back to the app"
])
urlSchemeTask.didFailWithError(error)
}

func webView(_ webView: WKWebView, stop urlSchemeTask: any WKURLSchemeTask) {
let error = NSError(domain: WebViewUserAgent.customSchemeRedirectionFailureMessage, code: 400, userInfo: [
NSLocalizedDescriptionKey: "WebViewProvider: WKURLSchemeHandler: Webview Resource Loading has been stopped"
])
urlSchemeTask.didFailWithError(error)
self.finish(with: .failure(WebAuthError(code: .webViewResourceLoadingStopped)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this error case be userCancelled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, updated accordingly

}
}

/// Handling HTTPS Callbacks
extension WebViewUserAgent: WKNavigationDelegate {
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let callbackUrl = navigationAction.request.url, callbackUrl.absoluteString.starts(with: redirectURL.absoluteString) {
_ = TransactionStore.shared.resume(callbackUrl)
decisionHandler(.cancel)
} else {
decisionHandler(.allow)
}
}

func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: any Error) {
if (error as NSError).domain == WebViewUserAgent.customSchemeRedirectionSuccessMessage {
return

Check warning on line 146 in Auth0/WebViewProvider.swift

View check run for this annotation

Codecov / codecov/patch

Auth0/WebViewProvider.swift#L146

Added line #L146 was not covered by tests
}
self.finish(with: .failure(WebAuthError(code: .webViewNavigationFailed, cause: error)))
}

func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: any Error) {
if (error as NSError).domain == WebViewUserAgent.customSchemeRedirectionSuccessMessage {
return

Check warning on line 153 in Auth0/WebViewProvider.swift

View check run for this annotation

Codecov / codecov/patch

Auth0/WebViewProvider.swift#L153

Added line #L153 was not covered by tests
}
self.finish(with: .failure(WebAuthError(code: .webViewProvisionalNavigationFailed, cause: error)))
}

func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
self.finish(with: .failure(WebAuthError(code: .webViewContentProcessTerminated)))
}
}

#endif
2 changes: 1 addition & 1 deletion Auth0Tests/CredentialsManagerSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ class CredentialsManagerSpec: QuickSpec {
credentials = Credentials(accessToken: AccessToken, tokenType: TokenType, idToken: IdToken, refreshToken: RefreshToken, expiresIn: Date(timeIntervalSinceNow: -ExpiresIn))
_ = credentialsManager.store(credentials: credentials)

waitUntil(timeout: Timeout) { done in
waitUntil(timeout: .seconds(5)) { done in
credentialsManager.credentials { result in
expect(result).to(haveCredentialsManagerError(expectedError))
done()
Expand Down
Loading
Loading