<?php
namespace App\Http\Controller\Auth;
use App\Application\CommandBus\Command\Apple\SetOrUpdateAppleSignInSubCommand;
use App\Application\CommandBus\Command\User\RegistrationCommand;
use App\Database\Domain\Entity\Log;
use App\Database\Domain\Entity\User\UserProfile;
use App\Database\Domain\Repository\UserRepository;
use App\Infrastructure\Logs\DbLogger;
use App\Infrastructure\Messenger\CommandBus\CommandBusInterface;
use App\Infrastructure\Security\AuthManager;
use App\Infrastructure\Service\AppleHelper;
use App\Infrastructure\Util\Identifier;
use AppleSignIn\ASDecoder;
use AppleSignIn\ASPayload;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("/apple", name="site_apple_")
*/
class AppleController extends AbstractController
{
/**
* @Route("/login", name="login")
*/
public function __invoke(Request $request, AppleHelper $appleHelper): Response
{
if ($request->getSession()->get('redirect-uri') == 'ios-login') {
return $this->redirect($appleHelper->generateLoginLink().'-ios');
}
return $this->redirect($appleHelper->generateLoginLink());
}
/**
* @Route("/sign-in", name="sign_in")
*/
public function register(
Request $request,
UserRepository $userRepository,
AuthManager $authManager,
CommandBusInterface $commandBus,
AppleHelper $appleHelper,
DbLogger $logger
): Response {
try {
$authCode = $request->request->get('code');
/** @var ASPayload $payload */
$payload = ASDecoder::getAppleSignInPayload($appleHelper->getIdentityToken($authCode));
$email = $payload->getEmail();
if (null !== $email) {
$user = $userRepository->findByEmail($email);
if (null !== $user) {
$commandBus->execute(new SetOrUpdateAppleSignInSubCommand($payload->sub, $user->getId()));
} else {
$command = new RegistrationCommand();
$command->id = Identifier::generate();
$command->name = 'Toast Lover';
$command->surname = '';
$command->email = $email;
$command->username = $email;
$command->emailConfirmed = true;
$command->registrationType = UserProfile::REGISTRATION_TYPE_APPLE;
$command->appleSignInSub = $payload->sub;
$commandBus->execute($command);
$user = $userRepository->find($command->id);
return $authManager->manualLogin($user, 'registration_finish_registration');
}
} else {
$user = $userRepository->findByAppleSignInSub($payload->sub);
if (null === $user) {
throw new \RuntimeException('User was not found by apple sign in');
}
}
} catch (\Exception $e) {
$logger->error($e->getMessage(), Log::SOURCE_APPLE, ['trace' => $e->getTraceAsString()]);
throw new \RuntimeException('Failed to auth with apple');
}
return $authManager->manualLogin($user);
}
/**
* @Route("/sign-in-ios", name="sign_in_ios")
*/
public function registerIos(
Request $request,
UserRepository $userRepository,
AuthManager $authManager,
CommandBusInterface $commandBus,
AppleHelper $appleHelper,
DbLogger $logger
): Response {
try {
$authCode = $request->request->get('code');
/** @var ASPayload $payload */
$payload = ASDecoder::getAppleSignInPayload($appleHelper->getIdentityToken($authCode));
$email = $payload->getEmail();
if (null !== $email) {
$user = $userRepository->findByEmail($email);
if (null !== $user) {
$commandBus->execute(new SetOrUpdateAppleSignInSubCommand($payload->sub, $user->getId()));
} else {
$command = new RegistrationCommand();
$command->id = Identifier::generate();
$command->name = 'Toast Lover';
$command->surname = '';
$command->email = $email;
$command->username = $email;
$command->emailConfirmed = true;
$command->registrationType = UserProfile::REGISTRATION_TYPE_APPLE;
$command->appleSignInSub = $payload->sub;
$commandBus->execute($command);
$user = $userRepository->find($command->id);
return $authManager->manualLogin($user, 'registration_finish_registration');
}
} else {
$user = $userRepository->findByAppleSignInSub($payload->sub);
if (null === $user) {
throw new \RuntimeException('User was not found by apple sign in');
}
}
} catch (\Exception $e) {
$logger->error($e->getMessage(), Log::SOURCE_APPLE, ['trace' => $e->getTraceAsString()]);
throw new \RuntimeException('Failed to auth with apple');
}
return $authManager->manualLogin($user, 'user_ios_login_index');
}
}