| Server IP : 52.25.153.185 / Your IP : 216.73.217.117 Web Server : Apache System : Linux ip-172-26-6-158 5.10.0-45-cloud-amd64 #1 SMP Debian 5.10.259-1 (2026-07-02) x86_64 User : daemon ( 1) PHP Version : 8.1.10 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /bitnami/wordpress/wp-content/plugins/fluentformpro/src/Integrations/Salesforce/ |
Upload File : |
<?php
namespace FluentFormPro\Integrations\Salesforce;
if (!defined('ABSPATH')) {
exit; // Exit if accessed directly.
}
class API
{
protected $clientId = null;
protected $clientSecret = null;
protected $instance_url = null;
protected $accessToken = null;
protected $callBackUrl = null;
protected $settings = [];
public function __construct($settings)
{
$this->clientId = $settings['client_id'];
$this->clientSecret = $settings['client_secret'];
$this->instance_url = rtrim($settings['instance_url'], '/');
$this->accessToken = $settings['access_token'];
$this->callBackUrl = admin_url('?ff_salesforce_auth=true');
$this->settings = $settings;
// SECURITY (PRO-38): Salesforce instance URLs are always on salesforce.com / force.com.
// A settings_manager could otherwise point instance_url at an internal or attacker host and
// the OAuth Bearer token attached to every request would be exfiltrated there (SSRF +
// credential exposure). Fail closed by emptying an out-of-policy host, so the derived URLs
// become relative and wp_remote_* rejects them before any token leaves.
if ($this->instance_url && !self::isAllowedSalesforceHost($this->instance_url)) {
$this->instance_url = '';
}
}
protected static function isAllowedSalesforceHost($url)
{
$host = strtolower((string) wp_parse_url($url, PHP_URL_HOST));
$scheme = strtolower((string) wp_parse_url($url, PHP_URL_SCHEME));
if ('https' !== $scheme || !$host) {
return false;
}
// COMPAT: filterable so an operator can add a legitimate Salesforce host this list does not
// anticipate (a new TLD/region) without patching, keeping the default-deny posture.
$suffixes = apply_filters('fluentform/salesforce_allowed_host_suffixes', ['salesforce.com', 'force.com']);
foreach ((array) $suffixes as $suffix) {
$suffix = strtolower((string) $suffix);
if ($host === $suffix || substr($host, -strlen('.' . $suffix)) === '.' . $suffix) {
return true;
}
}
return false;
}
public function getRedirectServerURL()
{
// SECURITY (PRO-17): bind the OAuth response to the initiating admin session so a
// forged callback (attacker's code) cannot graft the attacker's account onto the site.
return $this->instance_url .
'/services/oauth2/authorize?response_type=code&client_id=' .
$this->clientId .
'&state=' . rawurlencode(wp_create_nonce('ff_salesforce_oauth')) .
'&redirect_uri=' .
$this->callBackUrl;
}
public function generateAccessToken($code, $settings)
{
$url = $settings['is_sandbox'] == 'true' ? 'https://test.salesforce.com/services/oauth2/token' : 'https://login.salesforce.com/services/oauth2/token';
$response = wp_remote_post($url, [
'body' => [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'grant_type' => 'authorization_code',
'redirect_uri' => $this->callBackUrl,
'code' => $code
]
]);
if (is_wp_error($response)) {
return $response;
}
$body = wp_remote_retrieve_body($response);
$body = \json_decode($body, true);
if (isset($body['error_description'])) {
return new \WP_Error('invalid_client', $body['error_description']);
}
$settings['access_token'] = $body['access_token'];
$settings['refresh_token'] = $body['refresh_token'];
return $settings;
}
protected function getApiSettings()
{
$this->maybeRefreshToken();
if(!$this->settings['status']) {
return new \WP_Error('invalid', __('API key is invalid', 'fluentformpro'));
}
return [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'callback' => $this->callBackUrl,
'access_token' => $this->settings['access_token'],
'refresh_token' => $this->settings['refresh_token']
];
}
protected function maybeRefreshToken()
{
$url = $this->settings['is_sandbox'] == 'true' ? 'https://test.salesforce.com/services/oauth2/token' : 'https://login.salesforce.com/services/oauth2/token';
$response = wp_remote_post($url, [
'body' => [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'grant_type' => 'refresh_token',
'refresh_token' => $this->settings['refresh_token']
]
]);
if (is_wp_error($response)) {
return new \WP_Error('error', $response[0]['errorCode'] . ': ' .$response[0]['message']);
}
$body = wp_remote_retrieve_body($response);
$body = \json_decode($body, true);
if (isset($body['error_description'])) {
return new \WP_Error('invalid_client', $body['error_description']);
}
$this->settings['access_token'] = $body['access_token'];
}
public function makeRequest($url, $bodyArgs, $type = 'GET')
{
$apiSettings = $this->getApiSettings();
$this->accessToken = $apiSettings['access_token'];
$request = [];
if ($type == 'GET') {
$request = wp_remote_get($url, [
'headers' => [
'Authorization' => " Bearer ". $this->accessToken,
]
]);
}
if ($type == 'POST') {
$request = wp_remote_post($url, [
'headers' => [
'Authorization' => " Bearer ". $this->accessToken,
'Content-Type' => 'application/json'
],
'body' => $bodyArgs
]);
}
if (is_wp_error($request)) {
$message = $request->get_error_message();
return new \WP_Error($request->get_error_code(), $message);
} elseif ($request['response']['code'] >= 200 && $request['response']['code'] <= 299) {
return json_decode($request['body'], true);
}
$body = wp_remote_retrieve_body($request);
$body = \json_decode($body, true)[0];
$error = 'Unknown Error';
if (!empty($body['errorCode'])) {
if (isset($body['message'])) {
$error = $body['message'];
}
}
return new \WP_Error($request['response']['code'], $error);
}
public function subscribe($subscriber)
{
$url = $this->instance_url . '/services/data/v53.0/sobjects/' . $subscriber['list_id'];
$post = \json_encode($subscriber['attributes'], JSON_NUMERIC_CHECK);
$response = $this->makeRequest($url, $post, 'POST');
return $response;
}
}