src/Service/Backend.php line 297

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\Model\User;
  4. use App\Specification\KeycloakModeUsed;
  5. use App\Utils\JwtUtils;
  6. use MiladRahimi\Jwt\Exceptions\InvalidKeyException;
  7. use Psr\Log\LoggerInterface;
  8. use Symfony\Component\HttpFoundation\JsonResponse;
  9. use Symfony\Component\HttpFoundation\RedirectResponse;
  10. use Symfony\Component\HttpFoundation\RequestStack;
  11. use Symfony\Component\HttpFoundation\Response;
  12. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  13. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  14. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  15. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  16. use Symfony\Component\Serializer\SerializerInterface;
  17. use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
  18. use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
  19. use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
  20. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  21. use Symfony\Contracts\HttpClient\HttpClientInterface;
  22. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  23. use Symfony\Contracts\HttpClient\ResponseInterface;
  24. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  25. use Symfony\Component\Security\Core\Exception\UserNotFoundException;
  26. class Backend
  27. {
  28. //    use SessionUtils;
  29.     use JwtUtils;
  30.     protected $backend_url;
  31.     protected $cert_dir;
  32.     protected $api_url;
  33.     protected $proxy_api_url;
  34.     protected $serializer;
  35.     protected $client;
  36.     // User Backend
  37. //    const LOGIN = 'user/login'; // Used
  38.     const LOGIN 'api/login'// Used
  39.     const TOKEN 'user/token'// Not used
  40.     const ACTIVATE 'api/users/'// 'user/activate'; //Use for POST and PUT
  41.     const REACTIVATE 'api/emails/bubbles/' //Resend activation
  42.     const USER_UPDATE_ROLE 'user/role';
  43.     const GET_USER 'user/passwordReset'//Use for POST and PUT
  44.     const USER_RESET_PASSWORD_BY_EMAIL 'api/emails/reset-password';
  45.     const USER_RESET_PASSWORD 'api/users/reset-password';
  46.     // Bubble Backend
  47.     const BUBBLE 'api/bubbles';  // Used for POST new xx
  48.     const ACTIVATE_BUBBLE 'bubble/activate'// Used for PUT
  49.     const ADD_BUBBLE_USER 'api/bubbles/'// Used for POST xx
  50.     const DELETE_BUBBLE_USER 'bubble/user/'// Not used
  51.     const DELETE_BUBBLE_PROFILE 'api/bubbles/'//xx
  52.     const GET_BUBBLE_USER 'bubble/users';
  53. //    const GET_BUBBLE_PROFILES = 'bubble/profiles/all'; //xx
  54.     const GET_BUBBLE_PROFILES 'api/bubbles/';  // 'api/bubbles/:b_id/users/profiles'
  55.     const GET_BUBBLE_PROFILE_RIGTHS 'api/bubbles/'//Get one profile by profile id xx
  56.     const BUBBLE_PROFILES 'profiles/bubble/';
  57.     const BUBBLE_UPDATE_PROFILES 'api/bubbles/'//xx
  58.     const GET_VALIDATORS 'bubble/validators/print'// get the user validator of a bubble
  59.     const GET_USER_BY_PROFILE 'users/byProfile';
  60. //    const GET_ONE_PROFILE_RIGHTS = 'bubble/profiles/user/'; //To get the new profiles rights for one user
  61.     const GET_ONE_PROFILE_RIGHTS 'api/bubbles/';
  62. //    const GET_ALL_PROFILE_RIGHTS = 'bubble/profiles/default'; //To get the new profiles rights for all users xx
  63.     const GET_ALL_PROFILE_RIGHTS 'api/bubbles/';
  64.     // Site Backend
  65.     const ADD_SITE 'api/sites';  // POST  new site
  66. //    const SITE = 'site/';  // GET  get sites by Bubble ID
  67.     const SITES 'api/sites';  // GET  get sites by Bubble ID
  68.     const SITE_ADD_USER 'site/add/user'// Add user to a site
  69. //    const UPDATE_SITE = 'sites/'; // PUT site OLD
  70.     const UPDATE_SITE 'api/sites/';
  71.     const GET_SITE_BY_ID 'api/sites/'// GET site by ID
  72.     const UPDATE_CATALOGUE_STATUS 'api/sites/out_catalog_status/';
  73.     // Organization Backend
  74.     const ADD_ORGANIZATION 'organization'//POST new organization
  75.     const GET_ORGANIZATIONS 'organizations/'//GET organizations
  76.     const GET_ORGANIZATION_BY_ID 'organization/'//GET one organization by id
  77.     const UPDATE_ORGANIZATION 'organization/'//UPDATE organization
  78.     // Formation backend
  79.     const ADD_FORMATION 'formation'//POST new formation
  80.     const GET_FORMATIONS 'formations/b_id'//GET formation
  81.     const GET_FORMATION_BY_ID 'formation/'//GET one organization by id
  82.     //Structure backend
  83. //    const ADD_STRUCTURE = 'structure'; //POST new structure
  84.     const ADD_STRUCTURE 'api/structures'//POST new structure
  85.     const GET_STRUCTURE_ORG 'api/bubbles/'//'structures/organization/'; //GET structures org
  86.     const GET_STRUCTURE_FORM 'api/bubbles/'//GET structures form
  87.     const GET_STRUCTURE_CHILDREN 'api/structures/'//'structures/'; // GET structures children
  88.     const UPDATE_STRUCTURE 'api/structures/'//PUT structures
  89.     const GET_STRUCTURE_BY_ID 'api/structures/'//GET structure by ID
  90.     const GET_STRUCTURE_BY_B_ID 'api/structures/';
  91.     const DELETE_STRUCTURE 'api/structures';
  92.     // PrintJob Backend
  93.     const PRINT_REQUEST 'printJob/request';
  94.     const GET_PRINT_REQUEST 'printJob/requests';
  95. //    const GET_PRINT_LOGS = 'printJob/refreshPrintJob'; // get the print logs of BA and OP
  96.     const GET_PRINT_LOGS 'api/dashboards/';
  97.     const START_PRINT_JOB 'printJob/startPrint'//Start Print Job
  98.     const CRM_UPDATE_JOB 'api/job-orders/'// 'sites/job_orders/status/'; //Update job for crm
  99.     // Production Order
  100.     const ADD_PRODUCTION_ORDER 'api/production_orders'// POST production order
  101.     const GET_PRODUCTION_ORDER 'api/production_orders'// GET production order
  102.     const GET_EXTRA_PRODUCTION_ORDER 'productionOrder/children/'// GET production order
  103.     const PRODUCTION_ORDER_RECEIVED 'api/production_orders/received'// GET production order received
  104.     const GET_PO_BY_ID 'api/production_orders'//GET PO by ID
  105.     // Plan Backend
  106.     const GET_PLANS 'api/plans';
  107.     const POST_PLAN 'api/plans';
  108.     const VALIDATE_PLAN 'api/plans/'// to validate a plan as VPLAN
  109.     const ECO_MODEL 'api/plans/'// 'plan/eco_model'; // Add (POST), GET (GET) and UPDATE (PUT) an ecoModel
  110.     const PLAN_EM_TRANCHES 'plan/tranche';
  111.     const GET_PLAN 'api/plans/';
  112.     const GET_PLAN_PIECES 'api/plans/';
  113.     const PLAN_ADD_PIECE 'api/plans/'// 'plans/pieces';
  114.     const PLAN_DELETE_PIECE 'api/plans/'// Used for DELETE
  115.     const PLAN_ADD_INDUS 'plans/indus';
  116.     const PLAN_ATTACH_INDUS 'api/plans'//PATCH
  117. //    const PLAN_DELETE_INDUS = 'plans/indus';
  118.     const PLAN_DELETE_INDUS 'api/plans/'// 'api/industrials'; // 'plans/indus';
  119.     const PLAN_DELETE 'api/plans/'// "plans/";
  120.     const PLAN_UPDATE "plans/pieces";
  121.     const PLAN_PIECE_UPDATE 'api/plans/';
  122.     const NON_CATALOG_FILE 'api/prototype_orders';
  123.     const PLAN_MATERIALS 'api/materials/';
  124.     const PLAN_PRINTCORES 'api/printcores/';
  125.     // Printer Backend
  126.     const ADD_PRINTER 'printer/';
  127. //    const GET_PRINTERS = 'sites/printers/'; // get the printers of a bubble
  128. //    const GET_PRINTER_PER_SITE = 'site/printers/' ; // get printers per site
  129.     const GET_PRINTERS 'api/printers';
  130.     const GET_PRINTER_PER_SITE 'api/printers/';
  131.     const GET_PRINTERS_BY_BULLE 'api/bubbles/';
  132.     const DELETE_SITE 'api/sites/';
  133.     
  134.     // PRODUCTION PLANNING Backend
  135.     const GET_PLANNING 'api/planning';
  136.     const POST_PLANNING 'api/planning';
  137.     const DELETE_PLANNING 'api/planning/';
  138.     const UPDATE_PLANNING 'api/planning/';
  139.     // Job Order Backend
  140.     const GET_JOB_ORDERS 'api/job-orders'//'sites/job_orders/'; // get job order
  141.     const GET_JOB_ORDER_BY_ID 'api/job-orders/'//get one job order by id
  142.     const ADD_JOB_ORDER "api/job-orders"//POST job order
  143.     const GET_JOB_ORDERS_BY_STATUS "api/job-orders/controlled/job-order-status/"//GET job order by :job_order_status= All Error Finished
  144.     
  145.     // INDUSTRIAL Backend
  146.     //const GET_INDUSTRIALS = 'industrials/'; // GET INDUSTRIALS OLD
  147.     const GET_INDUSTRIALS 'api/industrials/';
  148.     const POST_INDUSTRIAL 'api/industrials/'// POST INDUSTRIAL
  149.     // QUALITY CONTROL
  150.     const GET_QC 'api/quality_controls';
  151.     const SEND_QC 'api/quality_controls'//'printJob/qualityControl';
  152.     // const GET_QC_CRM = 'api/quality_controls/'; //'sites/job_orders/qualityControl/'; // get job order crm case
  153.     const GET_QC_CRM 'api/job-orders'//'sites/job_orders/qualityControl/'; // get job order crm case
  154.     // BILLS
  155.     const GET_BILLS 'bills/';
  156.     const GET_BILL_DETAILS 'bills/'// id en get
  157.     // API
  158. //    const GET_API_TOKENS = 'bubble/apikeys'; //xx
  159.     const GET_API_TOKENS 'api/bubbles/';
  160.     const BUBBLE_API_TOKEN "tokens/bubble";
  161. //    const SITE_API_TOKEN = "tokens/site";
  162.     // DASHBOARD
  163.     const GET_DASHBOARD_LOGS 'api/dashboards/'// 'dashboard/logs/'; // get the print logs of BA and OP
  164.     const CONTACT_EMAIL 'api/emails/';
  165. //    private RequestStack $requestStack;
  166.     /**
  167.      * @param UrlGeneratorInterface $urlGenerator
  168.      * @param SerializerInterface $serializer
  169.      * @param HttpClientInterface $client
  170.      * @param ParameterBagInterface $param
  171.      * @param SessionInterface $session
  172.      * @param RequestStack $requestStack
  173.      * @param LoggerInterface $logger
  174.      */
  175.     public function __construct(
  176.         UrlGeneratorInterface $urlGenerator,
  177.         SerializerInterface $serializer,
  178.         HttpClientInterface $client,
  179.         ParameterBagInterface $param,
  180.         SessionInterface $session,
  181.         RequestStack $requestStack,
  182.         LoggerInterface $logger
  183.     ) {
  184.         $this->urlGenerator $urlGenerator;
  185.         $this->serializer $serializer;
  186.         $this->client$client;
  187.         $this->param $param;
  188.         $this->session $session;
  189.         $this->requestStack $requestStack;
  190.         $this->logger $logger;
  191.         $this->backend_url $param->get('backend_url');
  192.         $this->api_url $param->get('api_url');
  193.         $this->proxy_api_url $param->get('proxy_api_url');
  194.     }
  195.     /**
  196.      * When we need to make a call to the backend api, we should always use this function.
  197.      * It will make the call and log what we did
  198.      * It's all about control !
  199.      *
  200.      * @param string $reqType
  201.      * @param string $actionPath
  202.      * @param array $unloggedArguments
  203.      * @param array $loggedArguments
  204.      *
  205.      * @throws InvalidKeyException
  206.      * @throws TransportExceptionInterface
  207.      * @throws ClientExceptionInterface
  208.      * @throws RedirectionExceptionInterface
  209.      * @throws ServerExceptionInterface
  210.      */
  211.     public function apiRequestLogin(string $reqTypestring $actionPath, array $unloggedArguments, array $loggedArguments//: JsonResponse
  212.     {
  213.         $this->logger->info('Je rentre dans la fonction : apiRequestLogin de la classe : src/Service/Backend.php ');
  214.         $password $loggedArguments['u_pwd'];
  215.         $email $loggedArguments['u_email'];
  216.         // Credantials from login form
  217.         $credantials = [
  218.             'u_email' => $email,
  219.             'u_pwd' => $password
  220.         ];
  221.         $loggedArguments['verify_peer'] = false;
  222.         $jwtKeysDir $this->param->get('jwt.file.dir');
  223.         $token $this->generateFrontendJwtToken($jwtKeysDir$credantials);
  224.         if (!empty($unloggedArguments['x-token-keycloak']) && $unloggedArguments['x-token-keycloak'] != '') {
  225.             $headers =  [
  226.                 'Content-Type' => 'application/json',
  227.                 'Accept' => 'application/json',
  228.                 'Authorization' => 'Bearer ' $token,
  229.                 'x-token-keycloak' => $this->session->get('oidc_access_token'),
  230.                 'verify_peer' => false
  231.             ];
  232.         } else {
  233.             $headers = [
  234.                 'Content-Type' => 'application/json',
  235.                 'Accept' => 'application/json',
  236.                 'Authorization' => 'Bearer ' $token,
  237.                 'verify_peer' => false
  238.             ];
  239.         }
  240.         // Send request to backend API
  241.         $response $this->client->request($reqType$this->proxy_api_url $actionPath, [
  242.             'headers' => $headers,
  243.             'body' => json_encode($credantials),
  244.             'verify_peer' => false
  245.         ]);
  246.         $this->logger->debug(sprintf("[src/Service/Backend.php] Le status de la réponse du front api lors du logging : %s"$response->getStatusCode()));
  247.         $this->logger->debug(sprintf("[src/Service/Backend.php] La réponse du backend lors du logging : %s"$response->getContent(false)));
  248.         if (KeycloakModeUsed::isSatisfiedBy($this->param) &&
  249.             ($response->getStatusCode() == Response::HTTP_NOT_FOUND ||
  250.                 $response->getStatusCode() == Response::HTTP_UNAUTHORIZED)) {
  251.             return new RedirectResponse($this->urlGenerator->generate('user_not_found'));
  252.         }
  253.         if ($response->getStatusCode() === Response::HTTP_BAD_REQUEST) {
  254.             throw new UserNotFoundException('Ce compte n\'existe pas');
  255.             //throw new BadRequestHttpException('400 : Session expirée ou mauvais identifiants.');
  256.         }
  257.         if (Response::HTTP_FORBIDDEN == $response->getStatusCode() || Response::HTTP_NOT_FOUND == $response->getStatusCode()) {
  258.             throw new UserNotFoundException('Ce compte n\'existe pas');
  259.             //throw new AccessDeniedException("403 : Droits utilisateur. Vous ne disposez pas des droits pour effectuer cette action.");
  260.         }
  261.         $apiResponseJwtToken json_decode($response->getContent(), true)['token'];
  262.         // Decode JWT token
  263.         $claims $this->decodeProxyApiJwtToken($jwtKeysDir$apiResponseJwtToken);
  264.         $this->logger->debug(sprintf("[src/Service/Backend.php] Le token de la réponse du front api lors du logging : %s"$apiResponseJwtToken));
  265.         if (!empty($unloggedArguments['x-token-keycloak']) && $unloggedArguments['x-token-keycloak'] != '') {
  266.             $this->session->set('apiJwtToken'$apiResponseJwtToken);
  267.             $this->session->set('keycloak_access_token'$this->session->get('oidc_access_token')); //$unloggedArguments['x-token-keycloak']);
  268.             $resp = new JsonResponse($claims);
  269.         } else {
  270.             /**
  271.              * Verify if the password from login form is the same as password in JWT token
  272.              * and
  273.              * Verify if email from login form is the same as email in JWT token
  274.              */
  275.             if (password_verify($password$claims['u_pwd']) && $email === $claims['u_email']) {
  276.                 $this->session->set('apiJwtToken'$apiResponseJwtToken);
  277.                 $resp = new JsonResponse($claims);
  278.             } else {
  279.                 $resp = new JsonResponse([
  280.                     'status' => 'failed',
  281.                     'code' => '401',
  282.                     'message' => 'HTTP_UNAUTHORIZED',
  283.                     'contents' => 'Bad credentials'
  284.                 ]);
  285.             }
  286.         }
  287.         return $resp;
  288.     }
  289.     /**
  290.      * @param string $reqType
  291.      * @param string $actionPath
  292.      * @param array $unloggedArguments
  293.      * @param array $loggedArguments
  294.      * @return ResponseInterface
  295.      * @throws ClientExceptionInterface
  296.      * @throws RedirectionExceptionInterface
  297.      * @throws ServerExceptionInterface
  298.      * @throws TransportExceptionInterface
  299.      */
  300.     public function apiRequestNewUrls(string $reqTypestring $actionPath, array $unloggedArguments, array $loggedArguments)
  301.     {
  302.         $this->logger->info('[src/Service/Backend.php] Je rentre dans la fonction apiRequestNewUrls');
  303.         $session $this->requestStack->getMainRequest()->getSession();
  304.         $token $session->get('apiJwtToken');
  305.         $accessToken $session->get('oidc_access_token'); //  $session->get('keycloak_access_token');
  306.         if (!empty($accessToken) && $accessToken != '') {
  307.             $headers =  [
  308.                 'Content-Type' => 'application/json',
  309.                 'Accept' => 'application/json',
  310.                 'Authorization' => 'Bearer ' $token,
  311.                 'x-token-keycloak' => $accessToken
  312.             ];
  313.         } else {
  314.             $headers = [
  315.                 'Content-Type' => 'application/json',
  316.                 'Accept' => 'application/json',
  317.                 'Authorization' => 'Bearer ' $token
  318.             ];
  319.         }
  320.         $startTime microtime(true);
  321.         $response $this->client->request($reqType$this->proxy_api_url $actionPath, [
  322.             'headers' => $headers,
  323.             'body' => json_encode($loggedArguments),
  324.             'verify_peer' => false
  325.         ]);
  326.         $endTime microtime(true);
  327.         $executionTime $endTime $startTime;
  328.         $this->logger->info('[src/Service/Backend.php, METHOD : ' $reqType ', URL : ' $this->proxy_api_url $actionPath ', Response Time : ] ' $executionTime);
  329.         $this->logger->info('[src/Service/Backend.php - fonction: apiRequestNewUrls] Le status de la réponse pour chaque requête entre front api et le front web : ' $response->getStatusCode());
  330.         $this->logger->info('[src/Service/Backend.php - fonction: apiRequestNewUrls] La réponse pour chaque requête entre front api et le front web : ' $response->getContent(false));
  331.         return $response;
  332.     }
  333.     /**
  334.      * Activate user bulle
  335.      *
  336.      * @param string $reqType
  337.      * @param string $actionPath
  338.      * @param array $unloggedArguments
  339.      * @param array $loggedArguments
  340.      * @return ResponseInterface
  341.      * @throws ClientExceptionInterface
  342.      * @throws InvalidKeyException
  343.      * @throws RedirectionExceptionInterface
  344.      * @throws ServerExceptionInterface
  345.      * @throws TransportExceptionInterface
  346.      */
  347.     public function apiRequestAdmin(string $reqTypestring $actionPath, array $unloggedArguments, array $loggedArguments): ResponseInterface
  348.     {
  349.         $session $this->requestStack->getMainRequest()->getSession();
  350.         $token $this->generateFrontendJwtToken(
  351.             $this->param->get('jwt.file.dir'), [
  352.             'u_email' => $loggedArguments['u_email'],
  353.             'u_pwd' => $loggedArguments['u_pwd']
  354.         ]);
  355.         $loggedArguments['verify_peer'] = false;
  356.         $accessToken $session->get('keycloak_access_token');
  357.         if (!empty($accessToken) && $accessToken != '') {
  358.             $headers =  [
  359.                 'Content-Type' => 'application/json',
  360.                 'Accept' => 'application/json',
  361.                 'Authorization' => 'Bearer ' $token,
  362.                 'x-token-keycloak' => $accessToken,
  363.                 'verify_peer' => false
  364.             ];
  365.         } else {
  366.             $headers = [
  367.                 'Content-Type' => 'application/json',
  368.                 'Accept' => 'application/json',
  369.                 'Authorization' => 'Bearer ' $token,
  370.                 'verify_peer' => false
  371.             ];
  372.         }
  373.         $response $this->client->request($reqType$this->proxy_api_url $actionPath, [
  374.             'headers' => $headers,
  375.             'body' => json_encode($loggedArguments),
  376.             'verify_peer' => false
  377.         ]);
  378.         $this->logger->debug(sprintf("[src/Service/Backend.php - fonction: apiRequestAdmin()] Le status de la réponse lors du logging du super admin : %s",  $response->getStatusCode()));
  379.         $this->logger->debug(sprintf("[src/Service/Backend.php - fonction: apiRequestAdmin()] La réponse  lors du logging du super admin : %s",  $response->getContent(false)));
  380.         return $response;
  381.     }
  382.     /**
  383.      * @param string $reqType
  384.      * @param string $actionPath
  385.      * @param array $unloggedArguments
  386.      * @param array $loggedArguments
  387.      * @return ResponseInterface
  388.      * @throws ClientExceptionInterface
  389.      * @throws InvalidKeyException
  390.      * @throws RedirectionExceptionInterface
  391.      * @throws ServerExceptionInterface
  392.      * @throws TransportExceptionInterface
  393.      */
  394.     public function apiRequestPW(string $reqTypestring $actionPath, array $unloggedArguments, array $loggedArguments): ResponseInterface
  395.     {
  396.         $session $this->requestStack->getMainRequest()->getSession();
  397.         $token $this->generateFrontendJwtToken(
  398.             $this->param->get('jwt.file.dir'), [
  399.             'u_email' => $loggedArguments['u_email'],
  400.             'u_pwd' => $loggedArguments['u_pwd']
  401.         ]);
  402.         $accessToken $session->get('keycloak_access_token');
  403.         $response $this->getRequest($accessToken$token$reqType$actionPath$loggedArguments);
  404.         $this->logger->debug(sprintf("[src/Service/Backend.php - fonction: apiRequestPW()] Le status de la réponse lors du changement de mot de passe : %s",  $response->getStatusCode()));
  405.         $this->logger->debug(sprintf("[src/Service/Backend.php - fonction: apiRequestPW()] La réponse  lors du changement de mot de passe : %s",  $response->getContent(false)));
  406.         return $response;
  407.     }
  408.     /**
  409.      * @param mixed $accessToken
  410.      * @param mixed $token
  411.      * @param string $reqType
  412.      * @param string $actionPath
  413.      * @param array $loggedArguments
  414.      * @return ResponseInterface
  415.      * @throws TransportExceptionInterface
  416.      */
  417.     public function getRequest(mixed $accessTokenmixed $tokenstring $reqTypestring $actionPath, array $loggedArguments): ResponseInterface
  418.     {
  419.         if (!empty($accessToken) && $accessToken != '') {
  420.             $headers = [
  421.                 'Content-Type' => 'application/json',
  422.                 'Accept' => 'application/json',
  423.                 'Authorization' => 'Bearer ' $token,
  424.                 'x-token-keycloak' => $accessToken
  425.             ];
  426.         } else {
  427.             $headers = [
  428.                 'Content-Type' => 'application/json',
  429.                 'Accept' => 'application/json',
  430.                 'Authorization' => 'Bearer ' $token
  431.             ];
  432.         }
  433.         return $this->client->request($reqType$this->proxy_api_url $actionPath, [
  434.             'headers' => $headers,
  435.             'body' => json_encode($loggedArguments),
  436.             'verify_peer' => false
  437.         ]);
  438.     }
  439. }