66use PHPUnit \Framework \Attributes \Group ;
77use PHPUnit \Framework \Attributes \Test ;
88use Statamic \Auth \File \Passkey ;
9+ use Statamic \Facades \File ;
910use Statamic \Facades \User ;
1011use Symfony \Component \Uid \Uuid ;
1112use Tests \PreventSavingStacheItemsToDisk ;
1617#[Group('passkeys ' )]
1718class FilePasskeyTest extends TestCase
1819{
19- use PreventSavingStacheItemsToDisk;
20+ use PasskeyTests, PreventSavingStacheItemsToDisk;
2021
21- private function createTestCredential (string $ id = 'test-credential-id-123 ' ): PublicKeyCredentialSource
22+ public function setUp (): void
23+ {
24+ parent ::setUp ();
25+
26+ File::delete (storage_path ('statamic/users ' ));
27+ }
28+
29+ protected function newPasskey (): \Statamic \Contracts \Auth \Passkey
30+ {
31+ return new Passkey ;
32+ }
33+
34+ protected function createTestCredential (string $ id = 'test-credential-id-123 ' ): PublicKeyCredentialSource
2235 {
2336 return PublicKeyCredentialSource::create (
2437 publicKeyCredentialId: $ id ,
@@ -54,6 +67,25 @@ public function it_saves_passkey_to_user()
5467 $ freshUser = User::find ('test-user ' );
5568 $ this ->assertCount (1 , $ freshUser ->passkeys ());
5669 $ this ->assertEquals ('My Passkey ' , $ freshUser ->passkeys ()->first ()->name ());
70+ $ this ->assertEquals ([], $ user ->getMeta ('passkey_last_logins ' ));
71+ }
72+
73+ #[Test]
74+ public function it_reads_last_login_from_meta ()
75+ {
76+ $ user = User::make ()->id ('test-user ' )->email ('test@example.com ' );
77+ $ user ->save ();
78+
79+ $ passkey = (new Passkey )
80+ ->setName ('My Passkey ' )
81+ ->setUser ($ user )
82+ ->setCredential ($ this ->createTestCredential ());
83+ $ passkey ->save ();
84+
85+ $ lastLogin = Carbon::create (2024 , 1 , 15 , 10 , 30 , 0 );
86+ $ user ->setMeta ('passkey_last_logins ' , [$ passkey ->id () => $ lastLogin ->timestamp ]);
87+
88+ $ this ->assertTrue ($ passkey ->lastLogin ()->eq ($ lastLogin ));
5789 }
5890
5991 #[Test]
@@ -73,7 +105,7 @@ public function it_updates_existing_passkey()
73105
74106 // Update the passkey
75107 $ passkey ->setName ('Updated Passkey Name ' );
76- $ passkey ->setLastLogin (Carbon::create (2024 , 1 , 15 , 10 , 30 , 0 ));
108+ $ passkey ->setLastLogin ($ lastLogin = Carbon::create (2024 , 1 , 15 , 10 , 30 , 0 ));
77109 $ result = $ passkey ->save ();
78110
79111 $ this ->assertTrue ($ result );
@@ -83,6 +115,7 @@ public function it_updates_existing_passkey()
83115 $ this ->assertCount (1 , $ freshUser ->passkeys ());
84116 $ this ->assertEquals ('Updated Passkey Name ' , $ freshUser ->passkeys ()->first ()->name ());
85117 $ this ->assertNotNull ($ freshUser ->passkeys ()->first ()->lastLogin ());
118+ $ this ->assertEquals ([$ passkey ->id () => $ lastLogin ->timestamp ], $ user ->getMeta ('passkey_last_logins ' ));
86119 }
87120
88121 #[Test]
@@ -112,6 +145,7 @@ public function it_saves_multiple_passkeys_to_same_user()
112145 $ names = $ freshUser ->passkeys ()->map ->name ()->values ();
113146 $ this ->assertTrue ($ names ->contains ('Passkey 1 ' ));
114147 $ this ->assertTrue ($ names ->contains ('Passkey 2 ' ));
148+ $ this ->assertEquals ([], $ user ->getMeta ('passkey_last_logins ' ));
115149 }
116150
117151 #[Test]
@@ -139,6 +173,7 @@ public function it_deletes_passkey_from_user()
139173 // Verify passkey was removed
140174 $ freshUser = User::find ('test-user ' );
141175 $ this ->assertCount (0 , $ freshUser ->passkeys ());
176+ $ this ->assertEquals ([], $ user ->getMeta ('passkey_last_logins ' ));
142177 }
143178
144179 #[Test]
@@ -149,17 +184,20 @@ public function it_deletes_only_specified_passkey()
149184
150185 $ credential1 = $ this ->createTestCredential ('credential-1 ' );
151186 $ credential2 = $ this ->createTestCredential ('credential-2 ' );
187+ $ lastLogin = Carbon::create (2024 , 1 , 15 , 10 , 30 , 0 );
152188
153189 $ passkey1 = (new Passkey )
154190 ->setName ('Passkey 1 ' )
155191 ->setUser ($ user )
156- ->setCredential ($ credential1 );
192+ ->setCredential ($ credential1 )
193+ ->setLastLogin ($ lastLogin ->timestamp );
157194 $ passkey1 ->save ();
158195
159196 $ passkey2 = (new Passkey )
160197 ->setName ('Passkey 2 ' )
161198 ->setUser ($ user )
162- ->setCredential ($ credential2 );
199+ ->setCredential ($ credential2 )
200+ ->setLastLogin ($ lastLogin ->timestamp );
163201 $ passkey2 ->save ();
164202
165203 // Delete only the first passkey
@@ -168,13 +206,15 @@ public function it_deletes_only_specified_passkey()
168206 $ freshUser = User::find ('test-user ' );
169207 $ this ->assertCount (1 , $ freshUser ->passkeys ());
170208 $ this ->assertEquals ('Passkey 2 ' , $ freshUser ->passkeys ()->first ()->name ());
209+ $ this ->assertEquals ([$ passkey2 ->id () => $ lastLogin ->timestamp ], $ user ->getMeta ('passkey_last_logins ' ));
171210 }
172211
173212 #[Test]
174213 public function it_persists_all_passkey_data ()
175214 {
176215 $ user = User::make ()->id ('test-user ' )->email ('test@example.com ' );
177216 $ user ->save ();
217+ $ this ->assertNull ($ user ->getMeta ('passkey_last_logins ' ));
178218
179219 $ credential = $ this ->createTestCredential ();
180220 $ lastLogin = Carbon::create (2024 , 1 , 15 , 10 , 30 , 0 );
@@ -193,5 +233,6 @@ public function it_persists_all_passkey_data()
193233 $ this ->assertEquals ('test-credential-id-123 ' , $ savedPasskey ->credential ()->publicKeyCredentialId );
194234 $ this ->assertEquals ('2024-01-15 10:30:00 ' , $ savedPasskey ->lastLogin ()->format ('Y-m-d H:i:s ' ));
195235 $ this ->assertEquals ('test-user ' , $ savedPasskey ->user ()->id ());
236+ $ this ->assertEquals ([$ savedPasskey ->id () => $ lastLogin ->timestamp ], $ user ->getMeta ('passkey_last_logins ' ));
196237 }
197238}
0 commit comments