<?php
namespace App\EventListener\Strava;
use App\Entity\SocialToken;
use App\Entity\User;
use App\Repository\SocialTokenRepository;
use Doctrine\ORM\EntityManagerInterface;
use NuBox\Strava\Api\DataObject\StravaTokenInterface;
use NuBox\Strava\Api\Event\StravaApiEvents;
use NuBox\Strava\Api\Event\Token\CreatedEvent;
use NuBox\Strava\Api\Event\Token\InvalidEvent;
use NuBox\Strava\Api\Event\Token\RefreshedEvent;
use NuBox\Strava\Api\Event\Token\RequestEvent;
use NuBox\Strava\Api\Event\Token\RevokedEvent;
use NuBox\Strava\Api\Event\Token\TokenEventInterface;
use NuBox\Strava\Api\Service\StravaApi;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Security;
final class TokenSubscriber implements EventSubscriberInterface
{
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly Security $security,
) {
}
public static function getSubscribedEvents(): array
{
return [
StravaApiEvents::TOKEN_CREATED => 'onTokenCreated',
StravaApiEvents::TOKEN_REFRESHED => 'onTokenRefreshed',
StravaApiEvents::TOKEN_REVOKED => 'onTokenRevoked',
StravaApiEvents::TOKEN_INVALID => 'onTokenRevoked',
StravaApiEvents::TOKEN_REQUEST => 'onTokenRequest',
];
}
public function onTokenCreated(CreatedEvent $event): void
{
$token = $event->getToken();
$socialToken = new SocialToken();
$socialToken->setUser($this->getUserByLoggedUser());
$socialToken->setType(StravaApi::TYPE);
$socialToken->setTokenType($token->getTokenType());
$socialToken->setExpiresAt($token->getExpiresAt());
$socialToken->setExpiresIn($token->getExpiresIn());
$socialToken->setRefreshToken($token->getRefreshToken());
$socialToken->setAccessToken($token->getAccessToken());
$socialToken->setSocialUserId($token->getAthlete()?->getId() ?? 0);
$socialToken->setScopes($token->getScopes());
$this->entityManager->persist($socialToken);
$this->entityManager->flush();
}
public function onTokenRefreshed(RefreshedEvent $event): void
{
$token = $event->getToken();
$socialToken = $event->getOriginalToken();
$socialToken->setRefreshToken($token->getRefreshToken());
$socialToken->setTokenType($token->getTokenType());
$socialToken->setExpiresAt($token->getExpiresAt());
$socialToken->setExpiresIn($token->getExpiresIn());
$socialToken->setAccessToken($token->getAccessToken());
$this->entityManager->flush();
}
public function onTokenRequest(RequestEvent $event): void
{
$event->setToken($this->getSocialTokenByLoggedUser());
}
public function onTokenRevoked(RevokedEvent|InvalidEvent $event): void
{
$this->entityManager->remove($event->getToken());
$this->entityManager->flush();
}
public function getUserByLoggedUser(): User
{
$user = $this->security->getUser();
assert($user instanceof User);
return $user;
}
public function getSocialTokenByLoggedUser(): StravaTokenInterface
{
return $this->getUserByLoggedUser()->getSocialToken(StravaApi::TYPE);
}
}