Skip to content

Commit d1263a0

Browse files
authored
feat: Adding visionOS support to the WebAuthn APIs (#171)
1 parent 19eeb30 commit d1263a0

32 files changed

+92
-53
lines changed

Amplify/Categories/Auth/AuthCategory+WebAuthnBehaviour.swift

+10
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ extension AuthCategory: AuthCategoryWebAuthnBehaviour {
1919
options: options
2020
)
2121
}
22+
#elseif os(visionOS)
23+
public func associateWebAuthnCredential(
24+
presentationAnchor: AuthUIPresentationAnchor,
25+
options: AuthAssociateWebAuthnCredentialRequest.Options? = nil
26+
) async throws {
27+
try await plugin.associateWebAuthnCredential(
28+
presentationAnchor:presentationAnchor,
29+
options: options
30+
)
31+
}
2232
#endif
2333

2434
public func listWebAuthnCredentials(

Amplify/Categories/Auth/AuthCategoryWebAuthnBehaviour.swift

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ public protocol AuthCategoryWebAuthnBehaviour: AnyObject {
1515
presentationAnchor: AuthUIPresentationAnchor?,
1616
options: AuthAssociateWebAuthnCredentialRequest.Options?
1717
) async throws
18+
#elseif os(visionOS)
19+
func associateWebAuthnCredential(
20+
presentationAnchor: AuthUIPresentationAnchor,
21+
options: AuthAssociateWebAuthnCredentialRequest.Options?
22+
) async throws
1823
#endif
1924

2025
/// - Tag: AuthCategoryWebAuthnBehaviour.list

Amplify/Categories/Auth/Models/AuthFactorType.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ public enum AuthFactorType: String {
1919
/// An auth factor that uses Email OTP
2020
case emailOTP
2121

22-
#if os(iOS) || os(macOS)
22+
#if os(iOS) || os(macOS) || os(visionOS)
2323
/// An auth factor that uses WebAuthn
24-
@available(iOS 17.4, macOS 13.5, *)
24+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
2525
case webAuthn
2626
#endif
2727
}

Amplify/Categories/Auth/Request/AuthAssociateWebAuthnCredentialRequest.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
#if os(iOS) || os(macOS)
8+
#if os(iOS) || os(macOS) || os(visionOS)
99
import Foundation
1010

1111
/// Request for creating a new WebAuthn Credential and associating it with the signed in user

Amplify/Categories/Auth/Request/AuthConfirmSignInRequest.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public extension AuthConfirmSignInRequest {
3333
/// key/values
3434
public let pluginOptions: Any?
3535

36-
#if os(iOS) || os(macOS)
36+
#if os(iOS) || os(macOS) || os(visionOS)
3737
/// Provide a presentation anchor if you are confirming sign in with WebAuthn. The WebAuthn assertion will be presented
3838
/// in the presentation anchor provided.
3939
public let presentationAnchorForWebAuthn: AuthUIPresentationAnchor?

Amplify/Categories/Auth/Request/AuthSignInRequest.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public extension AuthSignInRequest {
3535
/// key/values
3636
public let pluginOptions: Any?
3737

38-
#if os(iOS) || os(macOS)
38+
#if os(iOS) || os(macOS) || os(visionOS)
3939
/// Provide a presentation anchor if you are signing in with WebAuthn. The WebAuthn assertion will be presented
4040
/// in the presentation anchor provided.
4141
public let presentationAnchorForWebAuthn: AuthUIPresentationAnchor?

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignIn/VerifySignInChallenge.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ struct VerifySignInChallenge: Action {
230230
}
231231

232232
private func isWebAuthn(_ factorType: AuthFactorType?) -> Bool {
233-
#if os(iOS) || os(macOS)
233+
#if os(iOS) || os(macOS) || os(visionOS)
234234
if #available(iOS 17.4, macOS 13.5, *) {
235235
return .webAuthn == factorType
236236
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignIn/WebAuthn/AssertWebAuthnCredentials.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
#if os(iOS) || os(macOS)
8+
#if os(iOS) || os(macOS) || os(visionOS)
99
import Amplify
1010
import Foundation
1111

12-
@available(iOS 17.4, macOS 13.5, *)
12+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
1313
struct AssertWebAuthnCredentials: Action {
1414
let identifier = "AssertWebAuthnCredentials"
1515
let username: String
@@ -75,10 +75,10 @@ struct AssertWebAuthnCredentials: Action {
7575
}
7676
}
7777

78-
@available(iOS 17.4, macOS 13.5, *)
78+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
7979
extension AssertWebAuthnCredentials: DefaultLogger { }
8080

81-
@available(iOS 17.4, macOS 13.5, *)
81+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
8282
extension AssertWebAuthnCredentials: CustomDebugDictionaryConvertible {
8383
var debugDictionary: [String: Any] {
8484
[
@@ -90,7 +90,7 @@ extension AssertWebAuthnCredentials: CustomDebugDictionaryConvertible {
9090
}
9191
}
9292

93-
@available(iOS 17.4, macOS 13.5, *)
93+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
9494
extension AssertWebAuthnCredentials: CustomDebugStringConvertible {
9595
var debugDescription: String {
9696
debugDictionary.debugDescription

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignIn/WebAuthn/FetchCredentialOptions.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
#if os(iOS) || os(macOS)
8+
#if os(iOS) || os(macOS) || os(visionOS)
99
import Amplify
1010
import Foundation
1111
import AWSCognitoIdentityProvider

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignIn/WebAuthn/InitializeWebAuthn.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
#if os(iOS) || os(macOS)
8+
#if os(iOS) || os(macOS) || os(visionOS)
99
import Amplify
1010
import Foundation
1111

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignIn/WebAuthn/PlatformWebAuthnCredentials.swift

+9-10
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,27 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
#if os(iOS) || os(macOS)
8+
#if os(iOS) || os(macOS) || os(visionOS)
99
import Amplify
1010
import AuthenticationServices
1111
import Foundation
1212

13-
@available(iOS 17.4, macOS 13.5, *)
1413
protocol WebAuthnCredentialsProtocol {
1514
var presentationAnchor: AuthUIPresentationAnchor? { get }
1615
}
1716

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

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

2827
// - MARK: WebAuthnCredentialsProtocol
29-
@available(iOS 17.4, macOS 13.5, *)
28+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
3029
class PlatformWebAuthnCredentials: NSObject, WebAuthnCredentialsProtocol {
3130
private enum OperationType: String {
3231
case assert
@@ -43,7 +42,7 @@ class PlatformWebAuthnCredentials: NSObject, WebAuthnCredentialsProtocol {
4342
}
4443

4544
// - MARK: CredentialAsserterProtocol
46-
@available(iOS 17.4, macOS 13.5, *)
45+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
4746
extension PlatformWebAuthnCredentials: CredentialAsserterProtocol{
4847
func assert(with options: CredentialAssertionOptions) async throws -> CredentialAssertionPayload {
4948
guard assertionContinuation == nil else {
@@ -96,7 +95,7 @@ extension PlatformWebAuthnCredentials: CredentialAsserterProtocol{
9695
}
9796

9897
// - MARK: CredentialRegistrantProtocol
99-
@available(iOS 17.4, macOS 13.5, *)
98+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
10099
extension PlatformWebAuthnCredentials: CredentialRegistrantProtocol {
101100
func create(with options: CredentialCreationOptions) async throws -> CredentialRegistrationPayload {
102101
guard registrationContinuation == nil else {
@@ -130,11 +129,11 @@ extension PlatformWebAuthnCredentials: CredentialRegistrantProtocol {
130129
}
131130
}
132131

133-
@available(iOS 17.4, macOS 13.5, *)
132+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
134133
extension PlatformWebAuthnCredentials: DefaultLogger {}
135134

136135
// - MARK: ASAuthorizationControllerDelegate
137-
@available(iOS 17.4, macOS 13.5, *)
136+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
138137
extension PlatformWebAuthnCredentials: ASAuthorizationControllerDelegate {
139138
func authorizationController(
140139
controller: ASAuthorizationController,
@@ -230,7 +229,7 @@ extension PlatformWebAuthnCredentials: ASAuthorizationControllerDelegate {
230229
}
231230

232231
// - MARK: ASAuthorizationControllerPresentationContextProviding
233-
@available(iOS 17.4, macOS 13.5, *)
232+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
234233
extension PlatformWebAuthnCredentials: ASAuthorizationControllerPresentationContextProviding {
235234
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
236235
return presentationAnchor ?? ASPresentationAnchor()

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Actions/SignIn/WebAuthn/VerifyWebAuthnCredential.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
#if os(iOS) || os(macOS)
8+
#if os(iOS) || os(macOS) || os(visionOS)
99
import Amplify
1010
import AWSCognitoIdentityProvider
1111
import Foundation
1212

13-
@available(iOS 17.4, macOS 13.5, *)
13+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
1414
struct VerifyWebAuthnCredential: Action {
1515
let identifier = "VerifyWebAuthnCredential"
1616
let username: String
@@ -91,10 +91,10 @@ struct VerifyWebAuthnCredential: Action {
9191
}
9292
}
9393

94-
@available(iOS 17.4, macOS 13.5, *)
94+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
9595
extension VerifyWebAuthnCredential: DefaultLogger { }
9696

97-
@available(iOS 17.4, macOS 13.5, *)
97+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
9898
extension VerifyWebAuthnCredential: CustomDebugDictionaryConvertible {
9999
var debugDictionary: [String: Any] {
100100
[
@@ -106,7 +106,7 @@ extension VerifyWebAuthnCredential: CustomDebugDictionaryConvertible {
106106
}
107107
}
108108

109-
@available(iOS 17.4, macOS 13.5, *)
109+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
110110
extension VerifyWebAuthnCredential: CustomDebugStringConvertible {
111111
var debugDescription: String {
112112
debugDictionary.debugDescription

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/ClientBehavior/AWSCognitoAuthPlugin+WebAuthnBehaviour.swift

+19
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,25 @@ extension AWSCognitoAuthPlugin: AuthCategoryWebAuthnBehaviour {
2525
userPoolFactory: authEnvironment.cognitoUserPoolFactory
2626
)
2727

28+
_ = try await taskQueue.sync {
29+
try await task.value
30+
}
31+
}
32+
#elseif os(visionOS)
33+
public func associateWebAuthnCredential(
34+
presentationAnchor: AuthUIPresentationAnchor,
35+
options: AuthAssociateWebAuthnCredentialRequest.Options? = nil
36+
) async throws {
37+
let request = AuthAssociateWebAuthnCredentialRequest(
38+
presentationAnchor: presentationAnchor,
39+
options: options ?? .init()
40+
)
41+
let task = AssociateWebAuthnCredentialTask(
42+
request: request,
43+
authStateMachine: authStateMachine,
44+
userPoolFactory: authEnvironment.cognitoUserPoolFactory
45+
)
46+
2847
_ = try await taskQueue.sync {
2948
try await task.value
3049
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/HubEvents/AuthHubEventHandler.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class AuthHubEventHandler: AuthHubEventBehavior {
5252
}
5353
self?.handleSignInEvent(result)
5454

55-
#if os(iOS) || os(macOS)
55+
#if os(iOS) || os(macOS) || os(visionOS)
5656
case HubPayload.EventName.Auth.webUISignInAPI:
5757
guard let event = payload.data as? AWSAuthWebUISignInTask.AmplifyAuthTaskResult,
5858
case let .success(result) = event else {

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Models/AuthFactorTypeExtension.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ extension AuthFactorType: DefaultLogger {
1616
case "SMS_OTP": self = .smsOTP
1717
case "EMAIL_OTP": self = .emailOTP
1818
case "WEB_AUTHN":
19-
#if os(iOS) || os(macOS)
19+
#if os(iOS) || os(macOS) || os(visionOS)
2020
if #available(iOS 17.4, macOS 13.5, *) {
2121
self = .webAuthn
2222
} else {
@@ -45,7 +45,7 @@ extension AuthFactorType: DefaultLogger {
4545
case .password: return "PASSWORD"
4646
case .smsOTP: return "SMS_OTP"
4747
case .emailOTP: return "EMAIL_OTP"
48-
#if os(iOS) || os(macOS)
48+
#if os(iOS) || os(macOS) || os(visionOS)
4949
case .webAuthn: return "WEB_AUTHN"
5050
#endif
5151
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Data/ChallengeNameTypeExtension.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ extension CognitoIdentityProviderClientTypes.ChallengeNameType {
2020
case .smsOtp:
2121
return .smsOTP
2222
case .webAuthn:
23-
#if os(iOS) || os(macOS)
23+
#if os(iOS) || os(macOS) || os(visionOS)
2424
if #available(iOS 17.4, macOS 13.5, *) {
2525
return .webAuthn
2626
}

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Data/ConfirmSignInEventData.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
#if os(iOS) || os(macOS)
8+
#if os(iOS) || os(macOS) || os(visionOS)
99
import typealias Amplify.AuthUIPresentationAnchor
1010
#endif
1111
import Foundation

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Data/SignInEventData.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
#if os(iOS) || os(macOS)
8+
#if os(iOS) || os(macOS) || os(visionOS)
99
import typealias Amplify.AuthUIPresentationAnchor
1010
#endif
1111

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Data/WebAuthnSignInData.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
#if os(iOS) || os(macOS)
8+
#if os(iOS) || os(macOS) || os(visionOS)
99
import typealias Amplify.AuthUIPresentationAnchor
1010
#endif
1111
import Foundation

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Events/SignInEvent.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import Foundation
99
import AWSCognitoIdentityProvider
10-
#if os(iOS) || os(macOS)
10+
#if os(iOS) || os(macOS) || os(visionOS)
1111
import typealias Amplify.AuthUIPresentationAnchor
1212
#endif
1313

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/CodeGen/Events/WebAuthnEvent.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
#if os(iOS) || os(macOS)
8+
#if os(iOS) || os(macOS) || os(visionOS)
99
import Foundation
1010
import Amplify
1111

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/Resolvers/SignIn/SignInState+Resolver.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ extension SignInState {
281281
actions: [action])
282282
}
283283

284-
#if os(iOS) || os(macOS)
284+
#if os(iOS) || os(macOS) || os(visionOS)
285285
if let signInEvent = event as? SignInEvent,
286286
case .initiateWebAuthnSignIn(let data, let respondToAuthChallenge) = signInEvent.eventType {
287287
let action = InitializeWebAuthn(
@@ -466,7 +466,7 @@ extension SignInState {
466466
), actions: [action])
467467
}
468468

469-
#if os(iOS) || os(macOS)
469+
#if os(iOS) || os(macOS) || os(visionOS)
470470
if let signInEvent = event as? SignInEvent,
471471
case .initiateWebAuthnSignIn(let data, let respondToAuthChallenge) = signInEvent.eventType {
472472
let action = InitializeWebAuthn(
@@ -504,7 +504,7 @@ extension SignInState {
504504
}
505505
return .from(oldState)
506506
case .signingInWithWebAuthn(let webAuthnState):
507-
#if os(iOS) || os(macOS)
507+
#if os(iOS) || os(macOS) || os(visionOS)
508508
if #available(iOS 17.4, macOS 13.5, *) {
509509
if case .throwAuthError(let error) = event.isSignInEvent {
510510
let action = ThrowSignInError(error: error)

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/StateMachine/Resolvers/SignIn/WebAuthnSignInState+Resolver.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
#if os(iOS) || os(macOS)
8+
#if os(iOS) || os(macOS) || os(visionOS)
99
import enum Amplify.AuthFactorType
1010
import Foundation
1111

1212
extension WebAuthnSignInState {
1313

14-
@available(iOS 17.4, macOS 13.5, *)
14+
@available(iOS 17.4, macOS 13.5, visionOS 1.0, *)
1515
struct Resolver: StateMachineResolver {
1616

1717
typealias StateType = WebAuthnSignInState

0 commit comments

Comments
 (0)