diff --git a/Auth0/APICredentials.swift b/Auth0/APICredentials.swift index 72681269..9e227b75 100644 --- a/Auth0/APICredentials.swift +++ b/Auth0/APICredentials.swift @@ -87,9 +87,7 @@ extension APICredentials: Codable { } -// MARK: - Internal Initializer - -extension APICredentials { +public extension APICredentials { init(from credentials: Credentials) { self.accessToken = credentials.accessToken diff --git a/Auth0/AuthenticationError.swift b/Auth0/AuthenticationError.swift index 8df293e3..f73e6b5f 100644 --- a/Auth0/AuthenticationError.swift +++ b/Auth0/AuthenticationError.swift @@ -142,7 +142,7 @@ public struct AuthenticationError: Auth0APIError, @unchecked Sendable { // MARK: - Error Messages -extension AuthenticationError { +public extension AuthenticationError { var message: String { if let description = self.info[apiErrorDescription] as? String ?? self.info["error_description"] as? String { diff --git a/Auth0/CredentialsManager.swift b/Auth0/CredentialsManager.swift index 3f024ecb..f8549b6e 100644 --- a/Auth0/CredentialsManager.swift +++ b/Auth0/CredentialsManager.swift @@ -610,7 +610,7 @@ public struct CredentialsManager { callback: callback) } - func store(apiCredentials: APICredentials, forAudience audience: String) -> Bool { + public func store(apiCredentials: APICredentials, forAudience audience: String) -> Bool { guard let data = try? apiCredentials.encode() else { return false } diff --git a/Auth0/CredentialsManagerError.swift b/Auth0/CredentialsManagerError.swift index a7d4e901..636afc07 100644 --- a/Auth0/CredentialsManagerError.swift +++ b/Auth0/CredentialsManagerError.swift @@ -70,12 +70,10 @@ public struct CredentialsManagerError: Auth0Error, Sendable { /// increase the **Token Expiration** value in the settings page of your [Auth0 API](https://manage.auth0.com/#/apis/). /// This error does not include a ``Auth0Error/cause-9wuyi``. public static let largeMinTTL: CredentialsManagerError = .init(code: .largeMinTTL(minTTL: 0, lifetime: 0)) - } // MARK: - Error Messages - -extension CredentialsManagerError { +public extension CredentialsManagerError { var message: String { switch self.code { diff --git a/Auth0/MyAccount/AuthenticationMethods/Auth0MyAccountAuthenticationMethods.swift b/Auth0/MyAccount/AuthenticationMethods/Auth0MyAccountAuthenticationMethods.swift index a508e5dd..f61c8825 100644 --- a/Auth0/MyAccount/AuthenticationMethods/Auth0MyAccountAuthenticationMethods.swift +++ b/Auth0/MyAccount/AuthenticationMethods/Auth0MyAccountAuthenticationMethods.swift @@ -1,6 +1,6 @@ import Foundation -struct Auth0MyAccountAuthenticationMethods: MyAccountAuthenticationMethods { +struct Auth0MyAccountAuthenticationMethods: MyAccountAuthenticationMethods { let url: URL let session: URLSession let token: String diff --git a/Auth0/MyAccount/AuthenticationMethods/MyAccountAuthenticationMethods.swift b/Auth0/MyAccount/AuthenticationMethods/MyAccountAuthenticationMethods.swift index cee548d3..263a1dfc 100644 --- a/Auth0/MyAccount/AuthenticationMethods/MyAccountAuthenticationMethods.swift +++ b/Auth0/MyAccount/AuthenticationMethods/MyAccountAuthenticationMethods.swift @@ -4,7 +4,7 @@ /// - ``MyAccount`` /// - ``MyAccountError`` public protocol MyAccountAuthenticationMethods: MyAccountClient { - + #if PASSKEYS_PLATFORM /// Requests a challenge for enrolling a new passkey. This is the first part of the enrollment flow. /// @@ -75,7 +75,7 @@ public protocol MyAccountAuthenticationMethods: MyAccountClient { @available(iOS 16.6, macOS 13.5, visionOS 1.0, *) func passkeyEnrollmentChallenge(userIdentityId: String?, connection: String?) -> Request - + /// Enrolls a new passkey credential. This is the last part of the enrollment flow. /// /// ## Availability @@ -184,7 +184,7 @@ public protocol MyAccountAuthenticationMethods: MyAccountClient { /// - authSession: The unique session identifier for the enrollment as returned by POST /authentication-methods /// - Returns: A request that will yield an enrolled recovery code authentication method. func confirmRecoveryCodeEnrollment(id: String, - authSession: String) -> Request + authSession: String) -> Request /// Requests a challenge for enrolling a TOTP authentication method. This is the first part of the enrollment flow. /// @@ -394,8 +394,8 @@ public protocol MyAccountAuthenticationMethods: MyAccountClient { /// - otpCode: The one-time password code sent to the email address. /// - Returns: A request that will yield an enrolled email authentication method. func confirmEmailEnrollment(id: String, - authSession: String, - otpCode: String) -> Request + authSession: String, + otpCode: String) -> Request /// Requests a challenge for enrolling a Phone authentication method. This is the first part of the enrollment flow. /// @@ -471,7 +471,7 @@ public protocol MyAccountAuthenticationMethods: MyAccountClient { authSession: String, otpCode: String) -> Request - /// Retrieve detailed list of authentication methods belonging to the authenticated user. + /// Delete an authentication method associated with an id /// /// ## Availability /// @@ -481,7 +481,7 @@ public protocol MyAccountAuthenticationMethods: MyAccountClient { /// /// ## Scopes Required /// - /// `read:me:authentication_methods` + /// `delete:me:authentication_methods` /// /// ## Usage /// @@ -489,21 +489,23 @@ public protocol MyAccountAuthenticationMethods: MyAccountClient { /// Auth0 /// .myAccount(token: apiCredentials.accessToken) /// .authenticationMethods - /// .getAuthenticationMethods() + /// .deleteAuthenticationMethod(by: id) /// .start { result in /// switch result { - /// case .success(let authenticationMethods): - /// print("List of Authentication methods: \(authenticationMethods)") + /// case .success: + /// print("Authentication method is deleted") /// case .failure(let error): /// print("Failed with: \(error)") /// } /// } /// ``` /// - /// - Returns: A request that will return list of authentication methods of an authenticated user - func getAuthenticationMethods() -> Request<[AuthenticationMethod], MyAccountError> + /// - Parameters: + /// - id: Id of the authentication method user wishes to delete + /// - Returns: A request that will delete an authentication method associated with an id + func deleteAuthenticationMethod(by id: String) -> Request - /// Delete an authentication method associated with an id + /// Fetch details of an authentication method associated with an id /// /// ## Availability /// @@ -513,7 +515,7 @@ public protocol MyAccountAuthenticationMethods: MyAccountClient { /// /// ## Scopes Required /// - /// `delete:me:authentication_methods` + /// `read:me:authentication_methods` /// /// ## Usage /// @@ -521,11 +523,11 @@ public protocol MyAccountAuthenticationMethods: MyAccountClient { /// Auth0 /// .myAccount(token: apiCredentials.accessToken) /// .authenticationMethods - /// .deleteAuthenticationMethod(by: id) + /// .getAuthenticationMethod(by: id) /// .start { result in /// switch result { - /// case .success: - /// print("Authentication method is deleted") + /// case .success(let authenticationMethod): + /// print("Fetched authentication method: \(authenticationMethod)") /// case .failure(let error): /// print("Failed with: \(error)") /// } @@ -533,11 +535,11 @@ public protocol MyAccountAuthenticationMethods: MyAccountClient { /// ``` /// /// - Parameters: - /// - id: Id of the authentication method user wishes to delete - /// - Returns: A request that will delete an authentication method associated with an id - func deleteAuthenticationMethod(by id: String) -> Request + /// - id: Id of the returned authentication method + /// - Returns: A request to fetch authentication method associated with the id. + func getAuthenticationMethod(by id: String) -> Request - /// Fetch details of an authentication method associated with an id + /// Retrieve detailed list of authentication methods belonging to the authenticated user. /// /// ## Availability /// @@ -555,21 +557,19 @@ public protocol MyAccountAuthenticationMethods: MyAccountClient { /// Auth0 /// .myAccount(token: apiCredentials.accessToken) /// .authenticationMethods - /// .getAuthenticationMethod(by: id) + /// .getAuthenticationMethods() /// .start { result in /// switch result { - /// case .success(let authenticationMethod): - /// print("Fetched authentication method: \(authenticationMethod)") + /// case .success(let authenticationMethods): + /// print("List of Authentication methods: \(authenticationMethods)") /// case .failure(let error): /// print("Failed with: \(error)") /// } /// } /// ``` /// - /// - Parameters: - /// - id: Id of the returned authentication method - /// - Returns: A request to fetch authentication method associated with the id. - func getAuthenticationMethod(by id: String) -> Request + /// - Returns: A request that will return list of authentication methods of an authenticated user + func getAuthenticationMethods() -> Request<[AuthenticationMethod], MyAccountError> /// List of factors enabled for the Auth0 tenant and available for enrollment by this user. /// diff --git a/Auth0/MyAccount/MyAccountError.swift b/Auth0/MyAccount/MyAccountError.swift index a162c329..779e9ccd 100644 --- a/Auth0/MyAccount/MyAccountError.swift +++ b/Auth0/MyAccount/MyAccountError.swift @@ -5,11 +5,14 @@ public struct MyAccountError: Auth0APIError, @unchecked Sendable { public struct ValidationError: Sendable, Equatable { /// Information about the validation error. - let detail: String + public let detail: String /// The property in the request payload that failed validation. - let pointer: String? + public let pointer: String? + public let source: String? + + public let field: String? } /// Raw error values. @@ -62,7 +65,7 @@ public struct MyAccountError: Auth0APIError, @unchecked Sendable { // MARK: - Error Messages -extension MyAccountError { +public extension MyAccountError { var message: String { if self.code == unknownError { @@ -98,6 +101,8 @@ extension MyAccountError.ValidationError { self.detail = dict["detail"] as? String ?? "" self.pointer = pointer.isEmpty ? nil : pointer + self.field = dict["field"] as? String + self.source = dict["source"] as? String } } diff --git a/Auth0/Request.swift b/Auth0/Request.swift index cee566de..13230a12 100644 --- a/Auth0/Request.swift +++ b/Auth0/Request.swift @@ -121,7 +121,9 @@ public struct Request: Requestable { } else { handle(.failure(error), callback) } + print(error) } catch { + print(error) handle(.failure(E(cause: error)), callback) } }) diff --git a/Auth0/Requestable.swift b/Auth0/Requestable.swift index fe438d30..970d4446 100644 --- a/Auth0/Requestable.swift +++ b/Auth0/Requestable.swift @@ -1,8 +1,8 @@ import Foundation +import Combine -protocol Requestable { +public protocol Requestable { associatedtype ResultType associatedtype ErrorType: Auth0APIError - func start(_ callback: @escaping (Result) -> Void) } diff --git a/Auth0/WebAuthError.swift b/Auth0/WebAuthError.swift index 750ddbb2..cc815baa 100644 --- a/Auth0/WebAuthError.swift +++ b/Auth0/WebAuthError.swift @@ -79,7 +79,7 @@ public struct WebAuthError: Auth0Error, Sendable { // MARK: - Error Messages -extension WebAuthError { +public extension WebAuthError { var message: String { switch self.code { diff --git a/Auth0Tests/MyAccount/AuthenticationMethods/MyAccountAuthenticationMethodsSpec.swift b/Auth0Tests/MyAccount/AuthenticationMethods/MyAccountAuthenticationMethodsSpec.swift index dce9f2d1..353fbbaf 100644 --- a/Auth0Tests/MyAccount/AuthenticationMethods/MyAccountAuthenticationMethodsSpec.swift +++ b/Auth0Tests/MyAccount/AuthenticationMethods/MyAccountAuthenticationMethodsSpec.swift @@ -456,7 +456,7 @@ class MyAccountAuthenticationMethodsSpec: QuickSpec { waitUntil(timeout: Timeout) { done in authMethods.enrollPhone(phoneNumber: PhoneNumber, preferredAuthenticationMethod: preferredAuthMethod).start { result in - expect(result).to(haveAuthMethodEnrolmentError(type: "https://auth0.com/api-errors/A0E-400-0003", title: "Validation Error", detail: "Invalid request payload input", statusCode: 400, validationErrors: [MyAccountError.ValidationError(detail: "data/preferred_authentication_method must be equal to one of the allowed values", pointer: "/preferred_authentication_method")])) + expect(result).to(haveAuthMethodEnrolmentError(type: "https://auth0.com/api-errors/A0E-400-0003", title: "Validation Error", detail: "Invalid request payload input", statusCode: 400, validationErrors: [MyAccountError.ValidationError(detail: "data/preferred_authentication_method must be equal to one of the allowed values", pointer: "/preferred_authentication_method", source: nil, field: nil)])) done() } } diff --git a/Auth0Tests/MyAccount/MyAccountErrorSpec.swift b/Auth0Tests/MyAccount/MyAccountErrorSpec.swift index f65179d6..2891110c 100644 --- a/Auth0Tests/MyAccount/MyAccountErrorSpec.swift +++ b/Auth0Tests/MyAccount/MyAccountErrorSpec.swift @@ -257,10 +257,10 @@ class MyAccountErrorSpec: QuickSpec { it("should return the validation errors") { let expectedValidationErrors: [(json: [String: String], error: MyAccountError.ValidationError)] = [ - (json: ["detail": ""], error: .init(detail: "", pointer: nil)), - (json: ["detail": "foo"], error: .init(detail: "foo", pointer: nil)), - (json: ["detail": "foo", "pointer": ""], error: .init(detail: "foo", pointer: nil)), - (json: ["detail": "foo", "pointer": "baz"], error: .init(detail: "foo", pointer: "baz")), + (json: ["detail": ""], error: .init(detail: "", pointer: nil, source: nil, field: nil)), + (json: ["detail": "foo"], error: .init(detail: "foo", pointer: nil, source: nil, field: nil)), + (json: ["detail": "foo", "pointer": ""], error: .init(detail: "foo", pointer: nil, source: nil, field: nil)), + (json: ["detail": "foo", "pointer": "baz"], error: .init(detail: "foo", pointer: "baz", source: nil, field: nil)), ] let info: [String: Any] = ["validation_errors": expectedValidationErrors.map(\.json)] let error = MyAccountError(info: info, statusCode: 400)