]> BookStack Code Mirror - bookstack/blob - app/Access/Controllers/ResetPasswordController.php
f8a63a8b6afa36dbe364d92b69de4eac55a86bc9
[bookstack] / app / Access / Controllers / ResetPasswordController.php
1 <?php
2
3 namespace BookStack\Access\Controllers;
4
5 use BookStack\Access\LoginService;
6 use BookStack\Activity\ActivityType;
7 use BookStack\Http\Controllers\Controller;
8 use BookStack\Users\Models\User;
9 use Illuminate\Http\RedirectResponse;
10 use Illuminate\Http\Request;
11 use Illuminate\Support\Facades\Hash;
12 use Illuminate\Support\Facades\Password;
13 use Illuminate\Support\Str;
14 use Illuminate\Validation\Rules\Password as PasswordRule;
15
16 class ResetPasswordController extends Controller
17 {
18     protected LoginService $loginService;
19
20     public function __construct(LoginService $loginService)
21     {
22         $this->middleware('guest');
23         $this->middleware('guard:standard');
24
25         $this->loginService = $loginService;
26     }
27
28     /**
29      * Display the password reset view for the given token.
30      * If no token is present, display the link request form.
31      */
32     public function showResetForm(Request $request)
33     {
34         $token = $request->route()->parameter('token');
35
36         return view('auth.passwords.reset')->with(
37             ['token' => $token, 'email' => $request->email]
38         );
39     }
40
41     /**
42      * Reset the given user's password.
43      */
44     public function reset(Request $request)
45     {
46         $request->validate([
47             'token' => 'required',
48             'email' => 'required|email',
49             'password' => ['required', 'confirmed', PasswordRule::defaults()],
50         ]);
51
52         // Here we will attempt to reset the user's password. If it is successful we
53         // will update the password on an actual user model and persist it to the
54         // database. Otherwise we will parse the error and return the response.
55         $credentials = $request->only('email', 'password', 'password_confirmation', 'token');
56         $response = Password::broker()->reset($credentials, function (User $user, string $password) {
57             $user->password = Hash::make($password);
58             $user->setRememberToken(Str::random(60));
59             $user->save();
60
61             $this->loginService->login($user, auth()->getDefaultDriver());
62         });
63
64         // If the password was successfully reset, we will redirect the user back to
65         // the application's home authenticated view. If there is an error we can
66         // redirect them back to where they came from with their error message.
67         return $response === Password::PASSWORD_RESET
68             ? $this->sendResetResponse()
69             : $this->sendResetFailedResponse($request, $response);
70     }
71
72     /**
73      * Get the response for a successful password reset.
74      */
75     protected function sendResetResponse(): RedirectResponse
76     {
77         $this->showSuccessNotification(trans('auth.reset_password_success'));
78         $this->logActivity(ActivityType::AUTH_PASSWORD_RESET_UPDATE, user());
79
80         return redirect('/');
81     }
82
83     /**
84      * Get the response for a failed password reset.
85      */
86     protected function sendResetFailedResponse(Request $request, string $response): RedirectResponse
87     {
88         // We show invalid users as invalid tokens as to not leak what
89         // users may exist in the system.
90         if ($response === Password::INVALID_USER) {
91             $response = Password::INVALID_TOKEN;
92         }
93
94         return redirect()->back()
95             ->withInput($request->only('email'))
96             ->withErrors(['email' => trans($response)]);
97     }
98 }