diff --git a/app/Http/Controllers/Auth/PasswordController.php b/app/Http/Controllers/Auth/PasswordController.php index 038e444d2..4dc6583ea 100644 --- a/app/Http/Controllers/Auth/PasswordController.php +++ b/app/Http/Controllers/Auth/PasswordController.php @@ -4,6 +4,8 @@ namespace BookStack\Http\Controllers\Auth; use BookStack\Http\Controllers\Controller; use Illuminate\Foundation\Auth\ResetsPasswords; +use Illuminate\Http\Request; +use Password; class PasswordController extends Controller { @@ -29,4 +31,46 @@ class PasswordController extends Controller { $this->middleware('guest'); } + + + /** + * Send a reset link to the given user. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function sendResetLinkEmail(Request $request) + { + $this->validate($request, ['email' => 'required|email']); + + $broker = $this->getBroker(); + + $response = Password::broker($broker)->sendResetLink( + $request->only('email'), $this->resetEmailBuilder() + ); + + switch ($response) { + case Password::RESET_LINK_SENT: + $message = 'A password reset link has been sent to ' . $request->get('email') . '.'; + session()->flash('success', $message); + return $this->getSendResetLinkEmailSuccessResponse($response); + + case Password::INVALID_USER: + default: + return $this->getSendResetLinkEmailFailureResponse($response); + } + } + + /** + * Get the response for after a successful password reset. + * + * @param string $response + * @return \Symfony\Component\HttpFoundation\Response + */ + protected function getResetSuccessResponse($response) + { + $message = 'Your password has been successfully reset.'; + session()->flash('success', $message); + return redirect($this->redirectPath())->with('status', trans($response)); + } } diff --git a/app/helpers.php b/app/helpers.php index b8abb1006..c12708877 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -84,6 +84,11 @@ function baseUrl($path, $forceAppDomain = false) $path = implode('/', array_splice($explodedPath, 3)); } + // Return normal url path if not specified in config + if (config('app.url') === '') { + return url($path); + } + return rtrim(config('app.url'), '/') . '/' . $path; } diff --git a/config/setting-defaults.php b/config/setting-defaults.php index 24a49c364..22c992aa4 100644 --- a/config/setting-defaults.php +++ b/config/setting-defaults.php @@ -8,6 +8,7 @@ return [ 'app-name' => 'BookStack', 'app-editor' => 'wysiwyg', 'app-color' => '#0288D1', - 'app-color-light' => 'rgba(21, 101, 192, 0.15)' + 'app-color-light' => 'rgba(21, 101, 192, 0.15)', + 'registration-enabled' => false, ]; \ No newline at end of file diff --git a/resources/views/auth/password.blade.php b/resources/views/auth/password.blade.php index d8536efa7..115785ab2 100644 --- a/resources/views/auth/password.blade.php +++ b/resources/views/auth/password.blade.php @@ -1,5 +1,12 @@ @extends('public') +@section('header-buttons') + Sign in + @if(setting('registration-enabled')) + Sign up + @endif +@stop + @section('content') diff --git a/resources/views/auth/reset.blade.php b/resources/views/auth/reset.blade.php index 9a9a65ff0..612b50ff8 100644 --- a/resources/views/auth/reset.blade.php +++ b/resources/views/auth/reset.blade.php @@ -1,5 +1,12 @@ @extends('public') +@section('header-buttons') + Sign in + @if(setting('registration-enabled')) + Sign up + @endif +@stop + @section('body-class', 'image-cover login') @section('content') diff --git a/resources/views/emails/email-confirmation.blade.php b/resources/views/emails/email-confirmation.blade.php index 6a0dc0378..0a211c369 100644 --- a/resources/views/emails/email-confirmation.blade.php +++ b/resources/views/emails/email-confirmation.blade.php @@ -162,14 +162,14 @@

Email Confirmation

- Thanks for joining {{ setting('app-name')}}.
+ Thanks for joining {{ setting('app-name')}}.
Please confirm your email address by clicking the button below.

diff --git a/resources/views/emails/password.blade.php b/resources/views/emails/password.blade.php index dfd8f3db5..a8f7911e0 100644 --- a/resources/views/emails/password.blade.php +++ b/resources/views/emails/password.blade.php @@ -1 +1 @@ -Password Reset From {{ setting('app-name')}}

- Confirm Email

Password Reset

A password reset was requested for this email address on {{ setting('app-name')}}. If you did not request a password change please ignore this email.

Click here to reset your password

\ No newline at end of file + Password Reset From {{ setting('app-name')}}

Password Reset

A password reset was requested for this email address on {{ setting('app-name')}}. If you did not request a password change please ignore this email.

Click here to reset your password

\ No newline at end of file diff --git a/tests/Auth/AuthTest.php b/tests/Auth/AuthTest.php index 306771ed5..99885d552 100644 --- a/tests/Auth/AuthTest.php +++ b/tests/Auth/AuthTest.php @@ -216,6 +216,37 @@ class AuthTest extends TestCase ->seePageIs('/login'); } + public function test_reset_password_flow() + { + $this->visit('/login')->click('Forgot Password?') + ->seePageIs('/password/email') + ->type('admin@admin.com', 'email') + ->press('Send Reset Link') + ->see('A password reset link has been sent to admin@admin.com'); + + $this->seeInDatabase('password_resets', [ + 'email' => 'admin@admin.com' + ]); + + $reset = DB::table('password_resets')->where('email', '=', 'admin@admin.com')->first(); + $this->visit('/password/reset/' . $reset->token) + ->see('Reset Password') + ->submitForm('Reset Password', [ + 'email' => 'admin@admin.com', + 'password' => 'randompass', + 'password_confirmation' => 'randompass' + ])->seePageIs('/') + ->see('Your password has been successfully reset'); + } + + public function test_reset_password_page_shows_sign_links() + { + $this->setSettings(['registration-enabled' => 'true']); + $this->visit('/password/email') + ->seeLink('Sign in') + ->seeLink('Sign up'); + } + /** * Perform a login * @param string $email