5 use BookStack\Auth\Access\UserInviteService;
6 use BookStack\Auth\User;
7 use BookStack\Notifications\UserInvite;
10 use Illuminate\Support\Str;
14 class UserInviteTest extends TestCase
16 public function test_user_creation_creates_invite()
19 $admin = $this->getAdmin();
21 $email = Str::random(16) . '@example.com';
22 $resp = $this->actingAs($admin)->post('/settings/users/create', [
25 'send_invite' => 'true',
27 $resp->assertRedirect('/settings/users');
29 $newUser = User::query()->where('email', '=', $email)->orderBy('id', 'desc')->first();
31 Notification::assertSentTo($newUser, UserInvite::class);
32 $this->assertDatabaseHas('user_invites', [
33 'user_id' => $newUser->id,
37 public function test_invite_set_password()
40 $user = $this->getViewer();
41 $inviteService = app(UserInviteService::class);
43 $inviteService->sendInvitation($user);
44 $token = DB::table('user_invites')->where('user_id', '=', $user->id)->first()->token;
46 $setPasswordPageResp = $this->get('/register/invite/' . $token);
47 $setPasswordPageResp->assertSuccessful();
48 $setPasswordPageResp->assertSee('Welcome to BookStack!');
49 $setPasswordPageResp->assertSee('Password');
50 $setPasswordPageResp->assertSee('Confirm Password');
52 $setPasswordResp = $this->followingRedirects()->post('/register/invite/' . $token, [
53 'password' => 'my test password',
55 $setPasswordResp->assertSee('Password set, you now have access to BookStack!');
56 $newPasswordValid = auth()->validate([
57 'email' => $user->email,
58 'password' => 'my test password',
60 $this->assertTrue($newPasswordValid);
61 $this->assertDatabaseMissing('user_invites', [
62 'user_id' => $user->id,
66 public function test_invite_set_has_password_validation()
69 $user = $this->getViewer();
70 $inviteService = app(UserInviteService::class);
72 $inviteService->sendInvitation($user);
73 $token = DB::table('user_invites')->where('user_id', '=', $user->id)->first()->token;
75 $this->get('/register/invite/' . $token);
76 $shortPassword = $this->followingRedirects()->post('/register/invite/' . $token, [
77 'password' => 'mypassw',
79 $shortPassword->assertSee('The password must be at least 8 characters.');
81 $this->get('/register/invite/' . $token);
82 $noPassword = $this->followingRedirects()->post('/register/invite/' . $token, [
85 $noPassword->assertSee('The password field is required.');
87 $this->assertDatabaseHas('user_invites', [
88 'user_id' => $user->id,
92 public function test_non_existent_invite_token_redirects_to_home()
94 $setPasswordPageResp = $this->get('/register/invite/' . Str::random(12));
95 $setPasswordPageResp->assertRedirect('/');
97 $setPasswordResp = $this->post('/register/invite/' . Str::random(12), ['password' => 'Password Test']);
98 $setPasswordResp->assertRedirect('/');
101 public function test_token_expires_after_two_weeks()
103 Notification::fake();
104 $user = $this->getViewer();
105 $inviteService = app(UserInviteService::class);
107 $inviteService->sendInvitation($user);
108 $tokenEntry = DB::table('user_invites')->where('user_id', '=', $user->id)->first();
109 DB::table('user_invites')->update(['created_at' => Carbon::now()->subDays(14)->subHour(1)]);
111 $setPasswordPageResp = $this->get('/register/invite/' . $tokenEntry->token);
112 $setPasswordPageResp->assertRedirect('/password/email');
113 $setPasswordPageResp->assertSessionHas('error', 'This invitation link has expired. You can instead try to reset your account password.');