119 lines
3.1 KiB
PHP
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;
|
|
}
|
|
}
|