new:[authentication apis]add classes required for password reset API #2

This commit is contained in:
weichien00
2021-06-26 18:19:54 +08:00
parent 9248592417
commit 116248b346
11 changed files with 434 additions and 0 deletions
@@ -0,0 +1,80 @@
<?php
namespace App\Classes\Modules\Accounts\ControllersLogic;
use App\Classes\Modules\Accounts\DataTransferObjects\NewPasswordObject;
use App\Classes\Modules\Accounts\DataTransferObjects\PasswordResetObject;
use App\Classes\Modules\Accounts\Services\ChangesPassword;
use App\Classes\Modules\Accounts\Services\CompletesPasswordReset;
use App\Classes\Modules\Accounts\Services\FetchesPasswordReset;
use App\Classes\Modules\Accounts\Standards\Rules\CanResetPassword;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Models\PasswordReset;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ResetPasswordLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Password Change',
'message' => 'You have successfully changed your account\'t password'
];
}
/** @var CanResetPassword */
private $canResetPassword;
/** @var FetchesPasswordReset */
private $fetchesPasswordReset;
/** @var ChangesPassword */
private $changePassword;
/** @var CompletesPasswordReset */
private $completesPasswordResetToken;
/**
* ResetPasswordLogic constructor.
* @param CanResetPassword $canResetPassword
* @param FetchesPasswordReset $fetchesPasswordReset
* @param ChangesPassword $changePassword
* @param CompletesPasswordReset $completesPasswordResetToken
*/
public function __construct(CanResetPassword $canResetPassword, FetchesPasswordReset $fetchesPasswordReset, ChangesPassword $changePassword, CompletesPasswordReset $completesPasswordResetToken)
{
$this->canResetPassword = $canResetPassword;
$this->fetchesPasswordReset = $fetchesPasswordReset;
$this->changePassword = $changePassword;
$this->completesPasswordResetToken = $completesPasswordResetToken;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\InternalServerErrorException
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function logic(Request $request): JsonResponse {
$object = new PasswordResetObject($request->input('token'),
new NewPasswordObject($request->input('password'), $request->input('confirmPassword')));
$this->canResetPassword->passes($object);
/** @var PasswordReset $passwordReset */
$passwordReset = $this->fetchesPasswordReset->execute(['token' => $object->getToken(), 'with_user']);
$this->changePassword->execute($passwordReset->user, $object->getNewPassword());
$this->completesPasswordResetToken->execute($passwordReset);
return $this->response();
}
}
@@ -0,0 +1,45 @@
<?php
namespace App\Classes\Modules\Accounts\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
class NewPasswordObject implements DataTransferObject
{
/** @var String */
private $password;
/** @var String */
private $ConfirmPassword;
/**
* NewPassword constructor.
* @param String $password
* @param String $ConfirmPassword
*/
public function __construct(String $password, String $ConfirmPassword)
{
$this->password = $password;
$this->ConfirmPassword = $ConfirmPassword;
}
/**
* @return String
*/
public function getPassword(): String
{
return $this->password;
}
/**
* @return String
*/
public function getConfirmPassword(): String
{
return $this->ConfirmPassword;
}
}
@@ -0,0 +1,42 @@
<?php
namespace App\Classes\Modules\Accounts\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
class PasswordResetObject implements DataTransferObject
{
/** @var String */
private $token;
/** @var NewPasswordObject */
private $newPassword;
/**
* PasswordResetObject constructor.
* @param String $token
* @param NewPasswordObject $newPassword
*/
public function __construct(String $token, NewPasswordObject $newPassword)
{
$this->token = $token;
$this->newPassword = $newPassword;
}
/**
* @return String
*/
public function getToken(): String
{
return $this->token;
}
/**
* @return NewPasswordObject
*/
public function getNewPassword(): NewPasswordObject
{
return $this->newPassword;
}
}
@@ -0,0 +1,32 @@
<?php
namespace App\Classes\Modules\Accounts\Services;
use App\Classes\Exceptions\InternalServerErrorException;
use App\Classes\Modules\Accounts\DataTransferObjects\NewPasswordObject;
use App\Models\User;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Hash;
class ChangesPassword
{
/**
* @param User $user
* @param NewPasswordObject $object
* @return bool
* @throws InternalServerErrorException
*/
public function execute(User $user, NewPasswordObject $object): bool {
try {
$user->password = Hash::make($object->getPassword());
return $user->save();
} catch (QueryException $exception){
throw new InternalServerErrorException($exception->getMessage());
}
}
}
@@ -0,0 +1,26 @@
<?php
namespace App\Classes\Modules\Accounts\Services;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Models\PasswordReset;
class CompletesPasswordReset extends AbstractUpdateRecord
{
/**
* @param PasswordReset $model
* @return \Illuminate\Database\Eloquent\Model
* @throws MalformedRequestException
*/
public function execute(PasswordReset $model){
$model->is_complete = true;
return $this->handler($model);
}
}
@@ -0,0 +1,34 @@
<?php
namespace App\Classes\Modules\Accounts\Services;
use App\Classes\General\Eloquent\AbstractFetchRecord;
use App\Models\PasswordReset;
use Illuminate\Database\Eloquent\Builder;
class FetchesPasswordReset extends AbstractFetchRecord
{
/** @var PasswordReset */
private $repository;
/**
* FetchesResetPasswordToken constructor.
* @param PasswordReset $repository
*/
public function __construct(PasswordReset $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,39 @@
<?php
namespace App\Classes\Modules\Accounts\Standards\Criteria;
use App\Classes\Exceptions\ResourceNotFoundException;
use App\Models\PasswordReset;
class PasswordResetTokenExists
{
/** @var PasswordReset */
private $repository;
/**
* TokenExistsValidation constructor.
* @param PasswordReset $repository
*/
public function __construct(PasswordReset $repository)
{
$this->repository = $repository;
}
/**
* @param string $token
* @return bool
* @throws ResourceNotFoundException
*/
public function execute(string $token){
if(!$this->repository->active()->where('token', $token)->first()){
throw new ResourceNotFoundException('The reset password token has expired or doesn\'t exist');
}
return true;
}
}
@@ -0,0 +1,65 @@
<?php
namespace App\Classes\Modules\Accounts\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\Exceptions\RequestValidationException;
use App\Classes\Exceptions\ResourceNotFoundException;
use App\Classes\Modules\Accounts\DataTransferObjects\PasswordResetObject;
use App\Classes\Modules\Accounts\Standards\Criteria\PasswordResetTokenExists;
use App\Classes\Modules\Accounts\Standards\Validators\ResetPasswordValidation;
class CanResetPassword extends AbstractRule
{
/** @var ResetPasswordValidation */
private $resetPasswordValidation;
/** @var PasswordResetTokenExists */
private $passwordResetTokenExists;
/**
* CanResetPassword constructor.
* @param ResetPasswordValidation $resetPasswordValidation
* @param PasswordResetTokenExists $passwordResetTokenExists
*/
public function __construct(ResetPasswordValidation $resetPasswordValidation, PasswordResetTokenExists $passwordResetTokenExists)
{
$this->resetPasswordValidation = $resetPasswordValidation;
$this->passwordResetTokenExists = $passwordResetTokenExists;
}
/**
* @return bool
*/
protected function authorized(): bool
{
return true;
}
/**
* @param PasswordResetObject $object
* @return bool
* @throws RequestValidationException
*/
protected function validators($object): bool
{
return $this->resetPasswordValidation->validate($object);
}
/**
* @param PasswordResetObject $object
* @return bool
* @throws ResourceNotFoundException
*/
protected function criteria($object): bool
{
return $this->passwordResetTokenExists->execute($object->getToken());
}
}
@@ -0,0 +1,50 @@
<?php
namespace App\Classes\Modules\Accounts\Standards\Validators;
use App\Classes\General\Abstracts\AbstractValidation;
use App\Classes\Modules\Accounts\DataTransferObjects\PasswordResetObject;
class ResetPasswordValidation extends AbstractValidation
{
/**
* @param PasswordResetObject $object
* @return array
*/
protected function data($object): array {
return [
'token' => $object->getToken(),
'password' => $object->getNewPassword()->getPassword(),
'confirm_password' => $object->getNewPassword()->getConfirmPassword()
];
}
/**
* @return array
*/
protected function rules(): array {
return [
'token' => 'required',
'password' => 'required|min:6',
'confirm_password' => 'same:password'
];
}
/**
* @return array
*/
protected function messages(): array {
return [
'confirm_password' => [
'same' => 'The :attribute and :other must match.'
]
];
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Accounts;
use App\Classes\Modules\Accounts\ControllersLogic\ResetPasswordLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ResetPasswordController
{
/**
* @param Request $request
* @param ResendEmailVerificationLogic $logic
* @return JsonResponse
*/
public function reset(Request $request, ResetPasswordLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
+1
View File
@@ -21,6 +21,7 @@ Route::group(['prefix' => 'account', 'namespace' => 'Accounts', 'as' => 'account
Route::group(['prefix' => 'password', 'as' => 'password.'], function () {
Route::post('/forget', 'GeneratePasswordResetController@generate')->name('forget');
Route::post('/reset', 'ResetPasswordController@reset')->name('reset');
});
});
});