diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php
index 98346b305..d533c8aeb 100644
--- a/app/Http/Controllers/Auth/AuthController.php
+++ b/app/Http/Controllers/Auth/AuthController.php
@@ -170,6 +170,18 @@ class AuthController extends Controller
return view('auth/register-confirm');
}
+ /**
+ * View the confirmation email as a standard web page.
+ * @param $token
+ * @return \Illuminate\View\View
+ * @throws UserRegistrationException
+ */
+ public function viewConfirmEmail($token)
+ {
+ $confirmation = $this->emailConfirmationService->getEmailConfirmationFromToken($token);
+ return view('emails/email-confirmation', ['token' => $confirmation->token]);
+ }
+
/**
* Confirms an email via a token and logs the user into the system.
* @param $token
diff --git a/app/Http/routes.php b/app/Http/routes.php
index 9681ad1f1..e605dbee1 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -94,6 +94,7 @@ Route::get('/register/confirm', 'Auth\AuthController@getRegisterConfirmation');
Route::get('/register/confirm/awaiting', 'Auth\AuthController@showAwaitingConfirmation');
Route::post('/register/confirm/resend', 'Auth\AuthController@resendConfirmation');
Route::get('/register/confirm/{token}', 'Auth\AuthController@confirmEmail');
+Route::get('/register/confirm/{token}/email', 'Auth\AuthController@viewConfirmEmail');
Route::get('/register/service/{socialDriver}', 'Auth\AuthController@socialRegister');
Route::post('/register', 'Auth\AuthController@postRegister');
diff --git a/app/User.php b/app/User.php
index c7ce6b11e..ffe41229b 100644
--- a/app/User.php
+++ b/app/User.php
@@ -134,6 +134,10 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
return '//www.gravatar.com/avatar/' . $emailHash . '?s=' . $size . '&d=identicon';
}
+ /**
+ * Get the url for editing this user.
+ * @return string
+ */
public function getEditUrl()
{
return '/users/' . $this->id;
diff --git a/config/mail.php b/config/mail.php
index a45145309..0386e0198 100644
--- a/config/mail.php
+++ b/config/mail.php
@@ -119,6 +119,6 @@ return [
|
*/
- 'pretend' => false,
+ 'pretend' => env('MAIL_PRETEND', false),
];
diff --git a/phpunit.xml b/phpunit.xml
index 59afb8613..0884937af 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -25,5 +25,6 @@
Here you can connect your other accounts for quicker and easier login.
diff --git a/tests/AuthTest.php b/tests/AuthTest.php
index 343823687..99f132d3b 100644
--- a/tests/AuthTest.php
+++ b/tests/AuthTest.php
@@ -1,5 +1,7 @@
visit('/')
- ->seePageIs('/login')
- ->type('admin@admin.com', '#email')
- ->type('password', '#password')
- ->press('Sign In')
+ ->seePageIs('/login');
+
+ $this->login('admin@admin.com', 'password')
->seePageIs('/')
->see('BookStack');
}
@@ -41,9 +42,11 @@ class AuthTest extends TestCase
public function testNormalRegistration()
{
+ // Set settings and get user instance
$this->setSettings(['registration-enabled' => 'true']);
$user = factory(\BookStack\User::class)->make();
+ // Test form and ensure user is created
$this->visit('/register')
->see('Sign Up')
->type($user->name, '#name')
@@ -51,15 +54,52 @@ class AuthTest extends TestCase
->type($user->password, '#password')
->press('Create Account')
->seePageIs('/')
- ->see($user->name);
+ ->see($user->name)
+ ->seeInDatabase('users', ['name' => $user->name, 'email' => $user->email]);
}
- private function setSettings($settingsArray)
+ public function testConfirmedRegistration()
{
- $settings = app('BookStack\Services\SettingService');
- foreach($settingsArray as $key => $value) {
- $settings->put($key, $value);
- }
+ // Set settings and get user instance
+ $this->setSettings(['registration-enabled' => 'true', 'registration-confirmation' => 'true']);
+ $user = factory(\BookStack\User::class)->make();
+
+ // Mock Mailer to ensure mail is being sent
+ $mockMailer = Mockery::mock('Illuminate\Contracts\Mail\Mailer');
+ $mockMailer->shouldReceive('send')->with('emails/email-confirmation', Mockery::type('array'), Mockery::type('callable'))->twice();
+ $this->app->instance('mailer', $mockMailer);
+
+ // Go through registration process
+ $this->visit('/register')
+ ->see('Sign Up')
+ ->type($user->name, '#name')
+ ->type($user->email, '#email')
+ ->type($user->password, '#password')
+ ->press('Create Account')
+ ->seePageIs('/register/confirm')
+ ->seeInDatabase('users', ['name' => $user->name, 'email' => $user->email, 'email_confirmed' => false]);
+
+ // Test access and resend confirmation email
+ $this->login($user->email, $user->password)
+ ->seePageIs('/register/confirm/awaiting')
+ ->see('Resend')
+ ->visit('/books')
+ ->seePageIs('/register/confirm/awaiting')
+ ->press('Resend Confirmation Email');
+
+ // Get confirmation
+ $user = $user->where('email', '=', $user->email)->first();
+ $emailConfirmation = EmailConfirmation::where('user_id', '=', $user->id)->first();
+
+
+ // Check confirmation email button and confirmation activation.
+ $this->visit('/register/confirm/' . $emailConfirmation->token . '/email')
+ ->see('Email Confirmation')
+ ->click('Confirm Email')
+ ->seePageIs('/')
+ ->see($user->name)
+ ->notSeeInDatabase('email_confirmations', ['token' => $emailConfirmation->token])
+ ->seeInDatabase('users', ['name' => $user->name, 'email' => $user->email, 'email_confirmed' => true]);
}
public function testLogout()
@@ -71,4 +111,30 @@ class AuthTest extends TestCase
->visit('/')
->seePageIs('/login');
}
+
+ /**
+ * Quickly sets an array of settings.
+ * @param $settingsArray
+ */
+ private function setSettings($settingsArray)
+ {
+ $settings = app('BookStack\Services\SettingService');
+ foreach ($settingsArray as $key => $value) {
+ $settings->put($key, $value);
+ }
+ }
+
+ /**
+ * Perform a login
+ * @param string $email
+ * @param string $password
+ * @return $this
+ */
+ private function login($email, $password)
+ {
+ return $this->visit('/login')
+ ->type($email, '#email')
+ ->type($password, '#password')
+ ->press('Sign In');
+ }
}