X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/ddb7f33868ea499ab8f48a7062f145e8c0fbe02f..ac519b3009e353448fc0541d21c08422d77dc57d:/app/Http/Controllers/Auth/ResetPasswordController.php diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php index 4d98eca59..a9914928e 100644 --- a/app/Http/Controllers/Auth/ResetPasswordController.php +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -2,50 +2,97 @@ namespace BookStack\Http\Controllers\Auth; +use BookStack\Actions\ActivityType; +use BookStack\Auth\Access\LoginService; +use BookStack\Auth\User; use BookStack\Http\Controllers\Controller; -use Illuminate\Foundation\Auth\ResetsPasswords; +use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Facades\Password; +use Illuminate\Support\Str; +use Illuminate\Validation\Rules\Password as PasswordRule; class ResetPasswordController extends Controller { - /* - |-------------------------------------------------------------------------- - | Password Reset Controller - |-------------------------------------------------------------------------- - | - | This controller is responsible for handling password reset requests - | and uses a simple trait to include this behavior. You're free to - | explore this trait and override any methods you wish to tweak. - | - */ + protected LoginService $loginService; - use ResetsPasswords; + public function __construct(LoginService $loginService) + { + $this->middleware('guest'); + $this->middleware('guard:standard'); - protected $redirectTo = '/'; + $this->loginService = $loginService; + } /** - * Create a new controller instance. - * - * @return void + * Display the password reset view for the given token. + * If no token is present, display the link request form. */ - public function __construct() + public function showResetForm(Request $request) { - $this->middleware('guest'); - parent::__construct(); + $token = $request->route()->parameter('token'); + + return view('auth.passwords.reset')->with( + ['token' => $token, 'email' => $request->email] + ); + } + + /** + * Reset the given user's password. + */ + public function reset(Request $request) + { + $request->validate([ + 'token' => 'required', + 'email' => 'required|email', + 'password' => ['required', 'confirmed', PasswordRule::defaults()], + ]); + + // Here we will attempt to reset the user's password. If it is successful we + // will update the password on an actual user model and persist it to the + // database. Otherwise we will parse the error and return the response. + $credentials = $request->only('email', 'password', 'password_confirmation', 'token'); + $response = Password::broker()->reset($credentials, function (User $user, string $password) { + $user->password = Hash::make($password); + $user->setRememberToken(Str::random(60)); + $user->save(); + + $this->loginService->login($user, auth()->getDefaultDriver()); + }); + + // If the password was successfully reset, we will redirect the user back to + // the application's home authenticated view. If there is an error we can + // redirect them back to where they came from with their error message. + return $response === Password::PASSWORD_RESET + ? $this->sendResetResponse() + : $this->sendResetFailedResponse($request, $response); } /** * Get the response for a successful password reset. - * - * @param Request $request - * @param string $response - * @return \Illuminate\Http\Response */ - protected function sendResetResponse(Request $request, $response) + protected function sendResetResponse(): RedirectResponse + { + $this->showSuccessNotification(trans('auth.reset_password_success')); + $this->logActivity(ActivityType::AUTH_PASSWORD_RESET_UPDATE, user()); + + return redirect('/'); + } + + /** + * Get the response for a failed password reset. + */ + protected function sendResetFailedResponse(Request $request, string $response): RedirectResponse { - $message = trans('auth.reset_password_success'); - $this->showSuccessNotification($message); - return redirect($this->redirectPath()) - ->with('status', trans($response)); + // We show invalid users as invalid tokens as to not leak what + // users may exist in the system. + if ($response === Password::INVALID_USER) { + $response = Password::INVALID_TOKEN; + } + + return redirect()->back() + ->withInput($request->only('email')) + ->withErrors(['email' => trans($response)]); } }