From eab0ca9648643c6b9f57091635ecad2250c487ee Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sun, 18 Aug 2019 13:55:28 +0100 Subject: [PATCH] Covered new invite system with testing Closes #316 --- app/Auth/Access/UserTokenService.php | 2 +- tests/Auth/UserInviteTest.php | 111 +++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 tests/Auth/UserInviteTest.php diff --git a/app/Auth/Access/UserTokenService.php b/app/Auth/Access/UserTokenService.php index 40f363ee1..34f3b2851 100644 --- a/app/Auth/Access/UserTokenService.php +++ b/app/Auth/Access/UserTokenService.php @@ -61,7 +61,7 @@ class UserTokenService } if ($this->entryExpired($entry)) { - throw new UserTokenExpiredException("Token of id {$token->id} has expired.", $entry->user_id); + throw new UserTokenExpiredException("Token of id {$entry->id} has expired.", $entry->user_id); } return $entry->user_id; diff --git a/tests/Auth/UserInviteTest.php b/tests/Auth/UserInviteTest.php new file mode 100644 index 000000000..331262690 --- /dev/null +++ b/tests/Auth/UserInviteTest.php @@ -0,0 +1,111 @@ +getAdmin(); + + $this->actingAs($admin)->post('/settings/users/create', [ + 'name' => 'Barry', + 'email' => 'tester@example.com', + 'send_invite' => 'true', + ]); + + $newUser = User::query()->where('email', '=', 'tester@example.com')->orderBy('id', 'desc')->first(); + + Notification::assertSentTo($newUser, UserInvite::class); + $this->assertDatabaseHas('user_invites', [ + 'user_id' => $newUser->id + ]); + } + + public function test_invite_set_password() + { + Notification::fake(); + $user = $this->getViewer(); + $inviteService = app(UserInviteService::class); + + $inviteService->sendInvitation($user); + $token = DB::table('user_invites')->where('user_id', '=', $user->id)->first()->token; + + $setPasswordPageResp = $this->get('/register/invite/' . $token); + $setPasswordPageResp->assertSuccessful(); + $setPasswordPageResp->assertSee('Welcome to BookStack!'); + $setPasswordPageResp->assertSee('Password'); + $setPasswordPageResp->assertSee('Confirm Password'); + + $setPasswordResp = $this->followingRedirects()->post('/register/invite/' . $token, [ + 'password' => 'my test password', + ]); + $setPasswordResp->assertSee('Password set, you now have access to BookStack!'); + $newPasswordValid = auth()->validate([ + 'email' => $user->email, + 'password' => 'my test password' + ]); + $this->assertTrue($newPasswordValid); + $this->assertDatabaseMissing('user_invites', [ + 'user_id' => $user->id + ]); + } + + public function test_invite_set_has_password_validation() + { + Notification::fake(); + $user = $this->getViewer(); + $inviteService = app(UserInviteService::class); + + $inviteService->sendInvitation($user); + $token = DB::table('user_invites')->where('user_id', '=', $user->id)->first()->token; + + $shortPassword = $this->followingRedirects()->post('/register/invite/' . $token, [ + 'password' => 'mypas', + ]); + $shortPassword->assertSee('The password must be at least 6 characters.'); + + $noPassword = $this->followingRedirects()->post('/register/invite/' . $token, [ + 'password' => '', + ]); + $noPassword->assertSee('The password field is required.'); + + $this->assertDatabaseHas('user_invites', [ + 'user_id' => $user->id + ]); + } + + public function test_non_existent_invite_token_redirects_to_home() + { + $setPasswordPageResp = $this->get('/register/invite/' . str_random(12)); + $setPasswordPageResp->assertRedirect('/'); + + $setPasswordResp = $this->post('/register/invite/' . str_random(12), ['password' => 'Password Test']); + $setPasswordResp->assertRedirect('/'); + } + + public function test_token_expires_after_two_weeks() + { + Notification::fake(); + $user = $this->getViewer(); + $inviteService = app(UserInviteService::class); + + $inviteService->sendInvitation($user); + $tokenEntry = DB::table('user_invites')->where('user_id', '=', $user->id)->first(); + DB::table('user_invites')->update(['created_at' => Carbon::now()->subDays(14)->subHour(1)]); + + $setPasswordPageResp = $this->get('/register/invite/' . $tokenEntry->token); + $setPasswordPageResp->assertRedirect('/password/email'); + $setPasswordPageResp->assertSessionHas('error', 'This invitation link has expired. You can instead try to reset your account password.'); + } + + +} \ No newline at end of file