Your IP : 216.73.216.162


Current Path : /home/x/b/o/xbodynamge/namtation/wp-content/
Upload File :
Current File : /home/x/b/o/xbodynamge/namtation/wp-content/wordpress-sdk.tar

app/WordPressSDK.php000066600000017636151143705220010350 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK;

use YoastSEO_Vendor\WordProof\SDK\Config\DefaultAppConfig;
use YoastSEO_Vendor\WordProof\SDK\Config\AppConfigInterface;
use YoastSEO_Vendor\WordProof\SDK\Controllers\NoticeController;
use YoastSEO_Vendor\WordProof\SDK\Controllers\PostEditorDataController;
use YoastSEO_Vendor\WordProof\SDK\Controllers\PostEditorTimestampController;
use YoastSEO_Vendor\WordProof\SDK\Controllers\RestApiController;
use YoastSEO_Vendor\WordProof\SDK\Controllers\AuthenticationController;
use YoastSEO_Vendor\WordProof\SDK\Controllers\CertificateController;
use YoastSEO_Vendor\WordProof\SDK\Controllers\SettingsController;
use YoastSEO_Vendor\WordProof\SDK\Controllers\TimestampController;
use YoastSEO_Vendor\WordProof\SDK\Support\Loader;
use YoastSEO_Vendor\WordProof\SDK\Translations\DefaultTranslations;
use YoastSEO_Vendor\WordProof\SDK\Translations\TranslationsInterface;
class WordPressSDK
{
    /**
     * The version of this SDK
     * @var string
     */
    public $version = '1.3.2';
    /**
     * @var null|WordPressSDK
     */
    private static $instance = null;
    /**
     * Loader responsible for the WordPress hooks
     * @var Loader
     */
    private $loader;
    /**
     * Appconfig object
     * @var AppConfigInterface
     */
    public $appConfig;
    /**
     * Translations object
     * @var TranslationsInterface
     */
    private $translations;
    /**
     * WordPressSDK constructor.
     *
     * @return WordPressSDK|void
     *
     * @throws \Exception
     */
    public function __construct(\YoastSEO_Vendor\WordProof\SDK\Config\AppConfigInterface $appConfig = null, \YoastSEO_Vendor\WordProof\SDK\Translations\TranslationsInterface $translations = null)
    {
        if (\defined('WORDPROOF_TIMESTAMP_SDK_VERSION')) {
            return;
        }
        $this->loader = new \YoastSEO_Vendor\WordProof\SDK\Support\Loader();
        $this->appConfig = $appConfig ?: new \YoastSEO_Vendor\WordProof\SDK\Config\DefaultAppConfig();
        $this->translations = $translations ?: new \YoastSEO_Vendor\WordProof\SDK\Translations\DefaultTranslations();
        $this->authentication();
        $this->api();
        $this->timestamp();
        $this->settings();
        $this->postEditorData();
        $this->notices();
        if (!\defined('WORDPROOF_TIMESTAMP_SDK_FILE')) {
            \define('WORDPROOF_TIMESTAMP_SDK_FILE', __FILE__);
        }
        if (!\defined('WORDPROOF_TIMESTAMP_SDK_VERSION')) {
            \define('WORDPROOF_TIMESTAMP_SDK_VERSION', $this->version);
        }
        return $this;
    }
    /**
     * Singleton implementation of WordPress SDK.
     *
     * @param AppConfigInterface|null $appConfig
     * @param TranslationsInterface|null $translations
     * @return WordPressSDK|null Returns the WordPress SDK instance.
     * @throws \Exception
     */
    public static function getInstance(\YoastSEO_Vendor\WordProof\SDK\Config\AppConfigInterface $appConfig = null, \YoastSEO_Vendor\WordProof\SDK\Translations\TranslationsInterface $translations = null)
    {
        if (self::$instance === null) {
            self::$instance = new \YoastSEO_Vendor\WordProof\SDK\WordPressSDK($appConfig, $translations);
        }
        return self::$instance;
    }
    /**
     * Runs the loader and initializes the class.
     *
     * @return $this
     */
    public function initialize()
    {
        $this->loader->run();
        return $this;
    }
    /**
     * Initializes the authentication feature.
     */
    private function authentication()
    {
        $class = new \YoastSEO_Vendor\WordProof\SDK\Controllers\AuthenticationController();
        $this->loader->addAction('wordproof_authenticate', $class, 'authenticate');
        $this->loader->addAction('admin_menu', $class, 'addRedirectPage');
        $this->loader->addAction('admin_menu', $class, 'addSelfDestructPage');
        $this->loader->addAction('load-admin_page_wordproof-redirect-authenticate', $class, 'redirectOnLoad');
    }
    /**
     * Initializes the api feature.
     */
    private function api()
    {
        $class = new \YoastSEO_Vendor\WordProof\SDK\Controllers\RestApiController();
        $this->loader->addAction('rest_api_init', $class, 'init');
    }
    /**
     * Adds hooks to timestamp posts on new inserts or on a custom action.
     */
    private function timestamp()
    {
        $class = new \YoastSEO_Vendor\WordProof\SDK\Controllers\TimestampController();
        $this->loader->addAction('added_post_meta', $class, 'syncPostMetaTimestampOverrides', \PHP_INT_MAX, 4);
        $this->loader->addAction('updated_post_meta', $class, 'syncPostMetaTimestampOverrides', \PHP_INT_MAX, 4);
        $this->loader->addAction('rest_after_insert_post', $class, 'timestampAfterRestApiRequest');
        $this->loader->addAction('wp_insert_post', $class, 'timestampAfterPostRequest', \PHP_INT_MAX, 2);
        $this->loader->addAction('edit_attachment', $class, 'timestampAfterAttachmentRequest', \PHP_INT_MAX);
        $this->loader->addAction('add_attachment', $class, 'timestampAfterAttachmentRequest', \PHP_INT_MAX);
        $this->loader->addAction('wordproof_timestamp', $class, 'timestamp');
        $this->loader->addAction('elementor/document/before_save', $class, 'beforeElementorSave');
    }
    /**
     * Adds admin pages that redirect to the WordProof My settings page.
     */
    private function settings()
    {
        $class = new \YoastSEO_Vendor\WordProof\SDK\Controllers\SettingsController();
        $this->loader->addAction('wordproof_settings', $class, 'redirect');
        $this->loader->addAction('admin_menu', $class, 'addRedirectPage');
        $this->loader->addAction('load-admin_page_wordproof-redirect-settings', $class, 'redirectOnLoad');
    }
    /**
     * Registers and localizes post editor scripts.
     */
    private function postEditorData()
    {
        $class = new \YoastSEO_Vendor\WordProof\SDK\Controllers\PostEditorDataController($this->translations);
        $this->loader->addAction('admin_enqueue_scripts', $class, 'addScript');
        $this->loader->addAction('elementor/editor/before_enqueue_scripts', $class, 'addScriptForElementor');
    }
    /**
     * Initializes the notices feature.
     */
    private function notices()
    {
        $class = new \YoastSEO_Vendor\WordProof\SDK\Controllers\NoticeController($this->translations);
        $this->loader->addAction('admin_notices', $class, 'show');
    }
    /**
     * Optional feature to include the schema and certificate to the page.
     *
     * @return $this
     */
    public function certificate()
    {
        $class = new \YoastSEO_Vendor\WordProof\SDK\Controllers\CertificateController();
        $this->loader->addAction('wp_head', $class, 'head');
        $this->loader->addFilter('the_content', $class, 'certificateTag');
        return $this;
    }
    /**
     * Optional feature to timestamp with JS in the post editor.
     *
     * @return $this
     */
    public function timestampInPostEditor()
    {
        $class = new \YoastSEO_Vendor\WordProof\SDK\Controllers\PostEditorTimestampController();
        // Gutenberg
        $this->loader->addAction('init', $class, 'registerPostMeta', \PHP_INT_MAX);
        $this->loader->addAction('enqueue_block_editor_assets', $class, 'enqueueBlockEditorScript');
        // Classic editor
        $this->loader->addAction('add_meta_boxes', $class, 'addMetaboxToClassicEditor');
        $this->loader->addAction('save_post', $class, 'saveClassicMetaboxPostMeta');
        $this->loader->addAction('edit_attachment', $class, 'saveClassicMetaboxPostMeta');
        $this->loader->addAction('admin_enqueue_scripts', $class, 'enqueueClassicEditorScript');
        // Elementor
        $this->loader->addAction('elementor/editor/after_enqueue_scripts', $class, 'enqueueElementorEditorScript');
        $this->loader->addAction('elementor/documents/register_controls', $class, 'registerControl');
        $this->loader->addAction('elementor/editor/after_save', $class, 'elementorSave');
        return $this;
    }
}
app/Translations/.htaccess000066600000000424151143705220011607 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>app/Translations/TranslationsInterface.php000066600000000760151143705220015027 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Translations;

interface TranslationsInterface
{
    public function getNoBalanceNotice();
    public function getTimestampSuccessNotice();
    public function getTimestampFailedNotice();
    public function getWebhookFailedNotice();
    public function getNotAuthenticatedNotice();
    public function getOpenSettingsButtonText();
    public function getOpenAuthenticationButtonText();
    public function getContactWordProofSupportButtonText();
}
app/Translations/DefaultTranslations.php000066600000003721151143705220014513 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Translations;

class DefaultTranslations implements \YoastSEO_Vendor\WordProof\SDK\Translations\TranslationsInterface
{
    public function getNoBalanceNotice()
    {
        return \sprintf(
            /* translators: %s expands to WordProof. */
            __('You are out of timestamps. Please upgrade your account by opening the %s settings.', 'wordproof'),
            'WordProof'
        );
    }
    public function getTimestampFailedNotice()
    {
        return \sprintf(
            /* translators: %s expands to WordProof. */
            __('%1$s failed to timestamp this page. Please check if you\'re correctly authenticated with %1$s and try to save this page again.', 'wordproof'),
            'WordProof'
        );
    }
    public function getTimestampSuccessNotice()
    {
        return \sprintf(
            /* translators: %s expands to WordProof. */
            __('%s has successfully timestamped this page.', 'wordproof'),
            'WordProof'
        );
    }
    public function getWebhookFailedNotice()
    {
        /* translators: %s expands to WordProof. */
        return \sprintf(__('The timestamp is not retrieved by your site. Please try again or contact %1$s support.', 'wordproof'), 'WordProof');
    }
    public function getNotAuthenticatedNotice()
    {
        /* translators: %s expands to WordProof. */
        return \sprintf(__('The timestamp is not created because you need to authenticate with %s first.', 'wordproof'), 'WordProof');
    }
    public function getOpenAuthenticationButtonText()
    {
        return __('Authenticate', 'wordproof');
    }
    public function getOpenSettingsButtonText()
    {
        return __('Open settings', 'wordproof');
    }
    public function getContactWordProofSupportButtonText()
    {
        return \sprintf(
            /* translators: %s expands to WordProof. */
            __('Contact %s support.', 'wordproof'),
            'WordProof'
        );
    }
}
app/DataTransferObjects/TimestampData.php000066600000001354151143705220014471 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\DataTransferObjects;

class TimestampData
{
    /**
     * Get timestamp data from post object.
     *
     * @param \WP_Post $post
     * @return array
     */
    public static function fromPost($post)
    {
        if ($post->post_type === 'attachment') {
            $file = \get_attached_file($post->ID);
            $content = '';
            if ($file) {
                $content = \hash_file('sha256', $file);
            }
        } else {
            $content = $post->post_content;
        }
        return ['uid' => $post->ID, 'date_modified' => \get_post_modified_time('c', \false, $post->ID), 'title' => $post->post_title, 'url' => \get_permalink($post), 'content' => $content];
    }
}
app/DataTransferObjects/.htaccess000066600000000424151143705220013016 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>app/Config/Config.php000066600000001670151143705220010457 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Config;

abstract class Config
{
    /**
     * Try to return config values using the dot syntax.
     *
     * @param string|null $key The key of the config using the dot syntax.
     * @return array|mixed Returns the entire config array if not found, otherwise the value itself.
     */
    public static function get($key = null)
    {
        if (!isset($key)) {
            return static::values();
        }
        $keys = \explode('.', $key);
        $value = static::values();
        foreach ($keys as $key) {
            if (isset($value[$key])) {
                $value = $value[$key];
            } else {
                return \false;
            }
        }
        return $value;
    }
    /**
     * Should return an array with the config.
     *
     * @return array An array containing the config values.
     */
    protected static function values()
    {
        return [];
    }
}
app/Config/RoutesConfig.php000066600000002012151143705220011650 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Config;

class RoutesConfig extends \YoastSEO_Vendor\WordProof\SDK\Config\Config
{
    /**
     * Returns an array with the environment config.
     *
     * @return array
     */
    protected static function values()
    {
        return ['hashInput' => ['endpoint' => '/posts/(?P<id>\\d+)/hashinput/(?P<hash>[a-fA-F0-9]{64})', 'method' => 'get'], 'authenticate' => ['endpoint' => '/oauth/authenticate', 'method' => 'post'], 'timestamp' => ['endpoint' => '/posts/(?P<id>\\d+)/timestamp', 'method' => 'post'], 'timestamp.transaction.latest' => ['endpoint' => '/posts/(?P<id>\\d+)/timestamp/transaction/latest', 'method' => 'get'], 'webhook' => ['endpoint' => '/webhook', 'method' => 'get'], 'settings' => ['endpoint' => '/settings', 'method' => 'get'], 'saveSettings' => ['endpoint' => '/settings', 'method' => 'POST'], 'authentication' => ['endpoint' => '/authentication', 'method' => 'post'], 'authentication.destroy' => ['endpoint' => '/oauth/destroy', 'method' => 'post']];
    }
}
app/Config/.htaccess000066600000000424151143705220010333 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>app/Config/OptionsConfig.php000066600000001537151143705220012035 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Config;

class OptionsConfig extends \YoastSEO_Vendor\WordProof\SDK\Config\Config
{
    /**
     * Returns an array with the settings config.
     *
     * @return array
     */
    protected static function values()
    {
        return ['source_id' => ['escape' => 'integer', 'default' => null], 'access_token' => ['escape' => 'text_field', 'default' => null], 'balance' => ['escape' => 'integer', 'default' => 0], 'settings' => ['cast' => 'object', 'options' => ['certificate_link_text' => ['escape' => 'text_field', 'default' => __('View this content\'s Timestamp certificate', 'wordproof')], 'hide_certificate_link' => ['escape' => 'boolean', 'default' => \false], 'selected_post_types' => ['escape' => 'text_field', 'default' => []], 'show_revisions' => ['escape' => 'boolean', 'default' => \true]]]];
    }
}
app/Config/DefaultAppConfig.php000066600000001465151143705220012427 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Config;

class DefaultAppConfig implements \YoastSEO_Vendor\WordProof\SDK\Config\AppConfigInterface
{
    /**
     * @return string
     */
    public function getPartner()
    {
        return 'wordproof';
    }
    /**
     * @return string
     */
    public function getEnvironment()
    {
        return 'production';
    }
    /**
     * @return boolean
     */
    public function getLoadUikitFromCdn()
    {
        return \true;
    }
    /**
     * @return null
     */
    public function getOauthClient()
    {
        return null;
    }
    /**
     * @return null
     */
    public function getWordProofUrl()
    {
        return null;
    }
    /**
     * @return null
     */
    public function getScriptsFileOverwrite()
    {
        return null;
    }
}
app/Config/ScriptsConfig.php000066600000001651151143705220012026 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Config;

class ScriptsConfig extends \YoastSEO_Vendor\WordProof\SDK\Config\Config
{
    /**
     * Returns an array with the environment config.
     *
     * @return array
     */
    protected static function values()
    {
        return ['data' => ['dependencies' => ['wp-data', 'lodash', 'wp-api-fetch'], 'type' => 'js'], 'wordproof-block-editor' => ['dependencies' => ['wp-i18n', 'wp-element', 'wp-components', 'wp-editor', 'wp-edit-post', 'wp-data', 'lodash', 'wordproof-data'], 'type' => 'js'], 'wordproof-elementor-editor' => ['dependencies' => ['wp-i18n', 'wp-element', 'wp-components', 'wp-editor', 'wp-edit-post', 'wp-data', 'lodash', 'wordproof-data', 'elementor-common'], 'type' => 'js'], 'wordproof-classic-editor' => ['dependencies' => ['wp-i18n', 'wp-element', 'wp-components', 'wp-editor', 'wp-edit-post', 'wp-data', 'lodash', 'wordproof-data'], 'type' => 'js']];
    }
}
app/Config/AppConfigInterface.php000066600000001676151143705220012747 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Config;

interface AppConfigInterface
{
    /**
     * Your partner name.
     *
     * @default wordproof
     * @return string
     */
    public function getPartner();
    /**
     * The WordProof environment used. Either staging or production.
     *
     * @default production
     * @return string
     */
    public function getEnvironment();
    /**
     * The WordProof environment used. Either staging or production.
     *
     * @default true
     * @return boolean
     */
    public function getLoadUikitFromCdn();
    /**
     * Only used for local development.
     *
     * @return integer
     */
    public function getOauthClient();
    /**
     * Only used for local development.
     *
     * @return string
     */
    public function getWordProofUrl();
    /**
     * Only used for local development.
     *
     * @return string
     */
    public function getScriptsFileOverwrite();
}
app/Config/EnvironmentConfig.php000066600000000676151143705220012711 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Config;

class EnvironmentConfig extends \YoastSEO_Vendor\WordProof\SDK\Config\Config
{
    /**
     * Returns an array with the environment config.
     *
     * @return array
     */
    protected static function values()
    {
        return ['staging' => ['url' => 'https://staging.wordproof.com', 'client' => 78], 'production' => ['url' => 'https://my.wordproof.com', 'client' => 79]];
    }
}
app/Controllers/AuthenticationController.php000066600000003066151143705220015377 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Controllers;

use YoastSEO_Vendor\WordProof\SDK\Support\Authentication;
class AuthenticationController
{
    /**
     * Triggers the authentication flow.
     *
     * @param null $redirectUrl
     */
    public function authenticate($redirectUrl = null)
    {
        return \YoastSEO_Vendor\WordProof\SDK\Support\Authentication::authorize($redirectUrl);
    }
    /**
     * Adds admin page that redirects to the authentication flow.
     */
    public function addRedirectPage()
    {
        \add_submenu_page(null, 'WordProof Authenticate', 'WordProof Authenticate', 'publish_pages', 'wordproof-redirect-authenticate', [$this, 'redirectPageContent']);
    }
    /**
     * The content for the redirect page.
     */
    public function redirectPageContent()
    {
    }
    /**
     * Gets triggered by the 'load-admin_page_' hook of the redirect page
     */
    public function redirectOnLoad()
    {
        \do_action('wordproof_authenticate', \admin_url('admin.php?page=wordproof-close-after-redirect'));
    }
    /**
     * Adds self destruct admin page.
     */
    public function addSelfDestructPage()
    {
        \add_submenu_page(null, 'WordProof After Authenticate', 'WordProof After Authenticate', 'publish_pages', 'wordproof-close-after-redirect', [$this, 'closeOnLoadContent']);
    }
    /**
     * Adds a script to the loaded page to close on load.
     */
    public function closeOnLoadContent()
    {
        echo '<script type="text/javascript">';
        echo 'window.close();';
        echo '</script>';
    }
}
app/Controllers/.htaccess000066600000000424151143705220011434 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>app/Controllers/SettingsController.php000066600000002521151143705220014213 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Controllers;

use YoastSEO_Vendor\WordProof\SDK\Support\Settings;
class SettingsController
{
    /**
     * Redirects user to the settings page. Returns false if not authenticated.
     *
     * @param null|string $redirectUrl
     * @return false
     */
    public function redirect($redirectUrl = null)
    {
        return \YoastSEO_Vendor\WordProof\SDK\Support\Settings::redirect($redirectUrl);
    }
    /**
     * Adds admin page that will redirect the user to a predefined url.
     *
     * @action admin_menu
     */
    public function addRedirectPage()
    {
        \add_submenu_page(null, 'WordProof Settings', 'WordProof Settings', 'publish_pages', 'wordproof-redirect-settings', [$this, 'redirectPageContent']);
    }
    /**
     * The content for the redirect page. Triggered by addRedirectPage().
     */
    public function redirectPageContent()
    {
        return;
    }
    /**
     * Redirects user on admin page load to the settings page on the WordProof My.
     *
     * @action load-admin_page_settings
     */
    public function redirectOnLoad()
    {
        $closeWindowUrl = \admin_url('admin.php?page=wordproof-close-after-redirect');
        if ($this->redirect($closeWindowUrl) === \false) {
            \do_action('wordproof_authenticate', $closeWindowUrl);
        }
    }
}
app/Controllers/PostEditorTimestampController.php000066600000014037151143705220016400 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Controllers;

use YoastSEO_Vendor\WordProof\SDK\Helpers\AssetHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\PostEditorHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\PostTypeHelper;
class PostEditorTimestampController
{
    private $metaKey = '_wordproof_timestamp';
    private $classicEditorNonceKey = 'wordproof_timestamp_classic_nonce';
    /**
     * Registers post meta for all public post types.
     *
     * @action init
     */
    public function registerPostMeta()
    {
        foreach (\YoastSEO_Vendor\WordProof\SDK\Helpers\PostTypeHelper::getPublicPostTypes() as $postType) {
            register_post_meta($postType, $this->metaKey, ['show_in_rest' => \true, 'single' => \true, 'type' => 'boolean', 'default' => \false, 'supports' => ['editor', 'title', 'custom-fields'], 'auth_callback' => [$this, 'userCanEditPosts']]);
        }
    }
    /**
     * Returns if the current user can edit posts.
     *
     * @return boolean
     */
    public function userCanEditPosts()
    {
        return \current_user_can('edit_posts');
    }
    /**
     * Enqueues the wordproof-block-editor script.
     *
     * @action enqueue_block_editor_assets
     * @script wordproof-block-editor
     */
    public function enqueueBlockEditorScript()
    {
        \YoastSEO_Vendor\WordProof\SDK\Helpers\AssetHelper::enqueue('wordproof-block-editor');
    }
    /**
     * Enqueues the wordproof-elementor-editor script.
     *
     * @action elementor/editor/after_enqueue_scripts
     * @script wordproof-elementor-editor
     */
    public function enqueueElementorEditorScript()
    {
        \YoastSEO_Vendor\WordProof\SDK\Helpers\AssetHelper::enqueue('wordproof-elementor-editor');
    }
    /**
     * Enqueues the wordproof-classic-editor script.
     *
     * @action admin_enqueue_scripts
     * @script wordproof-classic-editor
     */
    public function enqueueClassicEditorScript($hook)
    {
        if (!\YoastSEO_Vendor\WordProof\SDK\Helpers\PostEditorHelper::isPostEdit($hook)) {
            return;
        }
        if (\YoastSEO_Vendor\WordProof\SDK\Helpers\PostEditorHelper::getPostEditor() === 'classic') {
            \YoastSEO_Vendor\WordProof\SDK\Helpers\AssetHelper::enqueue('wordproof-classic-editor');
        }
    }
    /**
     * Add Metabox to classic editor.
     *
     * @action add_meta_boxes
     */
    public function addMetaboxToClassicEditor()
    {
        foreach (\YoastSEO_Vendor\WordProof\SDK\Helpers\PostTypeHelper::getPublicPostTypes() as $postType) {
            \add_meta_box('wordproof_timestamp_metabox', 'WordProof Timestamp', [$this, 'classicMetaboxHtml'], $postType, 'side', 'default', ['__back_compat_meta_box' => \true]);
        }
    }
    /**
     * Save the meta box meta value for the classic editor.
     *
     * @param integer $postId The post ID.
     * @action save_post
     */
    public function saveClassicMetaboxPostMeta($postId)
    {
        if (\array_key_exists($this->classicEditorNonceKey, $_POST)) {
            if (\wp_verify_nonce(\sanitize_key($_POST[$this->classicEditorNonceKey]), 'save_post')) {
                \update_post_meta($postId, $this->metaKey, \array_key_exists($this->metaKey, $_POST));
            }
        }
    }
    /**
     * Display the meta box HTML to Classic Editor users.
     *
     * @param \WP_Post $post Post object.
     */
    public function classicMetaboxHtml($post)
    {
        $value = \YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::get($post->ID, $this->metaKey);
        \wp_nonce_field('save_post', $this->classicEditorNonceKey);
        ?>
    
        <div id="wordproof-toggle">
            <input type="checkbox" id="<?php 
        echo \esc_attr($this->metaKey);
        ?>" name="<?php 
        echo \esc_attr($this->metaKey);
        ?>"
                   value="1" <?php 
        echo \boolval($value) ? 'checked' : '';
        ?>>
            <label for="<?php 
        echo \esc_attr($this->metaKey);
        ?>">Timestamp this post</label>
            <div id="wordproof-action-link"></div>
        </div>
        <?php 
    }
    /**
     * Registers control for the Elementor editor.
     *
     * @param \Elementor\Core\DocumentTypes\PageBase $document The PageBase document instance.
     *
     * @action elementor/documents/register_controls
     */
    public function registerControl($document)
    {
        if (!$document instanceof \Elementor\Core\DocumentTypes\PageBase || !$document::get_property('has_elements')) {
            return;
        }
        // Add Metabox
        $document->start_controls_section('wordproof_timestamp_section', ['label' => \esc_html__('WordProof Timestamp', 'wordproof'), 'tab' => \Elementor\Controls_Manager::TAB_SETTINGS]);
        // Get meta value
        $postId = $document->get_id();
        $metaValue = \YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::get($postId, $this->metaKey, \true);
        // Override elementor value
        $pageSettingsManager = \Elementor\Core\Settings\Manager::get_settings_managers('page');
        $pageSettingsModel = $pageSettingsManager->get_model($postId);
        $pageSettingsModel->set_settings($this->metaKey, \boolval($metaValue) ? 'yes' : '');
        // Add Switcher
        $document->add_control($this->metaKey, ['label' => \esc_html__('Timestamp this post', 'wordproof'), 'type' => \Elementor\Controls_Manager::SWITCHER, 'default' => 'no']);
        $document->end_controls_section();
    }
    /**
     * @param integer $postId
     * @action elementor/document/save/data
     */
    public function elementorSave($postId)
    {
        if (\get_post_type($postId) !== 'page') {
            return;
        }
        $pageSettingsManager = \Elementor\Core\Settings\Manager::get_settings_managers('page');
        $pageSettingsModel = $pageSettingsManager->get_model($postId);
        $value = $pageSettingsModel->get_settings($this->metaKey);
        // Update meta key with Elementor value.
        \YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::update($postId, $this->metaKey, $value === 'yes');
    }
}
app/Controllers/RestApiController.php000066600000024741151143705220013772 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Controllers;

use YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\SchemaHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\SettingsHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\AuthenticationHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\StringHelper;
use YoastSEO_Vendor\WordProof\SDK\Support\Authentication;
class RestApiController
{
    /**
     * Registers the rest api endpoints.
     *
     * @action rest_api_init
     * @throws \Exception
     */
    public function init()
    {
        \register_rest_route(\YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::getNamespace(), \YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::endpoint('authenticate'), ['methods' => 'POST', 'callback' => [$this, 'authenticate'], 'permission_callback' => [$this, 'canPublishPermission']]);
        \register_rest_route(\YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::getNamespace(), \YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::endpoint('webhook'), ['methods' => 'POST', 'callback' => [$this, 'webhook'], 'permission_callback' => [$this, 'isValidWebhookRequest']]);
        \register_rest_route(\YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::getNamespace(), \YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::endpoint('hashInput'), ['methods' => 'GET', 'callback' => [$this, 'hashInput'], 'permission_callback' => function () {
            return \true;
        }]);
        \register_rest_route(\YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::getNamespace(), \YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::endpoint('timestamp'), ['methods' => 'POST', 'callback' => [$this, 'timestamp'], 'permission_callback' => [$this, 'canPublishPermission']]);
        \register_rest_route(\YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::getNamespace(), \YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::endpoint('timestamp.transaction.latest'), ['methods' => 'GET', 'callback' => [$this, 'showLatestTimestampTransaction'], 'permission_callback' => [$this, 'canPublishPermission']]);
        \register_rest_route(\YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::getNamespace(), \YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::endpoint('settings'), ['methods' => 'GET', 'callback' => [$this, 'settings'], 'permission_callback' => [$this, 'canPublishPermission']]);
        \register_rest_route(\YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::getNamespace(), \YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::endpoint('saveSettings'), ['methods' => 'POST', 'callback' => [$this, 'saveSettings'], 'permission_callback' => [$this, 'canPublishPermission']]);
        \register_rest_route(\YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::getNamespace(), \YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::endpoint('authentication'), ['methods' => 'GET', 'callback' => [$this, 'authentication'], 'permission_callback' => [$this, 'canPublishPermission']]);
        \register_rest_route(\YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::getNamespace(), \YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::endpoint('authentication.destroy'), ['methods' => 'POST', 'callback' => [$this, 'destroyAuthentication'], 'permission_callback' => [$this, 'canPublishPermission']]);
    }
    /**
     * Returns an object containing the settings.
     *
     * @return \WP_REST_Response Returns the settings.
     */
    public function settings()
    {
        $data = \YoastSEO_Vendor\WordProof\SDK\Helpers\SettingsHelper::get();
        $data->status = 200;
        return new \WP_REST_Response($data, $data->status);
    }
    /**
     * Save the settings.
     *
     * @return \WP_REST_Response Returns the settings.
     */
    public function saveSettings(\WP_REST_Request $request)
    {
        $data = $request->get_params();
        $settings = $data['settings'];
        $snakeCaseSettings = [];
        foreach ($settings as $key => $value) {
            $key = \YoastSEO_Vendor\WordProof\SDK\Helpers\StringHelper::toUnderscore($key);
            $snakeCaseSettings[$key] = $value;
        }
        \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::set('settings', $snakeCaseSettings);
        $data = (object) [];
        $data->status = 200;
        return new \WP_REST_Response($data, $data->status);
    }
    /**
     * Returns if the user is authenticated.
     *
     * @return \WP_REST_Response Returns if the user is authenticated.
     */
    public function authentication()
    {
        $data = (object) ['is_authenticated' => \YoastSEO_Vendor\WordProof\SDK\Helpers\AuthenticationHelper::isAuthenticated(), 'status' => 200];
        return new \WP_REST_Response($data, $data->status);
    }
    /**
     * Logout the user and return if the user is authenticated.
     *
     * @return \WP_REST_Response Returns if the user is authenticated.
     */
    public function destroyAuthentication()
    {
        \YoastSEO_Vendor\WordProof\SDK\Helpers\AuthenticationHelper::logout();
        return $this->authentication();
    }
    /**
     * Send a post request to WordProof to timestamp a post.
     *
     * @param \WP_REST_Request $request The Rest Request.
     * @return \WP_REST_Response
     */
    public function timestamp(\WP_REST_Request $request)
    {
        $data = $request->get_params();
        $postId = \intval($data['id']);
        return \YoastSEO_Vendor\WordProof\SDK\Controllers\TimestampController::timestamp($postId);
    }
    /**
     * The latest timestamp transaction is returned.
     *
     * @param \WP_REST_Request $request
     * @return \WP_REST_Response
     */
    public function showLatestTimestampTransaction(\WP_REST_Request $request)
    {
        $data = $request->get_params();
        $postId = \intval($data['id']);
        $transactions = \YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::get($postId, '_wordproof_blockchain_transaction', \false);
        $transaction = \array_pop($transactions);
        $response = new \WP_REST_Response((object) $transaction);
        $response->header('X-Robots-Tag', 'noindex');
        return $response;
    }
    /**
     * Returns the hash input of a post.
     *
     * @param \WP_REST_Request $request The Rest Request.
     * @return \WP_REST_Response The hash input of a post.
     */
    public function hashInput(\WP_REST_Request $request)
    {
        $data = $request->get_params();
        $postId = \intval($data['id']);
        $hash = \sanitize_text_field($data['hash']);
        $hashInput = \YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::get($postId, '_wordproof_hash_input_' . $hash);
        $response = new \WP_REST_Response((object) $hashInput);
        $response->header('X-Robots-Tag', 'noindex');
        return $response;
    }
    /**
     * Retrieves the access token when the code and state are retrieved in the frontend.
     *
     * @throws \Exception
     */
    public function authenticate(\WP_REST_Request $request)
    {
        $state = \sanitize_text_field($request->get_param('state'));
        $code = \sanitize_text_field($request->get_param('code'));
        return \YoastSEO_Vendor\WordProof\SDK\Support\Authentication::token($state, $code);
    }
    /**
     * Handles webhooks sent by WordProof.
     *
     * @param \WP_REST_Request $request The Rest Request.
     * @return bool|null|\WP_REST_Response|void The value returned by the action undertaken.
     *
     * TODO: Improve
     */
    public function webhook(\WP_REST_Request $request)
    {
        $response = \json_decode($request->get_body());
        /**
         * Handle webhooks with type and data
         */
        if (isset($response->type) && isset($response->data)) {
            switch ($response->type) {
                case 'source_settings':
                    return \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::set('settings', $response->data);
                case 'ping':
                    $data = (object) ['status' => 200, 'source_id' => \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::sourceId()];
                    return new \WP_REST_Response($data, $data->status);
                case 'logout':
                    \YoastSEO_Vendor\WordProof\SDK\Helpers\AuthenticationHelper::logout();
                    break;
                case 'dump_item':
                    $key = '_wordproof_hash_input_' . $response->data->hash;
                    \YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::update($response->data->uid, $key, \json_decode($response->data->hash_input));
                    $this->setBlockchainTransaction($response->data);
                    break;
                default:
                    break;
            }
        }
        /**
         * Handle timestamping webhooks without type
         */
        if (isset($response->uid) && isset($response->schema)) {
            $this->setBlockchainTransaction($response);
        }
    }
    /**
     * @param $response
     *
     * TODO: Improve
     */
    private function setBlockchainTransaction($response)
    {
        $postId = \intval($response->uid);
        $blockchainTransaction = \YoastSEO_Vendor\WordProof\SDK\Helpers\SchemaHelper::getBlockchainTransaction($response);
        \YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::add($postId, '_wordproof_blockchain_transaction', $blockchainTransaction);
        $schema = \YoastSEO_Vendor\WordProof\SDK\Helpers\SchemaHelper::getSchema($postId);
        \YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::update($postId, '_wordproof_schema', $schema);
    }
    /**
     * Checks if the user has permission to publish a post.
     *
     * @return bool Returns if a user has permission to publish.
     */
    public function canPublishPermission()
    {
        return \current_user_can('publish_posts') && \current_user_can('publish_pages');
    }
    /**
     * Validates if the webhook is valid and signed with the correct secret.
     *
     * @param \WP_REST_Request $request The Rest Request.
     * @return bool If the webhook can be accepted.
     */
    public static function isValidWebhookRequest(\WP_REST_Request $request)
    {
        if (!\YoastSEO_Vendor\WordProof\SDK\Helpers\AuthenticationHelper::isAuthenticated()) {
            return \false;
        }
        $hashedToken = \hash('sha256', \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::accessToken());
        $hmac = \hash_hmac('sha256', $request->get_body(), $hashedToken);
        return $request->get_header('signature') === $hmac;
    }
}
app/Controllers/TimestampController.php000066600000006606151143705220014366 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Controllers;

use YoastSEO_Vendor\WordProof\SDK\Helpers\ClassicNoticeHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\TimestampHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper;
class TimestampController
{
    /**
     * Timestamp an post triggered by custom action.
     *
     * @param integer $postId The post id to be timestamped.
     * @action wordproof_timestamp
     */
    public static function timestamp($postId)
    {
        $post = \get_post(\intval($postId));
        return \YoastSEO_Vendor\WordProof\SDK\Helpers\TimestampHelper::debounce($post);
    }
    /**
     * Timestamp new posts except those inserted by the API.
     *
     * @param integer $postId The post id to be timestamped.
     * @param \WP_Post $post The post to be timestamped.
     * @action wp_insert_post
     */
    public function timestampAfterPostRequest($postId, $post)
    {
        if (\defined('REST_REQUEST') && \REST_REQUEST) {
            return;
        }
        $response = \YoastSEO_Vendor\WordProof\SDK\Helpers\TimestampHelper::debounce($post);
        \YoastSEO_Vendor\WordProof\SDK\Helpers\ClassicNoticeHelper::addTimestampNotice($response);
        return $response;
    }
    /**
     * Timestamp new attachments.
     *
     * @param integer $postId The post id to be timestamped.
     *
     * @action add_attachment|edit_attachment
     */
    public function timestampAfterAttachmentRequest($postId)
    {
        $post = \get_post($postId);
        $this->timestampAfterPostRequest($postId, $post);
    }
    /**
     * Timestamp posts inserted by the API.
     *
     * @param \WP_Post $post The post to be timestamped.
     * @action rest_after_insert_post
     */
    public function timestampAfterRestApiRequest($post)
    {
        return \YoastSEO_Vendor\WordProof\SDK\Helpers\TimestampHelper::debounce($post);
    }
    /**
     * Removes action to timestamp post on insert if Elementor is used.
     */
    public function beforeElementorSave()
    {
        \remove_action('rest_after_insert_post', [$this, 'timestampAfterRestApiRequest']);
        \remove_action('wp_insert_post', [$this, 'timestampAfterPostRequest'], \PHP_INT_MAX);
    }
    /**
     * Syncs timestamp override post meta keys.
     *
     * @param $metaId
     * @param $postId
     * @param $metaKey
     * @param $metaValue
     */
    public function syncPostMetaTimestampOverrides($metaId, $postId, $metaKey, $metaValue)
    {
        $timestampablePostMetaKeys = \apply_filters('wordproof_timestamp_post_meta_key_overrides', ['_wordproof_timestamp']);
        if (\in_array($metaKey, $timestampablePostMetaKeys, \true) && \count($timestampablePostMetaKeys) > 1) {
            $arrayKey = \array_search($metaKey, $timestampablePostMetaKeys, \true);
            unset($timestampablePostMetaKeys[$arrayKey]);
            \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::set('wordproof_debounce_post_meta_sync_' . $metaKey . '_' . $postId, \true, 5);
            foreach ($timestampablePostMetaKeys as $key) {
                \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::debounce($postId, 'post_meta_sync_' . $key, function () use($postId, $key, $metaValue) {
                    return \YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::update($postId, $key, $metaValue);
                });
            }
        }
    }
}
app/Controllers/CertificateController.php000066600000005623151143705220014643 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Controllers;

use YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\CertificateHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\EnvironmentHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\SettingsHelper;
class CertificateController
{
    /**
     * Add scripts and schema to the head of the current page.
     *
     * @action wp_head
     */
    public function head()
    {
        if (!\YoastSEO_Vendor\WordProof\SDK\Helpers\CertificateHelper::show()) {
            return;
        }
        global $post;
        $schema = "\n";
        if (\YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper::getLoadUikitFromCdn() === \true) {
            $schema .= '<script type="module" src="https://unpkg.com/@wordproof/uikit@1.0.*/dist/uikit/uikit.esm.js"></script>';
            $schema .= "\n";
            $schema .= '<script nomodule src="https://unpkg.com/@wordproof/uikit@1.0.*/dist/uikit/uikit.js"></script>';
            $schema .= "\n";
        }
        $schema .= '<script type="application/ld+json" class="' . \esc_attr('wordproof-schema-graph') . '">';
        $schema .= \json_encode(\YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::get($post->ID, '_wordproof_schema'), \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE);
        $schema .= "</script>";
        $schema .= "\n";
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        echo $schema;
    }
    /**
     * Adds the certificate tag to the content before rendering it.
     *
     * @param $content
     * @return mixed|string Content string from 'the_content' filter
     * @filter the_content
     */
    public function certificateTag($content)
    {
        if (!\YoastSEO_Vendor\WordProof\SDK\Helpers\CertificateHelper::show()) {
            return $content;
        }
        if (\YoastSEO_Vendor\WordProof\SDK\Helpers\SettingsHelper::hideCertificateLink()) {
            return $content;
        }
        global $post;
        $identifier = $post->ID;
        $text = \YoastSEO_Vendor\WordProof\SDK\Helpers\SettingsHelper::certificateLinkText();
        $showRevisions = \YoastSEO_Vendor\WordProof\SDK\Helpers\SettingsHelper::showRevisions() ? 'true' : 'false';
        $debug = \YoastSEO_Vendor\WordProof\SDK\Helpers\EnvironmentHelper::development() ? 'true' : 'false';
        $lastModified = \get_the_modified_date('c', $post->ID);
        $content .= "\n" . '<w-certificate debug="' . $debug . '" shared-identifier="' . $identifier . '" render-without-button="true" show-revisions="' . $showRevisions . '" last-modified="' . $lastModified . '"></w-certificate>';
        $content .= "\n" . '<p><w-certificate-button shared-identifier="' . $identifier . '" icon="shield" shape="text" text="' . $text . '"></w-certificate-button></p>';
        $content .= "\n";
        return $content;
    }
}
app/Controllers/NoticeController.php000066600000005403151143705220013636 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Controllers;

use YoastSEO_Vendor\WordProof\SDK\Helpers\ClassicNoticeHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper;
use YoastSEO_Vendor\WordProof\SDK\Translations\TranslationsInterface;
class NoticeController
{
    /**
     * @var string[] The screens on which notices should be rendered.
     */
    private $screens = ['post'];
    /**
     * @var TranslationsInterface The translations objects,
     */
    private $translations;
    public function __construct(\YoastSEO_Vendor\WordProof\SDK\Translations\TranslationsInterface $translations)
    {
        $this->translations = $translations;
    }
    /**
     * Showing notices for the classic editor and delete them so they are only shown once.
     *
     * @action admin_notices
     */
    public function show()
    {
        $screen = \get_current_screen();
        if (!\in_array($screen->base, $this->screens, \true)) {
            return;
        }
        $notice = \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::getOnce(\YoastSEO_Vendor\WordProof\SDK\Helpers\ClassicNoticeHelper::$transientKey);
        if (!isset($notice) || !$notice) {
            return;
        }
        switch ($notice) {
            case 'no_balance':
                $type = 'error';
                $message = $this->translations->getNoBalanceNotice();
                $buttonText = $this->translations->getOpenSettingsButtonText();
                $buttonEventName = 'wordproof:open_settings';
                break;
            case 'timestamp_success':
                $type = 'success';
                $message = $this->translations->getTimestampSuccessNotice();
                break;
            case 'timestamp_failed':
                $type = 'error';
                $message = $this->translations->getTimestampFailedNotice();
                break;
            case 'not_authenticated':
                $type = 'error';
                $message = $this->translations->getNotAuthenticatedNotice();
                $buttonText = $this->translations->getOpenAuthenticationButtonText();
                $buttonEventName = 'wordproof:open_authentication';
                break;
            default:
                break;
        }
        if (isset($message) && isset($type)) {
            $noticeClass = 'notice-' . $type;
            echo \sprintf('<div class="notice %1$s is-dismissible"><p>%2$s</p>', \esc_attr($noticeClass), \esc_html($message));
            if (isset($buttonText) && isset($buttonEventName)) {
                echo \sprintf('<p><button class="button button-primary" onclick="window.dispatchEvent( new window.CustomEvent( \'%2$s\' ) )">%1$s</button></p>', \esc_html($buttonText), \esc_attr($buttonEventName));
            }
            echo '</div>';
        }
    }
}
app/Controllers/PostEditorDataController.php000066600000003337151143705220015307 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Controllers;

use YoastSEO_Vendor\WordProof\SDK\Helpers\AssetHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\PostEditorHelper;
use YoastSEO_Vendor\WordProof\SDK\Translations\TranslationsInterface;
class PostEditorDataController
{
    /**
     * @var TranslationsInterface The translations objects,
     */
    private $translations;
    /**
     * PostEditorDataController constructor.
     *
     * @param TranslationsInterface $translations The implemented translations interface.
     */
    public function __construct(\YoastSEO_Vendor\WordProof\SDK\Translations\TranslationsInterface $translations)
    {
        $this->translations = $translations;
    }
    /**
     * Add script for post edit pages.
     *
     * @param string $hook The current page.
     */
    public function addScript($hook)
    {
        $loadWordProofData = \apply_filters('wordproof_load_data_on_pages', \YoastSEO_Vendor\WordProof\SDK\Helpers\PostEditorHelper::getPostEditPages());
        if (\in_array($hook, $loadWordProofData, \true)) {
            $this->enqueueAndLocalizeScript();
        }
    }
    /**
     * Localizes the elementor script.
     */
    public function addScriptForElementor()
    {
        $this->enqueueAndLocalizeScript();
    }
    /**
     * Enqueues and localizes data script.
     */
    private function enqueueAndLocalizeScript()
    {
        $data = \YoastSEO_Vendor\WordProof\SDK\Helpers\PostEditorHelper::getPostEditorData($this->translations);
        $data = \apply_filters('wordproof_data', $data);
        \YoastSEO_Vendor\WordProof\SDK\Helpers\AssetHelper::enqueue('data');
        \YoastSEO_Vendor\WordProof\SDK\Helpers\AssetHelper::localize('data', 'wordproofSdk', $data);
    }
}
app/.htaccess000066600000000424151143705220007126 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>app/Support/Template.php000066600000010405151143705220011270 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Support;

class Template
{
    private static $blocks = [];
    private static $cache_path = 'cache/';
    private static $template_path = 'templates/';
    private static $cache_enabled = \true;
    private static $store_cache = \false;
    public static function setOptions(array $options)
    {
        foreach ($options as $optionName => $optionValue) {
            if (\property_exists(__CLASS__, $optionName)) {
                self::${$optionName} = $optionValue;
            }
        }
    }
    public static function setCachePath($path)
    {
        self::$cache_path = $path;
    }
    public static function setTemplatePath($path)
    {
        self::$template_path = $path;
    }
    public static function render($file, $data = [])
    {
        \ob_start();
        self::view($file, $data);
        return \ob_get_contents();
    }
    public static function view($file, $data = [])
    {
        if (self::$store_cache) {
            $cached_file = self::cache($file);
            \extract($data, \EXTR_SKIP);
            require $cached_file;
        } else {
            $code = self::includeFiles($file);
            $code = self::compileCode($code);
            $code = '?>' . \PHP_EOL . $code . \PHP_EOL . "<?php";
            \extract($data, \EXTR_SKIP);
            eval($code);
        }
    }
    private static function cache($file)
    {
        if (!\file_exists(self::$cache_path)) {
            \mkdir(self::$cache_path, 0744);
        }
        $cached_file = self::$cache_path . \str_replace(['/', '.html'], ['_', ''], $file . '.php');
        if (!self::$cache_enabled || !\file_exists($cached_file) || \filemtime($cached_file) < \filemtime($file)) {
            $code = self::includeFiles($file);
            $code = self::compileCode($code);
            \file_put_contents($cached_file, '<?php class_exists(\'' . __CLASS__ . '\') or exit; ?>' . \PHP_EOL . $code);
        }
        return $cached_file;
    }
    public static function clearCache()
    {
        foreach (\glob(self::$cache_path . '*') as $file) {
            \unlink($file);
        }
    }
    private static function compileCode($code)
    {
        $code = self::compileBlock($code);
        $code = self::compileYield($code);
        $code = self::compileEscapedEchos($code);
        $code = self::compileEchos($code);
        $code = self::compilePHP($code);
        return $code;
    }
    private static function includeFiles($file)
    {
        $code = \file_get_contents(self::$template_path . $file);
        \preg_match_all('/{% ?(extends|include) ?\'?(.*?)\'? ?%}/i', $code, $matches, \PREG_SET_ORDER);
        foreach ($matches as $value) {
            $code = \str_replace($value[0], self::includeFiles($value[2]), $code);
        }
        $code = \preg_replace('/{% ?(extends|include) ?\'?(.*?)\'? ?%}/i', '', $code);
        return $code;
    }
    private static function compilePHP($code)
    {
        return \preg_replace('~{%\\s*(.+?)\\s*%}~is', '<?php $1 ?>', $code);
    }
    private static function compileEchos($code)
    {
        return \preg_replace('~{{\\s*(.+?)\\s*}}~is', '<?php echo $1 ?>', $code);
    }
    private static function compileEscapedEchos($code)
    {
        return \preg_replace('~{{{\\s*(.+?)\\s*}}}~is', '<?php echo htmlentities($1, ENT_QUOTES, \'UTF-8\') ?>', $code);
    }
    private static function compileBlock($code)
    {
        \preg_match_all('/{% ?block ?(.*?) ?%}(.*?){% ?endblock ?%}/is', $code, $matches, \PREG_SET_ORDER);
        foreach ($matches as $value) {
            if (!\array_key_exists($value[1], self::$blocks)) {
                self::$blocks[$value[1]] = '';
            }
            if (\strpos($value[2], '@parent') === \false) {
                self::$blocks[$value[1]] = $value[2];
            } else {
                self::$blocks[$value[1]] = \str_replace('@parent', self::$blocks[$value[1]], $value[2]);
            }
            $code = \str_replace($value[0], '', $code);
        }
        return $code;
    }
    private static function compileYield($code)
    {
        foreach (self::$blocks as $block => $value) {
            $code = \preg_replace('/{% ?yield ?' . $block . ' ?%}/', $value, $code);
        }
        $code = \preg_replace('/{% ?yield ?(.*?) ?%}/i', '', $code);
        return $code;
    }
}
app/Support/.htaccess000066600000000424151143705220010602 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>app/Support/Loader.php000066600000004502151143705220010724 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Support;

class Loader
{
    protected $actions;
    protected $filters;
    public function __construct()
    {
        $this->actions = [];
        $this->filters = [];
    }
    /**
     * @param string $hook The name of the WordPress action that is being registered.
     * @param object $component A reference to the instance of the object on which the action is defined.
     * @param string $callback The name of the function definition on the $component.
     * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
     * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
     */
    public function addAction($hook, $component, $callback, $priority = 10, $accepted_args = 1)
    {
        $this->actions = $this->add($this->actions, $hook, $component, $callback, $priority, $accepted_args);
    }
    /**
     * @param string $hook The name of the WordPress filter that is being registered.
     * @param object $component A reference to the instance of the object on which the filter is defined.
     * @param string $callback The name of the function definition on the $component.
     * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
     * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1
     */
    public function addFilter($hook, $component, $callback, $priority = 10, $accepted_args = 1)
    {
        $this->filters = $this->add($this->filters, $hook, $component, $callback, $priority, $accepted_args);
    }
    public function run()
    {
        foreach ($this->filters as $hook) {
            \add_filter($hook['hook'], [$hook['component'], $hook['callback']], $hook['priority'], $hook['accepted_args']);
        }
        foreach ($this->actions as $hook) {
            \add_action($hook['hook'], [$hook['component'], $hook['callback']], $hook['priority'], $hook['accepted_args']);
        }
    }
    private function add($hooks, $hook, $component, $callback, $priority, $accepted_args)
    {
        $hooks[] = ['hook' => $hook, 'component' => $component, 'callback' => $callback, 'priority' => $priority, 'accepted_args' => $accepted_args];
        return $hooks;
    }
}
app/Support/Timestamp.php000066600000002241151143705220011457 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Support;

use YoastSEO_Vendor\WordProof\SDK\Helpers\AuthenticationHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper;
class Timestamp
{
    /**
     * @param array $data
     *
     * @return mixed
     */
    public static function sendPostRequest($data)
    {
        $sourceId = \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::sourceId();
        $endpoint = '/api/sources/' . $sourceId . '/timestamps';
        $response = \YoastSEO_Vendor\WordProof\SDK\Support\Api::post($endpoint, $data);
        if (!$response || !isset($response->hash)) {
            //            AuthenticationHelper::logout(); // TODO Only if response is unauthenticated
            return \false;
        }
        if (isset($response->balance)) {
            \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::set('balance', $response->balance);
        }
        $key = '_wordproof_hash_input_' . $response->hash;
        \YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::update($data['uid'], $key, \json_decode($response->hash_input));
        return $response;
    }
}
app/Support/Api.php000066600000002405151143705220010227 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Support;

use YoastSEO_Vendor\WordProof\SDK\Helpers\EnvironmentHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper;
class Api
{
    /**
     * @param string $endpoint
     * @param array $body
     * @return mixed
     */
    public static function post($endpoint, $body = [])
    {
        $location = \YoastSEO_Vendor\WordProof\SDK\Helpers\EnvironmentHelper::url() . $endpoint;
        $body = \wp_json_encode($body);
        $accessToken = \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::accessToken();
        $headers = ['Content-Type' => 'application/json', 'Accept' => 'application/json'];
        $headers = $accessToken ? \array_merge($headers, ['Authorization' => 'Bearer ' . $accessToken]) : $headers;
        $options = ['body' => $body, 'headers' => $headers, 'timeout' => 60, 'redirection' => 5, 'blocking' => \true, 'data_format' => 'body', 'sslverify' => \YoastSEO_Vendor\WordProof\SDK\Helpers\EnvironmentHelper::sslVerify()];
        $request = \wp_remote_post($location, $options);
        $status = \wp_remote_retrieve_response_code($request);
        if ($status < 200 || $status >= 300) {
            return \false;
        }
        return \json_decode(\wp_remote_retrieve_body($request));
    }
}
app/Support/Authentication.php000066600000012440151143705220012475 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Support;

use YoastSEO_Vendor\WordProof\SDK\Helpers\AdminHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\AuthenticationHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\EnvironmentHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\PostTypeHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\SettingsHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper;
class Authentication
{
    private static $callbackEndpoint = 'wordproof/v1/oauth/callback';
    public static function authorize($redirectUrl = null)
    {
        $state = \wp_generate_password(40, \false);
        $codeVerifier = \wp_generate_password(128, \false);
        $originalUrl = \YoastSEO_Vendor\WordProof\SDK\Helpers\AdminHelper::currentUrl();
        \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::set('wordproof_authorize_state', $state, 1200);
        \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::set('wordproof_authorize_code_verifier', $codeVerifier, 1200);
        \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::set('wordproof_authorize_current_url', $redirectUrl ?: $originalUrl);
        $encoded = \base64_encode(\hash('sha256', $codeVerifier, \true));
        $codeChallenge = \strtr(\rtrim($encoded, '='), '+/', '-_');
        $data = ['client_id' => \YoastSEO_Vendor\WordProof\SDK\Helpers\EnvironmentHelper::client(), 'redirect_uri' => self::getCallbackUrl(), 'response_type' => 'code', 'scope' => '', 'state' => $state, 'code_challenge' => $codeChallenge, 'code_challenge_method' => 'S256', 'partner' => \YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper::getPartner()];
        /**
         * Login with user if v2 plugin data exist.
         */
        $accessToken = \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::get('wordproof_v2_authenticate_with_token');
        if ($accessToken) {
            $data = \array_merge($data, ['access_token_login' => $accessToken]);
        } else {
            $data = \array_merge($data, ['confirm_account' => \true]);
        }
        self::redirect('/wordpress-sdk/authorize', $data);
    }
    /**
     * Retrieve the access token with the state and code.
     *
     * @param string $state The state from remote
     * @param string $code The code from remote
     * @return \WP_REST_Response
     * @throws \Exception
     */
    public static function token($state, $code)
    {
        $localState = \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::getOnce('wordproof_authorize_state');
        $codeVerifier = \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::getOnce('wordproof_authorize_code_verifier');
        if (\strlen($localState) <= 0 || $localState !== $state) {
            throw new \Exception('WordProof: No state found.');
        }
        $data = ['grant_type' => 'authorization_code', 'client_id' => \YoastSEO_Vendor\WordProof\SDK\Helpers\EnvironmentHelper::client(), 'redirect_uri' => self::getCallbackUrl(), 'code_verifier' => $codeVerifier, 'code' => $code];
        $response = \YoastSEO_Vendor\WordProof\SDK\Support\Api::post('/api/wordpress-sdk/token', $data);
        if (isset($response->error) && $response->error === 'invalid_grant') {
            $data = (object) ['status' => 401, 'message' => 'invalid_grant'];
            return new \WP_REST_Response($data, $data->status);
        }
        if (!isset($response->access_token)) {
            $data = (object) ['status' => 401, 'message' => 'no_access_token'];
            return new \WP_REST_Response($data, $data->status);
        }
        \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::setAccessToken($response->access_token);
        $data = ['webhook_url' => \get_rest_url(null, 'wordproof/v1/webhook'), 'url' => \get_site_url(), 'available_post_types' => \YoastSEO_Vendor\WordProof\SDK\Helpers\PostTypeHelper::getPublicPostTypes(), 'partner' => \YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper::getPartner(), 'local_settings' => (array) \YoastSEO_Vendor\WordProof\SDK\Helpers\SettingsHelper::get()];
        /**
         * Use existing source if user was authenticated in v2 of the plugin.
         */
        $sourceId = \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::getOnce('wordproof_v2_get_existing_source');
        if ($sourceId) {
            $data = \array_merge($data, ['source_id' => \intval($sourceId)]);
        }
        $response = \YoastSEO_Vendor\WordProof\SDK\Support\Api::post('/api/wordpress-sdk/source', $data);
        \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::setSourceId($response->source_id);
        $data = (object) ['status' => 200, 'message' => 'authentication_success', 'source_id' => \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::get('source_id'), 'is_authenticated' => \YoastSEO_Vendor\WordProof\SDK\Helpers\AuthenticationHelper::isAuthenticated()];
        return new \WP_REST_Response($data, $data->status);
    }
    private static function getCallbackUrl()
    {
        return \get_rest_url(null, self::$callbackEndpoint);
    }
    public static function redirect($endpoint, $parameters)
    {
        $location = \YoastSEO_Vendor\WordProof\SDK\Helpers\EnvironmentHelper::url() . $endpoint . '?' . \http_build_query($parameters);
        \header("Location: " . $location);
    }
}
app/Support/Settings.php000066600000002132151143705220011313 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Support;

use YoastSEO_Vendor\WordProof\SDK\Helpers\AuthenticationHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper;
use YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper;
class Settings
{
    public static function redirect($redirectUrl = null)
    {
        if (!\YoastSEO_Vendor\WordProof\SDK\Helpers\AuthenticationHelper::isAuthenticated()) {
            return \false;
        }
        $options = \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::all();
        if (!$options->source_id) {
            return \false;
        }
        $endpoint = "/sources/" . $options->source_id . "/settings";
        if (\YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper::getPartner() === 'yoast') {
            $endpoint = '/yoast/dashboard';
        }
        \YoastSEO_Vendor\WordProof\SDK\Support\Authentication::redirect($endpoint, ['redirect_uri' => $redirectUrl, 'partner' => \YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper::getPartner(), 'source_id' => $options->source_id, 'access_token_login' => $options->access_token]);
    }
}
app/Helpers/RedirectHelper.php000066600000000512151143705220012342 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

class RedirectHelper
{
    /**
     * Does a safe redirect to an admin page.
     *
     * @param string $url The url to be redirected to.
     */
    public static function safe($url)
    {
        nocache_headers();
        \wp_safe_redirect($url);
        exit;
    }
}
app/Helpers/ReflectionHelper.php000066600000001000151143705220012664 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

use YoastSEO_Vendor\WordProof\SDK\WordPressSDK;
class ReflectionHelper
{
    /**
     * @param class $instance The class from which to get the name.
     * @return false|string
     */
    public static function name($instance)
    {
        if ($instance instanceof \YoastSEO_Vendor\WordProof\SDK\WordPressSDK) {
            $reflector = new \ReflectionClass($instance);
            return $reflector->getName();
        }
        return \false;
    }
}
app/Helpers/EscapeHelper.php000066600000004056151143705220012010 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

class EscapeHelper
{
    /**
     * Returns the value escaped according to the escape function set in the class.
     *
     * @param mixed $value The value to be sanitized.
     * @param string $escapeKey The escape function to be used.
     *
     * @return array|bool|int|string
     */
    public static function escape($value, $escapeKey)
    {
        if (\is_array($value)) {
            return self::escapeArray($value, $escapeKey);
        }
        if (\is_object($value)) {
            return (object) self::escapeArray((array) $value, $escapeKey);
        }
        return self::escapeSingleValue($value, $escapeKey);
    }
    /**
     * Loops through the array to escape the values inside.
     *
     * @param array $array The array with values to be escaped.
     * @param string $escapeKey The escape function to be used.
     * @return array Array with escapes values.
     */
    private static function escapeArray($array, $escapeKey)
    {
        $values = [];
        foreach ($array as $key => $value) {
            $values[$key] = self::escapeSingleValue($value, $escapeKey);
        }
        return $values;
    }
    /**
     * Escapes a single value using an escape function set in the class.
     *
     * @param string $value The value to be escaped.
     * @param string $escapeKey The escape function to be used.
     * @return bool|int|string The escaped value.
     */
    private static function escapeSingleValue($value, $escapeKey)
    {
        switch ($escapeKey) {
            case 'integer':
                return \intval($value);
            case 'boolean':
                return \boolval($value);
            case 'html_class':
                return \esc_html_class($value);
            case 'email':
                return \esc_email($value);
            case 'url':
                return \esc_url_raw($value);
            case 'key':
                return \esc_key($value);
            case 'text_field':
            default:
                return \esc_html($value);
        }
    }
}
app/Helpers/TimestampHelper.php000066600000006611151143705220012552 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

use YoastSEO_Vendor\WordProof\SDK\DataTransferObjects\TimestampData;
use YoastSEO_Vendor\WordProof\SDK\Support\Timestamp;
class TimestampHelper
{
    public static function debounce(\WP_Post $post)
    {
        $key = 'wordproof_timestamped_debounce_' . $post->id;
        $data = \YoastSEO_Vendor\WordProof\SDK\DataTransferObjects\TimestampData::fromPost($post);
        $transient = \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::get($key);
        if ($transient) {
            return new \WP_REST_Response($transient, $transient->status);
        }
        $response = self::shouldBeTimestamped($post, $data);
        if (\is_bool($response) && $response === \false) {
            $response = (object) ['status' => 200, 'message' => 'Post should not be timestamped'];
            return new \WP_REST_Response($response, $response->status);
        }
        if (\is_array($response) && $response['timestamp'] === \false) {
            $response = (object) ['status' => 400, 'message' => 'Post should not be timestamped', 'error' => 'not_authenticated'];
            return new \WP_REST_Response($response, $response->status);
        }
        $response = \YoastSEO_Vendor\WordProof\SDK\Support\Timestamp::sendPostRequest($data);
        if ($response === \false) {
            $response = (object) ['status' => 400, 'message' => 'Something went wrong.', 'error' => 'timestamp_failed'];
            return new \WP_REST_Response($response, $response->status);
        }
        $response->status = 201;
        \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::set($key, $response, 5);
        return new \WP_REST_Response($response, $response->status);
    }
    public static function shouldBeTimestamped(\WP_Post $post, $data)
    {
        if (!\YoastSEO_Vendor\WordProof\SDK\Helpers\AuthenticationHelper::isAuthenticated()) {
            if (self::hasPostMetaOverrideSetToTrue($post)) {
                return ['timestamp' => \false, 'notice' => 'not_authenticated'];
            }
            return \false;
        }
        if ($post->post_type !== 'attachment' && $post->post_content === '') {
            return \false;
        }
        if ($post->post_type === 'attachment' && \get_attached_file($post->ID) === \false) {
            return \false;
        }
        if (!\in_array($post->post_status, ['publish', 'inherit'], \true)) {
            return \false;
        }
        if (\YoastSEO_Vendor\WordProof\SDK\Helpers\SettingsHelper::postTypeIsInSelectedPostTypes($post->post_type)) {
            return \true;
        }
        if (self::hasPostMetaOverrideSetToTrue($post)) {
            return \true;
        }
        return \false;
    }
    private static function hasPostMetaOverrideSetToTrue(\WP_Post $post)
    {
        $timestampablePostMetaKeys = \apply_filters('wordproof_timestamp_post_meta_key_overrides', ['_wordproof_timestamp']);
        //Do not use PostMeta helper
        $meta = \get_post_meta($post->ID);
        foreach ($timestampablePostMetaKeys as $key) {
            if (!isset($meta[$key])) {
                continue;
            }
            if (\is_array($meta[$key])) {
                $value = \boolval($meta[$key][0]);
            } else {
                $value = \boolval($meta[$key]);
            }
            if (!$value) {
                continue;
            }
            return \true;
        }
        return \false;
    }
}
app/Helpers/TransientHelper.php000066600000002711151143705220012553 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

use YoastSEO_Vendor\WordProof\SDK\DataTransferObjects\TimestampData;
class TransientHelper
{
    /**
     * Set transient.
     *
     * @param $key
     * @param $value
     * @param int $expiration
     * @return bool
     */
    public static function set($key, $value, $expiration = 0)
    {
        return \set_transient($key, $value, $expiration);
    }
    /**
     * Returns and deletes site transient by key.
     *
     * @param $key
     * @return mixed
     */
    public static function getOnce($key)
    {
        $value = \get_transient($key);
        \delete_transient($key);
        return $value;
    }
    /**
     * Returns the transient by key.
     *
     * @param $key
     * @return mixed
     */
    public static function get($key)
    {
        return \get_transient($key);
    }
    /**
     * Debounce callback for post id.
     *
     * @param $postId
     * @param $action
     * @param $callback
     * @return mixed
     */
    public static function debounce($postId, $action, $callback)
    {
        $key = 'wordproof_debounce_' . $action . '_' . $postId;
        $transient = \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::get($key);
        if ($transient) {
            return $transient;
        } else {
            \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::set($key, \true, 4);
            $result = $callback();
            return $result;
        }
    }
}
app/Helpers/StringHelper.php000066600000001370151143705220012052 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

class StringHelper
{
    /**
     * Replace the last occurrence.
     *
     * @param string $search
     * @param string $replace
     * @param string $subject
     * @return string
     */
    public static function lastReplace($search, $replace, $subject)
    {
        $pos = \strrpos($subject, $search);
        if ($pos !== \false) {
            $subject = \substr_replace($subject, $replace, $pos, \strlen($search));
        }
        return $subject;
    }
    /**
     * PascalCase to snake_case
     *
     * @param $string
     * @return string
     */
    public static function toUnderscore($string)
    {
        return \strtolower(\preg_replace('/(?<!^)[A-Z]/', '_$0', $string));
    }
}
app/Helpers/SchemaHelper.php000066600000003351151143705220012005 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

class SchemaHelper
{
    /**
     * Builds an blockchain transaction schema object as array.
     *
     * @param object $response The response by WordProof.
     * @return array The blockchain transaction in the correct schema format.
     */
    public static function getBlockchainTransaction($response)
    {
        $postId = $response->uid;
        $hashLink = \YoastSEO_Vendor\WordProof\SDK\Helpers\RestApiHelper::getRestRoute('hashInput', [$postId, $response->hash]);
        $identifier = null;
        if (isset($response->transaction)) {
            $transaction = $response->transaction;
            if (isset($transaction->transactionId)) {
                $identifier = $transaction->transactionId;
            }
            if (isset($transaction->tx)) {
                $identifier = $transaction->tx;
            }
        }
        return ['@type' => 'BlockchainTransaction', 'identifier' => $identifier, 'hash' => $response->hash, 'hashLink' => $hashLink, 'recordedIn' => ['@type' => 'Blockchain', 'name' => $response->transaction->blockchain]];
    }
    /**
     * Retrieves the schema as array for a post.
     *
     * @param integer $postId The post id for which the schema should be returned.
     * @return array The schema as array.
     */
    public static function getSchema($postId)
    {
        $transactions = \YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::get($postId, '_wordproof_blockchain_transaction', \false);
        $latest = \array_pop($transactions);
        if (\count($transactions) === 0) {
            return ['timestamp' => $latest];
        }
        return ['timestamp' => \array_merge($latest, ['revisions' => \array_reverse($transactions)])];
    }
}
app/Helpers/AppConfigHelper.php000066600000002362151143705220012454 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

use YoastSEO_Vendor\WordProof\SDK\WordPressSDK;
class AppConfigHelper
{
    /**
     * Returns the partner set during initialization.
     *
     * @return string|null
     */
    public static function getPartner()
    {
        $appConfig = self::getAppConfig();
        if ($appConfig) {
            return $appConfig->getPartner();
        }
        return null;
    }
    /**
     * Returns the environment set during initialization.
     * @return string|null
     */
    public static function getEnvironment()
    {
        $appConfig = self::getAppConfig();
        if ($appConfig) {
            return $appConfig->getEnvironment();
        }
        return null;
    }
    /**
     * Returns the environment set during initialization.
     * @return boolean
     */
    public static function getLoadUikitFromCdn()
    {
        $appConfig = self::getAppConfig();
        if ($appConfig) {
            return $appConfig->getLoadUikitFromCdn();
        }
        return null;
    }
    public static function getAppConfig()
    {
        $sdk = \YoastSEO_Vendor\WordProof\SDK\WordPressSDK::getInstance();
        if ($sdk) {
            return $sdk->appConfig;
        }
        return null;
    }
}
app/Helpers/AuthenticationHelper.php000066600000001166151143705220013566 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

class AuthenticationHelper
{
    /**
     * Removes all the options set by WordProof.
     *
     * @return void
     */
    public static function logout()
    {
        \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::resetAuthentication();
    }
    /**
     * Returns if the user is authenticated.
     *
     * @return bool If the user is authenticated.
     */
    public static function isAuthenticated()
    {
        $options = \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::all();
        return $options->access_token && $options->source_id;
    }
}
app/Helpers/AdminHelper.php000066600000000760151143705220011636 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

class AdminHelper
{
    /**
     * Returns the current admin url of the user.
     *
     * @return null|string The current admin url of the logged in user.
     */
    public static function currentUrl()
    {
        if (isset($_SERVER['REQUEST_URI'])) {
            $requestUri = \esc_url_raw(\wp_unslash($_SERVER['REQUEST_URI']));
            return \admin_url(\sprintf(\basename($requestUri)));
        }
        return null;
    }
}
app/Helpers/PostEditorHelper.php000066600000007720151143705220012705 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

use YoastSEO_Vendor\WordProof\SDK\Translations\TranslationsInterface;
class PostEditorHelper
{
    /**
     * Returns the post editor that is in use.
     *
     * @return bool The post editor the user is using..
     */
    public static function getPostEditor()
    {
        if (!\function_exists('YoastSEO_Vendor\\get_current_screen')) {
            return null;
        }
        $screen = \get_current_screen();
        if (!self::isPostEdit($screen->base)) {
            return null;
        }
        // Start with Elementor, otherwise the block editor will be returned.
        $action = \filter_input(\INPUT_GET, 'action', \FILTER_SANITIZE_STRING);
        if ($action === 'elementor') {
            return 'elementor';
        }
        if (\method_exists($screen, 'is_block_editor') && $screen->is_block_editor()) {
            return 'block';
        }
        return 'classic';
    }
    /**
     * Returns if the page is a post edit page.
     *
     * @param string $page The page to check.
     * @return bool If the current page is a post edit page.
     */
    public static function isPostEdit($page)
    {
        return \in_array($page, self::getPostEditPages(), \true);
    }
    /**
     * Returns an array of edit page hooks.
     *
     * @return array Post edit page hooks.
     */
    public static function getPostEditPages()
    {
        return ['post.php', 'post', 'post-new.php', 'post-new'];
    }
    /**
     * Returns the data that should be added to the post editor.
     *
     * @param TranslationsInterface $translations The implemented translations interface.
     *
     * @return array[] The post editor data.
     */
    public static function getPostEditorData(\YoastSEO_Vendor\WordProof\SDK\Translations\TranslationsInterface $translations)
    {
        global $post;
        $postId = isset($post->ID) ? $post->ID : null;
        $postType = isset($post->post_type) ? $post->post_type : null;
        $translations = ['no_balance' => $translations->getNoBalanceNotice(), 'timestamp_success' => $translations->getTimestampSuccessNotice(), 'timestamp_failed' => $translations->getTimestampFailedNotice(), 'webhook_failed' => $translations->getWebhookFailedNotice(), 'not_authenticated' => $translations->getNotAuthenticatedNotice(), 'open_authentication_button_text' => $translations->getOpenAuthenticationButtonText(), 'open_settings_button_text' => $translations->getOpenSettingsButtonText(), 'contact_wordproof_support_button_text' => $translations->getContactWordProofSupportButtonText()];
        return ['data' => ['origin' => \YoastSEO_Vendor\WordProof\SDK\Helpers\EnvironmentHelper::url(), 'is_authenticated' => \YoastSEO_Vendor\WordProof\SDK\Helpers\AuthenticationHelper::isAuthenticated(), 'popup_redirect_authentication_url' => \admin_url('admin.php?page=wordproof-redirect-authenticate'), 'popup_redirect_settings_url' => \admin_url('admin.php?page=wordproof-redirect-settings'), 'settings' => \YoastSEO_Vendor\WordProof\SDK\Helpers\SettingsHelper::get(), 'current_post_id' => $postId, 'current_post_type' => $postType, 'post_editor' => self::getPostEditor(), 'translations' => $translations, 'balance' => \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::get('balance')]];
    }
    /**
     * Returns the current post type.
     *
     * @return null|string The current post type.
     */
    public static function getCurrentPostType()
    {
        global $post, $typenow, $current_screen;
        if ($post && $post->post_type) {
            return $post->post_type;
        }
        if ($typenow) {
            return $typenow;
        }
        if ($current_screen && $current_screen->post_type) {
            return $current_screen->post_type;
        }
        // phpcs:disable WordPress.Security.NonceVerification
        if (isset($_REQUEST['post_type'])) {
            return \sanitize_key($_REQUEST['post_type']);
        }
        // phpcs:enable WordPress.Security.NonceVerification
        return null;
    }
}
app/Helpers/AssetHelper.php000066600000005270151143705220011666 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

use YoastSEO_Vendor\WordProof\SDK\Config\ScriptsConfig;
class AssetHelper
{
    private static $prefix = 'wordproof-';
    private static $filePath = 'app/';
    private static $buildPath = 'build/';
    /**
     * Localizes script by name.
     *
     * @param string $name Name of the script
     * @param string $objectName The name of the object in Javascript.
     * @param array $data The data to be included.
     * @return bool|void
     */
    public static function localize($name, $objectName, $data)
    {
        $config = \YoastSEO_Vendor\WordProof\SDK\Config\ScriptsConfig::get($name);
        if (!isset($config)) {
            return;
        }
        return \wp_localize_script(self::getHandle($name), $objectName, $data);
    }
    /**
     * Enqueues a script defined in the scripts config.
     *
     * @param string $name The name of the script to enqueue.
     * @return false|mixed|void
     */
    public static function enqueue($name)
    {
        $config = \YoastSEO_Vendor\WordProof\SDK\Config\ScriptsConfig::get($name);
        if (!isset($config)) {
            return;
        }
        $path = self::getPathUrl($name, $config['type']);
        if ($config['type'] === 'css') {
            \wp_enqueue_style(self::getHandle($name), $path, $config['dependencies'], self::getVersion());
        } else {
            \wp_enqueue_script(self::getHandle($name), $path, $config['dependencies'], self::getVersion(), \false);
        }
    }
    /**
     * Returns the prefixed script handle.
     *
     * @param string $name The name of the script.
     * @return string Handle of the script.
     */
    private static function getHandle($name)
    {
        return self::$prefix . $name;
    }
    /**
     * Get path url of the script.
     *
     * @param string $name The name of the script.
     * @return string The url of the script.
     */
    private static function getPathUrl($name, $extension)
    {
        $appConfig = \YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper::getAppConfig();
        if ($appConfig->getScriptsFileOverwrite()) {
            $url = $appConfig->getScriptsFileOverwrite();
        } else {
            $url = \plugin_dir_url(WORDPROOF_TIMESTAMP_SDK_FILE);
        }
        $base = \YoastSEO_Vendor\WordProof\SDK\Helpers\StringHelper::lastReplace(self::$filePath, self::$buildPath, $url);
        return $base . $name . '.' . $extension;
    }
    /**
     * Returns version for file.
     *
     * @return false|string
     */
    private static function getVersion()
    {
        return \YoastSEO_Vendor\WordProof\SDK\Helpers\EnvironmentHelper::development() ? \false : WORDPROOF_TIMESTAMP_SDK_VERSION;
    }
}
app/Helpers/CertificateHelper.php000066600000001260151143705220013024 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

class CertificateHelper
{
    /**
     * Returns if the certificate should be displayed for this page.
     *
     * @return false If the certificate should be shown.
     */
    public static function show()
    {
        if (!\is_singular()) {
            return \false;
        }
        if (!\is_main_query()) {
            return \false;
        }
        if (\post_password_required()) {
            return \false;
        }
        global $post;
        return \apply_filters('wordproof_timestamp_show_certificate', \YoastSEO_Vendor\WordProof\SDK\Helpers\PostMetaHelper::has($post->ID, '_wordproof_schema'), $post);
    }
}
app/Helpers/PostTypeHelper.php000066600000001322151143705220012370 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

class PostTypeHelper
{
    /**
     * Returns public post types.
     *
     * @return array The public post types.
     */
    public static function getPublicPostTypes()
    {
        return \array_values(\get_post_types(['public' => \true]));
    }
    public static function getUnprotectedPosts($postType)
    {
        $query = ['post_type' => [$postType], 'fields' => 'ids', 'posts_per_page' => -1, 'post_status' => ['publish', 'inherit'], 'meta_query' => [['key' => '_wordproof_blockchain_transaction', 'compare' => 'NOT EXISTS']]];
        $query = new \WP_Query($query);
        return ['count' => $query->found_posts, 'postIds' => $query->posts];
    }
}
app/Helpers/EnvironmentHelper.php000066600000002653151143705220013115 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

use YoastSEO_Vendor\WordProof\SDK\Config\EnvironmentConfig;
class EnvironmentHelper
{
    public static function url()
    {
        $appConfig = \YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper::getAppConfig();
        if ($appConfig->getWordProofUrl()) {
            return $appConfig->getWordProofUrl();
        }
        return self::get('url');
    }
    public static function client()
    {
        $appConfig = \YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper::getAppConfig();
        if ($appConfig->getOauthClient()) {
            return $appConfig->getOauthClient();
        }
        return self::get('client');
    }
    public static function sslVerify()
    {
        return !\YoastSEO_Vendor\WordProof\SDK\Helpers\EnvironmentHelper::development();
    }
    public static function development()
    {
        return \YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper::getEnvironment() === 'development';
    }
    public static function get($key)
    {
        $envConfig = self::environmentConfig();
        if ($envConfig && isset($envConfig[$key])) {
            return $envConfig[$key];
        }
        return null;
    }
    private static function environmentConfig()
    {
        $env = \YoastSEO_Vendor\WordProof\SDK\Helpers\AppConfigHelper::getEnvironment();
        return \YoastSEO_Vendor\WordProof\SDK\Config\EnvironmentConfig::get($env);
    }
}
app/Helpers/SettingsHelper.php000066600000002741151143705220012407 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

use YoastSEO_Vendor\WordProof\SDK\Config\OptionsConfig;
class SettingsHelper
{
    private static $key = 'settings';
    /**
     * Retrieving settings from the option.
     *
     * @param null $setting The key for the setting
     * @return array|bool|int|mixed|object|string|null
     */
    public static function get($setting = null)
    {
        $settings = \YoastSEO_Vendor\WordProof\SDK\Helpers\OptionsHelper::get(self::$key);
        if ($setting) {
            $option = \YoastSEO_Vendor\WordProof\SDK\Config\OptionsConfig::get('settings.options.' . $setting);
            if (isset($settings->{$setting}) && $option) {
                return $settings->{$setting};
            }
            return $option['default'];
        }
        return (object) $settings;
    }
    public static function showRevisions()
    {
        return self::get('show_revisions');
    }
    public static function certificateLinkText()
    {
        return self::get('certificate_link_text');
    }
    public static function hideCertificateLink()
    {
        return self::get('hide_certificate_link');
    }
    public static function selectedPostTypes()
    {
        return \apply_filters('wordproof_timestamp_post_types', self::get('selected_post_types'));
    }
    public static function postTypeIsInSelectedPostTypes($postType)
    {
        $postTypes = self::selectedPostTypes();
        return \in_array($postType, $postTypes, \true);
    }
}
app/Helpers/PostMetaHelper.php000066600000003163151143705220012342 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

class PostMetaHelper
{
    /**
     * @param integer $postId The post id for which the meta should be set.
     * @param string $key The key for the post meta.
     * @param mixed $value The value for the post meta.
     * @return integer|boolean Returns the post meta id or false on failure.
     */
    public static function add($postId, $key, $value, $single = \false)
    {
        return \add_post_meta($postId, $key, $value, $single);
    }
    /**
     * @param integer $postId The post id for which the meta should be set.
     * @param string $key The key for the post meta.
     * @param mixed $value The value for the post meta.
     * @return integer|boolean Returns the post meta id or false on failure.
     */
    public static function update($postId, $key, $value)
    {
        return \update_post_meta($postId, $key, $value);
    }
    /**
     * @param integer $postId The post id for which the meta should be set.
     * @param string $key The key for the post meta.
     * @param bool $single If a single result should be returned.
     * @return mixed Returns the post meta data or false on failure.
     */
    public static function get($postId, $key, $single = \true)
    {
        return \get_post_meta($postId, $key, $single);
    }
    /**
     * @param integer $postId The post id for which the meta should be set.
     * @param string $key The key for the post meta.
     * @return boolean Returns if the post meta key exists for the post id.
     */
    public static function has($postId, $key)
    {
        return \boolval(self::get($postId, $key));
    }
}
app/Helpers/RestApiHelper.php000066600000002576151143705220012164 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

use YoastSEO_Vendor\WordProof\SDK\Config\RoutesConfig;
class RestApiHelper
{
    private static function buildPath($endpoint)
    {
        return 'wordproof/v1' . $endpoint;
    }
    public static function getNamespace()
    {
        return self::buildPath('');
    }
    public static function route($slug)
    {
        $routes = \YoastSEO_Vendor\WordProof\SDK\Config\RoutesConfig::get();
        if (isset($routes[$slug])) {
            return $routes[$slug];
        }
        throw new \Exception('Route slug does not exist.');
    }
    public static function endpoint($slug)
    {
        $route = self::route($slug);
        if (isset($route['endpoint'])) {
            return $route['endpoint'];
        }
        throw new \Exception('Endpoint for route does not exist.');
    }
    public static function getRestRoute($slug, $params = [])
    {
        $url = \get_rest_url(null, self::buildPath(self::endpoint($slug)));
        \preg_match_all("/\\(.+?\\)/", $url, $matches);
        if (!isset($matches) || !isset($matches[0])) {
            return $url;
        }
        if (!\is_array($params) || \count($params) !== \count($matches[0])) {
            return $url;
        }
        foreach ($matches[0] as $index => $match) {
            $url = \str_replace($match, $params[$index], $url);
        }
        return $url;
    }
}
app/Helpers/OptionsHelper.php000066600000013000151143705220012230 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

use YoastSEO_Vendor\WordProof\SDK\Config\OptionsConfig;
class OptionsHelper
{
    private static $prefix = 'wordproof_';
    /**
     * Sets site option while properly sanitizing the data.
     *
     * @param string $key The key to set.
     * @param mixed $value The value to save.
     * @return bool If update_option succeeded.
     */
    public static function set($key, $value)
    {
        if (self::optionContainsOptions($key)) {
            $sanitizedValue = self::secureOptionWithOptions($key, $value, 'sanitize');
            return \update_option(self::$prefix . $key, (object) $sanitizedValue);
        } else {
            $option = self::getOptionFromConfig($key);
            $sanitizedValue = \YoastSEO_Vendor\WordProof\SDK\Helpers\SanitizeHelper::sanitize($value, $option['escape']);
            return \update_option(self::$prefix . $key, $sanitizedValue);
        }
    }
    /**
     * Deletes the site options.
     *
     * @param string $key The key to be deleted.
     * @return mixed
     */
    public static function delete($key)
    {
        return \delete_option(self::$prefix . $key);
    }
    /**
     * Retrieves the site option while properly escaping the data.
     *
     * @param string $key The site option.
     * @return array|bool|int|object|string
     */
    public static function get($key)
    {
        $option = self::getOptionFromConfig($key);
        $value = \get_option(self::$prefix . $key);
        if (self::optionContainsOptions($key)) {
            return self::secureOptionWithOptions($key, $value, 'escape');
        } else {
            return \YoastSEO_Vendor\WordProof\SDK\Helpers\EscapeHelper::escape($value, $option['escape']);
        }
    }
    /**
     * Returns all site options as object.
     *
     * @return object
     */
    public static function all()
    {
        $optionKeys = \array_keys(\YoastSEO_Vendor\WordProof\SDK\Config\OptionsConfig::get());
        foreach ($optionKeys as $key) {
            $options[$key] = self::get($key);
        }
        return (object) $options;
    }
    /**
     * Deletes all site options.
     */
    public static function reset()
    {
        $optionKeys = \array_keys(\YoastSEO_Vendor\WordProof\SDK\Config\OptionsConfig::get());
        foreach ($optionKeys as $key) {
            self::delete($key);
        }
    }
    /**
     * Deletes authentication options.
     */
    public static function resetAuthentication()
    {
        $optionKeys = ['access_token', 'source_id'];
        foreach ($optionKeys as $key) {
            self::delete($key);
        }
    }
    /**
     * Retrieves the access token.
     *
     * @return string|null
     */
    public static function accessToken()
    {
        return self::get('access_token');
    }
    /**
     * Retrieves the source id.
     *
     * @return integer|null
     */
    public static function sourceId()
    {
        return self::get('source_id');
    }
    /**
     * Sets the access token.
     *
     * @param string|null $value The access token to be set.
     * @return bool
     */
    public static function setAccessToken($value)
    {
        return self::set('access_token', $value);
    }
    /**
     * Sets the source id.
     *
     * @param integer|null $value The source id to be set.
     * @return bool
     */
    public static function setSourceId($value)
    {
        return self::set('source_id', $value);
    }
    /**
     * Retrieves the option settings from the config.
     *
     * @param string $key The option key.
     * @return array|false|mixed
     */
    private static function getOptionFromConfig($key)
    {
        $option = \YoastSEO_Vendor\WordProof\SDK\Config\OptionsConfig::get($key);
        if ($option && \array_key_exists('escape', $option) && \array_key_exists('default', $option)) {
            return $option;
        }
        return \false;
    }
    /**
     * Returns if the given option key contains options itself.
     *
     * @param string $key The option key to be checked.
     * @return bool
     */
    private static function optionContainsOptions($key)
    {
        $option = \YoastSEO_Vendor\WordProof\SDK\Config\OptionsConfig::get($key);
        return $option && \array_key_exists('options', $option);
    }
    /**
     * Loops through an option that contains options to either sanitize or escape the result.
     *
     * @param $key
     * @param $value
     * @param string $method
     * @return array|object
     */
    private static function secureOptionWithOptions($key, $value, $method = 'sanitize')
    {
        $isObject = \is_object($value);
        if (\is_object($value)) {
            $value = (array) $value;
        }
        if (\is_array($value)) {
            $values = [];
            foreach ($value as $optionKey => $optionValue) {
                $optionConfig = self::getOptionFromConfig($key . '.options.' . $optionKey);
                if (!$optionConfig) {
                    continue;
                }
                if ($method === 'escape') {
                    $securedValue = \YoastSEO_Vendor\WordProof\SDK\Helpers\EscapeHelper::escape($optionValue, $optionConfig['escape']);
                } else {
                    $securedValue = \YoastSEO_Vendor\WordProof\SDK\Helpers\SanitizeHelper::sanitize($optionValue, $optionConfig['escape']);
                }
                $values[$optionKey] = $securedValue;
            }
            if ($isObject) {
                return (object) $values;
            }
            return $values;
        }
        return [];
    }
}
app/Helpers/ClassicNoticeHelper.php000066600000003154151143705220013331 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

class ClassicNoticeHelper
{
    /**
     * @var string The key used for the transient to save the single notice.
     */
    public static $transientKey = 'wordproof_notice';
    /**
     * Add a new transient with a notice key.
     *
     * @param string $noticeKey The noticeKey that should be displayed to the user.
     */
    public static function add($noticeKey)
    {
        \YoastSEO_Vendor\WordProof\SDK\Helpers\TransientHelper::set(self::$transientKey, $noticeKey);
    }
    /**
     * Add new notice depending on the timestamp response.
     *
     * @param \WP_REST_Response $response The timestamp response.
     */
    public static function addTimestampNotice($response)
    {
        $notice = self::getNoticeKeyForTimestampResponse($response->get_data());
        if ($notice) {
            self::add($notice);
        }
    }
    /**
     * Retrieve notice key for the timestamp response data.
     *
     * @param object $data The timestamp response data.
     * @return string The notice key for this response data.
     */
    private static function getNoticeKeyForTimestampResponse($data)
    {
        if (isset($data->error) && $data->error === 'not_authenticated') {
            return 'not_authenticated';
        }
        if (isset($data->balance) && $data->balance === 0) {
            return 'no_balance';
        }
        if (isset($data->hash)) {
            return 'timestamp_success';
        }
        if (isset($data->error) && $data->error === 'timestamp_failed') {
            return 'timestamp_failed';
        }
        return null;
    }
}
app/Helpers/SanitizeHelper.php000066600000004175151143705220012400 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Helpers;

class SanitizeHelper
{
    /**
     * Returns the value sanitized according to the escape function set in the class.
     *
     * @param mixed $value The value to be sanitized.
     * @param string $sanitizeKey The sanitize function to be used.
     *
     * @return array|bool|int|string
     */
    public static function sanitize($value, $sanitizeKey)
    {
        if (\is_array($value)) {
            return self::sanitizeArray($value, $sanitizeKey);
        }
        if (\is_object($value)) {
            return (object) self::sanitizeArray((array) $value, $sanitizeKey);
        }
        return self::sanitizeSingleValue($value, $sanitizeKey);
    }
    /**
     * Loops through the array to sanitize the values inside.
     *
     * @param array $array The array with values to be escaped.
     * @param string $sanitizeKey The sanitize function to be used.
     * @return array Array with escapes values.
     */
    private static function sanitizeArray($array, $sanitizeKey)
    {
        $values = [];
        foreach ($array as $key => $value) {
            $values[$key] = self::sanitizeSingleValue($value, $sanitizeKey);
        }
        return $values;
    }
    /**
     * Sanitize a single value using an escape function set in the class.
     *
     * @param string $value The value to be sanitized.
     * @param string $sanitizeKey The sanitize function to be used.
     * @return bool|int|string The sanitized value.
     */
    private static function sanitizeSingleValue($value, $sanitizeKey)
    {
        switch ($sanitizeKey) {
            case 'integer':
                return \intval($value);
            case 'boolean':
                return \boolval($value);
            case 'html_class':
                return \sanitize_html_class($value);
            case 'email':
                return \sanitize_email($value);
            case 'url':
                return \esc_url_raw($value);
            case 'key':
                return \sanitize_key($value);
            case 'text_field':
            default:
                return \sanitize_text_field($value);
        }
    }
}
app/Helpers/.htaccess000066600000000424151143705220010530 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>app/Exceptions/ValidationException.php000066600000000174151143705220014135 0ustar00<?php

namespace YoastSEO_Vendor\WordProof\SDK\Exceptions;

use Exception;
class ValidationException extends \Exception
{
}
app/Exceptions/.htaccess000066600000000424151143705220011247 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>.htaccess000066600000000424151143705220006346 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>build/wordproof-block-editor.js000066600000030054151143705220012604 0ustar00!function(){var e={703:function(e,t,o){"use strict";var n=o(414);function r(){}function a(){}a.resetWarningCache=r,e.exports=function(){function e(e,t,o,r,a,s){if(s!==n){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function t(){return e}e.isRequired=e;var o={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:r};return o.PropTypes=o,o}},697:function(e,t,o){e.exports=o(703)()},414:function(e){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"}},t={};function o(n){var r=t[n];if(void 0!==r)return r.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,o),a.exports}o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,{a:t}),t},o.d=function(e,t){for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){"use strict";var e=window.wp.element,t=window.wp.data,n=window.wp.apiFetch,r=o.n(n);async function a(e,t,o){let n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:200;try{const r=await e();return!!r&&(r.status===n?t(r):o(r))}catch(e){}}async function s(e){try{return await r()(e)}catch(e){return e.error&&e.status?e:e instanceof window.Response&&await e.json()}}const i=async()=>await a((async()=>await c()),(e=>e),(()=>!1)),c=async()=>await s({path:"wordproof/v1/oauth/destroy",method:"POST"}),{get:p}=lodash,d=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return p(window,"wordproofSdk.data"+(e?`.${e}`:""),t)};var l=o(697),u=o.n(l);function w(e){const t=new window.CustomEvent(e);window.dispatchEvent(t)}const f=e=>{const{response:t,createSuccessNotice:o,createErrorNotice:n,postId:r}=e;if(null===t||200===t.status)return;const a={id:"wordproof-timestamp-notice"};t&&201===t.status?0===t.balance?(a.actions=[{label:d("translations.open_settings_button_text"),onClick:()=>{w("wordproof:open_settings")},variant:"link"}],n(d("translations.no_balance"),a)):(o(d("translations.timestamp_success"),{type:"snackbar",id:"wordproof-timestamp-notice"}),h(r,t.hash,n,a)):t.error&&("not_authenticated"===t.error?(a.type="snackbar",a.actions=[{label:d("translations.open_authentication_button_text"),onClick:()=>{w("wordproof:open_authentication")},variant:"link"}],n(d("translations.not_authenticated"),a)):n(d("translations.timestamp_failed"),a))},h=async(e,t,o,n)=>{setTimeout((async()=>{const r=await(async e=>s({path:`wordproof/v1/posts/${e}/timestamp/transaction/latest`,method:"GET"}))(e);r.hash!==t&&(n.type="snackbar",o(d("translations.webhook_failed"),n))}),1e4)};f.proptypes={timestampResponse:u().any.isRequired,createSuccessNotice:u().func.isRequired,createErrorNotice:u().func.isRequired,postId:u().number.isRequired};const{debounce:m}=lodash,{applyFilters:y}=wp.hooks;const{dispatch:v}=wp.data;const{subscribe:_,select:g}=wp.data;function b(e){let t=!0;_((()=>{const o=g("core/editor").isSavingPost(),n=g("core/editor").isAutosavingPost(),r=g("core/editor").didPostSaveRequestSucceed();if(o&&r&&!n){if(t)return void(t=!1);e()}}))}const{__:__}=wp.i18n,{useCallback:E}=wp.element,{withSelect:P}=wp.data,{compose:k}=wp.compose,T=t=>{const{isAuthenticated:o}=t,n=d("popup_redirect_authentication_url"),r=d("popup_redirect_settings_url"),a=E((e=>{e.preventDefault(),w("wordproof:open_settings")})),s=E((e=>{e.preventDefault(),w("wordproof:open_authentication")}));return(0,e.createElement)(e.Fragment,null,o&&(0,e.createElement)("a",{href:r,onClick:a},__("Open settings","wordproof")),!o&&(0,e.createElement)("a",{href:n,onClick:s},__("Open authentication","wordproof")))};T.proptypes={isAuthenticated:u().bool.isRequired};var R=k([P((e=>({isAuthenticated:e("wordproof").getIsAuthenticated()})))])(T);const{Modal:S}=wp.components,C=t=>{const{title:o,children:n,close:r}=t;return(0,e.createElement)(e.Fragment,null,(0,e.createElement)(S,{style:{maxWidth:"440px"},title:o,onRequestClose:r},n))};C.proptypes={title:u().string.isRequired,children:u().any,close:u().func.isRequired};var O=C;const{Button:q}=wp.components,{useCallback:W}=wp.element,{__:A}=wp.i18n,L=t=>{const{close:o}=t,n=W((e=>{e.preventDefault(),w("wordproof:open_authentication")}));return(0,e.createElement)(O,{close:o,title:A("Authentication denied","wordproof")},(0,e.createElement)(e.Fragment,null,(0,e.createElement)("p",null,A("You need to allow WordProof to access your site to finish the WordProof installation.","wordproof")),(0,e.createElement)(q,{variant:"primary",onClick:n},A("Retry authentication","wordproof"))))};L.proptypes={close:u().func.isRequired};var $=L;function x(t,o){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return(0,e.createInterpolateElement)(t,{a:(0,e.createElement)("a",{id:n,href:o,target:"_blank",rel:"noopener noreferrer"})})}const{Button:I}=wp.components,{useCallback:D}=wp.element,{__:F,sprintf:M}=wp.i18n,N=t=>{const{close:o}=t,n=D((e=>{e.preventDefault(),w("wordproof:open_authentication")}));return(0,e.createElement)(O,{close:o,title:F("Authentication failed","wordproof")},(0,e.createElement)(e.Fragment,null,(0,e.createElement)("p",null,M(
/* Translators: %s expands to WordProof */
F("Something failed during the authentication of your %s account.","wordproof"),"WordProof"),x(M(
/* Translators: %1s and %2s are html tags. %3s expands to WordProof */
F("Please try again or contact the %1$s%3$s support team%2$s.","wordpress-seo"),"<a>","</a>","WordProof"),"https://help.wordproof.com/")),(0,e.createElement)(I,{variant:"primary",onClick:n},F("Retry authentication","wordproof"))))};N.proptypes={close:u().func.isRequired};var j=N;const{__:Y,sprintf:B}=wp.i18n,{compose:H}=wp.compose,{withSelect:U}=wp.data,z=t=>{const{close:o,postType:n}=t;return(0,e.createElement)(O,{close:o,title:Y("Authenticated","wordproof")},(0,e.createElement)("p",null,B(
/* translators: %s expands to WordProof. */
Y("You have successfully connected your %s account with this site.","wordproof"),"WordProof"),n&&B(
/* translators: %s is the singular post type. */
Y("Your %s will now be timestamped everytime you update or publish.","wordproof"),n)))};z.proptypes={close:u().func.isRequired};var G=H([U((e=>({postType:e("core/editor").getCurrentPostType()})))])(z);const{__:V,sprintf:X}=wp.i18n,J=t=>{const{close:o}=t;return(0,e.createElement)(O,{close:o,title:V("Webhook failed","wordproof")},(0,e.createElement)("p",null,X(
/* Translators: %s expands to WordProof */
V("The timestamp sent by %s was not received on your website.","WordProof"),"WordProof"),x(X(
/* Translators: %1s and %2s are html tags. %3s expands to WordProof */
V("Please contact the %1$s%3$s support team%2$s to help solve this problem.","wordpress-seo"),"<a>","</a>","WordProof"),"https://help.wordproof.com/")))};J.proptypes={close:u().func.isRequired};var K=J;const{useState:Q,useCallback:Z,useEffect:ee}=wp.element;var te=()=>{const[t,o]=Q(null),n=Z((()=>{o("oauth:failed")})),r=Z((()=>{o("oauth:denied")})),a=Z((()=>{o("webhook:failed")})),s=Z((()=>{o("oauth:success")})),i=Z((()=>{o(null)}));return ee((()=>(window.addEventListener("wordproof:oauth:success",s,!1),window.addEventListener("wordproof:oauth:failed",n,!1),window.addEventListener("wordproof:oauth:denied",r,!1),window.addEventListener("wordproof:webhook:failed",a,!1),()=>{window.removeEventListener("wordproof:oauth:success",s,!1),window.removeEventListener("wordproof:oauth:failed",n,!1),window.removeEventListener("wordproof:oauth:denied",r,!1),window.removeEventListener("wordproof:webhook:failed",a,!1)})),[]),(0,e.createElement)(e.Fragment,null,"oauth:success"===t&&(0,e.createElement)(G,{close:i}),"oauth:denied"===t&&(0,e.createElement)($,{close:i}),"oauth:failed"===t&&(0,e.createElement)(j,{close:i}),"webhook:failed"===t&&(0,e.createElement)(K,{close:i}))};const{__:oe,sprintf:ne}=wp.i18n,{PluginDocumentSettingPanel:re}=wp.editPost,{ToggleControl:ae,PanelRow:se}=wp.components,{compose:ie}=wp.compose,{withSelect:ce,withDispatch:pe}=wp.data,{useCallback:de}=wp.element,le=t=>{let{postType:o,postMeta:n,isAuthenticated:r,selectedPostTypes:a,setPostMeta:s}=t;const i=de((()=>a.includes(o)),[a,o]),c=de((()=>{w("wordproof:open_authentication")}));return void 0===n?(0,e.createElement)(e.Fragment,null):(0,e.createElement)(re,{title:oe("WordProof Timestamp","wordproof"),initialOpen:"true"},(0,e.createElement)(se,null,(0,e.createElement)(ae,{label:ne(
/* translators: %s expands to the post type */
oe("Timestamp this %s","wordproof"),o),onChange:e=>{s({_wordproof_timestamp:e}),r||!0!==e||c()},checked:n._wordproof_timestamp||i(),disabled:i()})),(0,e.createElement)(se,null,(0,e.createElement)(R,null)),(0,e.createElement)(te,null))};le.proptypes={postType:u().string.isRequired,postMeta:u().object.isRequired,isAuthenticated:u().bool.isRequired,setPostMeta:u().func.isRequired};var ue=ie([ce((e=>({postMeta:e("core/editor").getEditedPostAttribute("meta"),postType:e("core/editor").getCurrentPostType(),isAuthenticated:e("wordproof").getIsAuthenticated(),selectedPostTypes:e("wordproof").getSelectedPostTypes()}))),pe((e=>({setPostMeta(t){e("core/editor").editPost({meta:t})}})))])(le);const{registerPlugin:we}=wp.plugins;we("wordproof-timestamp-panel",{render:()=>(0,e.createElement)(ue,null)}),function(){const{createSuccessNotice:e,createErrorNotice:o}=(0,t.dispatch)("core/notices");(function(){const{setIsAuthenticated:e,setSelectedPostTypes:t}=v("wordproof"),o=d("popup_redirect_authentication_url"),n=d("popup_redirect_settings_url");let r=null;const c=(e,t)=>{r=function(e,t){let o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:800,r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:680;const a=e.top.outerHeight/2+e.top.screenY-r/2,s=e.top.outerWidth/2+e.top.screenX-n/2;return e.open(t,o,`toolbar=no,\n\t\tlocation=no,\n\t\tdirectories=no,\n\t\tstatus=no,\n\t\tmenubar=no,\n\t\tresizable=no,\n\t\tcopyhistory=no,\n\t\twidth=${n},\n\t\theight=${r},\n\t\ttop=${a},\n\t\tleft=${s}`)}(window,e,t),r&&r.focus(),window.addEventListener("message",p,!1)},p=async e=>{const{data:t,source:o,origin:n}=e;if(n===d("origin")&&r===o)switch(t.type){case"wordproof:oauth:granted":!1===await f(t)&&await l("wordproof:oauth:failed",!1);break;case"wordproof:oauth:failed":await l("wordproof:oauth:failed",!1);break;case"wordproof:oauth:denied":await l("wordproof:oauth:denied",!1);break;case"wordproof:webhook:success":await l("wordproof:oauth:success",!0);break;case"wordproof:webhook:failed":await l("wordproof:webhook:failed",!1);break;case"wordproof:settings:updated":await l("wordproof:settings:updated"),await h(t);break;case"wordproof:oauth:destroy":await l("wordproof:oauth:destroy",!1);break;case"wordproof:oauth:retry":await l("wordproof:open_authentication",!1);break;case"wordproof:oauth:close":u()}},l=async function(t){let o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;u(),w(t),!1===o&&(await i(),e(!1)),!0===o&&e(!0)},u=()=>{window.removeEventListener("message",p,!1),r.close()},f=async e=>{await a((()=>(async e=>{const{state:t,code:o}=e;return await s({path:"wordproof/v1/oauth/authenticate",method:"POST",data:{state:t,code:o}})})(e)),(async e=>{const t={type:"wordproof:sdk:access-token",source_id:e.source_id};return r.postMessage(t,d("origin")),!0}),(async()=>!1))},h=async e=>{await a((()=>(async e=>{const{settings:t}=e;return await s({path:"wordproof/v1/settings",method:"POST",data:{settings:t}})})(e)),(async()=>{const o=e.settings;return o.selectedPostTypes&&t(o.selectedPostTypes),!0}),(async()=>!1))};window.addEventListener("wordproof:open_authentication",(e=>{e.preventDefault(),c(o,"WordProof_Authentication")}),!1),window.addEventListener("wordproof:open_settings",(e=>{e.preventDefault(),c(n,"WordProof_Settings")}),!1)})(),function(e,t,o){e(m((async()=>{if(y("wordproof.timestamp",!0)){const e=d("current_post_id"),n=await(async e=>s({path:`wordproof/v1/posts/${e}/timestamp`,method:"POST"}))(e);f({response:n,createSuccessNotice:t,createErrorNotice:o,postId:e})}}),500))}(b,e,o)}()}()}();build/.htaccess000066600000000424151143705220007445 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>build/wordproof-elementor-editor.js000066600000014434151143705220013510 0ustar00!function(){var t={703:function(t,o,e){"use strict";var n=e(414);function a(){}function r(){}r.resetWarningCache=a,t.exports=function(){function t(t,o,e,a,r,s){if(s!==n){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function o(){return t}t.isRequired=t;var e={array:t,bigint:t,bool:t,func:t,number:t,object:t,string:t,symbol:t,any:t,arrayOf:o,element:t,elementType:t,instanceOf:o,node:t,objectOf:o,oneOf:o,oneOfType:o,shape:o,exact:o,checkPropTypes:r,resetWarningCache:a};return e.PropTypes=e,e}},697:function(t,o,e){t.exports=e(703)()},414:function(t){"use strict";t.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"}},o={};function e(n){var a=o[n];if(void 0!==a)return a.exports;var r=o[n]={exports:{}};return t[n](r,r.exports,e),r.exports}e.n=function(t){var o=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(o,{a:o}),o},e.d=function(t,o){for(var n in o)e.o(o,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:o[n]})},e.o=function(t,o){return Object.prototype.hasOwnProperty.call(t,o)},function(){"use strict";var t=window.wp.apiFetch,o=e.n(t);async function n(t,o,e){let n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:200;try{const a=await t();return!!a&&(a.status===n?o(a):e(a))}catch(t){}}async function a(t){try{return await o()(t)}catch(t){return t.error&&t.status?t:t instanceof window.Response&&await t.json()}}const r=async()=>await n((async()=>await s()),(t=>t),(()=>!1)),s=async()=>await a({path:"wordproof/v1/oauth/destroy",method:"POST"}),{get:i}=lodash,c=function(t){let o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return i(window,"wordproofSdk.data"+(t?`.${t}`:""),o)};var d=e(697),p=e.n(d);function u(t){const o=new window.CustomEvent(t);window.dispatchEvent(o)}const w=t=>{const{response:o,createSuccessNotice:e,createErrorNotice:n,postId:a}=t;if(null===o||200===o.status)return;const r={id:"wordproof-timestamp-notice"};o&&201===o.status?0===o.balance?(r.actions=[{label:c("translations.open_settings_button_text"),onClick:()=>{u("wordproof:open_settings")},variant:"link"}],n(c("translations.no_balance"),r)):(e(c("translations.timestamp_success"),{type:"snackbar",id:"wordproof-timestamp-notice"}),f(a,o.hash,n,r)):o.error&&("not_authenticated"===o.error?(r.type="snackbar",r.actions=[{label:c("translations.open_authentication_button_text"),onClick:()=>{u("wordproof:open_authentication")},variant:"link"}],n(c("translations.not_authenticated"),r)):n(c("translations.timestamp_failed"),r))},f=async(t,o,e,n)=>{setTimeout((async()=>{const r=await(async t=>a({path:`wordproof/v1/posts/${t}/timestamp/transaction/latest`,method:"GET"}))(t);r.hash!==o&&(n.type="snackbar",e(c("translations.webhook_failed"),n))}),1e4)};w.proptypes={timestampResponse:p().any.isRequired,createSuccessNotice:p().func.isRequired,createErrorNotice:p().func.isRequired,postId:p().number.isRequired};const{debounce:l}=lodash,{applyFilters:h}=wp.hooks;const{dispatch:y}=wp.data;$e.modules.hookUI.Base;class m extends $e.modules.hookData.Base{constructor(t,o,e){super(),this.hook=t,this.id=o,this.callback=e}getCommand(){return this.hook}getId(){return this.id}apply(){return this.callback()}}function b(t,o){let e=null;o.actions&&(e=[],o.actions.forEach((t=>{e.push({name:"wordproof_notice_button",text:t.label,callback(){t.onClick()}})}))),window.elementor.notifications.showToast({message:t,buttons:e})}(function(){const{setIsAuthenticated:t,setSelectedPostTypes:o}=y("wordproof"),e=c("popup_redirect_authentication_url"),s=c("popup_redirect_settings_url");let i=null;const d=(t,o)=>{i=function(t,o){let e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:800,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:680;const r=t.top.outerHeight/2+t.top.screenY-a/2,s=t.top.outerWidth/2+t.top.screenX-n/2;return t.open(o,e,`toolbar=no,\n\t\tlocation=no,\n\t\tdirectories=no,\n\t\tstatus=no,\n\t\tmenubar=no,\n\t\tresizable=no,\n\t\tcopyhistory=no,\n\t\twidth=${n},\n\t\theight=${a},\n\t\ttop=${r},\n\t\tleft=${s}`)}(window,t,o),i&&i.focus(),window.addEventListener("message",p,!1)},p=async t=>{const{data:o,source:e,origin:n}=t;if(n===c("origin")&&i===e)switch(o.type){case"wordproof:oauth:granted":!1===await l(o)&&await w("wordproof:oauth:failed",!1);break;case"wordproof:oauth:failed":await w("wordproof:oauth:failed",!1);break;case"wordproof:oauth:denied":await w("wordproof:oauth:denied",!1);break;case"wordproof:webhook:success":await w("wordproof:oauth:success",!0);break;case"wordproof:webhook:failed":await w("wordproof:webhook:failed",!1);break;case"wordproof:settings:updated":await w("wordproof:settings:updated"),await h(o);break;case"wordproof:oauth:destroy":await w("wordproof:oauth:destroy",!1);break;case"wordproof:oauth:retry":await w("wordproof:open_authentication",!1);break;case"wordproof:oauth:close":f()}},w=async function(o){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;f(),u(o),!1===e&&(await r(),t(!1)),!0===e&&t(!0)},f=()=>{window.removeEventListener("message",p,!1),i.close()},l=async t=>{await n((()=>(async t=>{const{state:o,code:e}=t;return await a({path:"wordproof/v1/oauth/authenticate",method:"POST",data:{state:o,code:e}})})(t)),(async t=>{const o={type:"wordproof:sdk:access-token",source_id:t.source_id};return i.postMessage(o,c("origin")),!0}),(async()=>!1))},h=async t=>{await n((()=>(async t=>{const{settings:o}=t;return await a({path:"wordproof/v1/settings",method:"POST",data:{settings:o}})})(t)),(async()=>{const e=t.settings;return e.selectedPostTypes&&o(e.selectedPostTypes),!0}),(async()=>!1))};window.addEventListener("wordproof:open_authentication",(t=>{t.preventDefault(),d(e,"WordProof_Authentication")}),!1),window.addEventListener("wordproof:open_settings",(t=>{t.preventDefault(),d(s,"WordProof_Settings")}),!1)})(),function(t,o,e){t(l((async()=>{if(h("wordproof.timestamp",!0)){const t=c("current_post_id"),n=await(async t=>a({path:`wordproof/v1/posts/${t}/timestamp`,method:"POST"}))(t);w({response:n,createSuccessNotice:o,createErrorNotice:e,postId:t})}}),500))}((function(t){!function(t,o,e){$e&&$e.hooks.registerDataAfter(new m("document/save/save","wordproof/timestamper",e))}(0,0,(()=>{window.setTimeout(t,1e3)}))}),b,b)}()}();build/data.js000066600000003361151143705220007121 0ustar00!function(){"use strict";var e={n:function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,{a:n}),n},d:function(t,n){for(var s in n)e.o(n,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:n[s]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t=window.wp.apiFetch,n=e.n(t);const{get:s}=lodash,c=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return s(window,"wordproofSdk.data"+(e?`.${e}`:""),t)},{createReduxStore:a,registerStore:r,register:o}=wp.data,d="wordproof",i={isAuthenticated:c("is_authenticated",!1),balance:c("balance",0),selectedPostTypes:c("settings.selected_post_types",[])},u={setIsAuthenticated:e=>({type:"SET_IS_AUTHENTICATED",isAuthenticated:e}),getIsAuthenticated:()=>({type:"GET_IS_AUTHENTICATED"}),setBalance:e=>({type:"SET_BALANCE",balance:e}),getBalance:()=>({type:"GET_BALANCE"}),setSelectedPostTypes:e=>({type:"SET_SELECTED_POST_TYPES",selectedPostTypes:e}),getSelectedPostTypes:()=>({type:"GET_SELECTED_POST_TYPES"})},T={reducer:function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:i,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case"SET_IS_AUTHENTICATED":return{...e,isAuthenticated:t.isAuthenticated};case"SET_BALANCE":return{...e,balance:t.balance};case"SET_SELECTED_POST_TYPES":return{...e,selectedPostTypes:t.selectedPostTypes};default:return e}},controls:{fetchIsAuthenticated:e=>n()({path:e.path})},selectors:{getIsAuthenticated(e){const{isAuthenticated:t}=e;return t},getBalance(e){const{balance:t}=e;return t},getSelectedPostTypes(e){const{selectedPostTypes:t}=e;return t}},resolvers:{*fetchIsAuthenticated(){const e=yield u.getIsAuthenticated();return u.setIsAuthenticated(e)}},actions:u};a?o(a(d,T)):r(d,T)}();build/wordproof-classic-editor.js000066600000013103151143705220013127 0ustar00!function(){var t={703:function(t,e,o){"use strict";var n=o(414);function r(){}function a(){}a.resetWarningCache=r,t.exports=function(){function t(t,e,o,r,a,s){if(s!==n){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function e(){return t}t.isRequired=t;var o={array:t,bigint:t,bool:t,func:t,number:t,object:t,string:t,symbol:t,any:t,arrayOf:e,element:t,elementType:t,instanceOf:e,node:t,objectOf:e,oneOf:e,oneOfType:e,shape:e,exact:e,checkPropTypes:a,resetWarningCache:r};return o.PropTypes=o,o}},697:function(t,e,o){t.exports=o(703)()},414:function(t){"use strict";t.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"}},e={};function o(n){var r=e[n];if(void 0!==r)return r.exports;var a=e[n]={exports:{}};return t[n](a,a.exports,o),a.exports}o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,{a:e}),e},o.d=function(t,e){for(var n in e)o.o(e,n)&&!o.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},function(){"use strict";var t=window.wp.element,e=window.wp.apiFetch,n=o.n(e);async function r(t,e,o){let n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:200;try{const r=await t();return!!r&&(r.status===n?e(r):o(r))}catch(t){}}async function a(t){try{return await n()(t)}catch(t){return t.error&&t.status?t:t instanceof window.Response&&await t.json()}}const s=async()=>await r((async()=>await(async()=>await a({path:"wordproof/v1/oauth/destroy",method:"POST"}))()),(t=>t),(()=>!1)),{get:i}=lodash,c=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return i(window,"wordproofSdk.data"+(t?`.${t}`:""),e)};function d(t){const e=new window.CustomEvent(t);window.dispatchEvent(e)}function p(){d("wordproof:open_authentication")}const{dispatch:u}=wp.data;var w=o(697),f=o.n(w);const{__:__}=wp.i18n,{useCallback:l}=wp.element,{withSelect:h}=wp.data,{compose:y}=wp.compose,g=e=>{const{isAuthenticated:o}=e,n=c("popup_redirect_authentication_url"),r=c("popup_redirect_settings_url"),a=l((t=>{t.preventDefault(),d("wordproof:open_settings")})),s=l((t=>{t.preventDefault(),p()}));return(0,t.createElement)(t.Fragment,null,o&&(0,t.createElement)("a",{href:r,onClick:a},__("Open settings","wordproof")),!o&&(0,t.createElement)("a",{href:n,onClick:s},__("Open authentication","wordproof")))};g.proptypes={isAuthenticated:f().bool.isRequired};var _=y([h((t=>({isAuthenticated:t("wordproof").getIsAuthenticated()})))])(g);const{render:v}=wp.element,{select:b,subscribe:m}=wp.data;(function(){const{setIsAuthenticated:t,setSelectedPostTypes:e}=u("wordproof"),o=c("popup_redirect_authentication_url"),n=c("popup_redirect_settings_url");let i=null;const p=(t,e)=>{i=function(t,e){let o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:800,r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:680;const a=t.top.outerHeight/2+t.top.screenY-r/2,s=t.top.outerWidth/2+t.top.screenX-n/2;return t.open(e,o,`toolbar=no,\n\t\tlocation=no,\n\t\tdirectories=no,\n\t\tstatus=no,\n\t\tmenubar=no,\n\t\tresizable=no,\n\t\tcopyhistory=no,\n\t\twidth=${n},\n\t\theight=${r},\n\t\ttop=${a},\n\t\tleft=${s}`)}(window,t,e),i&&i.focus(),window.addEventListener("message",w,!1)},w=async t=>{const{data:e,source:o,origin:n}=t;if(n===c("origin")&&i===o)switch(e.type){case"wordproof:oauth:granted":!1===await h(e)&&await f("wordproof:oauth:failed",!1);break;case"wordproof:oauth:failed":await f("wordproof:oauth:failed",!1);break;case"wordproof:oauth:denied":await f("wordproof:oauth:denied",!1);break;case"wordproof:webhook:success":await f("wordproof:oauth:success",!0);break;case"wordproof:webhook:failed":await f("wordproof:webhook:failed",!1);break;case"wordproof:settings:updated":await f("wordproof:settings:updated"),await y(e);break;case"wordproof:oauth:destroy":await f("wordproof:oauth:destroy",!1);break;case"wordproof:oauth:retry":await f("wordproof:open_authentication",!1);break;case"wordproof:oauth:close":l()}},f=async function(e){let o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;l(),d(e),!1===o&&(await s(),t(!1)),!0===o&&t(!0)},l=()=>{window.removeEventListener("message",w,!1),i.close()},h=async t=>{await r((()=>(async t=>{const{state:e,code:o}=t;return await a({path:"wordproof/v1/oauth/authenticate",method:"POST",data:{state:e,code:o}})})(t)),(async t=>{const e={type:"wordproof:sdk:access-token",source_id:t.source_id};return i.postMessage(e,c("origin")),!0}),(async()=>!1))},y=async t=>{await r((()=>(async t=>{const{settings:e}=t;return await a({path:"wordproof/v1/settings",method:"POST",data:{settings:e}})})(t)),(async()=>{const o=t.settings;return o.selectedPostTypes&&e(o.selectedPostTypes),!0}),(async()=>!1))};window.addEventListener("wordproof:open_authentication",(t=>{t.preventDefault(),p(o,"WordProof_Authentication")}),!1),window.addEventListener("wordproof:open_settings",(t=>{t.preventDefault(),p(n,"WordProof_Settings")}),!1)})(),window.addEventListener("DOMContentLoaded",(e=>{O=document.querySelector("#_wordproof_timestamp"),E=O.checked,O&&(P=document.querySelector("#wordproof-action-link"),P&&v((0,t.createElement)(_,null),P),T(S()),m((()=>{T(S())})),O.addEventListener("change",(t=>{!b("wordproof").getIsAuthenticated()&&O.checked&&p()})))}));const k=c("current_post_type");let O=null,E=null,P=null;function T(t){t.includes(k)?(O.disabled=!0,O.checked=!0):(O.disabled=!1,O.checked=E)}function S(){return b("wordproof").getSelectedPostTypes()}}()}();