validates email present + format (wraps EmailAddress vo's InvalidArgumentException as BadRequest), password present + >= 8 chars, then ensures email not already registered. hashes password through injected PasswordHasher and persists via UserRepository->create with isAdmin=false (admins are seeder- only per plan). throws DomainException on duplicate email so the controller layer can map it to 409. all 18 tests pass.
57 lines
1.6 KiB
PHP
57 lines
1.6 KiB
PHP
<?php
|
|
|
|
namespace App\User\UseCases\SignupUser;
|
|
|
|
use App\Auth\PasswordHasher;
|
|
use App\Exceptions\BadRequestException;
|
|
use App\Shared\ValueObject\EmailAddress;
|
|
use App\User\CreateUserDto;
|
|
use App\User\User;
|
|
use App\User\UserRepository;
|
|
use DomainException;
|
|
use InvalidArgumentException;
|
|
|
|
class SignupUser
|
|
{
|
|
private const MIN_PASSWORD_LENGTH = 8;
|
|
|
|
public function __construct(
|
|
private UserRepository $userRepo,
|
|
private PasswordHasher $hasher,
|
|
) {}
|
|
|
|
/**
|
|
* @throws BadRequestException
|
|
* @throws DomainException
|
|
*/
|
|
public function execute(SignupUserRequest $request): User
|
|
{
|
|
if ($request->email === null || $request->email === '') {
|
|
throw new BadRequestException('email is required');
|
|
}
|
|
if ($request->password === null || $request->password === '') {
|
|
throw new BadRequestException('password is required');
|
|
}
|
|
if (strlen($request->password) < self::MIN_PASSWORD_LENGTH) {
|
|
throw new BadRequestException(
|
|
'password must be at least '.self::MIN_PASSWORD_LENGTH.' characters'
|
|
);
|
|
}
|
|
|
|
try {
|
|
$email = new EmailAddress($request->email);
|
|
} catch (InvalidArgumentException $exception) {
|
|
throw new BadRequestException($exception->getMessage());
|
|
}
|
|
|
|
if ($this->userRepo->findByEmail($email) !== null) {
|
|
throw new DomainException('email already registered');
|
|
}
|
|
|
|
return $this->userRepo->create(new CreateUserDto(
|
|
email: $email,
|
|
passwordHash: $this->hasher->hash($request->password),
|
|
isAdmin: false,
|
|
));
|
|
}
|
|
}
|