generated from flo/template-backend
default functions
This commit is contained in:
parent
9237801bc1
commit
6d97fc24c4
@ -201,8 +201,8 @@ use Psr\\Http\\Server\\RequestHandlerInterface;
|
|||||||
class {$apiHandlerName} implements RequestHandlerInterface
|
class {$apiHandlerName} implements RequestHandlerInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly {$cqrsHandlerName} \${$cqrsHandlerVariableName},
|
private readonly {$cqrsHandlerName} \$handler,
|
||||||
private readonly {$cqrsBuilderName} \${$cqrsBuilderVariableName},
|
private readonly {$cqrsBuilderName} \$builder,
|
||||||
private readonly {$apiResponseFormatterName} \$responseFormatter,
|
private readonly {$apiResponseFormatterName} \$responseFormatter,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
@ -211,10 +211,10 @@ class {$apiHandlerName} implements RequestHandlerInterface
|
|||||||
{
|
{
|
||||||
\$data = \$request->getAttribute(AnalyzeBodyMiddleware::JSON_DATA);
|
\$data = \$request->getAttribute(AnalyzeBodyMiddleware::JSON_DATA);
|
||||||
|
|
||||||
\${$cqrsVariableName} = \$this->{$cqrsBuilderVariableName}->build(
|
\${$cqrsVariableName} = \$this->builder->build(
|
||||||
\$data
|
\$data
|
||||||
);
|
);
|
||||||
\$result = \$this->{$cqrsHandlerVariableName}->execute(\${$cqrsVariableName});
|
\$result = \$this->handler->execute(\${$cqrsVariableName});
|
||||||
|
|
||||||
return new SuccessResponse(\$this->responseFormatter->format(\$result));
|
return new SuccessResponse(\$this->responseFormatter->format(\$result));
|
||||||
}
|
}
|
||||||
@ -275,9 +275,7 @@ class {$cqrsHandlerName}
|
|||||||
|
|
||||||
public function execute({$cqrsName} \${$cqrsVariableName}): {$cqrsResultName}
|
public function execute({$cqrsName} \${$cqrsVariableName}): {$cqrsResultName}
|
||||||
{
|
{
|
||||||
return new {$cqrsResultName}(
|
return new {$cqrsResultName}();
|
||||||
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
|
|||||||
BIN
data/mails/reset-password/assets/icon.png
Normal file
BIN
data/mails/reset-password/assets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
63
data/mails/reset-password/template.latte
Normal file
63
data/mails/reset-password/template.latte
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Passwort zurücksetzen</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
}
|
||||||
|
.message-block {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
background-color: rgb(255, 199, 44);
|
||||||
|
width: 100%;
|
||||||
|
height: 15%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.wrapper {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.quote {
|
||||||
|
font-style: italic;
|
||||||
|
font-size: x-small;
|
||||||
|
color: slategray;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
margin: 1rem;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="header" class="header">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div id="title" class="title">
|
||||||
|
<img src="assets/icon.png" />
|
||||||
|
<h1>Beekeeper</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="message-block" class="message-block">
|
||||||
|
<p>Hallo {$username},</p>
|
||||||
|
<br />
|
||||||
|
<p>Dein Passwort wurde zurückgesetzt.</p>
|
||||||
|
<p>Bitte klicke auf <a href="{$passwordResetLink}">diesen Link</a> um ein neues Passwort zu vergeben.</p>
|
||||||
|
<br />
|
||||||
|
<p>Wenn du dein Passwort nicht zurückgesetzt hast, kannst du diese Nachricht ignorieren!</p>
|
||||||
|
<br />
|
||||||
|
<p>Mit fleißigen Grüßen,</p>
|
||||||
|
<p>Der Beekeeper</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
37
data/migrations/business/Version20240827155813.php
Normal file
37
data/migrations/business/Version20240827155813.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\Migrations\Bee;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20240827155813 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return "Create Table 'user_password_token'";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$sql = "CREATE TABLE user_password_token (
|
||||||
|
id binary(16) NOT NULL,
|
||||||
|
user_id binary(16) NOT NULL,
|
||||||
|
updated_at datetime NOT NULL,
|
||||||
|
created_at datetime NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);";
|
||||||
|
|
||||||
|
$this->addSql($sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql("DROP TABLE user_password_token;");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,9 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Bee\API\External\Authentication\Handler\ConfirmRegistrationHandler;
|
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\LoginUserHandler;
|
||||||
use Bee\API\External\Authentication\Handler\LogoutUserHandler;
|
use Bee\API\External\Authentication\Handler\LogoutUserHandler;
|
||||||
use Bee\API\External\Authentication\Handler\RegisterUserHandler;
|
use Bee\API\External\Authentication\Handler\RegisterUserHandler;
|
||||||
|
use Bee\API\External\Authentication\Handler\ResetPasswordHandler;
|
||||||
use Bee\Infrastructure\Session\Middleware\LoggedInUserMiddleware;
|
use Bee\Infrastructure\Session\Middleware\LoggedInUserMiddleware;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@ -40,4 +42,20 @@ return [
|
|||||||
RegisterUserHandler::class
|
RegisterUserHandler::class
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'name' => '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,
|
||||||
|
],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
@ -3,9 +3,13 @@
|
|||||||
use Bee\API\External\Authentication\Formatter\ConfirmRegistrationFormatter;
|
use Bee\API\External\Authentication\Formatter\ConfirmRegistrationFormatter;
|
||||||
use Bee\API\External\Authentication\Formatter\LoginUserFormatter;
|
use Bee\API\External\Authentication\Formatter\LoginUserFormatter;
|
||||||
use Bee\API\External\Authentication\Handler\ConfirmRegistrationHandler;
|
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\LoginUserHandler;
|
||||||
use Bee\API\External\Authentication\Handler\LogoutUserHandler;
|
use Bee\API\External\Authentication\Handler\LogoutUserHandler;
|
||||||
use Bee\API\External\Authentication\Handler\RegisterUserHandler;
|
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;
|
use Reinfi\DependencyInjection\Factory\AutoWiringFactory;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@ -13,11 +17,15 @@ return [
|
|||||||
// Formatter
|
// Formatter
|
||||||
ConfirmRegistrationFormatter::class => AutoWiringFactory::class,
|
ConfirmRegistrationFormatter::class => AutoWiringFactory::class,
|
||||||
LoginUserFormatter::class => AutoWiringFactory::class,
|
LoginUserFormatter::class => AutoWiringFactory::class,
|
||||||
|
ForgotPasswordResponseFormatter::class => AutoWiringFactory::class,
|
||||||
|
ResetPasswordResponseFormatter::class => AutoWiringFactory::class,
|
||||||
|
|
||||||
// Handler
|
// Handler
|
||||||
LoginUserHandler::class => AutoWiringFactory::class,
|
LoginUserHandler::class => AutoWiringFactory::class,
|
||||||
LogoutUserHandler::class => AutoWiringFactory::class,
|
LogoutUserHandler::class => AutoWiringFactory::class,
|
||||||
ConfirmRegistrationHandler::class => AutoWiringFactory::class,
|
ConfirmRegistrationHandler::class => AutoWiringFactory::class,
|
||||||
RegisterUserHandler::class => AutoWiringFactory::class
|
RegisterUserHandler::class => AutoWiringFactory::class,
|
||||||
|
ForgotPasswordHandler::class => AutoWiringFactory::class,
|
||||||
|
ResetPasswordHandler::class => AutoWiringFactory::class,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
39
src/ApiDomain/External/Authentication/src/Handler/ForgotPasswordHandler.php
vendored
Normal file
39
src/ApiDomain/External/Authentication/src/Handler/ForgotPasswordHandler.php
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\API\External\Authentication\Handler;
|
||||||
|
|
||||||
|
use Bee\API\External\Authentication\ResponseFormatter\ForgotPasswordResponseFormatter;
|
||||||
|
use Bee\Handling\User\Handler\Command\ForgotPassword\ForgotPasswordCommandBuilder;
|
||||||
|
use Bee\Handling\User\Handler\Command\ForgotPassword\ForgotPasswordCommandHandler;
|
||||||
|
use Bee\Infrastructure\Request\Middleware\AnalyzeBodyMiddleware;
|
||||||
|
use Bee\Infrastructure\Request\Middleware\AnalyzeHeaderMiddleware;
|
||||||
|
use Bee\Infrastructure\Response\SuccessResponse;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
|
|
||||||
|
class ForgotPasswordHandler implements RequestHandlerInterface
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly ForgotPasswordCommandHandler $forgotPasswordCommandHandler,
|
||||||
|
private readonly ForgotPasswordCommandBuilder $forgotPasswordCommandBuilder,
|
||||||
|
private readonly ForgotPasswordResponseFormatter $responseFormatter,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||||
|
{
|
||||||
|
$host = $request->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));
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/ApiDomain/External/Authentication/src/Handler/ResetPasswordHandler.php
vendored
Normal file
45
src/ApiDomain/External/Authentication/src/Handler/ResetPasswordHandler.php
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\API\External\Authentication\Handler;
|
||||||
|
|
||||||
|
use Bee\API\External\Authentication\ResponseFormatter\ResetPasswordResponseFormatter;
|
||||||
|
use Bee\Handling\User\Exception\UserPasswordConfirmationMismatchException;
|
||||||
|
use Bee\Handling\User\Exception\UserPasswordTokenNotFoundByIdException;
|
||||||
|
use Bee\Handling\User\Handler\Command\ResetPassword\ResetPasswordCommandBuilder;
|
||||||
|
use Bee\Handling\User\Handler\Command\ResetPassword\ResetPasswordCommandHandler;
|
||||||
|
use Bee\Infrastructure\Request\Middleware\AnalyzeBodyMiddleware;
|
||||||
|
use Bee\Infrastructure\Response\SuccessResponse;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
|
use Ramsey\Uuid\Uuid;
|
||||||
|
|
||||||
|
class ResetPasswordHandler implements RequestHandlerInterface
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly ResetPasswordCommandHandler $handler,
|
||||||
|
private readonly ResetPasswordCommandBuilder $builder,
|
||||||
|
private readonly ResetPasswordResponseFormatter $responseFormatter,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws UserPasswordConfirmationMismatchException
|
||||||
|
* @throws UserPasswordTokenNotFoundByIdException
|
||||||
|
*/
|
||||||
|
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||||
|
{
|
||||||
|
$data = $request->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));
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/ApiDomain/External/Authentication/src/ResponseFormatter/ForgotPasswordResponseFormatter.php
vendored
Normal file
17
src/ApiDomain/External/Authentication/src/ResponseFormatter/ForgotPasswordResponseFormatter.php
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\API\External\Authentication\ResponseFormatter;
|
||||||
|
|
||||||
|
use Bee\Handling\User\Handler\Command\ForgotPassword\ForgotPasswordCommandResult;
|
||||||
|
|
||||||
|
class ForgotPasswordResponseFormatter
|
||||||
|
{
|
||||||
|
public function format(ForgotPasswordCommandResult $forgotPasswordCommandResult): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/ApiDomain/External/Authentication/src/ResponseFormatter/ResetPasswordResponseFormatter.php
vendored
Normal file
17
src/ApiDomain/External/Authentication/src/ResponseFormatter/ResetPasswordResponseFormatter.php
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\API\External\Authentication\ResponseFormatter;
|
||||||
|
|
||||||
|
use Bee\Handling\User\Handler\Command\ResetPassword\ResetPasswordCommandResult;
|
||||||
|
|
||||||
|
class ResetPasswordResponseFormatter
|
||||||
|
{
|
||||||
|
public function format(ResetPasswordCommandResult $resetPasswordCommandResult): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -32,6 +32,7 @@ class ChangePasswordHandler implements RequestHandlerInterface
|
|||||||
$user,
|
$user,
|
||||||
$data['password'],
|
$data['password'],
|
||||||
$data['newPassword'],
|
$data['newPassword'],
|
||||||
|
$data['newPasswordConfirmation'],
|
||||||
);
|
);
|
||||||
$this->handler->execute($query);
|
$this->handler->execute($query);
|
||||||
|
|
||||||
|
|||||||
@ -14,8 +14,6 @@ return [
|
|||||||
'doctrine.entity_manager.orm_bee' => [BaseEntityManagerFactory::class, 'orm_bee'],
|
'doctrine.entity_manager.orm_bee' => [BaseEntityManagerFactory::class, 'orm_bee'],
|
||||||
'doctrine.configuration.orm_bee' => [ConfigurationFactory::class, 'orm_bee'],
|
'doctrine.configuration.orm_bee' => [ConfigurationFactory::class, 'orm_bee'],
|
||||||
'doctrine.connection.orm_bee' => [ConnectionFactory::class, 'orm_bee'],
|
'doctrine.connection.orm_bee' => [ConnectionFactory::class, 'orm_bee'],
|
||||||
EntityManager::class => EntityManagerFactory::class,
|
EntityManager::class => EntityManagerFactory::class
|
||||||
|
|
||||||
UserRepository::class => [AutowireRepositoryFactory::class, EntityManager::class, User::class],
|
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
namespace Bee\Data\Business\Entity;
|
namespace Bee\Data\Business\Entity;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Bee\Infrastructure\UuidGenerator\UuidGenerator;
|
use Bee\Infrastructure\UuidGenerator\UuidGenerator;
|
||||||
use Ramsey\Uuid\UuidInterface;
|
use Ramsey\Uuid\UuidInterface;
|
||||||
@ -39,6 +40,9 @@ class User {
|
|||||||
/** @ORM\OneToOne(targetEntity="Bee\Data\Business\Entity\UserSession", mappedBy="user") */
|
/** @ORM\OneToOne(targetEntity="Bee\Data\Business\Entity\UserSession", mappedBy="user") */
|
||||||
private ?UserSession $session;
|
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) */
|
/** @ORM\Column(name="last_login_at", type="datetime", nullable=true) */
|
||||||
private DateTime $lastLoginAt;
|
private DateTime $lastLoginAt;
|
||||||
|
|
||||||
|
|||||||
91
src/DataDomain/Business/src/Entity/UserPasswordToken.php
Normal file
91
src/DataDomain/Business/src/Entity/UserPasswordToken.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bee\Data\Business\Entity;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Bee\Infrastructure\UuidGenerator\UuidGenerator;
|
||||||
|
use Ramsey\Uuid\UuidInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Entity(repositoryClass="Bee\Data\Business\Repository\UserPasswordTokenRepository")
|
||||||
|
* @ORM\Table(name="user_password_token")
|
||||||
|
*/
|
||||||
|
class UserPasswordToken {
|
||||||
|
/**
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\Column(name="id", type="uuid_binary_ordered_time")
|
||||||
|
*/
|
||||||
|
private UuidInterface $id;
|
||||||
|
|
||||||
|
/** @ORM\Column(name="user_id", type="uuid_binary_ordered_time", nullable=false) */
|
||||||
|
private UuidInterface $userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity="Bee\Data\Business\Entity\User", inversedBy="session")
|
||||||
|
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true)
|
||||||
|
*/
|
||||||
|
private User $user;
|
||||||
|
|
||||||
|
/** @ORM\Column(name="created_at", type="datetime") */
|
||||||
|
private DateTime $createdAt;
|
||||||
|
|
||||||
|
/** @ORM\Column(name="updated_at", type="datetime") */
|
||||||
|
private DateTime $updatedAt;
|
||||||
|
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,5 +6,3 @@ use Doctrine\ORM\EntityRepository;
|
|||||||
|
|
||||||
class PermissionRepository extends EntityRepository {
|
class PermissionRepository extends EntityRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Bee\Data\Business\Repository;
|
|
||||||
|
|
||||||
use Doctrine\ORM\EntityRepository;
|
|
||||||
|
|
||||||
class ProductRepository extends EntityRepository {
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
@ -6,5 +6,3 @@ use Doctrine\ORM\EntityRepository;
|
|||||||
|
|
||||||
class RoleRepository extends EntityRepository {
|
class RoleRepository extends EntityRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bee\Data\Business\Repository;
|
||||||
|
|
||||||
|
use Bee\Data\Business\Entity\User;
|
||||||
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Bee\Data\Business\Entity\UserSession;
|
||||||
|
|
||||||
|
class UserPasswordTokenRepository extends EntityRepository {
|
||||||
|
}
|
||||||
@ -22,5 +22,3 @@ class UserRepository extends EntityRepository {
|
|||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
@ -7,16 +7,4 @@ use Doctrine\ORM\EntityRepository;
|
|||||||
use Bee\Data\Business\Entity\UserSession;
|
use Bee\Data\Business\Entity\UserSession;
|
||||||
|
|
||||||
class UserSessionRepository extends EntityRepository {
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
@ -41,6 +41,7 @@ class SendMailStep implements TaskInterface
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
recipient: $command->getMail(),
|
recipient: $command->getMail(),
|
||||||
|
sender: 'beekeeper@stack-up.de',
|
||||||
senderName: "Beekeeper"
|
senderName: "Beekeeper"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Bee\Handling\User\Builder\UserBuilder;
|
use Bee\Handling\User\Builder\UserBuilder;
|
||||||
|
use Bee\Handling\User\Builder\UserPasswordTokenBuilder;
|
||||||
use Bee\Handling\User\Handler\Command\ChangePassword\ChangePasswordCommandBuilder;
|
use Bee\Handling\User\Handler\Command\ChangePassword\ChangePasswordCommandBuilder;
|
||||||
use Bee\Handling\User\Handler\Command\ChangePassword\ChangePasswordCommandHandler;
|
use Bee\Handling\User\Handler\Command\ChangePassword\ChangePasswordCommandHandler;
|
||||||
use Bee\Handling\User\Handler\Command\ChangeUsername\ChangeUsernameCommandBuilder;
|
use Bee\Handling\User\Handler\Command\ChangeUsername\ChangeUsernameCommandBuilder;
|
||||||
use Bee\Handling\User\Handler\Command\ChangeUsername\ChangeUsernameCommandHandler;
|
use Bee\Handling\User\Handler\Command\ChangeUsername\ChangeUsernameCommandHandler;
|
||||||
use Bee\Handling\User\Handler\Command\CreateUser\CreateUserCommandBuilder;
|
use Bee\Handling\User\Handler\Command\CreateUser\CreateUserCommandBuilder;
|
||||||
use Bee\Handling\User\Handler\Command\CreateUser\CreateUserCommandHandler;
|
use Bee\Handling\User\Handler\Command\CreateUser\CreateUserCommandHandler;
|
||||||
|
use Bee\Handling\User\Handler\Command\ForgotPassword\ForgotPasswordCommandBuilder;
|
||||||
|
use Bee\Handling\User\Handler\Command\ForgotPassword\ForgotPasswordCommandHandler;
|
||||||
|
use Bee\Handling\User\Handler\Command\ResetPassword\ResetPasswordCommandBuilder;
|
||||||
|
use Bee\Handling\User\Handler\Command\ResetPassword\ResetPasswordCommandHandler;
|
||||||
use Bee\Handling\User\Rule\UserPasswordMatchRule;
|
use Bee\Handling\User\Rule\UserPasswordMatchRule;
|
||||||
use Bee\Handling\User\Rule\UserWithIdentifierAlreadyExistsRule;
|
use Bee\Handling\User\Rule\UserWithIdentifierAlreadyExistsRule;
|
||||||
use Reinfi\DependencyInjection\Factory\AutoWiringFactory;
|
use Reinfi\DependencyInjection\Factory\AutoWiringFactory;
|
||||||
@ -18,6 +23,7 @@ return [
|
|||||||
|
|
||||||
/// Builder
|
/// Builder
|
||||||
UserBuilder::class => InjectionFactory::class,
|
UserBuilder::class => InjectionFactory::class,
|
||||||
|
UserPasswordTokenBuilder::class => AutoWiringFactory::class,
|
||||||
|
|
||||||
/// Rule
|
/// Rule
|
||||||
UserWithIdentifierAlreadyExistsRule::class => InjectionFactory::class,
|
UserWithIdentifierAlreadyExistsRule::class => InjectionFactory::class,
|
||||||
@ -27,13 +33,17 @@ return [
|
|||||||
// Create User
|
// Create User
|
||||||
CreateUserCommandHandler::class => AutoWiringFactory::class,
|
CreateUserCommandHandler::class => AutoWiringFactory::class,
|
||||||
CreateUserCommandBuilder::class => AutoWiringFactory::class,
|
CreateUserCommandBuilder::class => AutoWiringFactory::class,
|
||||||
|
|
||||||
// Change Password
|
// Change Password
|
||||||
ChangePasswordCommandHandler::class => AutoWiringFactory::class,
|
ChangePasswordCommandHandler::class => AutoWiringFactory::class,
|
||||||
ChangePasswordCommandBuilder::class => AutoWiringFactory::class,
|
ChangePasswordCommandBuilder::class => AutoWiringFactory::class,
|
||||||
|
|
||||||
// Change Username
|
// Change Username
|
||||||
ChangeUsernameCommandHandler::class => AutoWiringFactory::class,
|
ChangeUsernameCommandHandler::class => AutoWiringFactory::class,
|
||||||
ChangeUsernameCommandBuilder::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,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bee\Handling\User\Builder;
|
||||||
|
|
||||||
|
use Bee\Data\Business\Entity\Role;
|
||||||
|
use Bee\Data\Business\Entity\User;
|
||||||
|
use Bee\Data\Business\Entity\UserPasswordToken;
|
||||||
|
use Bee\Data\Business\Repository\RoleRepository;
|
||||||
|
use Bee\Handling\Role\Exception\RoleNotFoundByIdentifierException;
|
||||||
|
use Bee\Infrastructure\Encryption\Client\EncryptionClient;
|
||||||
|
use Reinfi\DependencyInjection\Annotation\Inject;
|
||||||
|
use Reinfi\DependencyInjection\Annotation\InjectDoctrineRepository;
|
||||||
|
|
||||||
|
class UserPasswordTokenBuilder
|
||||||
|
{
|
||||||
|
public function build(
|
||||||
|
User $user
|
||||||
|
): UserPasswordToken
|
||||||
|
{
|
||||||
|
$userPasswordToken = new UserPasswordToken();
|
||||||
|
$userPasswordToken->setUser($user);
|
||||||
|
|
||||||
|
return $userPasswordToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bee\Handling\User\Exception;
|
||||||
|
|
||||||
|
use Bee\Infrastructure\Exception\ErrorCode;
|
||||||
|
use Bee\Infrastructure\Exception\ErrorDomain;
|
||||||
|
use Bee\Infrastructure\Exception\Exception\Exception;
|
||||||
|
|
||||||
|
class UserNotFoundByMailException extends Exception {
|
||||||
|
|
||||||
|
private const MESSAGE = 'The user with the mail %s was not found!';
|
||||||
|
|
||||||
|
public function __construct(string $identifier)
|
||||||
|
{
|
||||||
|
parent::__construct(
|
||||||
|
sprintf(
|
||||||
|
self::MESSAGE,
|
||||||
|
$identifier
|
||||||
|
),
|
||||||
|
ErrorDomain::User,
|
||||||
|
ErrorCode::NotFound
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bee\Handling\User\Exception;
|
||||||
|
|
||||||
|
use Bee\Infrastructure\Exception\ErrorCode;
|
||||||
|
use Bee\Infrastructure\Exception\ErrorDomain;
|
||||||
|
use Bee\Infrastructure\Exception\Exception\Exception;
|
||||||
|
|
||||||
|
class UserPasswordConfirmationMismatchException extends Exception {
|
||||||
|
|
||||||
|
private const MESSAGE = 'The two passwordConfirmation does not match the newPassword';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct(
|
||||||
|
self::MESSAGE,
|
||||||
|
ErrorDomain::UserPassword,
|
||||||
|
ErrorCode::Mismatch,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bee\Handling\User\Exception;
|
||||||
|
|
||||||
|
use Bee\Infrastructure\Exception\ErrorCode;
|
||||||
|
use Bee\Infrastructure\Exception\ErrorDomain;
|
||||||
|
use Bee\Infrastructure\Exception\Exception\Exception;
|
||||||
|
|
||||||
|
class UserPasswordTokenNotFoundByIdException extends Exception {
|
||||||
|
|
||||||
|
private const MESSAGE = 'User password token with the id %s was not found!';
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
string $identification
|
||||||
|
)
|
||||||
|
{
|
||||||
|
parent::__construct(
|
||||||
|
sprintf(
|
||||||
|
self::MESSAGE,
|
||||||
|
$identification
|
||||||
|
),
|
||||||
|
ErrorDomain::UserPassword,
|
||||||
|
ErrorCode::Mismatch,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,6 +10,7 @@ class ChangePasswordCommand
|
|||||||
private readonly User $user,
|
private readonly User $user,
|
||||||
private readonly string $password,
|
private readonly string $password,
|
||||||
private readonly string $newPassword,
|
private readonly string $newPassword,
|
||||||
|
private readonly string $newPasswordConfirmation,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,4 +25,9 @@ class ChangePasswordCommand
|
|||||||
public function getPassword(): string {
|
public function getPassword(): string {
|
||||||
return $this->password;
|
return $this->password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getNewPasswordConfirmation(): string
|
||||||
|
{
|
||||||
|
return $this->newPasswordConfirmation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,12 +10,14 @@ class ChangePasswordCommandBuilder
|
|||||||
User $user,
|
User $user,
|
||||||
string $password,
|
string $password,
|
||||||
string $newPassword,
|
string $newPassword,
|
||||||
|
string $newPasswordConfirmation,
|
||||||
): ChangePasswordCommand
|
): ChangePasswordCommand
|
||||||
{
|
{
|
||||||
return new ChangePasswordCommand(
|
return new ChangePasswordCommand(
|
||||||
$user,
|
$user,
|
||||||
$password,
|
$password,
|
||||||
$newPassword,
|
$newPassword,
|
||||||
|
$newPasswordConfirmation,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use Bee\Data\Business\Entity\User;
|
|||||||
use Bee\Data\Business\Repository\RoleRepository;
|
use Bee\Data\Business\Repository\RoleRepository;
|
||||||
use Bee\Data\Business\Repository\UserRepository;
|
use Bee\Data\Business\Repository\UserRepository;
|
||||||
use Bee\Handling\User\Exception\UserNotFoundByIdentifierException;
|
use Bee\Handling\User\Exception\UserNotFoundByIdentifierException;
|
||||||
|
use Bee\Handling\User\Exception\UserPasswordConfirmationMismatchException;
|
||||||
use Bee\Handling\User\Exception\UserWrongPasswordException;
|
use Bee\Handling\User\Exception\UserWrongPasswordException;
|
||||||
use Bee\Data\Business\Manager\EntityManager;
|
use Bee\Data\Business\Manager\EntityManager;
|
||||||
use Bee\Infrastructure\Encryption\Client\EncryptionClient;
|
use Bee\Infrastructure\Encryption\Client\EncryptionClient;
|
||||||
@ -20,6 +21,10 @@ class ChangePasswordCommandHandler
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws UserWrongPasswordException
|
||||||
|
* @throws UserPasswordConfirmationMismatchException
|
||||||
|
*/
|
||||||
public function execute(ChangePasswordCommand $command): void
|
public function execute(ChangePasswordCommand $command): void
|
||||||
{
|
{
|
||||||
$user = $command->getUser();
|
$user = $command->getUser();
|
||||||
@ -28,6 +33,10 @@ class ChangePasswordCommandHandler
|
|||||||
throw new UserWrongPasswordException();
|
throw new UserWrongPasswordException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($command->getNewPassword() !== $command->getNewPasswordConfirmation()) {
|
||||||
|
throw new UserPasswordConfirmationMismatchException();
|
||||||
|
}
|
||||||
|
|
||||||
$encryptedPassword = $this->encryptionClient->encrypt(
|
$encryptedPassword = $this->encryptionClient->encrypt(
|
||||||
$command->getNewPassword()
|
$command->getNewPassword()
|
||||||
);
|
);
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\Handling\User\Handler\Command\ForgotPassword;
|
||||||
|
|
||||||
|
class ForgotPasswordCommand
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly string $domain,
|
||||||
|
private readonly string $mail
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDomain(): string
|
||||||
|
{
|
||||||
|
return $this->domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMail(): string
|
||||||
|
{
|
||||||
|
return $this->mail;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\Handling\User\Handler\Command\ForgotPassword;
|
||||||
|
|
||||||
|
class ForgotPasswordCommandBuilder
|
||||||
|
{
|
||||||
|
public function build(
|
||||||
|
string $domain,
|
||||||
|
string $mail
|
||||||
|
): ForgotPasswordCommand {
|
||||||
|
return new ForgotPasswordCommand(
|
||||||
|
$domain,
|
||||||
|
$mail
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\Handling\User\Handler\Command\ForgotPassword;
|
||||||
|
|
||||||
|
use Bee\Data\Business\Entity\User;
|
||||||
|
use Bee\Data\Business\Manager\EntityManager;
|
||||||
|
use Bee\Data\Business\Repository\UserRepository;
|
||||||
|
use Bee\Handling\User\Builder\UserPasswordTokenBuilder;
|
||||||
|
use Bee\Handling\User\Exception\UserNotFoundByMailException;
|
||||||
|
use Bee\Infrastructure\Mail\Service\MailService;
|
||||||
|
use Reinfi\DependencyInjection\Annotation\Inject;
|
||||||
|
use Reinfi\DependencyInjection\Annotation\InjectDoctrineRepository;
|
||||||
|
|
||||||
|
class ForgotPasswordCommandHandler
|
||||||
|
{
|
||||||
|
private const RESET_PASSWORD_LINK = "https://%s/auth/reset-password/%s";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @InjectDoctrineRepository(
|
||||||
|
* entityManager="Bee\Data\Business\Manager\EntityManager",
|
||||||
|
* entity="Bee\Data\Business\Entity\User"
|
||||||
|
* )
|
||||||
|
* @Inject("Bee\Handling\User\Builder\UserPasswordTokenBuilder")
|
||||||
|
* @Inject("Bee\Infrastructure\Mail\Service\MailService")
|
||||||
|
* @Inject("Bee\Data\Business\Manager\EntityManager")
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
private readonly UserRepository $userRepository,
|
||||||
|
private readonly UserPasswordTokenBuilder $passwordTokenBuilder,
|
||||||
|
private readonly MailService $mailService,
|
||||||
|
private readonly EntityManager $entityManager,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(ForgotPasswordCommand $forgotPasswordCommand): ForgotPasswordCommandResult
|
||||||
|
{
|
||||||
|
$mail = $forgotPasswordCommand->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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\Handling\User\Handler\Command\ForgotPassword;
|
||||||
|
|
||||||
|
class ForgotPasswordCommandResult
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\Handling\User\Handler\Command\ResetPassword;
|
||||||
|
|
||||||
|
use Ramsey\Uuid\UuidInterface;
|
||||||
|
|
||||||
|
class ResetPasswordCommand
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private UuidInterface $passwordTokenUuid,
|
||||||
|
private string $newPassword,
|
||||||
|
private string $passwordConfirmation
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPasswordTokenUuid(): UuidInterface
|
||||||
|
{
|
||||||
|
return $this->passwordTokenUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNewPassword(): string
|
||||||
|
{
|
||||||
|
return $this->newPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPasswordConfirmation(): string
|
||||||
|
{
|
||||||
|
return $this->passwordConfirmation;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\Handling\User\Handler\Command\ResetPassword;
|
||||||
|
|
||||||
|
use Ramsey\Uuid\UuidInterface;
|
||||||
|
|
||||||
|
class ResetPasswordCommandBuilder
|
||||||
|
{
|
||||||
|
public function build(
|
||||||
|
UuidInterface $passwordTokenUuid,
|
||||||
|
string $newPassword,
|
||||||
|
string $passwordConfirmation
|
||||||
|
): ResetPasswordCommand {
|
||||||
|
return new ResetPasswordCommand(
|
||||||
|
$passwordTokenUuid,
|
||||||
|
$newPassword,
|
||||||
|
$passwordConfirmation
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\Handling\User\Handler\Command\ResetPassword;
|
||||||
|
|
||||||
|
use Bee\Data\Business\Entity\UserPasswordToken;
|
||||||
|
use Bee\Data\Business\Manager\EntityManager;
|
||||||
|
use Bee\Data\Business\Repository\UserPasswordTokenRepository;
|
||||||
|
use Bee\Handling\User\Exception\UserPasswordConfirmationMismatchException;
|
||||||
|
use Bee\Handling\User\Exception\UserPasswordTokenNotFoundByIdException;
|
||||||
|
use Bee\Infrastructure\Encryption\Client\EncryptionClient;
|
||||||
|
use Reinfi\DependencyInjection\Annotation\Inject;
|
||||||
|
use Reinfi\DependencyInjection\Annotation\InjectDoctrineRepository;
|
||||||
|
|
||||||
|
class ResetPasswordCommandHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @InjectDoctrineRepository(
|
||||||
|
* entityManager="Bee\Data\Business\Manager\EntityManager",
|
||||||
|
* entity="Bee\Data\Business\Entity\UserPasswordToken"
|
||||||
|
* )
|
||||||
|
* @Inject("Bee\Infrastructure\Encryption\Client\EncryptionClient")
|
||||||
|
* @Inject("Bee\Data\Business\Manager\EntityManager")
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
private readonly UserPasswordTokenRepository $repository,
|
||||||
|
private readonly EncryptionClient $encryptionClient,
|
||||||
|
private readonly EntityManager $entityManager,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(ResetPasswordCommand $resetPasswordCommand): ResetPasswordCommandResult
|
||||||
|
{
|
||||||
|
$passwordTokenId = $resetPasswordCommand->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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\Handling\User\Handler\Command\ResetPassword;
|
||||||
|
|
||||||
|
class ResetPasswordCommandResult
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
#TODO
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bee\Infrastructure\Database;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManager;
|
||||||
|
use Psr\Container\ContainerInterface;
|
||||||
|
use Roave\PsrContainerDoctrine\AbstractFactory;
|
||||||
|
|
||||||
|
class AutowireRepositoryFactory extends AbstractFactory
|
||||||
|
{
|
||||||
|
protected function createWithConfig(ContainerInterface $container, string $configKey)
|
||||||
|
{
|
||||||
|
/** @var EntityManager $em */
|
||||||
|
$em = $container->get(EntityManager::class);
|
||||||
|
return $em->getRepository($configKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDefaultConfig(string $configKey): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Bee\Infrastructure\Database;
|
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManager;
|
|
||||||
use Doctrine\ORM\EntityRepository;
|
|
||||||
use Doctrine\Persistence\ObjectRepository;
|
|
||||||
use Laminas\ServiceManager\Factory\FactoryInterface;
|
|
||||||
use Psr\Container\ContainerInterface;
|
|
||||||
|
|
||||||
class AutowireRepositoryFactory implements FactoryInterface
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly string $entityManagerClass,
|
|
||||||
private readonly string $entityClass,
|
|
||||||
) {
|
|
||||||
var_dump($this->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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -14,5 +14,3 @@ class UuidGenerator {
|
|||||||
return $factory->uuid1();
|
return $factory->uuid1();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
Reference in New Issue
Block a user