@@ -305,11 +305,17 @@ class AppState: ObservableObject {
305305 }
306306
307307 func handleTwoFactorOption( _ option: TwoFactorOption , authOptions: AuthOptionsResponse , serviceKey: String , sessionID: String , scnt: String ) {
308- self . presentedSheet = . twoFactor( . init(
309- option: option,
310- authOptions: authOptions,
311- sessionData: AppleSessionData ( serviceKey: serviceKey, sessionID: sessionID, scnt: scnt)
312- ) )
308+ let sessionData = AppleSessionData ( serviceKey: serviceKey, sessionID: sessionID, scnt: scnt)
309+
310+ if option == . securityKey, fido2DeviceIsPresent ( ) && !fido2DeviceNeedsPin( ) {
311+ createAndSubmitSecurityKeyAssertationWithPinCode ( nil , sessionData: sessionData, authOptions: authOptions)
312+ } else {
313+ self . presentedSheet = . twoFactor( . init(
314+ option: option,
315+ authOptions: authOptions,
316+ sessionData: sessionData
317+ ) )
318+ }
313319 }
314320
315321 func requestSMS( to trustedPhoneNumber: AuthOptionsResponse . TrustedPhoneNumber , authOptions: AuthOptionsResponse , sessionData: AppleSessionData ) {
@@ -355,9 +361,9 @@ class AppState: ObservableObject {
355361 . store ( in: & cancellables)
356362 }
357363
358- var fido2 : FIDO2 ?
359-
360- func createAndSubmitSecurityKeyAssertationWithPinCode( _ pinCode: String , sessionData: AppleSessionData , authOptions: AuthOptionsResponse ) {
364+ private lazy var fido2 = FIDO2 ( )
365+
366+ func createAndSubmitSecurityKeyAssertationWithPinCode( _ pinCode: String ? , sessionData: AppleSessionData , authOptions: AuthOptionsResponse ) {
361367 self . presentedSheet = . securityKeyTouchToConfirm
362368
363369 guard let fsaChallenge = authOptions. fsaChallenge else {
@@ -379,8 +385,6 @@ class AppState: ObservableObject {
379385
380386 Task {
381387 do {
382- let fido2 = FIDO2 ( )
383- self . fido2 = fido2
384388 let response = try fido2. respondToChallenge ( args: ChallengeArgs ( rpId: rpId, validCredentials: validCreds, devPin: pinCode, challenge: challenge, origin: origin) )
385389
386390 Task { @MainActor in
@@ -407,13 +411,31 @@ class AppState: ObservableObject {
407411 // we don't have to show an error
408412 // because the sheet will already be dismissed
409413 } catch {
414+ Task { @MainActor in
415+ authError = error
416+ }
417+ }
418+ }
419+ }
420+
421+ func fido2DeviceIsPresent( ) -> Bool {
422+ fido2. hasDeviceAttached ( )
423+ }
424+
425+ func fido2DeviceNeedsPin( ) -> Bool {
426+ do {
427+ return try fido2. deviceHasPin ( )
428+ } catch {
429+ Task { @MainActor in
410430 authError = error
411431 }
432+
433+ return true
412434 }
413435 }
414436
415437 func cancelSecurityKeyAssertationRequest( ) {
416- self . fido2? . cancel ( )
438+ self . fido2. cancel ( )
417439 }
418440
419441 private func handleAuthenticationFlowCompletion( _ completion: Subscribers . Completion < Error > ) {
0 commit comments