Skip to content

Add support for enrolling passkeys with My Account API [SDK-5543] #962

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

Open
wants to merge 35 commits into
base: master
Choose a base branch
from

Conversation

Widcket
Copy link
Contributor

@Widcket Widcket commented May 23, 2025

  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

📋 Changes

This PR adds:

  • A new API client for the My Account API, including its own error type MyAccountError.
  • A sub-client for the authentication methods endpoints.
    • A method for requesting a passkey enrollment challenge.
    • A method for enrolling a newly created passkey.

The new API client was built in a more self-contained fashion, to make it easier to extract into its own package in the future. This required a bit of refactoring of the existing code.

🎯 Testing

Besides a full test suite, the changes were tested manually with Xcode 16.3 (16E140), using:

  • Simulator running iOS 18.4
  • iPhone 14 Pro Max running iOS 18.4

@Widcket Widcket requested a review from a team as a code owner May 23, 2025 19:16
}

/// Generic representation of Auth0 API errors.
public protocol Auth0APIError: Auth0Error {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was moved into its own file.

@@ -27,15 +27,9 @@ public struct AuthenticationError: Auth0APIError, @unchecked Sendable {
/// HTTP status code of the response.
public let statusCode: Int

/// The underlying `Error` value, if any. Defaults to `nil`.
public var cause: Error? {
Copy link
Contributor Author

@Widcket Widcket May 23, 2025

Choose a reason for hiding this comment

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

This was moved into Auth0APIError.

/// - [callIsActive](https://developer.apple.com/documentation/foundation/urlerror/2293147-callisactive)
///
/// The underlying `URLError` is available in the ``Auth0Error/cause-9wuyi`` property.
public var isNetworkError: Bool {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was moved into Auth0APIError, so it's available for all API error types, not just AuthenticationError.

@@ -1,77 +0,0 @@
import Foundation
Copy link
Contributor Author

@Widcket Widcket May 23, 2025

Choose a reason for hiding this comment

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

The contents of this file were moved to AuthenticationHandlers.swift. Since the internal Response type now makes use of Swift 6's typed throws, most handlers no longer need that last catch: callback(.failure(AuthenticationError(cause: error))).

callback(.success(dictionary))
} else {
callback(.failure(ManagementError(from: response)))
}
} catch let error as ManagementError {
Copy link
Contributor Author

@Widcket Widcket May 23, 2025

Choose a reason for hiding this comment

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

Since the internal Response type now makes use of Swift 6's typed throws, these handlers no longer need that last catch: callback(.failure(ManagementError(cause: error))).

@@ -23,14 +23,9 @@ public struct ManagementError: Auth0APIError, @unchecked Sendable {
/// HTTP status code of the response.
public let statusCode: Int

/// The underlying `Error` value, if any. Defaults to `nil`.
public var cause: Error? {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was moved into Auth0APIError.


@testable import Auth0

extension SecKey {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was moved into Generators.swift.

// MARK: - Passkey Enrollment

#if PASSKEYS_PLATFORM
@available(iOS 16.6, macOS 13.5, visionOS 1.0, *)
Copy link
Contributor Author

@Widcket Widcket May 23, 2025

Choose a reason for hiding this comment

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

This is the implementation of the method that requests a passkey enrollment challenge.

telemetry: self.telemetry)
}

@available(iOS 16.6, macOS 13.5, visionOS 1.0, *)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the implementation of the method that enrolls the new passkey.

struct Response<E: Auth0APIError> {
let data: Data?
let response: HTTPURLResponse?
let error: Error?

func result() throws -> Any? {
func result() throws(E) -> JSONResponse? {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This internal method is now using a typed throw.


@available(iOS 16.6, macOS 13.5, visionOS 1.0, *)
extension ASAuthorizationPlatformPublicKeyCredentialRegistration: SignupPasskey {}

@available(iOS 16.6, macOS 13.5, visionOS 1.0, *)
extension ASAuthorizationPublicKeyCredentialAttachment {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was moved into NewPasskey.swift, so it can be used by both the Authentication API client and the My Account API client.

}

#if PASSKEYS_PLATFORM
if #available(iOS 16.6, macOS 13.5, visionOS 1.0, *) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here are the tests for:

  • The method for requesting an enrollment challenge
  • The method for enrolling a newly created passkey


@testable import Auth0

class MyAccountErrorSpec: QuickSpec {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here are the tests for the new error type MyAccountError.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant