Showing
7 changed files
with
96 additions
and
12 deletions
| ... | @@ -171,6 +171,18 @@ class AuthController extends Controller | ... | @@ -171,6 +171,18 @@ class AuthController extends Controller |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | /** | 173 | /** |
| 174 | + * View the confirmation email as a standard web page. | ||
| 175 | + * @param $token | ||
| 176 | + * @return \Illuminate\View\View | ||
| 177 | + * @throws UserRegistrationException | ||
| 178 | + */ | ||
| 179 | + public function viewConfirmEmail($token) | ||
| 180 | + { | ||
| 181 | + $confirmation = $this->emailConfirmationService->getEmailConfirmationFromToken($token); | ||
| 182 | + return view('emails/email-confirmation', ['token' => $confirmation->token]); | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + /** | ||
| 174 | * Confirms an email via a token and logs the user into the system. | 186 | * Confirms an email via a token and logs the user into the system. |
| 175 | * @param $token | 187 | * @param $token |
| 176 | * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector | 188 | * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector | ... | ... |
| ... | @@ -94,6 +94,7 @@ Route::get('/register/confirm', 'Auth\AuthController@getRegisterConfirmation'); | ... | @@ -94,6 +94,7 @@ Route::get('/register/confirm', 'Auth\AuthController@getRegisterConfirmation'); |
| 94 | Route::get('/register/confirm/awaiting', 'Auth\AuthController@showAwaitingConfirmation'); | 94 | Route::get('/register/confirm/awaiting', 'Auth\AuthController@showAwaitingConfirmation'); |
| 95 | Route::post('/register/confirm/resend', 'Auth\AuthController@resendConfirmation'); | 95 | Route::post('/register/confirm/resend', 'Auth\AuthController@resendConfirmation'); |
| 96 | Route::get('/register/confirm/{token}', 'Auth\AuthController@confirmEmail'); | 96 | Route::get('/register/confirm/{token}', 'Auth\AuthController@confirmEmail'); |
| 97 | +Route::get('/register/confirm/{token}/email', 'Auth\AuthController@viewConfirmEmail'); | ||
| 97 | Route::get('/register/service/{socialDriver}', 'Auth\AuthController@socialRegister'); | 98 | Route::get('/register/service/{socialDriver}', 'Auth\AuthController@socialRegister'); |
| 98 | Route::post('/register', 'Auth\AuthController@postRegister'); | 99 | Route::post('/register', 'Auth\AuthController@postRegister'); |
| 99 | 100 | ... | ... |
| ... | @@ -134,6 +134,10 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon | ... | @@ -134,6 +134,10 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon |
| 134 | return '//www.gravatar.com/avatar/' . $emailHash . '?s=' . $size . '&d=identicon'; | 134 | return '//www.gravatar.com/avatar/' . $emailHash . '?s=' . $size . '&d=identicon'; |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | + /** | ||
| 138 | + * Get the url for editing this user. | ||
| 139 | + * @return string | ||
| 140 | + */ | ||
| 137 | public function getEditUrl() | 141 | public function getEditUrl() |
| 138 | { | 142 | { |
| 139 | return '/users/' . $this->id; | 143 | return '/users/' . $this->id; | ... | ... |
| ... | @@ -25,5 +25,6 @@ | ... | @@ -25,5 +25,6 @@ |
| 25 | <env name="SESSION_DRIVER" value="array"/> | 25 | <env name="SESSION_DRIVER" value="array"/> |
| 26 | <env name="QUEUE_DRIVER" value="sync"/> | 26 | <env name="QUEUE_DRIVER" value="sync"/> |
| 27 | <env name="DB_CONNECTION" value="mysql_testing"/> | 27 | <env name="DB_CONNECTION" value="mysql_testing"/> |
| 28 | + <env name="MAIL_PRETEND" value="true"/> | ||
| 28 | </php> | 29 | </php> |
| 29 | </phpunit> | 30 | </phpunit> | ... | ... |
| ... | @@ -42,7 +42,7 @@ | ... | @@ -42,7 +42,7 @@ |
| 42 | 42 | ||
| 43 | <hr class="margin-top large"> | 43 | <hr class="margin-top large"> |
| 44 | 44 | ||
| 45 | - @if($currentUser->id === $user->id) | 45 | + @if($currentUser->id === $user->id && count($activeSocialDrivers) > 0) |
| 46 | <h3>Social Accounts</h3> | 46 | <h3>Social Accounts</h3> |
| 47 | <p class="text-muted"> | 47 | <p class="text-muted"> |
| 48 | Here you can connect your other accounts for quicker and easier login. <br> | 48 | Here you can connect your other accounts for quicker and easier login. <br> | ... | ... |
| 1 | <?php | 1 | <?php |
| 2 | 2 | ||
| 3 | +use BookStack\EmailConfirmation; | ||
| 4 | + | ||
| 3 | class AuthTest extends TestCase | 5 | class AuthTest extends TestCase |
| 4 | { | 6 | { |
| 5 | 7 | ||
| ... | @@ -12,10 +14,9 @@ class AuthTest extends TestCase | ... | @@ -12,10 +14,9 @@ class AuthTest extends TestCase |
| 12 | public function testLogin() | 14 | public function testLogin() |
| 13 | { | 15 | { |
| 14 | $this->visit('/') | 16 | $this->visit('/') |
| 15 | - ->seePageIs('/login') | 17 | + ->seePageIs('/login'); |
| 16 | - ->type('admin@admin.com', '#email') | 18 | + |
| 17 | - ->type('password', '#password') | 19 | + $this->login('admin@admin.com', 'password') |
| 18 | - ->press('Sign In') | ||
| 19 | ->seePageIs('/') | 20 | ->seePageIs('/') |
| 20 | ->see('BookStack'); | 21 | ->see('BookStack'); |
| 21 | } | 22 | } |
| ... | @@ -41,9 +42,11 @@ class AuthTest extends TestCase | ... | @@ -41,9 +42,11 @@ class AuthTest extends TestCase |
| 41 | 42 | ||
| 42 | public function testNormalRegistration() | 43 | public function testNormalRegistration() |
| 43 | { | 44 | { |
| 45 | + // Set settings and get user instance | ||
| 44 | $this->setSettings(['registration-enabled' => 'true']); | 46 | $this->setSettings(['registration-enabled' => 'true']); |
| 45 | $user = factory(\BookStack\User::class)->make(); | 47 | $user = factory(\BookStack\User::class)->make(); |
| 46 | 48 | ||
| 49 | + // Test form and ensure user is created | ||
| 47 | $this->visit('/register') | 50 | $this->visit('/register') |
| 48 | ->see('Sign Up') | 51 | ->see('Sign Up') |
| 49 | ->type($user->name, '#name') | 52 | ->type($user->name, '#name') |
| ... | @@ -51,15 +54,52 @@ class AuthTest extends TestCase | ... | @@ -51,15 +54,52 @@ class AuthTest extends TestCase |
| 51 | ->type($user->password, '#password') | 54 | ->type($user->password, '#password') |
| 52 | ->press('Create Account') | 55 | ->press('Create Account') |
| 53 | ->seePageIs('/') | 56 | ->seePageIs('/') |
| 54 | - ->see($user->name); | 57 | + ->see($user->name) |
| 58 | + ->seeInDatabase('users', ['name' => $user->name, 'email' => $user->email]); | ||
| 55 | } | 59 | } |
| 56 | 60 | ||
| 57 | - private function setSettings($settingsArray) | 61 | + public function testConfirmedRegistration() |
| 58 | { | 62 | { |
| 59 | - $settings = app('BookStack\Services\SettingService'); | 63 | + // Set settings and get user instance |
| 60 | - foreach($settingsArray as $key => $value) { | 64 | + $this->setSettings(['registration-enabled' => 'true', 'registration-confirmation' => 'true']); |
| 61 | - $settings->put($key, $value); | 65 | + $user = factory(\BookStack\User::class)->make(); |
| 62 | - } | 66 | + |
| 67 | + // Mock Mailer to ensure mail is being sent | ||
| 68 | + $mockMailer = Mockery::mock('Illuminate\Contracts\Mail\Mailer'); | ||
| 69 | + $mockMailer->shouldReceive('send')->with('emails/email-confirmation', Mockery::type('array'), Mockery::type('callable'))->twice(); | ||
| 70 | + $this->app->instance('mailer', $mockMailer); | ||
| 71 | + | ||
| 72 | + // Go through registration process | ||
| 73 | + $this->visit('/register') | ||
| 74 | + ->see('Sign Up') | ||
| 75 | + ->type($user->name, '#name') | ||
| 76 | + ->type($user->email, '#email') | ||
| 77 | + ->type($user->password, '#password') | ||
| 78 | + ->press('Create Account') | ||
| 79 | + ->seePageIs('/register/confirm') | ||
| 80 | + ->seeInDatabase('users', ['name' => $user->name, 'email' => $user->email, 'email_confirmed' => false]); | ||
| 81 | + | ||
| 82 | + // Test access and resend confirmation email | ||
| 83 | + $this->login($user->email, $user->password) | ||
| 84 | + ->seePageIs('/register/confirm/awaiting') | ||
| 85 | + ->see('Resend') | ||
| 86 | + ->visit('/books') | ||
| 87 | + ->seePageIs('/register/confirm/awaiting') | ||
| 88 | + ->press('Resend Confirmation Email'); | ||
| 89 | + | ||
| 90 | + // Get confirmation | ||
| 91 | + $user = $user->where('email', '=', $user->email)->first(); | ||
| 92 | + $emailConfirmation = EmailConfirmation::where('user_id', '=', $user->id)->first(); | ||
| 93 | + | ||
| 94 | + | ||
| 95 | + // Check confirmation email button and confirmation activation. | ||
| 96 | + $this->visit('/register/confirm/' . $emailConfirmation->token . '/email') | ||
| 97 | + ->see('Email Confirmation') | ||
| 98 | + ->click('Confirm Email') | ||
| 99 | + ->seePageIs('/') | ||
| 100 | + ->see($user->name) | ||
| 101 | + ->notSeeInDatabase('email_confirmations', ['token' => $emailConfirmation->token]) | ||
| 102 | + ->seeInDatabase('users', ['name' => $user->name, 'email' => $user->email, 'email_confirmed' => true]); | ||
| 63 | } | 103 | } |
| 64 | 104 | ||
| 65 | public function testLogout() | 105 | public function testLogout() |
| ... | @@ -71,4 +111,30 @@ class AuthTest extends TestCase | ... | @@ -71,4 +111,30 @@ class AuthTest extends TestCase |
| 71 | ->visit('/') | 111 | ->visit('/') |
| 72 | ->seePageIs('/login'); | 112 | ->seePageIs('/login'); |
| 73 | } | 113 | } |
| 114 | + | ||
| 115 | + /** | ||
| 116 | + * Quickly sets an array of settings. | ||
| 117 | + * @param $settingsArray | ||
| 118 | + */ | ||
| 119 | + private function setSettings($settingsArray) | ||
| 120 | + { | ||
| 121 | + $settings = app('BookStack\Services\SettingService'); | ||
| 122 | + foreach ($settingsArray as $key => $value) { | ||
| 123 | + $settings->put($key, $value); | ||
| 124 | + } | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + /** | ||
| 128 | + * Perform a login | ||
| 129 | + * @param string $email | ||
| 130 | + * @param string $password | ||
| 131 | + * @return $this | ||
| 132 | + */ | ||
| 133 | + private function login($email, $password) | ||
| 134 | + { | ||
| 135 | + return $this->visit('/login') | ||
| 136 | + ->type($email, '#email') | ||
| 137 | + ->type($password, '#password') | ||
| 138 | + ->press('Sign In'); | ||
| 139 | + } | ||
| 74 | } | 140 | } | ... | ... |
-
Please register or sign in to post a comment