@@ -296,6 +296,41 @@ public function test_two_factor_challenge_can_be_passed_via_code()
296
296
->assertSessionMissing ('login.id ' );
297
297
}
298
298
299
+ public function test_two_factor_challenge_fails_for_old_otp_and_zero_window ()
300
+ {
301
+ app ('config ' )->set ('auth.providers.users.model ' , TestTwoFactorAuthenticationSessionUser::class);
302
+
303
+ //Setting window to 0 should mean any old OTP is instantly invalid
304
+ app ('config ' )->set ('fortify.features ' , [
305
+ Features::twoFactorAuthentication (['window ' => 0 ]),
306
+ ]);
307
+
308
+ $ this ->loadLaravelMigrations (['--database ' => 'testbench ' ]);
309
+ $ this ->artisan ('migrate ' , ['--database ' => 'testbench ' ])->run ();
310
+
311
+ $ tfaEngine = app (Google2FA::class);
312
+ $ userSecret = $ tfaEngine ->generateSecretKey ();
313
+ $ currentTs = $ tfaEngine ->getTimestamp ();
314
+ $ previousOtp = $ tfaEngine ->oathTotp ($ userSecret , $ currentTs - 1 );
315
+
316
+ $ user = TestTwoFactorAuthenticationSessionUser::forceCreate ([
317
+ 'name ' => 'Taylor Otwell ' ,
318
+
319
+ 'password ' => bcrypt ('secret ' ),
320
+ 'two_factor_secret ' => encrypt ($ userSecret ),
321
+ ]);
322
+
323
+ $ response = $ this ->withSession ([
324
+ 'login.id ' => $ user ->id ,
325
+ 'login.remember ' => false ,
326
+ ])->withoutExceptionHandling ()->post ('/two-factor-challenge ' , [
327
+ 'code ' => $ previousOtp ,
328
+ ]);
329
+
330
+ $ response ->assertRedirect ('/two-factor-challenge ' )
331
+ ->assertSessionHas ('login.id ' );
332
+ }
333
+
299
334
public function test_two_factor_challenge_can_be_passed_via_recovery_code ()
300
335
{
301
336
app ('config ' )->set ('auth.providers.users.model ' , TestTwoFactorAuthenticationSessionUser::class);
0 commit comments