Current File : /home/kelaby89/kelaby.company/wp-content/plugins/advanced-google-recaptcha/wf-licensing.php |
<?php
/**
* WebFactory Ltd Licensing Manager
* (c) WebFactory Ltd, 2019 - 2021, www.webfactoryltd.com
*/
if (false === class_exists('WF_Licensing_WPCaptcha')) {
class WF_Licensing_WPCaptcha
{
public $prefix = '';
private $licensing_servers = array();
private $version = '';
private $slug = '';
private $basename = '';
private $plugin_file = '';
private $js_folder = '';
protected $api_ver = 'v1/';
protected $valid_forever = '2035-01-01';
protected $unlimited_installs = 99999;
public $disable_remote = false;
public $debug = false;
/**
* Init licensing by setting up various params and hooking into actions.
*
* @param array $params Prefix, licensing_servers, version, plugin_file, skip_hooks
*
* @return void
*/
function __construct($params)
{
$this->prefix = trim($params['prefix']);
$this->licensing_servers = $params['licensing_servers'];
$this->version = trim($params['version']);
$this->slug = dirname(plugin_basename(trim($params['plugin_file'])));
$this->basename = plugin_basename(trim($params['plugin_file']));
$this->plugin_file = $params['plugin_file'];
$this->disable_remote = !empty($params['disable_remote']);
$this->debug = !empty($params['debug']);
if ($params['js_folder']) {
$this->js_folder = trim($params['js_folder']);
} else {
$this->js_folder = plugin_dir_url($this->plugin_file) . 'js/';
}
if (empty($params['skip_hooks'])) {
register_activation_hook($this->plugin_file, array($this, 'activate_plugin'));
register_deactivation_hook($this->plugin_file, array($this, 'deactivate_plugin'));
add_filter('pre_set_site_transient_update_plugins', array($this, 'update_filter'));
add_filter('plugins_api', array($this, 'update_details'), 100, 3);
add_action('init', array($this, 'init'));
add_action('wp_ajax_wf_licensing_' . $this->prefix . '_validate', array($this, 'validate_ajax'));
add_action('wp_ajax_wf_licensing_' . $this->prefix . '_save', array($this, 'save_ajax'));
add_action('wp_ajax_wf_licensing_' . $this->prefix . '_deactivate', array($this, 'deactivate_ajax'));
}
$this->log('__construct', $params, get_object_vars($this));
add_action('wf_licensing_' . trim($this->prefix, '_') . '_remote_action_refresh', array($this, 'remote_action_refresh'));
add_action('wf_licensing_' . trim($this->prefix, '_') . '_remote_action_deactivate_license', array($this, 'remote_action_deactivate_license'));
add_action('wf_licensing_' . trim($this->prefix, '_') . '_remote_action_validate_license', array($this, 'remote_action_validate_license'));
add_action('plugins_loaded', array($this, 'monitor_remote_actions'));
} // __construct
/**
* Actions performed on WP init action.
*
* @return void
*/
function init()
{
if (is_admin()) {
$vars = array(
'prefix' => $this->prefix,
'debug' => $this->debug,
'nonce' => wp_create_nonce('wf_licensing_' . $this->prefix),
'licensing_endpoint' => $this->licensing_servers[0] . $this->api_ver,
'request_data' => array(
'action' => 'validate_license',
'license_key' => '',
'rand' => rand(1000, 9999),
'version' => $this->version,
'wp_version' => get_bloginfo('version'),
'site_url' => get_home_url(),
'site_title' => get_bloginfo('name'),
'meta' => array()
)
);
wp_enqueue_script('wf_licensing_wpcaptcha', $this->js_folder . 'wf-licensing.js', array(), 1.0, true);
wp_localize_script('wf_licensing_wpcaptcha', 'wf_licensing_' . $this->prefix, $vars);
}
} // init
function monitor_remote_actions()
{
if ($this->disable_remote || is_admin()) {
return;
}
if (!empty($_REQUEST[$this->prefix . '_access_key']) && !empty($_REQUEST[$this->prefix . '_action']) && isset($_REQUEST[$this->prefix . '_action_params'])) {
$access_key = substr(trim($_REQUEST[$this->prefix . '_access_key']), 0, 32);
$action = substr(trim($_REQUEST[$this->prefix . '_action']), 0, 32);
$action_params = $_REQUEST[$this->prefix . '_action_params'];
$rand = substr($_REQUEST[$this->prefix . '_rand'], 0, 5);
$rand = preg_replace("/[^0-9]/", '', $rand);
nocache_headers();
header('X-WF-Licensing-' . $this->prefix . ': ' . $this->version);
if (strlen($rand) != 5) {
wp_send_json_error('Invalid random value.');
}
if (false == $this->is_active(false, false, true)) {
wp_send_json_error('License is not active.');
}
if (false == $this->is_remote_action($action)) {
wp_send_json_error('Unknown remote action.');
}
$access_key = preg_replace("/[^0-9a-zA-Z]/", '', $access_key);
if (strlen($access_key) != 32) {
wp_send_json_error('Invalid access key format.');
}
$license = $this->get_license();
if ($access_key != $license['access_key']) {
wp_send_json_error('Invalid access key.');
}
$post_data = @json_decode(file_get_contents('php://input'), true);
do_action('wf_licensing_' . trim($this->prefix, '_') . '_remote_action_' . $action, $action_params, $this, $post_data);
wp_send_json_error('Remote action did not execute.');
die();
}
} // monitor_remote_actions
function remote_action_refresh($action_params)
{
$data = $this->prepare_server_query_data('remote_refresh');
wp_send_json_success($data);
} // remote_action_refresh
function remote_action_validate_license($action_params)
{
$validate = $this->validate();
$license = $this->get_license();
wp_send_json_success(array('validate' => $validate, 'license' => $license));
} // remote_action_validate_license
function remote_action_deactivate_license($action_params)
{
$license = $this->get_license();
$this->update_license(false);
if ($action_params['keep_license_key']) {
$tmp = array('error' => 'License is no longer valid for this site.', 'license_key' => $license['license_key']);
$this->update_license($tmp);
}
wp_send_json_success();
} // remote_action_deactivate_license
private function is_remote_action($action)
{
$actions = array('refresh', 'validate_license', 'deactivate_license');
$actions = apply_filters('wf_licensing_' . trim($this->prefix, '_') . '_remote_actions', $actions);
if (in_array($action, $actions)) {
return true;
} else {
return false;
}
} // is_remote_action
/**
* Log message if debugging is enabled.
* Log file: /wp-content/wf-licensing.log
*
* @param string $message Message to write to log.
* @param mixed $data Optional, extra data to write to debug log.
*
* @return void
*/
function log($message, ...$data)
{
if (!$this->debug) {
return;
}
$log_file = trailingslashit(WP_CONTENT_DIR) . 'wf-licensing.log';
$fp = fopen($log_file, 'a+');
fputs($fp, '[' . date('r') . '] ' . $this->prefix . ': ');
fputs($fp, (string) $message . PHP_EOL);
foreach ($data as $tmp) {
fputs($fp, print_r($tmp, true));
}
fputs($fp, PHP_EOL);
fclose($fp);
} // log
/**
* Fetches license details from the database.
*
* @param string $key If set returns only requested options key.
*
* @return string
*/
function get_license($key = '')
{
$default = array(
'license_key' => '',
'error' => '',
'valid_until' => '',
'last_check' => 0,
'name' => '',
'access_key' => '',
'meta' => array()
);
$options = get_option('wf_licensing_' . $this->prefix, array());
$options = array_merge($default, $options);
if (empty($options['access_key'])) {
$options['access_key'] = $this->generate_access_key();
$this->update_license($options);
}
if (!empty($key)) {
return $options[$key];
} else {
return $options;
}
} // get_license
function generate_access_key()
{
$keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$pieces = array();
$max = strlen($keyspace) - 1;
for ($i = 0; $i < 32; ++$i) {
$pieces[] = $keyspace[random_int(0, $max)];
}
return implode('', $pieces);
} // generate_access_key
function get_license_formatted($key = '')
{
$license = $this->get_license();
$out = array(
'name' => '',
'name_long' => '',
'valid_until' => '',
'expires' => '',
'license_key' => '',
'license_key_hidden' => '',
'recurring' => false,
'keyless' => false,
);
if (!$this->is_active()) {
return $out;
}
$license['valid_until'] = $license['valid_until'];
$out['name'] = $license['name'];
$out['name_long'] = $license['name'];
if ($license['meta']) {
$tmp = '';
foreach ($license['meta'] as $meta => $meta_value) {
if ($meta[0] == '_' || filter_var($meta_value, FILTER_VALIDATE_BOOLEAN) != true) {
continue;
}
$meta = str_replace('_', ' ', $meta);
$meta = ucwords($meta);
$tmp .= $meta . ', ';
}
$tmp = trim($tmp, ', ');
if ($tmp) {
$out['name_long'] .= ' with ' . $tmp;
}
}
if ($license['valid_until'] == $this->valid_forever) {
$out['valid_until'] = 'forever';
$out['recurring'] = false;
} else {
$out['valid_until'] = 'until ' . date(get_option('date_format'), strtotime($license['valid_until']));
$out['recurring'] = true;
}
if (date('Y-m-d') == $license['valid_until']) {
$out['expires'] = 'today';
} elseif (date('Y-m-d', time() + 30 * DAY_IN_SECONDS) > $license['valid_until']) {
$tmp = (strtotime($license['valid_until'] . date(' G:i:s')) - time()) / DAY_IN_SECONDS;
$out['expires'] = 'in ' . round($tmp) . ' days';
} else {
$out['expires'] = 'in more than 30 days';
}
if (empty($license['license_key']) || $license['license_key'] == 'keyless') {
$out['keyless'] = true;
} else {
$out['keyless'] = false;
$out['license_key'] = $license['license_key'];
$tmp = strlen($license['license_key']);
$dash = false;
$new = '';
for ($i = $tmp - 1; $i >= 0; $i--) {
if ($dash == false || $out['license_key'][$i] == '-') {
$new = $out['license_key'][$i] . $new;
} else {
$new = '*' . $new;
}
if ($out['license_key'][$i] == '-') {
$dash = true;
}
}
$out['license_key_hidden'] = $new;
}
$out = apply_filters('wf_licensing_license_formatted_' . $this->prefix, $out);
if (!empty($key)) {
return $out[$key];
} else {
return $out;
}
} // get_license_formatted
/**
* Updates license details in the database.
*
* @param string $data License data to save; or empty to delete license
*
* @return bool
*/
function update_license($data = false)
{
if (false === $data) {
$tmp = delete_option('wf_licensing_' . $this->prefix);
} else {
if (!isset($data['access_key'])) {
$data['access_key'] = $this->get_license('access_key');
}
$tmp = update_option('wf_licensing_' . $this->prefix, $data);
}
do_action('wf_licensing_' . $this->prefix . '_update_license', $data, false);
return $tmp;
} // update_license
/**
* Check if license is valid
*
* @param string $feature If set it checks for a specific feature.
* @param bool $force_check Forces license recheck on server instead of just cached values.
*
* @return boolean
*/
function is_active($feature = '', $force_check = false, $local_only = false)
{
$last_check = $this->get_license('last_check');
if ($local_only == false) {
if ($force_check || ($last_check && ($last_check + HOUR_IN_SECONDS * 8) < time())) {
$this->log('auto recheck license');
$this->validate();
}
}
$license = $this->get_license();
if (
!empty($license['license_key']) && !empty($license['name']) &&
!empty($license['valid_until']) && $license['valid_until'] >= date('Y-m-d')
) {
if (!empty($feature)) {
if (!empty($license['meta'][$feature]) && filter_var($license['meta'][$feature], FILTER_VALIDATE_BOOLEAN) == true) {
return true;
} else {
return false;
}
} else {
return true;
}
} else {
return false;
}
} // is_active
/**
* Hook to plugin activation action.
* If there's a license key, try to activate & write response.
*
* @return void
*/
function activate_plugin()
{
$license = $this->get_license();
if ($this->is_active() || !$license['license_key']) {
return false;
}
$tmp = $this->validate();
if ($tmp) {
$this->log('activating plugin, license activated');
return true;
} else {
$this->log('activating plugin, unable to activate license');
return false;
}
} // activate_plugin
/**
* Hook to plugin deactivation action.
* If there's a license key, try to deactivate & write response.
*
* @return void
*/
function deactivate_plugin()
{
if (!$this->is_active()) {
return false;
}
$license = $this->get_license();
$result = $this->query_licensing_server('deactivate_license');
if (is_wp_error($result) || !is_array($result) || !isset($result['success']) || $result['success'] == false) {
$this->log('unable to deactivate license');
return false;
} else {
$license['error'] = '';
$license['name'] = '';
$license['valid_until'] = '';
$license['meta'] = '';
$license['last_check'] = 0;
$this->update_license($license);
$this->log('license deactivated');
return true;
}
} // deactivate_plugin
/**
* Use when uninstalling (deleting) the plugin to clean up.
*
* @param string $prefix Same prefix as used when initialising the class.
* @return bool
*/
static function uninstall_plugin($prefix)
{
$tmp = delete_option('wf_licensing_' . $prefix);
return $tmp;
} // uninstall_plugin
/**
* Delete license locally and send deactivate ping to licensing server
*
* @return void
*/
function deactivate() {
$license = $this->get_license();
$result = $this->query_licensing_server('deactivate_license', array());
$this->update_license(false);
return $result;
} // deactivate
/**
* Validate license key on server and save response.
*
* @param string $license_key License key, or leave empty to pull from saved.
*
* @return void
*/
function validate($license_key = '')
{
$license = $this->get_license();
if (empty($license_key)) {
$license_key = $license['license_key'];
}
$out = array(
'license_key' => $license_key,
'error' => '',
'name' => '',
'last_check' => 0,
'valid_until' => '',
'meta' => array()
);
$result = $this->query_licensing_server('validate_license', array('license_key' => $license_key));
if (is_wp_error($result)) {
$out['error'] = 'Error querying licensing server. ' . $result->get_error_message() . ' Please try again in a few moments.';
//$this->update_license($out);
return false;
} elseif (!is_array($result) || !isset($result['success'])) {
$out['error'] = 'Invalid response from licensing server. Please try again in a few moments.';
$this->update_license($out);
return false;
} elseif ($result['success'] == false) {
$out['error'] = $result['data'];
$this->update_license($out);
return true;
} else {
$out['error'] = $result['data']['error'];
$out['name'] = $result['data']['name'];
$out['valid_until'] = $result['data']['valid_until'];
$out['meta'] = $result['data']['meta'];
$out['last_check'] = time();
$this->update_license($out);
return true;
}
} // validate
function validate_ajax()
{
check_ajax_referer('wf_licensing_' . $this->prefix);
$license_key = trim($_REQUEST['license_key']);
if(empty($license_key)){
$license = $this->get_license();
$license_key = $license['license_key'];
}
if (empty($license_key)) {
$this->update_license(false);
do_action('wf_licensing_' . $this->prefix . 'validate_ajax', $license_key, false);
wp_send_json_success();
} else {
$result = $this->validate($license_key);
$license = $this->get_license();
do_action('wf_licensing_' . $this->prefix . 'validate_ajax', $license_key, $result);
if ($result == true) {
wp_send_json_success($result);
} else {
wp_send_json_error($license);
}
}
} // validate_ajax
function deactivate_ajax()
{
check_ajax_referer('wf_licensing_' . $this->prefix);
$old_license = $this->get_license();
$result = $this->deactivate();
do_action('wf_licensing_' . $this->prefix . 'deactivate_ajax', $old_license, $result);
wp_send_json_success($result);
} // deactivate_ajax
function save_ajax()
{
check_ajax_referer('wf_licensing_' . $this->prefix);
$out['license_key'] = trim($_POST['license_key']);
if ($_POST['success'] == 'true') {
$out['error'] = trim($_POST['data']['error']);
$out['name'] = trim($_POST['data']['name']);
$out['valid_until'] = trim($_POST['data']['valid_until']);
$out['meta'] = $_POST['data']['meta'];
} else {
$out['error'] = trim($_POST['data']);
$out['name'] = '';
$out['valid_until'] = '';
$out['meta'] = array();
}
$out['last_check'] = time();
$this->update_license($out);
do_action('wf_licensing_' . $this->prefix . 'save_ajax', $out);
wp_send_json_success();
} // save_ajax
function prepare_server_query_data($action)
{
$license = $this->get_license();
$query_data = array(
'action' => $action,
'license_key' => $license['license_key'],
'rand' => rand(1000, 9999),
'version' => $this->version,
'wp_version' => get_bloginfo('version'),
'site_url' => get_home_url(),
'site_title' => get_bloginfo('name'),
'access_key' => $license['access_key'],
'meta' => apply_filters('wf_licensing_' . trim($this->prefix, '_') . '_query_server_meta', array(), $action)
);
if (substr($action, 0, 7) == 'remote_') {
unset($query_data['action'], $query_data['license_key']);
}
return $query_data;
} // prepare_server_query_data
/**
* Run license server query.
*
* @param string $action
* @param array $data
*
* @return string response|bool
*/
function query_licensing_server($action, $data = array())
{
$request_params = array('sslverify' => false, 'timeout' => 25, 'redirection' => 2);
$default_data = $this->prepare_server_query_data($action);
$request_data = array_merge($default_data, $data, array('action' => $action));
$request_data = apply_filters('wf_licensing_' . trim($this->prefix, '_') . '_query_server_data', $request_data, $action);
array_walk_recursive($request_data, function (&$val, $ind) {
$val = rawurlencode($val);
});
$this->log('query licensing server', $request_data);
$url = rtrim(add_query_arg($request_data, trailingslashit($this->licensing_servers[0] . $this->api_ver)), '&');
$response = wp_remote_get($url, $request_params);
$body = wp_remote_retrieve_body($response);
$result = @json_decode($body, true);
$this->log('licensing server response', $response);
if (is_wp_error($response) || empty($body) || !is_array($result) || !isset($result['success'])) {
if (is_wp_error($response)) {
return $response;
} else {
return new WP_Error(1, 'Invalid server response format.');
}
} else {
return $result;
}
} // query_licensing_server
/**
* Plugin info lightbox
*
* @param object $return
* @param string $action
* @param object $args
*
* @return object
*/
function update_details($return, $action, $args)
{
if (!$this->is_active()) {
return $return;
}
static $response = false;
if ($action != 'plugin_information' || empty($args->slug) || $args->slug != $this->slug) {
return $return;
}
if (empty($response) || is_wp_error($response)) {
$response = $this->query_licensing_server('plugin_information', array('request_details' => serialize($args)));
}
if (is_wp_error($response)) {
$res = new WP_Error('plugins_api_failed', 'An unexpected HTTP error occurred during the API request.', $response->get_error_message());
} elseif ($response['success'] != true) {
$res = new WP_Error('plugins_api_failed', 'Invalid response data received during the API request.', $response['data']);
} else {
$res = (object) $response['data'];
$res->sections = (array) $res->sections;
$res->banners = (array) $res->banners;
$res->icons = (array) $res->icons;
}
return $res;
} // update_details
/**
* Get info on new plugin version if one exists
*
* @param object current plugin info
*
* @return object update info
*/
function update_filter($current)
{
if (!$this->is_active()) {
return $current;
}
static $response = false;
$response = get_transient('wf_plugin_update_' . $this->prefix);
if (empty($response)) {
$response = $this->query_licensing_server('update_info');
set_transient('wf_plugin_update_' . $this->prefix, $response, 120);
}
if (!is_wp_error($response) && $response['success'] == true) {
$data = (object)$response['data'];
if (empty($current)) {
$current = new stdClass();
}
if (empty($current->response)) {
$current->response = array();
}
if (!empty($data) && is_object($data) && version_compare($data->new_version, $this->version) === 1) {
$data->icons = (array) $data->icons;
$data->banners = (array) $data->banners;
$current->response[$this->basename] = $data;
}
}
return $current;
} // update_filter
} // WF_Licensing_WPCaptcha
} // if WF_Licensing_WPCaptcha