browse(function (PterodactylBrowser $browser) { $browser->loginAs($this->user) ->visit(new AccountPage) ->assertMissing('.modal-mask') ->click('@2fa_button') ->waitFor('@2fa_modal') ->pause(500)// seems to fix fragile test ->clickPosition(100, 100) ->waitUntilMissing('@2fa_modal') ->click('@2fa_button') ->waitFor('@2fa_modal') ->click('svg[role="button"][aria-label="Close modal"]') ->waitUntilMissing('@2fa_modal') ->click('@2fa_button') ->waitFor('@2fa_modal') ->keys('', [WebDriverKeys::ESCAPE]) ->waitUntilMissing('@2fa_modal'); }); } /** * Test that a user that does not have two-factor enabled can enable it on their account. */ public function testTwoFactorCanBeEnabled() { $this->browse(function (PterodactylBrowser $browser) { $browser->loginAs($this->user) ->visit(new AccountPage) ->click('@2fa_button') ->waitForText(trans('dashboard/account.two_factor.setup.title')) ->assertFocused('@2fa_token') ->waitFor('#grid-qr-code') ->assertSee(trans('dashboard/account.two_factor.setup.help')); // Grab information from the database so we can ensure the correct things are showing up. // Also because we need to generate a code to send through and activate it with. $updated = $this->user->fresh(); $secret = Crypt::decrypt($updated->totp_secret); $code = (new Google2FA())->getCurrentOtp($secret); $browser->assertSeeIn('code', $secret) ->assertVisible('@2fa_enable[disabled="disabled"]') ->assertMissing('@2fa_token ~ .input-help.error') ->type('@2fa_token', '12') ->assertSeeIn('@2fa_token ~ .input-help.error', 'The token length must be 6.') ->type('@2fa_token', $code) ->assertMissing('@2fa_token ~ .input-help.error') ->click('@2fa_enable') ->waitUntilMissing('@2fa_modal') ->assertSeeIn('@@success', trans('dashboard/account.two_factor.enabled')); $this->assertDatabaseHas('users', ['id' => $this->user->id, 'use_totp' => 1]); }); } /** * Test that a user can disable two-factor authentication on thier account. */ public function testTwoFactorCanBeDisabled() { $secret = (new Google2FA)->generateSecretKey(16); $this->user->update([ 'use_totp' => true, 'totp_secret' => Crypt::encrypt($secret), ]); $this->browse(function (PterodactylBrowser $browser) use ($secret) { $browser->loginAs($this->user) ->visit(new AccountPage) ->click('@2fa_button') ->waitForText(trans('dashboard/account.two_factor.disable.title')) ->click('@2fa_cancel') ->waitUntilMissing('@2fa_modal') ->click('@2fa_button') ->waitForText(trans('dashboard/account.two_factor.disable.title')) ->assertVisible('@2fa_disable[disabled="disabled"]') ->assertVisible('@2fa_cancel') ->assertFocused('@2fa_token_disable') ->assertMissing('@2fa_token_disable ~ .input-help.error') ->type('@2fa_token_disable', '12') ->assertSeeIn('@2fa_token_disable ~ .input-help.error', 'The token length must be 6.'); $token = (new Google2FA())->getCurrentOtp($secret); $browser->type('@2fa_token_disable', $token) ->assertMissing('@2fa_token_disable ~ .input-help.error') ->click('@2fa_disable') ->waitUntilMissing('@2fa_modal') ->assertSeeIn('@@success', trans('dashboard/account.two_factor.disabled')); }); } }