@@ -438,3 +438,63 @@ async fn make_credential_returns_err_when_rk_is_requested_but_not_supported() {
438438 // Assert
439439 assert_eq ! ( err, Ctap2Error :: UnsupportedOption . into( ) ) ;
440440}
441+ #[ tokio:: test]
442+ async fn empty_store_with_exclude_credentials_succeeds ( ) {
443+ // This test verifies the fix for the issue where an empty credential store
444+ // would return NoCredentials error when checking excludeCredentials,
445+ // causing credential creation to fail incorrectly.
446+
447+ let cred_id: Bytes = random_vec ( 16 ) . into ( ) ;
448+ let request = Request {
449+ exclude_list : Some ( vec ! [ webauthn:: PublicKeyCredentialDescriptor {
450+ ty: webauthn:: PublicKeyCredentialType :: PublicKey ,
451+ id: cred_id. clone( ) ,
452+ transports: Some ( vec![ webauthn:: AuthenticatorTransport :: Usb ] ) ,
453+ } ] ) ,
454+ ..good_request ( )
455+ } ;
456+
457+ // Use an empty store - previously this would cause NoCredentials error
458+ let shared_store = Arc :: new ( Mutex :: new ( MemoryStore :: new ( ) ) ) ;
459+ let user_mock = MockUserValidationMethod :: verified_user_with_hint (
460+ 1 ,
461+ MockUiHint :: RequestNewCredential ( request. user . clone ( ) . into ( ) , request. rp . clone ( ) ) ,
462+ ) ;
463+
464+ let mut authenticator =
465+ Authenticator :: new ( Aaguid :: new_empty ( ) , shared_store. clone ( ) , user_mock) ;
466+
467+ // This should succeed - an empty store means no credentials to exclude
468+ authenticator
469+ . make_credential ( request)
470+ . await
471+ . expect ( "make_credential should succeed with empty store and exclude_credentials" ) ;
472+
473+ // Verify the credential was created
474+ assert_eq ! ( shared_store. lock( ) . await . len( ) , 1 ) ;
475+ }
476+
477+ #[ tokio:: test]
478+ async fn empty_exclude_credentials_with_empty_store_succeeds ( ) {
479+ // Edge case: empty exclude list with empty store should also succeed
480+ let request = Request {
481+ exclude_list : Some ( vec ! [ ] ) ,
482+ ..good_request ( )
483+ } ;
484+
485+ let shared_store = Arc :: new ( Mutex :: new ( MemoryStore :: new ( ) ) ) ;
486+ let user_mock = MockUserValidationMethod :: verified_user_with_hint (
487+ 1 ,
488+ MockUiHint :: RequestNewCredential ( request. user . clone ( ) . into ( ) , request. rp . clone ( ) ) ,
489+ ) ;
490+
491+ let mut authenticator =
492+ Authenticator :: new ( Aaguid :: new_empty ( ) , shared_store. clone ( ) , user_mock) ;
493+
494+ authenticator
495+ . make_credential ( request)
496+ . await
497+ . expect ( "make_credential should succeed with empty exclude list" ) ;
498+
499+ assert_eq ! ( shared_store. lock( ) . await . len( ) , 1 ) ;
500+ }
0 commit comments