HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/gift.naniguide.com/wp-content/plugins/send-app/core/api.php
<?php
namespace Send_App\Core;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

use Send_App\Core\Connect\Classes\Config;
use Send_App\Core\Connect\Classes\Exceptions\Service_Exception;
use Send_App\Core\Connect\Classes\Service as Connect_Service;
use Send_App\Core\Connect\Classes\Data as Connect_Data;
use Send_App\Core\Connect\Classes\Utils as Connect_Utils;
use Send_App\Core\Classes\Data_Reporting;

final class API {

	const BASE_URL = 'https://emp.send2app.com/emp/api/';

	private static bool $refreshed = false;

	public static function get_site_info(): array {
		return [
			// Which API version is used.
			'app_version' => SEND_VERSION,
			// Which language to return.
			'site_lang' => \get_bloginfo( 'language' ),
			// site to connect
			'site_url' => \trailingslashit( home_url() ),
			// current user
			'client_id' => \get_current_user_id(),
			// User Agent
			'user_agent' => ! empty( $_SERVER['HTTP_USER_AGENT'] )
				? \sanitize_text_field( \wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) )
				: 'Unknown',
			'webhook_url' => \rest_url( 'send/v1/webhook' ),
		];
	}

	public static function make_request( $method, $endpoint, $body = [], array $headers = [], $file = false, $file_name = '' ) {
		$additional_headers = [
			'x-elementor-send' => SEND_VERSION,
			'x-elementor-apps' => Config::APP_NAME,
			'Content-Type' => 'application/json',
		];

		$site_id = Connect_Data::get_client_id();

		if ( ! empty( $site_id ) ) {
			$additional_headers['site-id'] = $site_id;
		} else {
			// Prevent form/woo events from being sent without site-id
			$is_form_event = strpos( $endpoint, 'events/form/' ) !== false;
			$is_woo_event = strpos( $endpoint, 'woo/' ) !== false;
			$is_client_logs = strpos( $endpoint, 'client-logs' ) !== false;

			if ( ( $is_form_event || $is_woo_event ) && ! $is_client_logs ) {
				$event_type = $is_form_event ? 'form' : 'woo';

				// Log the prevention
				$data_reporting = new Data_Reporting();
				$data_reporting->send_client_log(
					"Prevented sending {$event_type} event without site-id",
					'warn',
					'plugin',
					[
						'endpoint' => $endpoint,
						'method' => $method,
						'event_type' => $event_type,
						'has_access_token' => ! empty( Connect_Data::get_access_token() ),
						'is_connected' => Connect_Utils::is_connected(),
					]
				);

				return;
			}
		}

		// Replace the headers array
		$headers = array_replace_recursive( $additional_headers, $headers );

		$headers = array_replace_recursive(
			$headers,
			self::is_connected() ? self::generate_authentication_headers( $endpoint ) : []
		);

		$body = array_replace_recursive( $body, self::get_site_info() );

		$args = [
			'timeout' => 100,
			'headers' => $headers,
			'body'    => wp_json_encode( $body ),
		];

		try {
			return self::request(
				$method,
				$endpoint,
				$args,
			);
		} catch ( Service_Exception $e ) {
			return new \WP_Error( $e->getCode(), $e->getMessage(), $args );
		}
	}

	private static function get_remote_url( $endpoint ): string {
		return self::get_base_url() . $endpoint;
	}

	private static function get_base_url() {
		return apply_filters( 'send_app_api_base_url', self::BASE_URL );
	}

	private static function is_connected(): bool {
		return Connect_Utils::is_connected();
	}

	private static function add_bearer_token( $headers ) {
		if ( self::is_connected() ) {
			$headers['Authorization'] = 'Bearer ' . Connect_Data::get_access_token();
		}
		return $headers;
	}

	private static function generate_authentication_headers( $endpoint ): array {
		$headers = [
			'endpoint' => $endpoint,
		];

		return self::add_bearer_token( $headers );
	}

	/**
	 * @throws Service_Exception
	 */
	private static function request( $method, $endpoint, $args = [] ) {
		$args['method'] = $method;

		$response = \wp_safe_remote_request(
			self::get_remote_url( $endpoint ),
			$args
		);

		if ( \is_wp_error( $response ) ) {
			$message = $response->get_error_message();

			return new \WP_Error(
				$response->get_error_code(),
				is_array( $message ) ? join( ', ', $message ) : $message
			);
		}

		$body = \wp_remote_retrieve_body( $response );

		$response_code = (int) \wp_remote_retrieve_response_code( $response );

		if ( ! $response_code ) {
			return new \WP_Error( 500, 'No Response' );
		}

		// If the token is invalid (401 Unauthorized), refresh it and try again once only.
		if ( ! self::$refreshed && 401 === $response_code ) {
			Connect_Service::refresh_token();
			self::$refreshed = true;
			$args['headers'] = self::add_bearer_token( $args['headers'] );
			return self::request( $method, $endpoint, $args );
		}

		// Return with no content on successfull delettion of domain from service.
		if ( 204 === $response_code ) {
			return true;
		}

		// Server sent a success message without content.
		$body = ( 'null' === $body ) ? true : json_decode( $body );

		if ( false === $body ) {
			return new \WP_Error( 422, 'Wrong Server Response' );
		}

		if ( 200 !== $response_code && 201 !== $response_code ) {
			// In case $as_array = true.
			$message = $body->message ?? \wp_remote_retrieve_response_message( $response );
			$message = is_array( $message ) ? wp_json_encode( $message ) : $message;
			$code = isset( $body->code ) ? (int) $body->code : $response_code;

			return new \WP_Error( $code, $message );
		}

		return $body;
	}

	public static function register_connected_site(): bool {
		$token = Connect_Data::get_access_token();

		if ( ! $token ) {
			Logger::warn( 'No access token found' );
			return false;
		}

		try {
			$response = self::make_request( 'POST', 'sites', [
				'token' => $token,
			] );
		} catch ( \Exception $e ) {
			Logger::error( 'Error registering site on collection: ' . $e->getMessage() );

			return false;
		}
		if ( is_wp_error( $response ) ) {
			Logger::debug( $response->get_error_code() . ': "' . $response->get_error_message() . '" | data: ' . wp_json_encode( $response->get_error_data() ) );
			Logger::error( 'Failed to create site on collection: ' . wp_json_encode( $response->get_error_messages() ) );

			return false;
		}
		if ( ! empty( $response->subscriptionId ) ) { //@phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
			Connect_Data::set_subscription_id( $response->subscriptionId ); //@phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
		}
		Logger::info( 'Site registered on collection' );

		return true;
	}
}