Skip to content

Commit

Permalink
feat: Adding visionOS support to the WebAuthn APIs (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
ruisebas authored Nov 15, 2024
1 parent 19eeb30 commit d1263a0
Show file tree
Hide file tree
Showing 32 changed files with 92 additions and 53 deletions.
10 changes: 10 additions & 0 deletions Amplify/Categories/Auth/AuthCategory+WebAuthnBehaviour.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ extension AuthCategory: AuthCategoryWebAuthnBehaviour {
options: options
)
}
#elseif os(visionOS)
public func associateWebAuthnCredential(
presentationAnchor: AuthUIPresentationAnchor,
options: AuthAssociateWebAuthnCredentialRequest.Options? = nil
) async throws {
try await plugin.associateWebAuthnCredential(
presentationAnchor:presentationAnchor,

Check failure on line 28 in Amplify/Categories/Auth/AuthCategory+WebAuthnBehaviour.swift

View workflow job for this annotation

GitHub Actions / run-swiftlint

Colons should be next to the identifier when specifying a type and next to the key in dictionary literals (colon)
options: options
)
}
#endif

public func listWebAuthnCredentials(
Expand Down
5 changes: 5 additions & 0 deletions Amplify/Categories/Auth/AuthCategoryWebAuthnBehaviour.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public protocol AuthCategoryWebAuthnBehaviour: AnyObject {
presentationAnchor: AuthUIPresentationAnchor?,
options: AuthAssociateWebAuthnCredentialRequest.Options?
) async throws
#elseif os(visionOS)
func associateWebAuthnCredential(
presentationAnchor: AuthUIPresentationAnchor,
options: AuthAssociateWebAuthnCredentialRequest.Options?
) async throws
#endif

/// - Tag: AuthCategoryWebAuthnBehaviour.list
Expand Down
4 changes: 2 additions & 2 deletions Amplify/Categories/Auth/Models/AuthFactorType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public enum AuthFactorType: String {
/// An auth factor that uses Email OTP
case emailOTP

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
/// An auth factor that uses WebAuthn
@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
case webAuthn
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// SPDX-License-Identifier: Apache-2.0
//

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import Foundation

/// Request for creating a new WebAuthn Credential and associating it with the signed in user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public extension AuthConfirmSignInRequest {
/// key/values
public let pluginOptions: Any?

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
/// Provide a presentation anchor if you are confirming sign in with WebAuthn. The WebAuthn assertion will be presented
/// in the presentation anchor provided.
public let presentationAnchorForWebAuthn: AuthUIPresentationAnchor?
Expand Down
2 changes: 1 addition & 1 deletion Amplify/Categories/Auth/Request/AuthSignInRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public extension AuthSignInRequest {
/// key/values
public let pluginOptions: Any?

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
/// Provide a presentation anchor if you are signing in with WebAuthn. The WebAuthn assertion will be presented
/// in the presentation anchor provided.
public let presentationAnchorForWebAuthn: AuthUIPresentationAnchor?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ struct VerifySignInChallenge: Action {
}

private func isWebAuthn(_ factorType: AuthFactorType?) -> Bool {
#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
if #available(iOS 17.4, macOS 13.5, *) {
return .webAuthn == factorType
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
// SPDX-License-Identifier: Apache-2.0
//

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import Amplify
import Foundation

@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
struct AssertWebAuthnCredentials: Action {
let identifier = "AssertWebAuthnCredentials"
let username: String
Expand Down Expand Up @@ -75,10 +75,10 @@ struct AssertWebAuthnCredentials: Action {
}
}

@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
extension AssertWebAuthnCredentials: DefaultLogger { }

@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
extension AssertWebAuthnCredentials: CustomDebugDictionaryConvertible {
var debugDictionary: [String: Any] {
[
Expand All @@ -90,7 +90,7 @@ extension AssertWebAuthnCredentials: CustomDebugDictionaryConvertible {
}
}

@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
extension AssertWebAuthnCredentials: CustomDebugStringConvertible {
var debugDescription: String {
debugDictionary.debugDescription
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// SPDX-License-Identifier: Apache-2.0
//

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import Amplify
import Foundation
import AWSCognitoIdentityProvider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// SPDX-License-Identifier: Apache-2.0
//

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import Amplify
import Foundation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,27 @@
// SPDX-License-Identifier: Apache-2.0
//

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import Amplify
import AuthenticationServices
import Foundation

@available(iOS 17.4, macOS 13.5, *)
protocol WebAuthnCredentialsProtocol {
var presentationAnchor: AuthUIPresentationAnchor? { get }
}

@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
protocol CredentialRegistrantProtocol: WebAuthnCredentialsProtocol {
func create(with options: CredentialCreationOptions) async throws -> CredentialRegistrationPayload
}

@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
protocol CredentialAsserterProtocol: WebAuthnCredentialsProtocol {
func assert(with options: CredentialAssertionOptions) async throws -> CredentialAssertionPayload
}

// - MARK: WebAuthnCredentialsProtocol
@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
class PlatformWebAuthnCredentials: NSObject, WebAuthnCredentialsProtocol {
private enum OperationType: String {
case assert
Expand All @@ -43,7 +42,7 @@ class PlatformWebAuthnCredentials: NSObject, WebAuthnCredentialsProtocol {
}

// - MARK: CredentialAsserterProtocol
@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
extension PlatformWebAuthnCredentials: CredentialAsserterProtocol{
func assert(with options: CredentialAssertionOptions) async throws -> CredentialAssertionPayload {
guard assertionContinuation == nil else {
Expand Down Expand Up @@ -96,7 +95,7 @@ extension PlatformWebAuthnCredentials: CredentialAsserterProtocol{
}

// - MARK: CredentialRegistrantProtocol
@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
extension PlatformWebAuthnCredentials: CredentialRegistrantProtocol {
func create(with options: CredentialCreationOptions) async throws -> CredentialRegistrationPayload {
guard registrationContinuation == nil else {
Expand Down Expand Up @@ -130,11 +129,11 @@ extension PlatformWebAuthnCredentials: CredentialRegistrantProtocol {
}
}

@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
extension PlatformWebAuthnCredentials: DefaultLogger {}

// - MARK: ASAuthorizationControllerDelegate
@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
extension PlatformWebAuthnCredentials: ASAuthorizationControllerDelegate {
func authorizationController(
controller: ASAuthorizationController,
Expand Down Expand Up @@ -230,7 +229,7 @@ extension PlatformWebAuthnCredentials: ASAuthorizationControllerDelegate {
}

// - MARK: ASAuthorizationControllerPresentationContextProviding
@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
extension PlatformWebAuthnCredentials: ASAuthorizationControllerPresentationContextProviding {
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
return presentationAnchor ?? ASPresentationAnchor()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
// SPDX-License-Identifier: Apache-2.0
//

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import Amplify
import AWSCognitoIdentityProvider
import Foundation

@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
struct VerifyWebAuthnCredential: Action {
let identifier = "VerifyWebAuthnCredential"
let username: String
Expand Down Expand Up @@ -91,10 +91,10 @@ struct VerifyWebAuthnCredential: Action {
}
}

@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
extension VerifyWebAuthnCredential: DefaultLogger { }

@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
extension VerifyWebAuthnCredential: CustomDebugDictionaryConvertible {
var debugDictionary: [String: Any] {
[
Expand All @@ -106,7 +106,7 @@ extension VerifyWebAuthnCredential: CustomDebugDictionaryConvertible {
}
}

@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
extension VerifyWebAuthnCredential: CustomDebugStringConvertible {
var debugDescription: String {
debugDictionary.debugDescription
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@ extension AWSCognitoAuthPlugin: AuthCategoryWebAuthnBehaviour {
userPoolFactory: authEnvironment.cognitoUserPoolFactory
)

_ = try await taskQueue.sync {
try await task.value
}
}
#elseif os(visionOS)
public func associateWebAuthnCredential(
presentationAnchor: AuthUIPresentationAnchor,
options: AuthAssociateWebAuthnCredentialRequest.Options? = nil
) async throws {
let request = AuthAssociateWebAuthnCredentialRequest(
presentationAnchor: presentationAnchor,
options: options ?? .init()
)
let task = AssociateWebAuthnCredentialTask(
request: request,
authStateMachine: authStateMachine,
userPoolFactory: authEnvironment.cognitoUserPoolFactory
)

_ = try await taskQueue.sync {
try await task.value
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class AuthHubEventHandler: AuthHubEventBehavior {
}
self?.handleSignInEvent(result)

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
case HubPayload.EventName.Auth.webUISignInAPI:
guard let event = payload.data as? AWSAuthWebUISignInTask.AmplifyAuthTaskResult,
case let .success(result) = event else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extension AuthFactorType: DefaultLogger {
case "SMS_OTP": self = .smsOTP
case "EMAIL_OTP": self = .emailOTP
case "WEB_AUTHN":
#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
if #available(iOS 17.4, macOS 13.5, *) {
self = .webAuthn
} else {
Expand Down Expand Up @@ -45,7 +45,7 @@ extension AuthFactorType: DefaultLogger {
case .password: return "PASSWORD"
case .smsOTP: return "SMS_OTP"
case .emailOTP: return "EMAIL_OTP"
#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
case .webAuthn: return "WEB_AUTHN"
#endif
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extension CognitoIdentityProviderClientTypes.ChallengeNameType {
case .smsOtp:
return .smsOTP
case .webAuthn:
#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
if #available(iOS 17.4, macOS 13.5, *) {
return .webAuthn
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// SPDX-License-Identifier: Apache-2.0
//

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import typealias Amplify.AuthUIPresentationAnchor
#endif
import Foundation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// SPDX-License-Identifier: Apache-2.0
//

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import typealias Amplify.AuthUIPresentationAnchor
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// SPDX-License-Identifier: Apache-2.0
//

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import typealias Amplify.AuthUIPresentationAnchor
#endif
import Foundation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation
import AWSCognitoIdentityProvider
#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import typealias Amplify.AuthUIPresentationAnchor
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// SPDX-License-Identifier: Apache-2.0
//

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import Foundation
import Amplify

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ extension SignInState {
actions: [action])
}

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
if let signInEvent = event as? SignInEvent,
case .initiateWebAuthnSignIn(let data, let respondToAuthChallenge) = signInEvent.eventType {
let action = InitializeWebAuthn(
Expand Down Expand Up @@ -466,7 +466,7 @@ extension SignInState {
), actions: [action])
}

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
if let signInEvent = event as? SignInEvent,
case .initiateWebAuthnSignIn(let data, let respondToAuthChallenge) = signInEvent.eventType {
let action = InitializeWebAuthn(
Expand Down Expand Up @@ -504,7 +504,7 @@ extension SignInState {
}
return .from(oldState)
case .signingInWithWebAuthn(let webAuthnState):
#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
if #available(iOS 17.4, macOS 13.5, *) {
if case .throwAuthError(let error) = event.isSignInEvent {
let action = ThrowSignInError(error: error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
// SPDX-License-Identifier: Apache-2.0
//

#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import enum Amplify.AuthFactorType
import Foundation

extension WebAuthnSignInState {

@available(iOS 17.4, macOS 13.5, *)
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
struct Resolver: StateMachineResolver {

typealias StateType = WebAuthnSignInState
Expand Down
Loading

0 comments on commit d1263a0

Please sign in to comment.