Plugin Directory

Changeset 3446589


Ignore:
Timestamp:
01/25/2026 03:59:02 PM (2 months ago)
Author:
tripleatechnology
Message:

Version 2.0.24 - Custom encryption key system

with setup wizard and security improvements

Location:
triplea-cryptocurrency-payment-gateway-for-woocommerce/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • triplea-cryptocurrency-payment-gateway-for-woocommerce/trunk/includes/WooCommerce/TripleA_Payment_Gateway.php

    r3446489 r3446589  
    4747        // load the settings.
    4848        $this->init_settings();
     49
     50        // Migrate old encryption if needed (one-time migration when TRIPLEA_ENCRYPTION_KEY is first added)
     51        if (is_admin()) {
     52            $this->migrate_old_encryption();
     53        }
    4954
    5055        $this->enabled          = $this->get_option('enabled');
     
    146151    public function save_plugin_options()
    147152    {
    148         // Handle client_secret encryption with placeholder detection
     153        // Handle client_secret encryption
    149154        $client_secret_raw = null;
    150155        $client_secret_posted = !empty($_POST['woocommerce_triplea_payment_gateway_client_secret']) ? $_POST['woocommerce_triplea_payment_gateway_client_secret'] : '';
    151         $client_secret_exists = !empty($_POST['clientSecretExists']) && $_POST['clientSecretExists'] === '1';
    152 
    153         // Detect placeholder pattern: **********XXXX (10 asterisks + last 4 chars)
    154         $is_placeholder = (strlen($client_secret_posted) >= 10 && substr($client_secret_posted, 0, 10) === str_repeat('*', 10));
    155 
    156         // Only update client_secret if it's NOT the placeholder (i.e., user entered a new value)
    157         if (!empty($client_secret_posted) && !$is_placeholder) {
    158             // User entered a new secret - encrypt and save it
     156
     157        // Check if encryption key is defined
     158        if (!defined('TRIPLEA_ENCRYPTION_KEY') || empty(TRIPLEA_ENCRYPTION_KEY)) {
     159            // Add admin notice about missing encryption key
     160            add_settings_error(
     161                'triplea_payment_gateway',
     162                'triplea_encryption_key_missing',
     163                __('TripleA Encryption Error: TRIPLEA_ENCRYPTION_KEY is not defined in wp-config.php. Please add your encryption key to wp-config.php before configuring credentials.', 'wc-triplea-crypto-payment'),
     164                'error'
     165            );
     166            return; // Stop processing settings save
     167        }
     168
     169        // If client_secret is posted, encrypt and save it
     170        if (!empty($client_secret_posted)) {
    159171            $client_secret_raw = $client_secret_posted;
    160172            $client_secret_encrypted = $this->encrypt_credential($client_secret_raw);
     173
     174            if ($client_secret_encrypted === false) {
     175                // Encryption failed
     176                add_settings_error(
     177                    'triplea_payment_gateway',
     178                    'triplea_encryption_failed',
     179                    __('TripleA Encryption Error: Failed to encrypt client secret. Please check your TRIPLEA_ENCRYPTION_KEY in wp-config.php.', 'wc-triplea-crypto-payment'),
     180                    'error'
     181                );
     182                return; // Stop processing settings save
     183            }
     184
    161185            $this->settings['client_secret'] = $client_secret_encrypted;
    162         } elseif ($is_placeholder && $client_secret_exists) {
    163             // User left placeholder unchanged - keep existing encrypted value, decrypt for OAuth
    164             $client_secret_raw = $this->decrypt_credential($this->get_option('client_secret'));
    165         }
    166         // If empty or other case, $client_secret_raw remains null
     186        }
    167187
    168188        if (!empty($_POST['clientID']) && (isset($_POST['oAuthToken']) || isset($_POST['oAuthTokenExpiry']))) {
     
    23942414        }
    23952415
    2396         // Check if required WordPress constants are defined
    2397         if (!defined('AUTH_KEY') || !defined('SECURE_AUTH_KEY')) {
     2416        // Check if TripleA custom encryption key is defined in wp-config.php
     2417        if (!defined('TRIPLEA_ENCRYPTION_KEY') || empty(TRIPLEA_ENCRYPTION_KEY)) {
    23982418            if (isset($this->logger)) {
    2399                 $this->logger->write_log('encrypt_credential(): WordPress security keys not defined. Cannot encrypt credentials.', true);
    2400             }
    2401             return $value; // Return unencrypted if keys missing
    2402         }
    2403 
    2404         $key = hash('sha256', AUTH_KEY . SECURE_AUTH_KEY);
     2419                $this->logger->write_log('encrypt_credential(): TRIPLEA_ENCRYPTION_KEY not defined in wp-config.php. Cannot encrypt credentials.', true);
     2420            }
     2421            return false; // Return false to indicate encryption failure
     2422        }
     2423
     2424        $key = hash('sha256', TRIPLEA_ENCRYPTION_KEY);
    24052425        $iv = openssl_random_pseudo_bytes(16);
    24062426        $encrypted = openssl_encrypt($value, 'AES-256-CBC', $key, 0, $iv);
     
    24102430                $this->logger->write_log('encrypt_credential(): OpenSSL encryption failed.', true);
    24112431            }
    2412             return $value; // Return unencrypted if encryption fails
     2432            return false; // Return false to indicate encryption failure
    24132433        }
    24142434
     
    24292449        }
    24302450
    2431         // Check if required WordPress constants are defined
    2432         if (!defined('AUTH_KEY') || !defined('SECURE_AUTH_KEY')) {
     2451        // Check if TripleA custom encryption key is defined in wp-config.php
     2452        if (!defined('TRIPLEA_ENCRYPTION_KEY') || empty(TRIPLEA_ENCRYPTION_KEY)) {
    24332453            if (isset($this->logger)) {
    2434                 $this->logger->write_log('decrypt_credential(): WordPress security keys not defined. Cannot decrypt credentials.', true);
     2454                $this->logger->write_log('decrypt_credential(): TRIPLEA_ENCRYPTION_KEY not defined in wp-config.php. Cannot decrypt credentials.', true);
    24352455            }
    24362456            return ''; // Return empty string if cannot decrypt
    24372457        }
    24382458
    2439         $key = hash('sha256', AUTH_KEY . SECURE_AUTH_KEY);
     2459        $key = hash('sha256', TRIPLEA_ENCRYPTION_KEY);
    24402460        $data = base64_decode(substr($value, 4));
    24412461
     
    24612481        return $decrypted;
    24622482    }
     2483
     2484    /**
     2485     * Migrate old credentials encrypted with WordPress keys to new TRIPLEA_ENCRYPTION_KEY
     2486     *
     2487     * @return bool True if migration was successful or not needed, false on failure
     2488     * @since 2.0.24
     2489     */
     2490    protected function migrate_old_encryption()
     2491    {
     2492        // Only proceed if new encryption key is defined
     2493        if (!defined('TRIPLEA_ENCRYPTION_KEY') || empty(TRIPLEA_ENCRYPTION_KEY)) {
     2494            return false;
     2495        }
     2496
     2497        // Check if WordPress keys are defined (needed to decrypt old data)
     2498        if (!defined('AUTH_KEY') || !defined('SECURE_AUTH_KEY')) {
     2499            // Can't migrate without old keys - admin will need to re-enter credentials
     2500            if (isset($this->logger)) {
     2501                $this->logger->write_log('migrate_old_encryption(): Cannot migrate - WordPress security keys not defined.', true);
     2502            }
     2503            return false;
     2504        }
     2505
     2506        // Get current client_secret from database
     2507        $client_secret_encrypted = $this->get_option('client_secret');
     2508
     2509        if (empty($client_secret_encrypted) || strpos($client_secret_encrypted, 'ENC:') !== 0) {
     2510            // No encrypted secret to migrate
     2511            return true;
     2512        }
     2513
     2514        // Try to decrypt using old method (WordPress AUTH_KEY + SECURE_AUTH_KEY)
     2515        $old_key = hash('sha256', AUTH_KEY . SECURE_AUTH_KEY);
     2516        $data = base64_decode(substr($client_secret_encrypted, 4));
     2517
     2518        if (strlen($data) < 16) {
     2519            return false;
     2520        }
     2521
     2522        $iv = substr($data, 0, 16);
     2523        $encrypted = substr($data, 16);
     2524
     2525        $decrypted = openssl_decrypt($encrypted, 'AES-256-CBC', $old_key, 0, $iv);
     2526
     2527        if ($decrypted === false) {
     2528            // Decryption with old key failed - might already be using new key
     2529            // Try with new key to verify
     2530            $new_key = hash('sha256', TRIPLEA_ENCRYPTION_KEY);
     2531            $test_decrypt = openssl_decrypt($encrypted, 'AES-256-CBC', $new_key, 0, $iv);
     2532
     2533            if ($test_decrypt !== false) {
     2534                // Already using new encryption key - migration not needed
     2535                if (isset($this->logger)) {
     2536                    $this->logger->write_log('migrate_old_encryption(): Credentials already using new encryption key.', true);
     2537                }
     2538                return true;
     2539            }
     2540
     2541            // Can't decrypt with either key - credentials are corrupted
     2542            if (isset($this->logger)) {
     2543                $this->logger->write_log('migrate_old_encryption(): Failed to decrypt credentials with old or new key.', true);
     2544            }
     2545            return false;
     2546        }
     2547
     2548        // Successfully decrypted with old key - now re-encrypt with new key
     2549        $new_encrypted = $this->encrypt_credential($decrypted);
     2550
     2551        if ($new_encrypted === false) {
     2552            if (isset($this->logger)) {
     2553                $this->logger->write_log('migrate_old_encryption(): Failed to re-encrypt credentials with new key.', true);
     2554            }
     2555            return false;
     2556        }
     2557
     2558        // Save the re-encrypted credential
     2559        $this->settings['client_secret'] = $new_encrypted;
     2560        update_option($this->get_option_key(), apply_filters('woocommerce_settings_api_sanitized_fields_' . $this->id, $this->settings), 'yes');
     2561
     2562        if (isset($this->logger)) {
     2563            $this->logger->write_log('migrate_old_encryption(): Successfully migrated credentials to new encryption key.', true);
     2564        }
     2565
     2566        return true;
     2567    }
    24632568}
  • triplea-cryptocurrency-payment-gateway-for-woocommerce/trunk/includes/WooCommerce/views/triplea_options.php

    r3446493 r3446589  
    2727    $merchantKey  = ( !empty( $plugin_settings['merchant_key'] ) ) ? $plugin_settings['merchant_key'] : '';
    2828    $clientID     = ( !empty( $plugin_settings['client_id'] ) ) ? $plugin_settings['client_id'] : '';
    29     // Use placeholder for security - show last 4 characters only
     29    // Check if client secret exists (never display the actual value)
    3030    $clientSecret_encrypted = ( !empty( $plugin_settings['client_secret'] ) ) ? $plugin_settings['client_secret'] : '';
    31     $clientSecret_exists = !empty($clientSecret_encrypted);
    32 
    33     if ($clientSecret_exists) {
    34         // Decrypt temporarily to get last 4 characters for placeholder
    35         $clientSecret_real = $this->decrypt_credential($clientSecret_encrypted);
    36         $last4 = strlen($clientSecret_real) >= 4 ? substr($clientSecret_real, -4) : $clientSecret_real;
    37         $clientSecret = str_repeat('*', 10) . $last4; // Format: **********9384
    38     } else {
    39         $clientSecret = '';
    40     }
     31    $clientSecret_exists = !empty($clientSecret_encrypted) && strpos($clientSecret_encrypted, 'ENC:') === 0;
    4132
    4233    //Settings Section
     
    6556        <div class="triplea-tab-content">
    6657            <div id="account" class="tab-content">
     58                <?php
     59                // Check if encryption key is defined
     60                $encryption_key_defined = defined('TRIPLEA_ENCRYPTION_KEY') && !empty(TRIPLEA_ENCRYPTION_KEY);
     61
     62                if (!$encryption_key_defined):
     63                ?>
     64                <div class="triplea-settings-notice" style="background-color:#fff3cd;border-left:4px solid #ffc107;padding:20px;margin-bottom:20px;">
     65                    <h3 style="margin-top:0;color:#856404;">&#9888; <?php _e('Encryption Key Setup Required', 'wc-triplea-crypto-payment'); ?></h3>
     66                    <p style="margin-bottom:15px;"><?php _e('Before configuring your TripleA credentials, you must add an encryption key to your wp-config.php file.', 'wc-triplea-crypto-payment'); ?></p>
     67
     68                    <div style="background:#fff;padding:20px;border-radius:4px;margin:20px 0;border:1px solid #ddd;">
     69                        <h4 style="margin-top:0;"><?php _e('Step 1: Create Your Encryption Key', 'wc-triplea-crypto-payment'); ?></h4>
     70                        <p><?php _e('You can either generate a random passphrase or enter your own (minimum 16 characters):', 'wc-triplea-crypto-payment'); ?></p>
     71
     72                        <div style="margin:15px 0;">
     73                            <label style="display:block;margin-bottom:5px;font-weight:600;"><?php _e('Your Passphrase:', 'wc-triplea-crypto-payment'); ?></label>
     74                            <div style="display:flex;gap:10px;align-items:flex-start;">
     75                                <input type="text" id="triplea_passphrase_value" placeholder="<?php _e('Enter your passphrase or click Generate button', 'wc-triplea-crypto-payment'); ?>" style="flex:1;padding:10px;font-family:monospace;background:#fff;border:1px solid #ddd;border-radius:4px;font-size:14px;">
     76                                <button type="button" id="triplea_generate_passphrase" class="button" style="white-space:nowrap;">
     77                                    <span class="dashicons dashicons-update" style="margin-top:3px;"></span> <?php _e('Generate Random', 'wc-triplea-crypto-payment'); ?>
     78                                </button>
     79                            </div>
     80                            <p style="margin-top:8px;color:#666;font-size:13px;"><?php _e('Minimum 16 characters. Use letters, numbers, and special characters for better security.', 'wc-triplea-crypto-payment'); ?></p>
     81                        </div>
     82
     83                        <p style="margin-top:15px;color:#dc3232;font-weight:600;">&#9888; <?php _e('IMPORTANT: Save this passphrase securely! If you lose it, you will need to re-enter all credentials.', 'wc-triplea-crypto-payment'); ?></p>
     84                    </div>
     85
     86                    <div style="background:#fff;padding:20px;border-radius:4px;margin:20px 0;border:1px solid #ddd;">
     87                        <h4 style="margin-top:0;"><?php _e('Step 2: Add to wp-config.php', 'wc-triplea-crypto-payment'); ?></h4>
     88                        <p><?php _e('Copy the code below and add it to your wp-config.php file:', 'wc-triplea-crypto-payment'); ?></p>
     89
     90                        <div style="position:relative;margin:15px 0;">
     91                            <textarea id="triplea_config_code" readonly style="width:100%;height:80px;font-family:monospace;padding:12px;background:#f6f7f7;border:1px solid #ddd;border-radius:4px;resize:none;font-size:13px;line-height:1.6;">define('TRIPLEA_ENCRYPTION_KEY', 'your-passphrase-here');</textarea>
     92                            <button type="button" id="triplea_copy_code_btn" class="button" style="margin-top:8px;">
     93                                <span class="dashicons dashicons-clipboard" style="margin-top:3px;"></span> <?php _e('Copy to Clipboard', 'wc-triplea-crypto-payment'); ?>
     94                            </button>
     95                        </div>
     96
     97                        <div style="background:#f0f0f1;padding:15px;border-radius:4px;margin-top:15px;">
     98                            <p style="margin:0 0 10px 0;font-weight:600;"><?php _e('Where to add this code:', 'wc-triplea-crypto-payment'); ?></p>
     99                            <ol style="margin:0;padding-left:20px;">
     100                                <li><?php _e('Open your wp-config.php file (located in WordPress root directory)', 'wc-triplea-crypto-payment'); ?></li>
     101                                <li><?php _e('Find the line that says: <code>/* That\'s all, stop editing! Happy publishing. */</code>', 'wc-triplea-crypto-payment'); ?></li>
     102                                <li><?php _e('Paste the code <strong>before</strong> that line', 'wc-triplea-crypto-payment'); ?></li>
     103                                <li><?php _e('Save the file', 'wc-triplea-crypto-payment'); ?></li>
     104                                <li><?php _e('Refresh this page', 'wc-triplea-crypto-payment'); ?></li>
     105                            </ol>
     106                        </div>
     107                    </div>
     108                </div>
     109                <?php else: ?>
     110                <div class="triplea-settings-notice" style="background-color:#d4edda;border-left:4px solid #28a745;padding:15px;margin-bottom:20px;">
     111                    <p style="margin:0;color:#155724;"><strong>&#10004; <?php _e('Encryption Key Configured', 'wc-triplea-crypto-payment'); ?></strong> - <?php _e('Your wp-config.php encryption key is set up correctly.', 'wc-triplea-crypto-payment'); ?></p>
     112                </div>
     113                <?php endif; ?>
     114
    67115                <div class="triplea-settings-notice">
    68116                <?php
     
    90138                <div class="triplea-form-group">
    91139                    <label for="clientSecret"><?php _e( 'Client Secret', 'wc-triplea-crypto-payment' ); ?></label>
    92                     <input id="clientSecret" type="password" name="clientSecret" value="<?php echo $clientSecret; ?>" placeholder="<?php echo $clientSecret_exists ? __('Enter new secret to update', 'wc-triplea-crypto-payment') : __('Enter client secret', 'wc-triplea-crypto-payment'); ?>" style="width:300px;">
    93                     <input type="hidden" name="clientSecretExists" value="<?php echo $clientSecret_exists ? '1' : '0'; ?>">
    94                 </div>
    95                 <?php if ($clientSecret_exists): ?>
    96                     <div style="margin-top:-15px;margin-bottom:20px;margin-left:0;">
    97                         <small style="color:#666;font-style:italic;"><?php _e('Leave unchanged to keep existing secret, or enter new value to update.', 'wc-triplea-crypto-payment'); ?></small>
    98                     </div>
    99                 <?php endif; ?>
     140                    <?php if ($clientSecret_exists): ?>
     141                        <div style="margin-bottom:10px;">
     142                            <span style="color:#46b450;font-weight:600;">&#10004; <?php _e('Client Secret configured', 'wc-triplea-crypto-payment'); ?></span>
     143                        </div>
     144                        <input id="clientSecret" type="password" name="clientSecret" value="" placeholder="<?php _e('Enter new secret to update', 'wc-triplea-crypto-payment'); ?>" style="width:300px;">
     145                        <div style="margin-top:5px;">
     146                            <small style="color:#666;font-style:italic;"><?php _e('Leave empty to keep existing secret, or enter new value to update.', 'wc-triplea-crypto-payment'); ?></small>
     147                        </div>
     148                    <?php else: ?>
     149                        <div style="margin-bottom:10px;">
     150                            <span style="color:#dc3232;font-weight:600;">&#10008; <?php _e('Client Secret not configured', 'wc-triplea-crypto-payment'); ?></span>
     151                        </div>
     152                        <input id="clientSecret" type="password" name="clientSecret" value="" placeholder="<?php _e('Enter client secret', 'wc-triplea-crypto-payment'); ?>" style="width:300px;">
     153                    <?php endif; ?>
     154                </div>
    100155                <input type="hidden" name="oAuthToken" id="oAuthToken">
    101156                <input type="hidden" name="oAuthTokenExpiry" id="oAuthTokenExpiry">
     
    226281        $('.triplea-btn.verify-acnt-btn').hide();
    227282
     283        // Update config code when passphrase changes (manual or generated)
     284        function updateConfigCode() {
     285            var passphrase = $('#triplea_passphrase_value').val().trim();
     286            if (passphrase) {
     287                var configCode = "define('TRIPLEA_ENCRYPTION_KEY', '" + passphrase.replace(/'/g, "\\'") + "');";
     288                $('#triplea_config_code').val(configCode);
     289            } else {
     290                $('#triplea_config_code').val("define('TRIPLEA_ENCRYPTION_KEY', 'your-passphrase-here');");
     291            }
     292        }
     293
     294        // Generate Strong Passphrase
     295        $('#triplea_generate_passphrase').on('click', function() {
     296            // Generate a random 32-character passphrase
     297            var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+';
     298            var passphrase = '';
     299            var length = 32;
     300
     301            for (var i = 0; i < length; i++) {
     302                passphrase += chars.charAt(Math.floor(Math.random() * chars.length));
     303            }
     304
     305            // Set the generated passphrase
     306            $('#triplea_passphrase_value').val(passphrase);
     307
     308            // Update the config code
     309            updateConfigCode();
     310        });
     311
     312        // Update config code when user manually types passphrase
     313        $('#triplea_passphrase_value').on('input', function() {
     314            updateConfigCode();
     315        });
     316
     317        // Copy to Clipboard Button
     318        $('#triplea_copy_code_btn').on('click', function() {
     319            var $textarea = $('#triplea_config_code');
     320            var $btn = $(this);
     321            var passphrase = $('#triplea_passphrase_value').val().trim();
     322
     323            // Validate passphrase before copying
     324            if (!passphrase || passphrase.length < 16) {
     325                alert('<?php _e('Please enter or generate a passphrase (minimum 16 characters) before copying.', 'wc-triplea-crypto-payment'); ?>');
     326                $('#triplea_passphrase_value').focus();
     327                return;
     328            }
     329
     330            $textarea.select();
     331            document.execCommand('copy');
     332
     333            // Visual feedback
     334            var originalHtml = $btn.html();
     335            $btn.html('<span class="dashicons dashicons-yes" style="margin-top:3px;"></span> <?php _e('Copied!', 'wc-triplea-crypto-payment'); ?>').css('background-color', '#46b450').css('color', '#fff').css('border-color', '#46b450');
     336
     337            setTimeout(function() {
     338                $btn.html(originalHtml).css('background-color', '').css('color', '').css('border-color', '');
     339            }, 2000);
     340        });
     341
    228342        $('#triplea-final-step').on('click', function(){
    229343            //First Tab Codes
  • triplea-cryptocurrency-payment-gateway-for-woocommerce/trunk/readme.txt

    r3446472 r3446589  
    77Requires at least: 5.5
    88Tested up to: 6.6.2
    9 Stable tag: 2.0.23
     9Stable tag: 2.0.24
    1010Requires PHP: 7.0
    1111License: GPLv2 or later
     
    104104== Changelog ==
    105105
     106= 2.0.24 =
     107* Security: Custom encryption key system (TRIPLEA_ENCRYPTION_KEY in wp-config.php)
     108* Security: Removed client secret display from admin UI
     109* Feature: Encryption key setup wizard with passphrase generator
     110* Feature: Automatic migration from old encryption method
     111* Improved: Better error handling and validation
     112
    106113= 2.0.22 =
    107114Add: Order-pay feaure
  • triplea-cryptocurrency-payment-gateway-for-woocommerce/trunk/triplea-cryptocurrency-payment-gateway-for-woocommerce.php

    r3446472 r3446589  
    1717 * Plugin URI:        https://wordpress.org/plugins/triplea-cryptocurrency-payment-gateway-for-woocommerce/
    1818 * Description:       Offer cryptocurrency as a payment option on your website and get access to even more clients. Receive payments in cryptocurrency or in your local currency, directly in your bank account. Enjoy an easy setup, no cryptocurrency expertise required. Powered by Triple-A.
    19  * Version:           2.0.23
     19 * Version:           2.0.24
    2020 * Author:            Triple-A Team
    2121 * Author URI:        https://triple-a.io
     
    4949     * $var string
    5050     */
    51     public const version = '2.0.23';
     51    public const version = '2.0.24';
    5252
    5353    /*
Note: See TracChangeset for help on using the changeset viewer.