From 6d97fc24c4debfca7bd8f0848a048b1b855a8995 Mon Sep 17 00:00:00 2001 From: Flo Date: Tue, 27 Aug 2024 20:49:35 +0000 Subject: [PATCH] default functions --- bin/createApi.php | 22 ++--- data/mails/reset-password/assets/icon.png | Bin 0 -> 1766 bytes data/mails/reset-password/template.latte | 63 ++++++++++++ .../business/Version20240827155813.php | 37 +++++++ .../External/Authentication/config/routes.php | 18 ++++ .../Authentication/config/service_manager.php | 10 +- .../src/Handler/ForgotPasswordHandler.php | 39 ++++++++ .../src/Handler/ResetPasswordHandler.php | 45 +++++++++ .../ForgotPasswordResponseFormatter.php | 17 ++++ .../ResetPasswordResponseFormatter.php | 17 ++++ .../src/Handler/ChangePasswordHandler.php | 1 + .../Business/config/service_manager.php | 4 +- src/DataDomain/Business/src/Entity/User.php | 4 + .../Business/src/Entity/UserPasswordToken.php | 91 ++++++++++++++++++ .../src/Repository/PermissionRepository.php | 4 +- .../src/Repository/ProductRepository.php | 10 -- .../src/Repository/RoleRepository.php | 2 - .../UserPasswordTokenRepository.php | 10 ++ .../src/Repository/UserRepository.php | 2 - .../src/Repository/UserSessionRepository.php | 14 +-- .../RegisterUser/Step/SendMailStep.php | 1 + .../User/config/service_manager.php | 14 ++- .../src/Builder/UserPasswordTokenBuilder.php | 25 +++++ .../Exception/UserNotFoundByMailException.php | 24 +++++ ...rPasswordConfirmationMismatchException.php | 21 ++++ ...UserPasswordTokenNotFoundByIdException.php | 26 +++++ .../ChangePassword/ChangePasswordCommand.php | 6 ++ .../ChangePasswordCommandBuilder.php | 2 + .../ChangePasswordCommandHandler.php | 9 ++ .../ForgotPassword/ForgotPasswordCommand.php | 24 +++++ .../ForgotPasswordCommandBuilder.php | 18 ++++ .../ForgotPasswordCommandHandler.php | 70 ++++++++++++++ .../ForgotPasswordCommandResult.php | 12 +++ .../ResetPassword/ResetPasswordCommand.php | 32 ++++++ .../ResetPasswordCommandBuilder.php | 22 +++++ .../ResetPasswordCommandHandler.php | 63 ++++++++++++ .../ResetPasswordCommandResult.php | 13 +++ .../src/AutowireRepositoryFactory.php | 24 +++++ .../Database/src/ConfigServiceFactory.php | 33 ------- .../UuidGenerator/src/UuidGenerator.php | 4 +- 40 files changed, 769 insertions(+), 84 deletions(-) create mode 100644 data/mails/reset-password/assets/icon.png create mode 100644 data/mails/reset-password/template.latte create mode 100644 data/migrations/business/Version20240827155813.php create mode 100644 src/ApiDomain/External/Authentication/src/Handler/ForgotPasswordHandler.php create mode 100644 src/ApiDomain/External/Authentication/src/Handler/ResetPasswordHandler.php create mode 100644 src/ApiDomain/External/Authentication/src/ResponseFormatter/ForgotPasswordResponseFormatter.php create mode 100644 src/ApiDomain/External/Authentication/src/ResponseFormatter/ResetPasswordResponseFormatter.php create mode 100644 src/DataDomain/Business/src/Entity/UserPasswordToken.php delete mode 100644 src/DataDomain/Business/src/Repository/ProductRepository.php create mode 100644 src/DataDomain/Business/src/Repository/UserPasswordTokenRepository.php create mode 100644 src/HandlingDomain/User/src/Builder/UserPasswordTokenBuilder.php create mode 100644 src/HandlingDomain/User/src/Exception/UserNotFoundByMailException.php create mode 100644 src/HandlingDomain/User/src/Exception/UserPasswordConfirmationMismatchException.php create mode 100644 src/HandlingDomain/User/src/Exception/UserPasswordTokenNotFoundByIdException.php create mode 100644 src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommand.php create mode 100644 src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommandBuilder.php create mode 100644 src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommandHandler.php create mode 100644 src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommandResult.php create mode 100644 src/HandlingDomain/User/src/Handler/Command/ResetPassword/ResetPasswordCommand.php create mode 100644 src/HandlingDomain/User/src/Handler/Command/ResetPassword/ResetPasswordCommandBuilder.php create mode 100644 src/HandlingDomain/User/src/Handler/Command/ResetPassword/ResetPasswordCommandHandler.php create mode 100644 src/HandlingDomain/User/src/Handler/Command/ResetPassword/ResetPasswordCommandResult.php create mode 100644 src/Infrastructure/Database/src/AutowireRepositoryFactory.php delete mode 100644 src/Infrastructure/Database/src/ConfigServiceFactory.php diff --git a/bin/createApi.php b/bin/createApi.php index 24c4b0b..8be687c 100644 --- a/bin/createApi.php +++ b/bin/createApi.php @@ -201,8 +201,8 @@ use Psr\\Http\\Server\\RequestHandlerInterface; class {$apiHandlerName} implements RequestHandlerInterface { public function __construct( - private readonly {$cqrsHandlerName} \${$cqrsHandlerVariableName}, - private readonly {$cqrsBuilderName} \${$cqrsBuilderVariableName}, + private readonly {$cqrsHandlerName} \$handler, + private readonly {$cqrsBuilderName} \$builder, private readonly {$apiResponseFormatterName} \$responseFormatter, ) { } @@ -211,10 +211,10 @@ class {$apiHandlerName} implements RequestHandlerInterface { \$data = \$request->getAttribute(AnalyzeBodyMiddleware::JSON_DATA); - \${$cqrsVariableName} = \$this->{$cqrsBuilderVariableName}->build( + \${$cqrsVariableName} = \$this->builder->build( \$data ); - \$result = \$this->{$cqrsHandlerVariableName}->execute(\${$cqrsVariableName}); + \$result = \$this->handler->execute(\${$cqrsVariableName}); return new SuccessResponse(\$this->responseFormatter->format(\$result)); } @@ -251,10 +251,10 @@ namespace {$cqrsHandlerNamespace}; class {$cqrsName} { public function __construct( - #TODO - ) { + #TODO + ) { } - + #TODO } "; @@ -270,14 +270,12 @@ class {$cqrsHandlerName} { public function __construct( #TODO - ) { + ) { } - + public function execute({$cqrsName} \${$cqrsVariableName}): {$cqrsResultName} { - return new {$cqrsResultName}( - - ); + return new {$cqrsResultName}(); } } "; diff --git a/data/mails/reset-password/assets/icon.png b/data/mails/reset-password/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..07e8b9d9cba7a4dc27cd800357a7ca8e4b45ec2c GIT binary patch literal 1766 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vHNyZ``ByaAytitqpc02y>eSaefwW^{L9 za%BK_cXuvnZfkR6VQ^(GZ*pgw?mQX*00ve`L_t(|UhSM`sPse>hOc7p4SW0S3Mwd8 z1jXJfqJk)*_`@G|YzT^q3N}Ph5qm+z&w{;yU@!PbR8;KPd++Ui*aULpNivg}l)IY; z9vYtO4wiiYuG4rCfk7;422iKP>zKGze+2PtMU(d zqolwmh8^XL(khTTQivDHMdjGCq`XyH1rWmz6rd0kCmOU zygW+M>3&~k+oLb#Bl38;mULxr`J2ps$)-J5w#K^hCi%OxK8)on@+7&EEaDK!-C(`H zX-}7pLUlYkEM_vGSw@x8RJLf$K7Q|u>yl-7BDB!tRF0>Fdh8ENgG zm+I}sThcmE-cKY$eKA>EUL$=HtyLZ^v(V66`&k|)y`UOd2eKri96De=kK_wIDx1jb zy)08W7mdBOpXKh-i({m9pdufTWHNl1SMDn5Lw+HxMk=XL3G zM-k!QC7+dySCAh1K>}Bshrz0nFTs!>@gXDqZE>+A3-g+EO;geKFD@xWFYb}~t1y%O zOx~CKTb1;*YC#Zd9dMFlkg7Ix_^pFZf;2-*$l8#8j}dFlMCm#PLmJyU_&7_ihpB5( zI7eD1>5H*z$AvN~N6MH{e=NC6_R0M%#J6QSQ8FrLO6!DOnhw+uTU!73kqhCIpY)<{ zLy>gl)|9|hF>4=JIaXtHRlq01+=k=;Q^=ff=UDqyN%Ge_0pJ7efOX<7-B)I*Q!|*c z746Ad1cS`h$-9#7RzAhPleG3N@-i7^6+l%IV7X-57f3=d5i-kTk^ym780)1FgQ+S! z?{sv-khsXhAovZVmrjtY3!Ojh#MUx@+jk|YuA)&fQeQp^)oo=kRd*hfwfh3oI`UOE zg=+iw=%o`(AP=Uh@ZL?feSpE6GOkOuF3>xP^3bT_Q)%7$ZOh178Dy?~CL1xaDF~O8 zdv+kDOIY(!2D3w1J><$>$+l6*tXfyDZI_l+tS_ziTGB6W9J)YVEi%dKy6Dbl!5=>< zQX7|Q`;{a$-!;r>apBrz>%!*AwozDG(8R#BkFK-xSvg7IY#k%-39>dWcOEdFd&}r$ zXSfcqe=SLFx)3ym>{@tmoMfI#S8SMUU2vVrMR-#ipTc9(Ad{%M-MheNk+JK;rIkQA z%ZW1IcC;Y_J}y<4C#Y-t%>10zxl~#orfKh&WwnKB_@K1jYk7cd9lpR7()vJ6%hCas z<>w*n@Lettv{W>-&YzLkcH2Ql`CiEbjGo6fl5olgrtx + + + Passwort zurücksetzen + + + + +
+

Hallo {$username},

+
+

Dein Passwort wurde zurückgesetzt.

+

Bitte klicke auf diesen Link um ein neues Passwort zu vergeben.

+
+

Wenn du dein Passwort nicht zurückgesetzt hast, kannst du diese Nachricht ignorieren!

+
+

Mit fleißigen Grüßen,

+

Der Beekeeper

+
+ + diff --git a/data/migrations/business/Version20240827155813.php b/data/migrations/business/Version20240827155813.php new file mode 100644 index 0000000..59162dc --- /dev/null +++ b/data/migrations/business/Version20240827155813.php @@ -0,0 +1,37 @@ +addSql($sql); + } + + public function down(Schema $schema): void + { + $this->addSql("DROP TABLE user_password_token;"); + } +} diff --git a/src/ApiDomain/External/Authentication/config/routes.php b/src/ApiDomain/External/Authentication/config/routes.php index 06dda9f..dc8b4fd 100644 --- a/src/ApiDomain/External/Authentication/config/routes.php +++ b/src/ApiDomain/External/Authentication/config/routes.php @@ -1,9 +1,11 @@ 'auth.forgot-password', + 'path' => '/api/auth/forgot-password', + 'allowed_methods' => ['POST'], + 'middleware' => [ + ForgotPasswordHandler::class, + ], + ], + [ + 'name' => 'auth.reset-password', + 'path' => '/api/auth/reset-password', + 'allowed_methods' => ['POST'], + 'middleware' => [ + ResetPasswordHandler::class, + ], + ], ]; \ No newline at end of file diff --git a/src/ApiDomain/External/Authentication/config/service_manager.php b/src/ApiDomain/External/Authentication/config/service_manager.php index 61124b9..3d22b21 100644 --- a/src/ApiDomain/External/Authentication/config/service_manager.php +++ b/src/ApiDomain/External/Authentication/config/service_manager.php @@ -3,9 +3,13 @@ use Bee\API\External\Authentication\Formatter\ConfirmRegistrationFormatter; use Bee\API\External\Authentication\Formatter\LoginUserFormatter; use Bee\API\External\Authentication\Handler\ConfirmRegistrationHandler; +use Bee\API\External\Authentication\Handler\ForgotPasswordHandler; use Bee\API\External\Authentication\Handler\LoginUserHandler; use Bee\API\External\Authentication\Handler\LogoutUserHandler; use Bee\API\External\Authentication\Handler\RegisterUserHandler; +use Bee\API\External\Authentication\Handler\ResetPasswordHandler; +use Bee\API\External\Authentication\ResponseFormatter\ForgotPasswordResponseFormatter; +use Bee\API\External\Authentication\ResponseFormatter\ResetPasswordResponseFormatter; use Reinfi\DependencyInjection\Factory\AutoWiringFactory; return [ @@ -13,11 +17,15 @@ return [ // Formatter ConfirmRegistrationFormatter::class => AutoWiringFactory::class, LoginUserFormatter::class => AutoWiringFactory::class, + ForgotPasswordResponseFormatter::class => AutoWiringFactory::class, + ResetPasswordResponseFormatter::class => AutoWiringFactory::class, // Handler LoginUserHandler::class => AutoWiringFactory::class, LogoutUserHandler::class => AutoWiringFactory::class, ConfirmRegistrationHandler::class => AutoWiringFactory::class, - RegisterUserHandler::class => AutoWiringFactory::class + RegisterUserHandler::class => AutoWiringFactory::class, + ForgotPasswordHandler::class => AutoWiringFactory::class, + ResetPasswordHandler::class => AutoWiringFactory::class, ], ]; diff --git a/src/ApiDomain/External/Authentication/src/Handler/ForgotPasswordHandler.php b/src/ApiDomain/External/Authentication/src/Handler/ForgotPasswordHandler.php new file mode 100644 index 0000000..76da25a --- /dev/null +++ b/src/ApiDomain/External/Authentication/src/Handler/ForgotPasswordHandler.php @@ -0,0 +1,39 @@ +getAttribute(AnalyzeHeaderMiddleware::HOST_ATTRIBUTE); + $data = $request->getAttribute(AnalyzeBodyMiddleware::JSON_DATA); + + $forgotPasswordCommand = $this->forgotPasswordCommandBuilder->build( + domain: $host, + mail: $data['mail'], + ); + $result = $this->forgotPasswordCommandHandler->execute($forgotPasswordCommand); + + return new SuccessResponse($this->responseFormatter->format($result)); + } +} diff --git a/src/ApiDomain/External/Authentication/src/Handler/ResetPasswordHandler.php b/src/ApiDomain/External/Authentication/src/Handler/ResetPasswordHandler.php new file mode 100644 index 0000000..b3b5cd2 --- /dev/null +++ b/src/ApiDomain/External/Authentication/src/Handler/ResetPasswordHandler.php @@ -0,0 +1,45 @@ +getAttribute(AnalyzeBodyMiddleware::JSON_DATA); + + $resetPasswordCommand = $this->builder->build( + Uuid::fromString($data['passwordToken']), + $data['newPassword'], + $data['passwordConfirmation'], + ); + $result = $this->handler->execute($resetPasswordCommand); + + return new SuccessResponse($this->responseFormatter->format($result)); + } +} diff --git a/src/ApiDomain/External/Authentication/src/ResponseFormatter/ForgotPasswordResponseFormatter.php b/src/ApiDomain/External/Authentication/src/ResponseFormatter/ForgotPasswordResponseFormatter.php new file mode 100644 index 0000000..39ec4c8 --- /dev/null +++ b/src/ApiDomain/External/Authentication/src/ResponseFormatter/ForgotPasswordResponseFormatter.php @@ -0,0 +1,17 @@ +handler->execute($query); diff --git a/src/DataDomain/Business/config/service_manager.php b/src/DataDomain/Business/config/service_manager.php index 0dc87f1..78f14c3 100644 --- a/src/DataDomain/Business/config/service_manager.php +++ b/src/DataDomain/Business/config/service_manager.php @@ -14,8 +14,6 @@ return [ 'doctrine.entity_manager.orm_bee' => [BaseEntityManagerFactory::class, 'orm_bee'], 'doctrine.configuration.orm_bee' => [ConfigurationFactory::class, 'orm_bee'], 'doctrine.connection.orm_bee' => [ConnectionFactory::class, 'orm_bee'], - EntityManager::class => EntityManagerFactory::class, - - UserRepository::class => [AutowireRepositoryFactory::class, EntityManager::class, User::class], + EntityManager::class => EntityManagerFactory::class ], ]; diff --git a/src/DataDomain/Business/src/Entity/User.php b/src/DataDomain/Business/src/Entity/User.php index 48d1646..77215c1 100644 --- a/src/DataDomain/Business/src/Entity/User.php +++ b/src/DataDomain/Business/src/Entity/User.php @@ -3,6 +3,7 @@ namespace Bee\Data\Business\Entity; use DateTime; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Bee\Infrastructure\UuidGenerator\UuidGenerator; use Ramsey\Uuid\UuidInterface; @@ -39,6 +40,9 @@ class User { /** @ORM\OneToOne(targetEntity="Bee\Data\Business\Entity\UserSession", mappedBy="user") */ private ?UserSession $session; + /* @ORM\OneToMany(targetEntity="Bee\Data\Business\Entity\UserPasswordToken", mappedBy="user") */ + private Collection $passwordTokens; + /** @ORM\Column(name="last_login_at", type="datetime", nullable=true) */ private DateTime $lastLoginAt; diff --git a/src/DataDomain/Business/src/Entity/UserPasswordToken.php b/src/DataDomain/Business/src/Entity/UserPasswordToken.php new file mode 100644 index 0000000..73c0c39 --- /dev/null +++ b/src/DataDomain/Business/src/Entity/UserPasswordToken.php @@ -0,0 +1,91 @@ +id = UuidGenerator::generate(); + + $now = new DateTime(); + $this->setCreatedAt($now); + $this->setUpdatedAt($now); + } + + + /** + * @ORM\PrePersist + * @ORM\PreUpdate + */ + public function updateTimestamps(): void { + $now = new DateTime(); + $this->setUpdatedAt($now); + } + + + public function getId(): UuidInterface { + return $this->id; + } + + public function getUserId(): UuidInterface { + return $this->userId; + } + + public function setUserId(UuidInterface $userId): void { + $this->userId = $userId; + } + + public function getUser(): User { + return $this->user; + } + + public function setUser(User $user): void { + $this->user = $user; + } + + public function getCreatedAt(): DateTime { + return $this->createdAt; + } + + public function setCreatedAt(DateTime $createdAt): void { + $this->createdAt = $createdAt; + } + + public function getUpdatedAt(): DateTime { + return $this->updatedAt; + } + + public function setUpdatedAt(DateTime $updatedAt): void { + $this->updatedAt = $updatedAt; + } +} \ No newline at end of file diff --git a/src/DataDomain/Business/src/Repository/PermissionRepository.php b/src/DataDomain/Business/src/Repository/PermissionRepository.php index ac02a73..dfb1892 100644 --- a/src/DataDomain/Business/src/Repository/PermissionRepository.php +++ b/src/DataDomain/Business/src/Repository/PermissionRepository.php @@ -5,6 +5,4 @@ namespace Bee\Data\Business\Repository; use Doctrine\ORM\EntityRepository; class PermissionRepository extends EntityRepository { -} - -?> \ No newline at end of file +} \ No newline at end of file diff --git a/src/DataDomain/Business/src/Repository/ProductRepository.php b/src/DataDomain/Business/src/Repository/ProductRepository.php deleted file mode 100644 index 8769b29..0000000 --- a/src/DataDomain/Business/src/Repository/ProductRepository.php +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/src/DataDomain/Business/src/Repository/RoleRepository.php b/src/DataDomain/Business/src/Repository/RoleRepository.php index d624dee..31b34c6 100644 --- a/src/DataDomain/Business/src/Repository/RoleRepository.php +++ b/src/DataDomain/Business/src/Repository/RoleRepository.php @@ -6,5 +6,3 @@ use Doctrine\ORM\EntityRepository; class RoleRepository extends EntityRepository { } - -?> \ No newline at end of file diff --git a/src/DataDomain/Business/src/Repository/UserPasswordTokenRepository.php b/src/DataDomain/Business/src/Repository/UserPasswordTokenRepository.php new file mode 100644 index 0000000..f06abb5 --- /dev/null +++ b/src/DataDomain/Business/src/Repository/UserPasswordTokenRepository.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/src/DataDomain/Business/src/Repository/UserSessionRepository.php b/src/DataDomain/Business/src/Repository/UserSessionRepository.php index cdb91ee..ae12783 100644 --- a/src/DataDomain/Business/src/Repository/UserSessionRepository.php +++ b/src/DataDomain/Business/src/Repository/UserSessionRepository.php @@ -7,16 +7,4 @@ use Doctrine\ORM\EntityRepository; use Bee\Data\Business\Entity\UserSession; class UserSessionRepository extends EntityRepository { - public function findByUser(User $user) : ?UserSession { - $queryBuilder = $this->createQueryBuilder('us'); - $queryBuilder - ->where("us.userId = :userId") - ->setParameter('userId', $user->getId()); - - /** @var ?UserSession $userSession */ - $userSession = $queryBuilder->getQuery()->execute()[0] ?? null; - return $userSession; - } -} - -?> \ No newline at end of file +} \ No newline at end of file diff --git a/src/HandlingDomain/Registration/src/Pipeline/RegisterUser/Step/SendMailStep.php b/src/HandlingDomain/Registration/src/Pipeline/RegisterUser/Step/SendMailStep.php index b99f9b8..d7222ec 100644 --- a/src/HandlingDomain/Registration/src/Pipeline/RegisterUser/Step/SendMailStep.php +++ b/src/HandlingDomain/Registration/src/Pipeline/RegisterUser/Step/SendMailStep.php @@ -41,6 +41,7 @@ class SendMailStep implements TaskInterface ) ], recipient: $command->getMail(), + sender: 'beekeeper@stack-up.de', senderName: "Beekeeper" ); diff --git a/src/HandlingDomain/User/config/service_manager.php b/src/HandlingDomain/User/config/service_manager.php index 22439a9..ef46308 100644 --- a/src/HandlingDomain/User/config/service_manager.php +++ b/src/HandlingDomain/User/config/service_manager.php @@ -1,12 +1,17 @@ InjectionFactory::class, + UserPasswordTokenBuilder::class => AutoWiringFactory::class, /// Rule UserWithIdentifierAlreadyExistsRule::class => InjectionFactory::class, @@ -27,13 +33,17 @@ return [ // Create User CreateUserCommandHandler::class => AutoWiringFactory::class, CreateUserCommandBuilder::class => AutoWiringFactory::class, - // Change Password ChangePasswordCommandHandler::class => AutoWiringFactory::class, ChangePasswordCommandBuilder::class => AutoWiringFactory::class, - // Change Username ChangeUsernameCommandHandler::class => AutoWiringFactory::class, ChangeUsernameCommandBuilder::class => AutoWiringFactory::class, + // Forgot Password + ForgotPasswordCommandHandler::class => InjectionFactory::class, + ForgotPasswordCommandBuilder::class => AutoWiringFactory::class, + // Reset Password + ResetPasswordCommandHandler::class => InjectionFactory::class, + ResetPasswordCommandBuilder::class => AutoWiringFactory::class, ], ]; diff --git a/src/HandlingDomain/User/src/Builder/UserPasswordTokenBuilder.php b/src/HandlingDomain/User/src/Builder/UserPasswordTokenBuilder.php new file mode 100644 index 0000000..ce78bfd --- /dev/null +++ b/src/HandlingDomain/User/src/Builder/UserPasswordTokenBuilder.php @@ -0,0 +1,25 @@ +setUser($user); + + return $userPasswordToken; + } +} diff --git a/src/HandlingDomain/User/src/Exception/UserNotFoundByMailException.php b/src/HandlingDomain/User/src/Exception/UserNotFoundByMailException.php new file mode 100644 index 0000000..4dd0601 --- /dev/null +++ b/src/HandlingDomain/User/src/Exception/UserNotFoundByMailException.php @@ -0,0 +1,24 @@ +password; } + + public function getNewPasswordConfirmation(): string + { + return $this->newPasswordConfirmation; + } } diff --git a/src/HandlingDomain/User/src/Handler/Command/ChangePassword/ChangePasswordCommandBuilder.php b/src/HandlingDomain/User/src/Handler/Command/ChangePassword/ChangePasswordCommandBuilder.php index 2995991..a9f6561 100644 --- a/src/HandlingDomain/User/src/Handler/Command/ChangePassword/ChangePasswordCommandBuilder.php +++ b/src/HandlingDomain/User/src/Handler/Command/ChangePassword/ChangePasswordCommandBuilder.php @@ -10,12 +10,14 @@ class ChangePasswordCommandBuilder User $user, string $password, string $newPassword, + string $newPasswordConfirmation, ): ChangePasswordCommand { return new ChangePasswordCommand( $user, $password, $newPassword, + $newPasswordConfirmation, ); } } diff --git a/src/HandlingDomain/User/src/Handler/Command/ChangePassword/ChangePasswordCommandHandler.php b/src/HandlingDomain/User/src/Handler/Command/ChangePassword/ChangePasswordCommandHandler.php index 263d800..5887cd7 100644 --- a/src/HandlingDomain/User/src/Handler/Command/ChangePassword/ChangePasswordCommandHandler.php +++ b/src/HandlingDomain/User/src/Handler/Command/ChangePassword/ChangePasswordCommandHandler.php @@ -6,6 +6,7 @@ use Bee\Data\Business\Entity\User; use Bee\Data\Business\Repository\RoleRepository; use Bee\Data\Business\Repository\UserRepository; use Bee\Handling\User\Exception\UserNotFoundByIdentifierException; +use Bee\Handling\User\Exception\UserPasswordConfirmationMismatchException; use Bee\Handling\User\Exception\UserWrongPasswordException; use Bee\Data\Business\Manager\EntityManager; use Bee\Infrastructure\Encryption\Client\EncryptionClient; @@ -20,6 +21,10 @@ class ChangePasswordCommandHandler ) { } + /** + * @throws UserWrongPasswordException + * @throws UserPasswordConfirmationMismatchException + */ public function execute(ChangePasswordCommand $command): void { $user = $command->getUser(); @@ -28,6 +33,10 @@ class ChangePasswordCommandHandler throw new UserWrongPasswordException(); } + if ($command->getNewPassword() !== $command->getNewPasswordConfirmation()) { + throw new UserPasswordConfirmationMismatchException(); + } + $encryptedPassword = $this->encryptionClient->encrypt( $command->getNewPassword() ); diff --git a/src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommand.php b/src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommand.php new file mode 100644 index 0000000..6cca779 --- /dev/null +++ b/src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommand.php @@ -0,0 +1,24 @@ +domain; + } + + public function getMail(): string + { + return $this->mail; + } +} diff --git a/src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommandBuilder.php b/src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommandBuilder.php new file mode 100644 index 0000000..63ca3ef --- /dev/null +++ b/src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommandBuilder.php @@ -0,0 +1,18 @@ +getMail(); + + /** @var User $user */ + $user = $this->userRepository->findOneBy(['mail' => $mail]); + + if ($user === null) { + throw new UserNotFoundByMailException($mail); + } + + $passwordToken = $this->passwordTokenBuilder->build($user); + + $this->entityManager->persist($passwordToken); + $this->entityManager->flush(); + + $this->mailService->send( + 'reset-password', + templateData: [ + 'username' => $user->getUsername(), + 'passwordResetLink' => sprintf( + self::RESET_PASSWORD_LINK, + $forgotPasswordCommand->getDomain(), + $passwordToken->getId()->toString() + ) + ], + recipient: $mail, + sender: 'beekeeper@stack-up.de', + senderName: 'Beekeeper' + ); + + return new ForgotPasswordCommandResult(); + } +} diff --git a/src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommandResult.php b/src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommandResult.php new file mode 100644 index 0000000..f7315b7 --- /dev/null +++ b/src/HandlingDomain/User/src/Handler/Command/ForgotPassword/ForgotPasswordCommandResult.php @@ -0,0 +1,12 @@ +passwordTokenUuid; + } + + public function getNewPassword(): string + { + return $this->newPassword; + } + + public function getPasswordConfirmation(): string + { + return $this->passwordConfirmation; + } +} diff --git a/src/HandlingDomain/User/src/Handler/Command/ResetPassword/ResetPasswordCommandBuilder.php b/src/HandlingDomain/User/src/Handler/Command/ResetPassword/ResetPasswordCommandBuilder.php new file mode 100644 index 0000000..0e6786c --- /dev/null +++ b/src/HandlingDomain/User/src/Handler/Command/ResetPassword/ResetPasswordCommandBuilder.php @@ -0,0 +1,22 @@ +getPasswordTokenUuid(); + + // Load and check password token + /** @var ?UserPasswordToken $passwordToken */ + $passwordToken = $this->repository->findOneBy(['id' => $passwordTokenId]); + if ($passwordToken === null) { + throw new UserPasswordTokenNotFoundByIdException($passwordTokenId->toString()); + } + + if ($resetPasswordCommand->getNewPassword() !== $resetPasswordCommand->getPasswordConfirmation()) { + throw new UserPasswordConfirmationMismatchException(); + } + + // Update Password + $user = $passwordToken->getUser(); + $user->setPassword($this->encryptionClient->encrypt($resetPasswordCommand->getNewPassword())); + + // Save to DB + $this->entityManager->remove($passwordToken); + $this->entityManager->persist($user); + if ($user->getSession() !== null) { + $this->entityManager->remove($user->getSession()); + } + + $this->entityManager->flush(); + + return new ResetPasswordCommandResult(); + } +} diff --git a/src/HandlingDomain/User/src/Handler/Command/ResetPassword/ResetPasswordCommandResult.php b/src/HandlingDomain/User/src/Handler/Command/ResetPassword/ResetPasswordCommandResult.php new file mode 100644 index 0000000..acb9182 --- /dev/null +++ b/src/HandlingDomain/User/src/Handler/Command/ResetPassword/ResetPasswordCommandResult.php @@ -0,0 +1,13 @@ +get(EntityManager::class); + return $em->getRepository($configKey); + } + + protected function getDefaultConfig(string $configKey): array + { + return []; + } +} diff --git a/src/Infrastructure/Database/src/ConfigServiceFactory.php b/src/Infrastructure/Database/src/ConfigServiceFactory.php deleted file mode 100644 index 0548333..0000000 --- a/src/Infrastructure/Database/src/ConfigServiceFactory.php +++ /dev/null @@ -1,33 +0,0 @@ -entityClass, $this->entityClass); - } - - public function __invoke( - ContainerInterface $container, - $requestedName, - ?array $options = null - ): ObjectRepository|EntityRepository - { - /** @var EntityManager $em */ - $em = $container->get($this->entityManagerClass); - - return $em->getRepository($this->entityClass); - } -} diff --git a/src/Infrastructure/UuidGenerator/src/UuidGenerator.php b/src/Infrastructure/UuidGenerator/src/UuidGenerator.php index 31a2235..a078253 100644 --- a/src/Infrastructure/UuidGenerator/src/UuidGenerator.php +++ b/src/Infrastructure/UuidGenerator/src/UuidGenerator.php @@ -13,6 +13,4 @@ class UuidGenerator { $factory->setCodec($codec); return $factory->uuid1(); } -} - -?> \ No newline at end of file +} \ No newline at end of file