first commit
This commit is contained in:
237
app/Http/Controllers/PasswordResetController.php
Normal file
237
app/Http/Controllers/PasswordResetController.php
Normal file
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Exceptions\Entities\AuthorizationException;
|
||||
use App\Helpers\Recaptcha;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Events\PasswordReset as PasswordResetEvent;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use DB;
|
||||
use Mail;
|
||||
use Password;
|
||||
use Validator;
|
||||
|
||||
class PasswordResetController extends BaseController
|
||||
{
|
||||
public function __construct(private Recaptcha $recaptcha)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} /v1/auth/password/reset/validate Validate
|
||||
* @apiDescription Validates password reset token
|
||||
*
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName Validate token
|
||||
* @apiGroup Password Reset
|
||||
*
|
||||
* @apiParam {String} email User email
|
||||
* @apiParam {String} token Password reset token
|
||||
*
|
||||
* @apiParamExample {json} Request Example
|
||||
* {
|
||||
* "email": "johndoe@example.com",
|
||||
* "token": "03AOLTBLR5UtIoenazYWjaZ4AFZiv1OWegWV..."
|
||||
* }
|
||||
*
|
||||
* @apiSuccess {String} message Message from server
|
||||
*
|
||||
* @apiSuccessExample {json} Response Example
|
||||
* HTTP/1.1 200 OK
|
||||
* {
|
||||
* "message": "Password reset data is valid"
|
||||
* }
|
||||
*
|
||||
* @apiUse 400Error
|
||||
* @apiUse ParamsValidationError
|
||||
* @apiUse InvalidPasswordResetDataError
|
||||
*/
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws AuthorizationException
|
||||
*/
|
||||
public function validate(Request $request): JsonResponse
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'email' => 'required|email',
|
||||
'token' => 'required|string'
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
throw new AuthorizationException(AuthorizationException::ERROR_TYPE_VALIDATION_FAILED);
|
||||
}
|
||||
|
||||
$user = Password::broker()->getUser($request->all());
|
||||
if (!$user) {
|
||||
throw new AuthorizationException(AuthorizationException::ERROR_TYPE_INVALID_PASSWORD_RESET_DATA);
|
||||
}
|
||||
|
||||
$isValidToken = Password::broker()->getRepository()->exists($user, $request->input('token'));
|
||||
if (!$isValidToken) {
|
||||
throw new AuthorizationException(AuthorizationException::ERROR_TYPE_INVALID_PASSWORD_RESET_DATA);
|
||||
}
|
||||
|
||||
return new JsonResponse(['message' => 'Password reset data is valid']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /v1/auth/password/reset/request Request
|
||||
* @apiDescription Sends email to user with reset link
|
||||
*
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName Request
|
||||
* @apiGroup Password Reset
|
||||
*
|
||||
* @apiParam {String} login User login
|
||||
* @apiParam {String} [recaptcha] Recaptcha token
|
||||
*
|
||||
* @apiParamExample {json} Request Example
|
||||
* {
|
||||
* "email": "johndoe@example.com",
|
||||
* "recaptcha": "03AOLTBLR5UtIoenazYWjaZ4AFZiv1OWegWV..."
|
||||
* }
|
||||
*
|
||||
* @apiSuccess {String} message Message from server
|
||||
*
|
||||
* @apiSuccessExample {json} Response Example
|
||||
* HTTP/1.1 200 OK
|
||||
* {
|
||||
* "message": "Link for restore password has been sent to specified email"
|
||||
* }
|
||||
*
|
||||
* @apiUse 400Error
|
||||
* @apiUse ParamsValidationError
|
||||
* @apiUse NoSuchUserError
|
||||
* @apiUse CaptchaError
|
||||
* @apiUse LimiterError
|
||||
*/
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws AuthorizationException
|
||||
*/
|
||||
public function request(Request $request): JsonResponse
|
||||
{
|
||||
$validator = Validator::make($request->all(), ['email' => 'required|email']);
|
||||
|
||||
if ($validator->fails()) {
|
||||
throw new AuthorizationException(AuthorizationException::ERROR_TYPE_VALIDATION_FAILED);
|
||||
}
|
||||
|
||||
$credentials = $request->only(['email', 'recaptcha']);
|
||||
$this->recaptcha->check($credentials);
|
||||
$user = User::where('email', $credentials['email'])->first();
|
||||
|
||||
if (!$user) {
|
||||
$this->recaptcha->incrementCaptchaAmounts();
|
||||
$this->recaptcha->check($credentials);
|
||||
|
||||
throw new AuthorizationException(AuthorizationException::ERROR_TYPE_USER_NOT_FOUND);
|
||||
}
|
||||
|
||||
$this->recaptcha->clearCaptchaAmounts();
|
||||
|
||||
Password::broker()->sendResetLink(['email' => $credentials['email']]);
|
||||
|
||||
return new JsonResponse([
|
||||
'message' => 'Link for restore password has been sent to specified email',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @api {post} /v1/auth/password/reset/process Process
|
||||
* @apiDescription Resets user password
|
||||
*
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName Process
|
||||
* @apiGroup Password Reset
|
||||
*
|
||||
* @apiParam {String} email User email
|
||||
* @apiParam {String} token Password reset token
|
||||
* @apiParam {String} password New password
|
||||
* @apiParam {String} password_confirmation Password confirmation
|
||||
*
|
||||
* @apiParamExample {json} Request Example
|
||||
* {
|
||||
* "email": "johndoe@example.com",
|
||||
* "token": "16184cf3b2510464a53c0e573c75740540fe...",
|
||||
* "password_confirmation": "amazingpassword",
|
||||
* "password": "amazingpassword"
|
||||
* }
|
||||
*
|
||||
* @apiSuccess {String} access_token Token
|
||||
* @apiSuccess {String} token_type Token Type
|
||||
* @apiSuccess {String} expires_in Token TTL in seconds
|
||||
* @apiSuccess {Object} user User Entity
|
||||
*
|
||||
* @apiUse UserObject
|
||||
*
|
||||
* @apiSuccessExample {json} Response Example
|
||||
* HTTP/1.1 200 OK
|
||||
* {
|
||||
* "access_token": "16184cf3b2510464a53c0e573c75740540fe...",
|
||||
* "token_type": "bearer",
|
||||
* "password": "amazingpassword",
|
||||
* "expires_in": "3600",
|
||||
* "user": {}
|
||||
* }
|
||||
*
|
||||
* @apiUse 400Error
|
||||
* @apiUse ParamsValidationError
|
||||
* @apiUse InvalidPasswordResetDataError
|
||||
* @apiUse UnauthorizedError
|
||||
*/
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws AuthorizationException
|
||||
*/
|
||||
public function process(Request $request): JsonResponse
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'email' => 'required|email',
|
||||
'token' => 'required|string',
|
||||
'password' => 'required',
|
||||
'password_confirmation' => 'required'
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
throw new AuthorizationException(AuthorizationException::ERROR_TYPE_VALIDATION_FAILED);
|
||||
}
|
||||
|
||||
$resetRequest = DB::table('password_resets')
|
||||
->where('email', $request->input('email'))
|
||||
->first();
|
||||
|
||||
if (!$resetRequest) {
|
||||
throw new AuthorizationException(AuthorizationException::ERROR_TYPE_INVALID_PASSWORD_RESET_DATA);
|
||||
}
|
||||
|
||||
$response = Password::broker()->reset(
|
||||
$request->all(),
|
||||
static function (User $user, string $password) {
|
||||
$user->password = $password;
|
||||
$user->save();
|
||||
event(new PasswordResetEvent($user));
|
||||
auth()->login($user);
|
||||
}
|
||||
);
|
||||
|
||||
if ($response !== Password::PASSWORD_RESET) {
|
||||
throw new AuthorizationException(AuthorizationException::ERROR_TYPE_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$token = auth()->setTTL(config('auth.lifetime_minutes.jwt'))->refresh();
|
||||
|
||||
return new JsonResponse([
|
||||
'access_token' => $token,
|
||||
'token_type' => 'bearer',
|
||||
'expires_in' => now()->addMinutes(config('auth.lifetime_minutes.jwt'))->toIso8601String(),
|
||||
'user' => auth()->user(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user