ldc-boutique-cnc-sable/infra/Adapters/Services/AppCustomerAuthService.php
2026-10-27 09:58:12 +01:00

119 lines
3.1 KiB
PHP

<?php
declare(strict_types=1);
namespace Infrastructure\Adapters\Services;
use App\Exceptions\AuthServiceException;
use App\Exceptions\CrmServiceException;
use App\Models\Customer;
use App\Services\CrmService;
use Domain\Contracts\CustomerDetails;
use Domain\Models\ValueObjects\CrmCustomer;
use Domain\Ports\Services\CustomerAuthenticationService;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\StatefulGuard;
/** @implements CustomerAuthenticationService<Customer> */
class AppCustomerAuthService implements CustomerAuthenticationService
{
public function __construct(
private readonly StatefulGuard $guard,
private readonly CrmService $crmService
) {
}
public function canWithCustomer(\UnitEnum | string $abilities, mixed $arguments = []): bool
{
return $this->getCustomer()?->can($abilities, $arguments) ?? false;
}
public function logIn(CustomerDetails $customer): void
{
if (! $customer instanceof Authenticatable || ! $customer instanceof Customer) {
throw new \InvalidArgumentException(
'Expected an instance of Authenticatable and Customer for logging in'
);
}
$this->guard->login($customer);
}
public function logout(): void
{
$this->guard->logout();
}
public function check(): bool
{
return $this->guard->check();
}
public function guest(): bool
{
return ! $this->check();
}
public function getCustomer(): ?CustomerDetails
{
$customer = $this->guard->user();
if ($customer && ! ($customer instanceof Customer)) {
throw new \InvalidArgumentException('Auth service needs a frontend guard');
}
return $customer ? clone $customer : null;
}
public function getCustomerAsMandatory(): CustomerDetails
{
$customer = $this->getCustomer();
if ($customer === null) {
throw new AuthServiceException('Authenticated user is required from here');
}
return clone $customer;
}
public function resetPasswordFor(CustomerDetails $customer, string $password): bool | \Exception
{
return $this->crmService->resetPasswordFor($customer->email, $password);
}
public function hasVerifiedEmail(CustomerDetails $customer): bool
{
$crmCustomer = $this->getCrmCustomerFrom($customer);
if ($crmCustomer === null) {
return false;
}
return $crmCustomer->status;
}
public function verifyEmail(CustomerDetails $customer): bool
{
$crmCustomer = $this->getCrmCustomerFrom($customer);
if ($crmCustomer === null) {
return false;
}
$activation = $this->crmService->activate($crmCustomer);
return $activation->result;
}
private function getCrmCustomerFrom(Customer $customer): ?CrmCustomer
{
$crmCustomer = $this->crmService->getCustomerFromHashCode($customer->hashcode);
if ($crmCustomer instanceof CrmServiceException) {
report($crmCustomer);
throw $crmCustomer;
}
return $crmCustomer;
}
}