diff --git a/Auth0/AuthenticationServicesSession.swift b/Auth0/AuthenticationServicesSession.swift index 53cb6ba5..fbefff90 100644 --- a/Auth0/AuthenticationServicesSession.swift +++ b/Auth0/AuthenticationServicesSession.swift @@ -44,9 +44,9 @@ final class AuthenticationServicesSession: SessionTransaction { guard $1 == nil, let callbackURL = $0 else { let authError = $1 ?? WebAuthError.unknownError if case ASWebAuthenticationSessionError.canceledLogin = authError { - self?.callback(.failure(error: WebAuthError.userCancelled)) + self?.callback(.failure(WebAuthError.userCancelled)) } else { - self?.callback(.failure(error: authError)) + self?.callback(.failure(authError)) } return TransactionStore.shared.clear() } diff --git a/Auth0/BaseAuthTransaction.swift b/Auth0/BaseAuthTransaction.swift index a69334b1..de73fe37 100644 --- a/Auth0/BaseAuthTransaction.swift +++ b/Auth0/BaseAuthTransaction.swift @@ -47,20 +47,20 @@ class BaseAuthTransaction: NSObject, AuthTransaction { } func cancel() { - self.callback(Result.failure(error: WebAuthError.userCancelled)) + self.callback(Result.failure(WebAuthError.userCancelled)) } func handleUrl(_ url: URL) -> Bool { self.logger?.trace(url: url, source: "iOS Safari") guard url.absoluteString.lowercased().hasPrefix(self.redirectURL.absoluteString.lowercased()) else { return false } guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else { - self.callback(.failure(error: AuthenticationError(string: url.absoluteString, statusCode: 200))) + self.callback(.failure(AuthenticationError(string: url.absoluteString, statusCode: 200))) return false } let items = self.handler.values(fromComponents: components) guard has(state: self.state, inItems: items) else { return false } if items["error"] != nil { - self.callback(.failure(error: AuthenticationError(info: items, statusCode: 0))) + self.callback(.failure(AuthenticationError(info: items, statusCode: 0))) } else { self.handler.credentials(from: items, callback: self.callback) } diff --git a/Auth0/BaseWebAuth.swift b/Auth0/BaseWebAuth.swift index 0b34c8e0..e01a8602 100644 --- a/Auth0/BaseWebAuth.swift +++ b/Auth0/BaseWebAuth.swift @@ -152,10 +152,10 @@ class BaseWebAuth: WebAuthenticatable { func start(_ callback: @escaping (Result) -> Void) { guard let redirectURL = self.redirectURL else { - return callback(Result.failure(error: WebAuthError.noBundleIdentifierFound)) + return callback(Result.failure(WebAuthError.noBundleIdentifierFound)) } if self.responseType.contains(.idToken) { - guard self.nonce != nil else { return callback(Result.failure(error: WebAuthError.noNonceProvided)) } + guard self.nonce != nil else { return callback(Result.failure(WebAuthError.noNonceProvided)) } } let handler = self.handler(redirectURL) let state = self.parameters["state"] ?? generateDefaultState() @@ -165,7 +165,7 @@ class BaseWebAuth: WebAuthenticatable { guard let queryItems = URLComponents(url: invitationURL, resolvingAgainstBaseURL: false)?.queryItems, let organizationId = queryItems.first(where: { $0.name == "organization" })?.value, let invitationId = queryItems.first(where: { $0.name == "invitation" })?.value else { - return callback(.failure(error: WebAuthError.unknownError)) // TODO: On the next major, create a new error case + return callback(.failure(WebAuthError.unknownError)) // TODO: On the next major, create a new error case } organization = organizationId invitation = invitationId @@ -205,7 +205,7 @@ class BaseWebAuth: WebAuthenticatable { } #endif // TODO: On the next major add a new case to WebAuthError - callback(.failure(error: WebAuthError.unknownError)) + callback(.failure(WebAuthError.unknownError)) return nil } diff --git a/Auth0/Handlers.swift b/Auth0/Handlers.swift index 8833a87d..ad51b7eb 100644 --- a/Auth0/Handlers.swift +++ b/Auth0/Handlers.swift @@ -25,13 +25,13 @@ import Foundation func plainJson(from response: Response, callback: Request<[String: Any], AuthenticationError>.Callback) { do { if let dictionary = try response.result() as? [String: Any] { - callback(.success(result: dictionary)) + callback(.success(dictionary)) } else { - callback(.failure(error: AuthenticationError(string: string(response.data)))) + callback(.failure(AuthenticationError(string: string(response.data)))) } } catch let error { - callback(.failure(error: error)) + callback(.failure(error)) } } @@ -41,26 +41,26 @@ func codable(from response: Response, callback: let data = try JSONSerialization.data(withJSONObject: dictionary) let decoder = JSONDecoder() let decodedObject = try decoder.decode(T.self, from: data) - callback(.success(result: decodedObject)) + callback(.success(decodedObject)) } else { - callback(.failure(error: AuthenticationError(string: string(response.data)))) + callback(.failure(AuthenticationError(string: string(response.data)))) } } catch let error { - callback(.failure(error: error)) + callback(.failure(error)) } } func authenticationObject(from response: Response, callback: Request.Callback) { do { if let dictionary = try response.result() as? [String: Any], let object = T(json: dictionary) { - callback(.success(result: object)) + callback(.success(object)) } else { - callback(.failure(error: AuthenticationError(string: string(response.data)))) + callback(.failure(AuthenticationError(string: string(response.data)))) } } catch let error { - callback(.failure(error: error)) + callback(.failure(error)) } } @@ -69,23 +69,23 @@ func databaseUser(from response: Response, callback: Reques if let dictionary = try response.result() as? [String: Any], let email = dictionary["email"] as? String { let username = dictionary["username"] as? String let verified = dictionary["email_verified"] as? Bool ?? false - callback(.success(result: (email: email, username: username, verified: verified))) + callback(.success((email: email, username: username, verified: verified))) } else { - callback(.failure(error: AuthenticationError(string: string(response.data)))) + callback(.failure(AuthenticationError(string: string(response.data)))) } } catch let error { - callback(.failure(error: error)) + callback(.failure(error)) } } func noBody(from response: Response, callback: Request.Callback) { do { _ = try response.result() - callback(.success(result: ())) + callback(.success(())) } catch let error as Auth0Error where error.code == emptyBodyError { - callback(.success(result: ())) + callback(.success(())) } catch let error { - callback(.failure(error: error)) + callback(.failure(error)) } } diff --git a/Auth0/Management.swift b/Auth0/Management.swift index 839bfadb..c9c26dca 100644 --- a/Auth0/Management.swift +++ b/Auth0/Management.swift @@ -45,24 +45,24 @@ struct Management: Trackable, Loggable { func managementObject(response: Response, callback: Request.Callback) { do { if let dictionary = try response.result() as? ManagementObject { - callback(.success(result: dictionary)) + callback(.success(dictionary)) } else { - callback(.failure(error: ManagementError(string: string(response.data)))) + callback(.failure(ManagementError(string: string(response.data)))) } } catch let error { - callback(.failure(error: error)) + callback(.failure(error)) } } func managementObjects(response: Response, callback: Request<[ManagementObject], ManagementError>.Callback) { do { if let list = try response.result() as? [ManagementObject] { - callback(.success(result: list)) + callback(.success(list)) } else { - callback(.failure(error: ManagementError(string: string(response.data)))) + callback(.failure(ManagementError(string: string(response.data)))) } } catch let error { - callback(.failure(error: error)) + callback(.failure(error)) } } diff --git a/Auth0/MobileWebAuth.swift b/Auth0/MobileWebAuth.swift index b4e3defa..368c0017 100644 --- a/Auth0/MobileWebAuth.swift +++ b/Auth0/MobileWebAuth.swift @@ -187,7 +187,7 @@ final class MobileWebAuth: BaseWebAuth, WebAuth { } else { DispatchQueue.main.async { guard let presenting = controller?.presentingViewController else { - return callback(Result.failure(error: WebAuthError.cannotDismissWebAuthController)) + return callback(Result.failure(WebAuthError.cannotDismissWebAuthController)) } presenting.dismiss(animated: true) { callback(result) @@ -285,9 +285,9 @@ final class SafariServicesSession: SessionTransaction { guard $1 == nil, let callbackURL = $0 else { let authError = $1 ?? WebAuthError.unknownError if case SFAuthenticationError.canceledLogin = authError { - self.callback(.failure(error: WebAuthError.userCancelled)) + self.callback(.failure(WebAuthError.userCancelled)) } else { - self.callback(.failure(error: authError)) + self.callback(.failure(authError)) } return TransactionStore.shared.clear() } diff --git a/Auth0/NativeAuth.swift b/Auth0/NativeAuth.swift index c261f09f..b669ca2e 100644 --- a/Auth0/NativeAuth.swift +++ b/Auth0/NativeAuth.swift @@ -74,7 +74,7 @@ public protocol NativeAuthTransaction: AuthTransaction { ``` let credetials = NativeAuthCredentials(token: "{IdP Token}", extras: [:]) - let result = Auth0.Result.success(result: credentials) + let result = Auth0.Result.success(credentials) ``` - parameter callback: callback with the IdP credentials on success or the cause of the error. */ @@ -121,7 +121,7 @@ public extension NativeAuthTransaction { self.authentication.loginSocial(token: credentials.token, connection: self.connection, scope: self.scope, parameters: parameters) .start(callback) case .failure(let error): - callback(.failure(error: error)) + callback(.failure(error)) } } } diff --git a/Auth0/OAuth2Grant.swift b/Auth0/OAuth2Grant.swift index 9723cb15..601a717f 100644 --- a/Auth0/OAuth2Grant.swift +++ b/Auth0/OAuth2Grant.swift @@ -72,11 +72,11 @@ struct ImplicitGrant: OAuth2Grant { nonce: self.defaults["nonce"], organization: self.organization) validateFrontChannelIDToken(idToken: values["id_token"], for: responseType, with: validatorContext) { error in - if let error = error { return callback(.failure(error: error)) } + if let error = error { return callback(.failure(error)) } guard !responseType.contains(.token) || values["access_token"] != nil else { - return callback(.failure(error: WebAuthError.missingAccessToken)) + return callback(.failure(WebAuthError.missingAccessToken)) } - callback(.success(result: Credentials(json: values as [String: Any]))) + callback(.success(Credentials(json: values as [String: Any]))) } } @@ -152,7 +152,7 @@ struct PKCE: OAuth2Grant { func credentials(from values: [String: String], callback: @escaping (Result) -> Void) { guard let code = values["code"] else { let string = "No code found in parameters \(values)" - return callback(.failure(error: AuthenticationError(string: string))) + return callback(.failure(AuthenticationError(string: string))) } let idToken = values["id_token"] let responseType = self.responseType @@ -168,7 +168,7 @@ struct PKCE: OAuth2Grant { nonce: self.defaults["nonce"], organization: self.organization) validateFrontChannelIDToken(idToken: idToken, for: responseType, with: validatorContext) { error in - if let error = error { return callback(.failure(error: error)) } + if let error = error { return callback(.failure(error)) } authentication .tokenExchange(withCode: code, codeVerifier: verifier, redirectURI: redirectUrlString) .start { result in @@ -176,12 +176,12 @@ struct PKCE: OAuth2Grant { case .failure(let error as AuthenticationError) where error.description == "Unauthorized": // Special case for PKCE when the correct method for token endpoint authentication is not set (it should be None) let webAuthError = WebAuthError.pkceNotAllowed("Unable to complete authentication with PKCE. PKCE support can be enabled by setting Application Type to 'Native' and Token Endpoint Authentication Method to 'None' for this app at 'https://manage.auth0.com/#/applications/\(clientId)/settings'.") - return callback(.failure(error: webAuthError)) - case .failure(let error): return callback(.failure(error: error)) + return callback(.failure(webAuthError)) + case .failure(let error): return callback(.failure(error)) case .success(let credentials): guard isFrontChannelIdTokenExpected else { return validate(idToken: credentials.idToken, with: validatorContext) { error in - if let error = error { return callback(.failure(error: error)) } + if let error = error { return callback(.failure(error)) } callback(result) } } @@ -191,7 +191,7 @@ struct PKCE: OAuth2Grant { refreshToken: credentials.refreshToken, expiresIn: credentials.expiresIn, scope: credentials.scope) - return callback(.success(result: newCredentials)) + return callback(.success(newCredentials)) } } } diff --git a/Auth0/Request.swift b/Auth0/Request.swift index cdffa216..b899695f 100644 --- a/Auth0/Request.swift +++ b/Auth0/Request.swift @@ -116,7 +116,7 @@ public struct ConcatRequest: Requestable { first.start { result in switch result { case .failure(let cause): - callback(.failure(error: cause)) + callback(.failure(cause)) case .success: second.start(callback) } diff --git a/Auth0/Result.swift b/Auth0/Result.swift index 5d9d1664..7552d3a8 100644 --- a/Auth0/Result.swift +++ b/Auth0/Result.swift @@ -22,6 +22,7 @@ import Foundation +#if swift(<5.0) /** Result object for Auth0 APIs requests @@ -29,6 +30,35 @@ import Foundation - Failure: request failed with a specific error */ public enum Result { - case success(result: T) - case failure(error: Error) + case success(T) + case failure(Error) } + +// Shims for older interface with named parameters +extension Result { + @available(*, deprecated, renamed: "success(_:)") + public static func success(result: T) -> Self { + return .success(result) + } + + @available(*, deprecated, renamed: "failure(_:)") + public static func failure(error: Error) -> Self { + return .failure(error) + } +} +#else +public typealias Result = Swift.Result + +// Shims for older interface with named parameters +extension Result { + @available(*, deprecated, renamed: "success(_:)") + public static func success(result: Success) -> Self { + return .success(result) + } + + @available(*, deprecated, renamed: "failure(_:)") + public static func failure(error: Failure) -> Self { + return .failure(error) + } +} +#endif diff --git a/Auth0Tests/NativeAuthSpec.swift b/Auth0Tests/NativeAuthSpec.swift index 22d76536..c61ff8ce 100644 --- a/Auth0Tests/NativeAuthSpec.swift +++ b/Auth0Tests/NativeAuthSpec.swift @@ -62,7 +62,7 @@ class MockNativeAuthTransaction: NativeAuthTransaction { } func cancel() { - self.delayed(.failure(error: WebAuthError.userCancelled)) + self.delayed(.failure(WebAuthError.userCancelled)) self.delayed = { _ in } } @@ -82,7 +82,7 @@ class MockNativeAuthTransaction: NativeAuthTransaction { /// Test Hooks var onNativeAuth: () -> Result = { - return .success(result: NativeAuthCredentials(token: FacebookToken, extras: [:])) + return .success(NativeAuthCredentials(token: FacebookToken, extras: [:])) } } @@ -162,7 +162,7 @@ class NativeAuthSpec: QuickSpec { it("should yield error on native auth failure") { nativeTransaction.onNativeAuth = { - return .failure(error: WebAuthError.missingAccessToken) + return .failure(WebAuthError.missingAccessToken) } waitUntil(timeout: Timeout) { done in nativeTransaction.start { result in @@ -181,7 +181,7 @@ class NativeAuthSpec: QuickSpec { it("should yield auth error on invalid native access token") { nativeTransaction.onNativeAuth = { - return .success(result: NativeAuthCredentials(token: InvalidFacebookToken, extras: [:])) + return .success(NativeAuthCredentials(token: InvalidFacebookToken, extras: [:])) } waitUntil(timeout: Timeout) { done in nativeTransaction.start { result in diff --git a/Auth0Tests/WebAuthSpec.swift b/Auth0Tests/WebAuthSpec.swift index e2e7671b..44893295 100644 --- a/Auth0Tests/WebAuthSpec.swift +++ b/Auth0Tests/WebAuthSpec.swift @@ -425,13 +425,13 @@ class WebAuthSpec: QuickSpec { it("should fail if controller is not presented") { let callback = newWebAuth().newSafari(DomainURL, callback: { result = $0 }).1 - callback(.success(result: Credentials(json: ["access_token": "at", "token_type": "bearer"]))) + callback(.success(Credentials(json: ["access_token": "at", "token_type": "bearer"]))) expect(result).toEventually(beFailure()) } it("should fail if user dismissed safari viewcontroller") { let callback = newWebAuth().newSafari(DomainURL, callback: { result = $0 }).1 - callback(.failure(error: WebAuthError.userCancelled)) + callback(.failure(WebAuthError.userCancelled)) expect(result).toEventually(beFailure()) } diff --git a/README.md b/README.md index a3fd3e0d..c1e9ecdc 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Swift toolkit that lets you communicate efficiently with many of the [Auth0 API](https://auth0.com/docs/api/info) functions and enables you to seamlessly integrate the Auth0 login. ## Important Notices + [Behaviour changes in iOS 13](https://github.com/auth0/Auth0.swift/pull/297) related to Web Authentication require that developers using Xcode 11 with this library **must** compile using Swift 5.x. This *should* be the default setting applied when updating, unless it has been manually set. However, we recommend checking that this value is set correctly. ## Table of Contents