src/Controller/Api/SecurityController.php line 49

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Api;
  3. use App\Entity\Gos\PortalSettings;
  4. use App\Entity\Gos\User;
  5. use App\Utils\Api\ApiRegistrationService;
  6. use App\Utils\OrderFreeAccessService;
  7. use App\Utils\PasswordResetService;
  8. use App\Utils\RegistrationUtils;
  9. use App\Utils\UserServices;
  10. use Doctrine\ORM\EntityManagerInterface;
  11. use FOS\UserBundle\Model\UserManagerInterface;
  12. use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
  13. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  14. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  15. use Symfony\Component\HttpFoundation\JsonResponse;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  19. use Symfony\Component\Routing\Annotation\Route;
  20. use OpenApi\Annotations as OA;
  21. /** @Route("/apiv2") */
  22. class SecurityController extends AbstractController
  23. {
  24.     use JsonNotSerializedTrait;
  25.     private $em;
  26.     private $userServices;
  27.     private $registrationUtils;
  28.     public function __construct(
  29.         EntityManagerInterface $em,
  30.         UserServices $userServices,
  31.         RegistrationUtils $registrationUtils
  32.     ) {
  33.         $this->em $em;
  34.         $this->userServices $userServices;
  35.         $this->registrationUtils $registrationUtils;
  36.     }
  37.     /**
  38.      * @Route("/facebook_login")
  39.      */
  40.     public function facebookLogin(Request $requestUserManagerInterface $userManagerJWTTokenManagerInterface $JWTTokenManager)
  41.     {
  42.         $token $request->get('access_token');
  43.         $tokenResponse = @file_get_contents("https://graph.facebook.com/app/?access_token=${token}");
  44.         if (!$tokenResponse)
  45.         {
  46.             throw new AccessDeniedHttpException();
  47.         }
  48.         $tokenApp json_decode($tokenResponsetrue);
  49.         if (!isset($tokenApp['id']) || $tokenApp['id'] !== $_ENV['FB_ID'])
  50.         {
  51.             throw new AccessDeniedHttpException();
  52.         }
  53.         $userTokenResponse = @file_get_contents("https://graph.facebook.com/me/?access_token=${token}&fields=email,first_name,last_name");
  54.         if (!$userTokenResponse)
  55.         {
  56.             throw new AccessDeniedHttpException();
  57.         }
  58.         $userToken json_decode($userTokenResponsetrue);
  59.         if (!isset($userToken['id']) || !isset($userToken['email']))
  60.         {
  61.             throw new AccessDeniedHttpException();
  62.         }
  63.         $user $userManager->findUserBy(['facebook_id' => $userToken['id']]);
  64.         if ($user === null)
  65.         {
  66.             $user $userManager->findUserByEmail($userToken['email']);
  67.         }
  68.         if ($user === null)
  69.         {
  70.             /** @var User $user */
  71.             $user $userManager->createUser();
  72.             $user->setUsername($userToken['email']);
  73.             $user->setUsernameCanonical($userToken['email']);
  74.             $user->setEmail($userToken['email']);
  75.             $user->setEmailCanonical($userToken['email']);
  76.             if (isset($userToken['first_name']))
  77.             {
  78.                 $user->setFirstName($userToken['first_name']);
  79.             }
  80.             if (isset($userToken['last_name']))
  81.             {
  82.                 $user->setLastName($userToken['last_name']);
  83.             }
  84.             $user->setEnabled(true);
  85.             $user->setPlainPassword(random_bytes(8));
  86.             if ($request->get('hash'))
  87.             {
  88.                 $portal $this->em->getRepository(PortalSettings::class)->findOneByHash($request->get('hash'));
  89.                 $user->setRegisteredFrom($portal);
  90.             }
  91.         }
  92.         $user->setFacebookId($userToken['id']);
  93.         $user->setFacebookAccessToken($token);
  94.         $userManager->updateUser($user);
  95.         $this->registrationUtils->createLeadFormCompleted($user$portal ?? null$requestnull);
  96.         $token $JWTTokenManager->create($user);
  97.         return $this->json(['token' => $token]);
  98.     }
  99.     /**
  100.      * @Route("/google_login")
  101.      */
  102.     public function googleLogin(Request $requestUserManagerInterface $userManagerJWTTokenManagerInterface $JWTTokenManager)
  103.     {
  104.         $token $request->get('id_token');
  105.         $client = new \Google_Client(['client_id' => $_ENV['GOOGLE_ID']]);
  106.         $client->addScope('email');
  107.         $payload $client->verifyIdToken($token);
  108.         if (!$payload)
  109.         {
  110.             throw new AccessDeniedHttpException();
  111.         }
  112.         $user $userManager->findUserBy(['google_id' => $payload['sub']]);
  113.         if ($user === null)
  114.         {
  115.             $user $userManager->findUserByEmail($payload['email']);
  116.         }
  117.         if ($user === null)
  118.         {
  119.             /** @var User $user */
  120.             $user $userManager->createUser();
  121.             $user->setUsername($payload['email']);
  122.             $user->setUsernameCanonical($payload['email']);
  123.             $user->setEmail($payload['email']);
  124.             $user->setEmailCanonical($payload['email']);
  125.             if (isset($payload['given_name']))
  126.             {
  127.                 $user->setFirstName($payload['given_name']);
  128.             }
  129.             if (isset($payload['family_name']))
  130.             {
  131.                 $user->setLastName($payload['family_name']);
  132.             }
  133.             $user->setEnabled(true);
  134.             $user->setPlainPassword(random_bytes(8));
  135.             if ($request->get('hash'))
  136.             {
  137.                 $portal $this->em->getRepository(PortalSettings::class)->findOneByHash($request->get('hash'));
  138.                 $user->setRegisteredFrom($portal);
  139.             }
  140.         }
  141.         $accessToken $client->getAccessToken();
  142.         $user->setGoogleId($payload['sub']);
  143.         $user->setGoogleAccessToken($accessToken['access_token'] ?? '');
  144.         $userManager->updateUser($user);
  145.         $this->registrationUtils->createLeadFormCompleted($user$portal ?? null$requestnull);
  146.         $token $JWTTokenManager->create($user);
  147.         return $this->json(['token' => $token]);
  148.     }
  149.     /**
  150.      * @Route("/otp_login")
  151.      */
  152.     public function otpLogin(Request $requestUserManagerInterface $userManagerJWTTokenManagerInterface $JWTTokenManager): JsonResponse
  153.     {
  154.         $otpCode $request->get('code');
  155.         $user $userManager->findUserByEmail($request->get('email'));
  156.         if ($user instanceof User && $user->getOtpLoginCode() === $otpCode
  157.             && $user->getOtpLoginCreatedAt() instanceof \DateTime && (strtotime((new \DateTime())->format('Y-m-d H:i:s'))
  158.                 - strtotime($user->getOtpLoginCreatedAt()->format('Y-m-d H:i:s'))) / 60 60)
  159.         {
  160.             $token $JWTTokenManager->create($user);
  161.             $user->setOtpLoginCode(null);
  162.             $user->setOtpLoginCreatedAt(null);
  163.             $user->setOtpLoginToken(null);
  164.             $userManager->updateUser($user);
  165.             return $this->json(['token' => $token]);
  166.         }
  167.         return $this->json(false);
  168.     }
  169.     /**
  170.      * @Route("/register", name="newApiRegister", methods={"POST"})
  171.      *
  172.      * @OA\Tag(name="Security")
  173.      * @OA\Post(summary="Register new user")
  174.      *
  175.      * @OA\RequestBody(
  176.      *   required=true,
  177.      *   @OA\JsonContent(
  178.      *     required={"email", "hash", "firstName", "country"},
  179.      *     @OA\Property(property="email", type="string"),
  180.      *     @OA\Property(property="password", type="string"),
  181.      *     @OA\Property(property="hash", type="string", description="Hash portalu"),
  182.      *     @OA\Property(property="firstName", type="string"),
  183.      *     @OA\Property(property="lastName", type="string"),
  184.      *     @OA\Property(property="phoneNumber", type="string"),
  185.      *     @OA\Property(property="position", type="string"),
  186.      *     @OA\Property(property="npwz", type="string"),
  187.      *     @OA\Property(property="language", type="string"),
  188.      *     @OA\Property(property="lead", type="int", description="Id leada, odpowiedzialny np. za wysłanie OTP"),
  189.      *     @OA\Property(property="country", type="integer", default="153", description="Id kraju"),
  190.      *   ),
  191.      * )
  192.      *
  193.      * @OA\Response(
  194.      *   response=201,
  195.      *   description="Success",
  196.      *   @OA\JsonContent(
  197.      *     required={"token"},
  198.      *     @OA\Property(property="otpToken", type="string", description="Jeśli rejestracja z OTP"),
  199.      *     @OA\Property(property="token", type="string", description="JSON Web Token, patrz lexik/jwt-authentication-bundle"),
  200.      *   )
  201.      * )
  202.      *
  203.      * @OA\Response(
  204.      *   response=403,
  205.      *   description="Error",
  206.      *   @OA\JsonContent(
  207.      *     required={"status", "errors"},
  208.      *     @OA\Property(property="status", type="string", default="error"),
  209.      *     @OA\Property(property="errors", type="object"),
  210.      *   )
  211.      * )
  212.      *
  213.      * Accepts fields from RegistrationType form
  214.      * Returns json status
  215.      */
  216.     public function register(ApiRegistrationService $apiRegistrationServiceRequest $request)
  217.     {
  218.         $data $request->request->all();
  219.         $portal $this->em->getRepository(PortalSettings::class)->findOneByHash($data['hash']);
  220.         return $this->json(...$apiRegistrationService->register($data$portal));
  221.     }
  222.     /**
  223.      * @Route("/resend-registration-email", name="resendRegistrationEmail", methods={"POST"})
  224.      *
  225.      * Accepts ['email'] - user email
  226.      * Accepts ['hash'] - portal settings hash
  227.      * Returns json status
  228.      */
  229.     public function resendRegistrationEmail(Request $requestUserManagerInterface $userManager): Response
  230.     {
  231.         $user   $userManager->findUserByEmail($request->get('email'));
  232.         $portal $this->em->getRepository(PortalSettings::class)->findOneByHash($request->get('hash'));
  233.         if (!$user instanceof User || !$portal instanceof PortalSettings)
  234.         {
  235.             return $this->json([
  236.                 'status'  => 'error',
  237.                 'message' => 'User found: ' var_export($user instanceof User) . '. Portal found: ' var_export($portal instanceof PortalSettings),
  238.             ]);
  239.         }
  240.         $this->userServices->sendRegisterConfirmationMail($portal$user);
  241.         return $this->json(['status' => 'success']);
  242.     }
  243.     /**
  244.      * @Route("/forgot-password", name="newApiForgotPassword", methods={"POST"})
  245.      *
  246.      * @OA\Tag(name="Security")
  247.      * @OA\Post(summary="Send email to change password")
  248.      *
  249.      * @OA\RequestBody(
  250.      *   required=true,
  251.      *   @OA\JsonContent(
  252.      *     required={"hash", "username"},
  253.      *     @OA\Property(property="hash", type="string", description="Hash portalu"),
  254.      *     @OA\Property(property="username", type="string", description="Email"),
  255.      *     @OA\Property(property="sendActivationMail", type="boolean", description="Wysyła maila z potwierdzeniem rejestracji", default="false"),
  256.      *   ),
  257.      * )
  258.      *
  259.      * @OA\Response(
  260.      *   response=200,
  261.      *   description="Success",
  262.      *   @OA\JsonContent(
  263.      *     @OA\Property(property="success", type="string", default="ok"),
  264.      *   )
  265.      * )
  266.      *
  267.      * @OA\Response(
  268.      *   response=403,
  269.      *   description="Error",
  270.      *   @OA\JsonContent(
  271.      *     @OA\Property(property="error", type="string", default="Nieprawidłowy token"),
  272.      *   )
  273.      * )
  274.      *
  275.      * Accepts ['username'] - user email
  276.      * Accepts ['hash'] - portal settings hash
  277.      * Returns json status
  278.      */
  279.     public function forgotPassword(Request $requestPasswordResetService $passwordReset)
  280.     {
  281.         $request->getSession()->set('portalSettingsHash'$request->request->get('hash'));
  282.         try
  283.         {
  284.             $username $request->request->get('username');
  285.             $sendActivationMail $request->request->getBoolean('sendActivationMail');
  286.             $locale $request->request->get('language');
  287.             $portalHash $request->request->get('hash');
  288.             return $this->json($passwordReset->confirm(
  289.                 $username,
  290.                 $sendActivationMail,
  291.                 $locale,
  292.                 $portalHash
  293.             ));
  294.         }
  295.         catch (\Exception $e)
  296.         {
  297.             return $this->json(['error' => $e->getMessage()]);
  298.         }
  299.     }
  300.     /**
  301.      * @Route("/reset-password", name="newApiResetPassword", methods={"POST"})
  302.      *
  303.      * @OA\Tag(name="Security")
  304.      * @OA\Post(summary="Reset password")
  305.      *
  306.      * @OA\RequestBody(
  307.      *   required=true,
  308.      *   @OA\JsonContent(
  309.      *     required={"token", "new"},
  310.      *     @OA\Property(property="token", type="string", description="Confirmation token (z prośby o zmiane hasła lub walidacji OTP)"),
  311.      *     @OA\Property(property="new", type="string", description="Nowe hasło"),
  312.      *     @OA\Property(property="current", type="string", description="Aktualne hasło"),
  313.      *   ),
  314.      * )
  315.      *
  316.      * @OA\Response(
  317.      *   response=200,
  318.      *   description="Success",
  319.      *   @OA\JsonContent(
  320.      *     @OA\Property(property="success", type="string", default="ok"),
  321.      *   )
  322.      * )
  323.      *
  324.      * @OA\Response(
  325.      *   response=403,
  326.      *   description="Error",
  327.      *   @OA\JsonContent(
  328.      *     @OA\Property(property="error", type="string", default="Nieprawidłowy token"),
  329.      *   )
  330.      * )
  331.      *
  332.      * Accepts ['current'] - current password
  333.      * Accepts ['new'] - new password
  334.      * Accepts ['token'] - user resetting token
  335.      * Returns json status
  336.      */
  337.     public function resetPassword(PasswordResetService $passwordReset): JsonResponse
  338.     {
  339.         return $this->json($passwordReset->reset());
  340.     }
  341.     /**
  342.      * @Route("/validate-otp-code", name="newApiValidateOtpCode", methods={"POST"})
  343.      *
  344.      * @OA\Tag(name="Security")
  345.      * @OA\Post(summary="Validate otp code")
  346.      *
  347.      * @OA\RequestBody(
  348.      *   required=true,
  349.      *   @OA\JsonContent(
  350.      *     required={"email", "hash", "otpToken", "otpCode", "lead"},
  351.      *     @OA\Property(property="hash", type="string"),
  352.      *     @OA\Property(property="email", type="string"),
  353.      *     @OA\Property(property="otpToken", type="string", description="Hash portalu"),
  354.      *     @OA\Property(property="otpCode", type="string"),
  355.      *     @OA\Property(property="lead", type="string"),
  356.      *   ),
  357.      * )
  358.      *
  359.      * @OA\Response(
  360.      *   response=200,
  361.      *   description="Success",
  362.      *   @OA\JsonContent(
  363.      *     required={"token"},
  364.      *     @OA\Property(property="status", type="string", description="Jeśli rejestracja z OTP"),
  365.      *     @OA\Property(property="success", type="boolean"),
  366.      *     @OA\Property(property="confirmationToken", type="string", description="Dla resetowania hasła"),
  367.      *   )
  368.      * )
  369.      *
  370.      * @OA\Response(
  371.      *   response=403,
  372.      *   description="Error",
  373.      *   @OA\JsonContent(
  374.      *     required={"success", "errors"},
  375.      *     @OA\Property(property="success", type="boolean", default="false"),
  376.      *     @OA\Property(property="errors", type="string"),
  377.      *   )
  378.      * )
  379.      * Accepts ['email'] - user email
  380.      * Accepts ['otpToken'] - user otp token
  381.      * Accepts ['otpCode'] - user otp code
  382.      * Returns json status
  383.      */
  384.     public function validateOtpCode(
  385.         Request $request
  386.     ): Response {
  387.         $request->getSession()->set('portalSettingsHash'$request->request->get('hash'));
  388.         $data $request->request->all();
  389.         return $this->forward('App\Controller\Frontend\OneTimePasswordController::activate'$data);
  390.     }
  391.     /**
  392.      * @Route("/resend-otp-code", name="newApiResendOtpCode")
  393.      * @Method("POST")
  394.      *
  395.      * Accepts ['hash'] - portal hash
  396.      * Accepts ['email'] - user email
  397.      * Accepts ['token'] - user otp token
  398.      * Accepts ['templateType'] - leadTemplate
  399.      * Accepts ['templateId'] - gosLeadId
  400.      * Returns json status
  401.      */
  402.     public function resendOtpCode(Request $request): Response
  403.     {
  404.         $request->getSession()->set('portalSettingsHash'$request->request->get('hash'));
  405.         $data $request->request->all();
  406.         $response $this->forward('App\Controller\Frontend\OneTimePasswordController::sendEmailWithCode'$data);
  407.         return $response;
  408.     }
  409.     /**
  410.      * @Route("/send-otp-code-by-sms", name="newApiSendOtpCodeBySMS")
  411.      * @Method("POST")
  412.      *
  413.      * Accepts ['hash'] - portal hash
  414.      * Accepts ['email'] - user email
  415.      * Accepts ['token'] - user otp token
  416.      * Returns json status
  417.      */
  418.     public function sendOtpCodeBySms(Request $request): Response
  419.     {
  420.         $request->getSession()->set('portalSettingsHash'$request->request->get('hash'));
  421.         $data $request->request->all();
  422.         $response $this->forward('App\Controller\Frontend\OneTimePasswordController::sendSMSWithCode'$data);
  423.         return $response;
  424.     }
  425.     /**
  426.      * @Route("/autologin", name="autologin", methods={"POST"})
  427.      */
  428.     public function autologin(): Response
  429.     {
  430.         return new Response(null);
  431.     }
  432. }