Plugin Directory

Changeset 3217196


Ignore:
Timestamp:
01/05/2025 01:35:48 PM (14 months ago)
Author:
MrViSiOn
Message:

Version 1.0.1: Enhanced security in communication with Multi WP platform and bug fixes

Location:
multi-connect
Files:
2 added
11 edited
1 copied

Legend:

Unmodified
Added
Removed
  • multi-connect

    • Property svn:global-ignores set to
      .idea
      node_modules
      .DS_Store
    • Property svn:ignore set to
      .idea
  • multi-connect/tags/1.0.1/.editorconfig

    r3215732 r3217196  
    11[*]
    22end_of_line = lf
     3charset = utf-8
     4trim_trailing_whitespace = true
     5indent_size = 4
     6indent_style = space
     7insert_final_newline = true
  • multi-connect/tags/1.0.1/includes/class-admin.php

    r3215732 r3217196  
    88namespace MultiConnect;
    99
     10use WP_Application_Passwords;
     11
    1012if ( ! defined( 'ABSPATH' ) ) {
    11     // Exit if accessed directly.
    12     exit;
     13    // Exit if accessed directly.
     14    exit;
    1315}
    1416
     
    1921 */
    2022class Admin {
    21     /**
    22     * Constructor
    23     */
    24     public function __construct() {
    25         add_action( 'admin_init', array( $this, 'check_connection' ) );
    26         add_action( 'admin_notices', array( $this, 'display_connection_notice' ) );
    27         add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
    28         add_action( 'wp_ajax_multiconnect_connect', array( $this, 'handle_connection' ) );
    29     }
     23    /**
     24    * Constructor
     25    */
     26    public function __construct() {
     27        add_action( 'admin_init', array( $this, 'check_connection' ) );
     28        add_action( 'admin_notices', array( $this, 'display_connection_notice' ) );
     29        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
     30        add_action( 'wp_ajax_multiconnect_connect', array( $this, 'handle_connection' ) );
     31    }
    3032
    31     /**
    32     * Check if the connection is established
    33     *
    34     * @return void
    35     */
    36     public function check_connection() {
    37         $connection_status = get_option( 'multiconnect_connection_status' );
    38         if ( ! $connection_status ) {
    39             update_option( 'multiconnect_show_notice', true );
    40         }
    41     }
     33    /**
     34    * Check if the connection is established
     35    *
     36    * @return void
     37    */
     38    public function check_connection() {
     39        $connection_status = get_option( 'multiconnect_connection_status' );
     40        if ( ! $connection_status ) {
     41            update_option( 'multiconnect_show_notice', true );
     42        }
     43    }
    4244
    43     /**
    44     * Display the connection notice
    45     *
    46     * @return void
    47     */
    48     public function display_connection_notice() {
    49         if ( ! get_option( 'multiconnect_show_notice' ) ) {
    50             return;
    51         }
     45    /**
     46    * Display the connection notice
     47    *
     48    * @return void
     49    */
     50    public function display_connection_notice() {
     51        if ( ! get_option( 'multiconnect_show_notice' ) ) {
     52//            return;
     53        }
    5254
    53         ?>
    54         <div class="notice notice-info is-dismissible multiconnect-connect-notice">
    55             <h3><?php esc_html_e( 'Connect with Multi-WP', 'multi-connect' ); ?></h3>
    56             <p>
    57                 <?php
    58                 esc_html_e(
    59                     'Connect your WordPress site with Multi-WP to manage updates and maintenance from a central dashboard.',
    60                     'multi-connect'
    61                 );
    62                 ?>
    63             </p>
    64             <p>
    65                 <button type="button" class="button button-primary" id="multiconnect-connect-button">
    66                     <?php esc_html_e( 'Connect Now', 'multi-connect' ); ?>
    67                 </button>
    68                 <a href="https://multi-wp.com/learn-more" target="_blank" class="button button-secondary">
    69                     <?php esc_html_e( 'Learn More', 'multi-connect' ); ?>
    70                 </a>
    71             </p>
    72         </div>
    73         <?php
    74     }
     55        ?>
     56        <div class="notice notice-info is-dismissible multiconnect-connect-notice">
     57            <h3><?php esc_html_e( 'Connect with Multi-WP', 'multi-connect' ); ?></h3>
     58            <p>
     59                <?php
     60                esc_html_e(
     61                    'Connect your WordPress site with Multi-WP to manage updates and maintenance from a central dashboard.',
     62                    'multi-connect'
     63                );
     64                ?>
     65            </p>
     66            <p>
     67                <button type="button" class="button button-primary" id="multiconnect-connect-button">
     68                    <?php esc_html_e( 'Connect Now', 'multi-connect' ); ?>
     69                </button>
     70                <a href="https://multi-wp.com/learn-more" target="_blank" class="button button-secondary">
     71                    <?php esc_html_e( 'Learn More', 'multi-connect' ); ?>
     72                </a>
     73            </p>
     74        </div>
     75        <?php
     76    }
    7577
    76     /**
    77     * Enqueue admin assets
    78     *
    79     * @return void
    80     */
    81     public function enqueue_admin_assets() {
     78    /**
     79    * Enqueue admin assets
     80    *
     81    * @return void
     82    */
     83    public function enqueue_admin_assets() {
    8284
    83         wp_enqueue_style(
    84             'multiconnect-admin',
    85             MULTICONNECT_PLUGIN_URL . 'assets/css/admin.css',
    86             array(),
    87             MULTICONNECT_VERSION
    88         );
     85        wp_enqueue_style(
     86            'multiconnect-admin',
     87            MULTICONNECT_PLUGIN_URL . 'assets/css/admin.css',
     88            array(),
     89            MULTICONNECT_VERSION
     90        );
    8991
    90         wp_enqueue_script(
    91             'multiconnect-admin',
    92             MULTICONNECT_PLUGIN_URL . 'assets/js/admin.js',
    93             array( 'jquery' ),
    94             MULTICONNECT_VERSION,
    95             true
    96         );
     92        wp_enqueue_script(
     93            'multiconnect-admin',
     94            MULTICONNECT_PLUGIN_URL . 'assets/js/admin.js',
     95            array( 'jquery' ),
     96            MULTICONNECT_VERSION,
     97            true
     98        );
    9799
    98         wp_localize_script(
    99             'multiconnect-admin',
    100             'multiConnectData',
    101             array(
    102                 'ajaxurl'    => admin_url( 'admin-ajax.php' ),
    103                 'nonce'      => wp_create_nonce( 'multiconnect-connect' ),
    104                 'connecting' => __( 'Connecting...', 'multi-connect' ),
    105                 'error'      => __( 'Connection failed. Please try again.', 'multi-connect' ),
    106             )
    107         );
    108     }
     100        wp_localize_script(
     101            'multiconnect-admin',
     102            'multiConnectData',
     103            array(
     104                'ajaxurl'    => admin_url( 'admin-ajax.php' ),
     105                'nonce'      => wp_create_nonce( 'multiconnect-connect' ),
     106                'connecting' => __( 'Connecting...', 'multi-connect' ),
     107                'error'      => __( 'Connection failed. Please try again.', 'multi-connect' ),
     108            )
     109        );
     110    }
    109111
    110     /**
    111     * Handle the connection request
    112     *
    113     * @return void
    114     */
    115     public function handle_connection() {
    116         check_ajax_referer( 'multiconnect-connect', 'nonce' );
     112    /**
     113    * Handle the connection request
     114    *
     115    * @return void
     116    */
     117    public function handle_connection() {
     118        check_ajax_referer( 'multiconnect-connect', 'nonce' );
    117119
    118         if ( ! current_user_can( 'manage_options' ) ) {
    119             wp_send_json_error( 'Unauthorized' );
    120         }
     120        if ( ! current_user_can( 'manage_options' ) ) {
     121            wp_send_json_error( 'Unauthorized' );
     122        }
    121123
    122         // Generate application password.
    123         $app_password = wp_generate_password( 24, false );
    124         $user         = wp_get_current_user();
     124        // Generate application password.
     125        $app_password = $this->generate_password();
     126        if (function_exists('openssl_pkey_get_public') && extension_loaded('openssl')) {
     127            $app_password = $this->encrypt_password_with_public_key($app_password);
     128        }
     129        $user = wp_get_current_user();
    125130
    126         // Store connection info.
    127         update_option(
    128             'multiconnect_connection_status',
    129             array(
    130                 'connected'    => true,
    131                 'user_id'      => $user->ID,
    132                 'app_password' => $app_password,
    133                 'connected_at' => current_time( 'mysql' ),
    134             )
    135         );
     131        // Store connection info.
     132        update_option(
     133            'multiconnect_connection_status',
     134            array(
     135                'connected'    => true,
     136                'user_id'      => $user->ID,
     137                'app_password' => $app_password,
     138                'connected_at' => current_time( 'mysql' ),
     139            )
     140        );
    136141
    137         // Hide the notice.
    138         update_option( 'multiconnect_show_notice', false );
     142        // Hide the notice.
     143        update_option( 'multiconnect_show_notice', false );
    139144
    140         wp_send_json_success(
    141             array(
    142                 'site_url'     => get_site_url(),
    143                 'username'     => $user->user_login,
    144                 'app_password' => $app_password,
    145             )
    146         );
    147     }
     145        wp_send_json_success(
     146            array(
     147                'site_url'     => get_site_url(),
     148                'username'     => $user->user_login,
     149                'app_password' => $app_password,
     150            )
     151        );
     152    }
     153
     154    function generate_password(): string {
     155        if (!class_exists('WP_Application_Passwords')) {
     156            require_once(MULTICONNECT_PLUGIN_ABSPATH . 'wp-includes/class-wp-application-passwords.php');
     157        }
     158
     159        $user = wp_get_current_user();
     160        $prepared = array(
     161            'name'   => 'Multi-WP Connection',
     162            'app_id' => 'multi-connect',
     163        );
     164
     165        $created = WP_Application_Passwords::create_new_application_password( $user->ID, wp_slash( (array) $prepared ) );
     166
     167        if ( is_wp_error( $created ) ) {
     168            return wp_generate_password( 24, false );
     169        }
     170
     171        $password = $created[0];
     172        $item     = WP_Application_Passwords::get_user_application_password( $user->ID, $created[1]['uuid'] );
     173
     174        $item['new_password'] = WP_Application_Passwords::chunk_password( $password );
     175
     176        return $item['new_password'];
     177    }
     178
     179    function encrypt_password_with_public_key( $password ): string {
     180        // Clave pública distribuida con el plugin
     181        $public_key = file_get_contents(MULTICONNECT_PLUGIN_PATH . 'includes/public.key');
     182
     183        // Crear el recurso de clave pública
     184        $key_resource = openssl_pkey_get_public( $public_key );
     185
     186        // Cifrar la contraseña
     187        openssl_public_encrypt( $password, $encrypted, $key_resource );
     188
     189        // Codificar para URL
     190        return urlencode( base64_encode( $encrypted ) );
     191    }
    148192}
  • multi-connect/tags/1.0.1/includes/class-multi-connect-api.php

    r3215732 r3217196  
    188188                            break;
    189189                        case 'includes':
    190                             $selected_folders[] = MULTICONNECT_PLUGIN_PATH . '../../wp-includes';
     190                            $selected_folders[] = MULTICONNECT_PLUGIN_ABSPATH . 'wp-includes';
    191191                            break;
    192192                        case 'core':
    193                             $selected_folders = array_merge( $selected_folders, glob( MULTICONNECT_PLUGIN_PATH . '../../wp-*.php' ) );
     193                            $selected_folders = array_merge( $selected_folders, glob( MULTICONNECT_PLUGIN_ABSPATH . 'wp-*.php' ) );
    194194                            break;
    195195                    }
     
    201201            if ( empty( $folders ) ) {
    202202                $folders = array(
    203                     MULTICONNECT_PLUGIN_PATH . '../../wp-includes',
     203                    MULTICONNECT_PLUGIN_PATH . '/wp-includes',
    204204                    get_theme_root(),
    205                     MULTICONNECT_PLUGIN_PATH . '../',
     205                    MULTICONNECT_PLUGIN_PATH . '/',
    206206                );
    207207
    208                 $root_files = glob( MULTICONNECT_PLUGIN_PATH . '../../wp-*.php' );
     208                $root_files = glob( MULTICONNECT_PLUGIN_PATH . '/wp-*.php' );
    209209                $folders    = array_merge( $folders, $root_files );
    210210            }
     
    240240
    241241            $response = array(
    242                 'files_backup_url' => content_url( 'backups/backup-files-' . $timestamp . '.zip' ),
     242                'files_backup_url' =>
     243                    wp_upload_dir()['baseurl'] . '/backups/backup-files-' . $timestamp . '.zip',
    243244                'files_size'       => filesize( $files_zip ),
    244245                'files_added'      => $files_added,
     
    246247
    247248            if ( $db_backed_up ) {
    248                 $response['db_backup_url'] = content_url( 'backups/backup-db-' . $timestamp . '.zip' );
     249                $response['db_backup_url'] =
     250                    wp_upload_dir()['baseurl'] . '/backups/backup-db-' . $timestamp . '.zip';
    249251                $response['db_size']       = filesize( $db_zip );
    250252            }
     
    334336    private function create_database_backup( $zip_file, $tables, $log_file ) {
    335337        $db_backup = $this->backup_database( $tables );
     338        $this->log('', 'backup_database: ' . file_get_contents($db_backup));
    336339        if ( ! $db_backup ) {
    337340            $this->log( $log_file, 'Failed to create database dump' );
     
    370373     */
    371374    private function log( $log_file, $message ) {
     375        if ( empty( $log_file ) ) {
     376            $backup_dir = wp_upload_dir()['basedir'] . '/backups';
     377            $log_file = $backup_dir . '/backup.log';
     378        }
     379        $enable_logging = get_option('multi_connect_log');
     380        if ($enable_logging !== '1') {
     381//          return;
     382        }
    372383        $timestamp   = gmdate( 'Y-m-d H:i:s' );
    373384        $log_message = "[$timestamp] $message\n";
     
    377388            WP_Filesystem();
    378389        }
    379         $wp_filesystem->put_contents( $log_file, $log_message, FS_CHMOD_FILE );
     390        $existing_content = $wp_filesystem->get_contents($log_file) ?: '';
     391        $wp_filesystem->put_contents( $log_file, $existing_content . $log_message, FS_CHMOD_FILE );
    380392    }
    381393
     
    400412
    401413        global $wp_filesystem;
    402         if ( ! $wp_filesystem ) {
    403             require_once MULTICONNECT_PLUGIN_ABSPATH . '/wp-admin/includes/file.php';
    404             WP_Filesystem();
    405         }
    406         $handle = $wp_filesystem->put_contents( $backup_file, '', FS_CHMOD_FILE );
    407414
    408415        // Header del archivo SQL.
    409         $wp_filesystem->put_contents( $backup_file, "-- WordPress Database Backup\n", FILE_APPEND );
    410         $wp_filesystem->put_contents( $backup_file, '-- Generated: ' . gmdate( 'Y-m-d H:i:s' ) . "\n\n", FILE_APPEND );
    411         $wp_filesystem->put_contents( $backup_file, "SET FOREIGN_KEY_CHECKS=0;\n\n", FILE_APPEND );
     416        $content = "-- WordPress Database Backup\n";
     417
     418        $content .= '-- Generated: ' . gmdate( 'Y-m-d H:i:s' ) . "\n\n";
     419        $content .= "SET FOREIGN_KEY_CHECKS=0;\n\n";
    412420
    413421        foreach ( $tables as $table ) {
     
    421429            $create_table = $wpdb->get_row(
    422430                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange
    423                 $wpdb->prepare( 'SHOW CREATE TABLE `%s`', $table_name ),
     431                sprintf('SHOW CREATE TABLE %s', "`{$table_name}`"),
    424432                ARRAY_N
    425433            );
    426             $wp_filesystem->put_contents( $backup_file, "DROP TABLE IF EXISTS `{$table_name}`;\n", FILE_APPEND );
    427             $wp_filesystem->put_contents( $backup_file, $create_table[1] . ";\n\n", FILE_APPEND );
     434            $content .= "DROP TABLE IF EXISTS `{$table_name}`;\n";
     435            $content .= $create_table[1] . ";\n\n";
    428436
    429437            // Datos de la tabla.
    430438            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    431439            $rows = $wpdb->get_results(
    432                 $wpdb->prepare( 'SELECT * FROM `%s`', $table_name ),
     440                sprintf('SELECT * FROM %s', "`{$table_name}`"),
    433441                ARRAY_A
    434442            );
     
    449457                    }
    450458
    451                     $wp_filesystem->put_contents(
    452                         $backup_file,
    453                         "INSERT INTO `{$table_name}` VALUES " . implode( ',', $values ) . ";\n"
    454                     );
     459                    $content .= "INSERT INTO `{$table_name}` VALUES " . implode( ',', $values ) . ";\n";
    455460                }
    456                 $wp_filesystem->put_contents( $backup_file, "\n" );
    457             }
    458         }
    459 
    460         $wp_filesystem->put_contents( $backup_file, "SET FOREIGN_KEY_CHECKS=1;\n" );
    461         $wp_filesystem->close( $handle );
     461                $content .= "\n";
     462            }
     463        }
     464        $content .= "SET FOREIGN_KEY_CHECKS=1;\n";
     465        $wp_filesystem->put_contents( $backup_file, $content );
    462466
    463467        return $backup_file;
     
    540544
    541545        // Forzar la verificación de actualizaciones.
    542         delete_site_transient( 'available_translations' );
    543         wp_version_check( array(), true );
    544         wp_update_plugins();
    545         wp_update_themes();
     546        delete_site_transient('update_core');
     547        delete_site_transient('update_plugins');
     548        delete_site_transient('update_themes');
     549        delete_site_transient('available_translations');
     550
     551        // Limpiar la caché de actualizaciones
     552        wp_clean_update_cache();
     553
     554        // Forzar la verificación de actualizaciones con tiempo actual
     555        wp_version_check(array(), true);
     556        wp_update_plugins();
     557        wp_update_themes();
     558
    546559
    547560        $updates = array(
  • multi-connect/tags/1.0.1/multi-connect.php

    r3215732 r3217196  
    44 * Plugin URI: https://multi-wp.com
    55 * Description: Connect your WordPress site with Multi-WP for centralized management and updates.
    6  * Version: 1.0.0
     6 * Version: 1.0.1
    77 * Requires at least: 5.8
    88 * Requires PHP: 7.4
     
    2424define( 'MULTICONNECT_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
    2525define( 'MULTICONNECT_PLUGIN_DIR', plugin_dir_path( __DIR__ ) . '' );
    26 define( 'MULTICONNECT_PLUGIN_ABSPATH', plugin_dir_path( __DIR__ ) . '../../' );
     26define( 'MULTICONNECT_PLUGIN_ABSPATH', ABSPATH . '' );
    2727define( 'MULTICONNECT_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
    2828const MULTICONNECT_VERSION = '1.0.0';
  • multi-connect/tags/1.0.1/readme.txt

    r3215732 r3217196  
    55Tested up to: 6.7
    66Requires PHP: 7.4
    7 Stable tag: 1.0.0
     7Stable tag: 1.0.1
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    4141== Changelog ==
    4242
     43= 1.0.1 =
     44* Enhanced security in the communication between plugin and Multi WP platform
     45* Fixed various minor bugs and improved stability
     46* Optimized authentication process
     47
    4348= 1.0.0 =
    4449* Initial release
     
    4651== Upgrade Notice ==
    4752
     53= 1.0.1 =
     54Security enhancement update: Includes improved communication security with Multi WP platform and bug fixes. Upgrade recommended for all users.
     55
    4856= 1.0.0 =
    4957Initial release of Multi Connect
  • multi-connect/trunk/.editorconfig

    r3215732 r3217196  
    11[*]
    22end_of_line = lf
     3charset = utf-8
     4trim_trailing_whitespace = true
     5indent_size = 4
     6indent_style = space
     7insert_final_newline = true
  • multi-connect/trunk/includes/class-admin.php

    r3215732 r3217196  
    88namespace MultiConnect;
    99
     10use WP_Application_Passwords;
     11
    1012if ( ! defined( 'ABSPATH' ) ) {
    11     // Exit if accessed directly.
    12     exit;
     13    // Exit if accessed directly.
     14    exit;
    1315}
    1416
     
    1921 */
    2022class Admin {
    21     /**
    22     * Constructor
    23     */
    24     public function __construct() {
    25         add_action( 'admin_init', array( $this, 'check_connection' ) );
    26         add_action( 'admin_notices', array( $this, 'display_connection_notice' ) );
    27         add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
    28         add_action( 'wp_ajax_multiconnect_connect', array( $this, 'handle_connection' ) );
    29     }
     23    /**
     24    * Constructor
     25    */
     26    public function __construct() {
     27        add_action( 'admin_init', array( $this, 'check_connection' ) );
     28        add_action( 'admin_notices', array( $this, 'display_connection_notice' ) );
     29        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
     30        add_action( 'wp_ajax_multiconnect_connect', array( $this, 'handle_connection' ) );
     31    }
    3032
    31     /**
    32     * Check if the connection is established
    33     *
    34     * @return void
    35     */
    36     public function check_connection() {
    37         $connection_status = get_option( 'multiconnect_connection_status' );
    38         if ( ! $connection_status ) {
    39             update_option( 'multiconnect_show_notice', true );
    40         }
    41     }
     33    /**
     34    * Check if the connection is established
     35    *
     36    * @return void
     37    */
     38    public function check_connection() {
     39        $connection_status = get_option( 'multiconnect_connection_status' );
     40        if ( ! $connection_status ) {
     41            update_option( 'multiconnect_show_notice', true );
     42        }
     43    }
    4244
    43     /**
    44     * Display the connection notice
    45     *
    46     * @return void
    47     */
    48     public function display_connection_notice() {
    49         if ( ! get_option( 'multiconnect_show_notice' ) ) {
    50             return;
    51         }
     45    /**
     46    * Display the connection notice
     47    *
     48    * @return void
     49    */
     50    public function display_connection_notice() {
     51        if ( ! get_option( 'multiconnect_show_notice' ) ) {
     52//            return;
     53        }
    5254
    53         ?>
    54         <div class="notice notice-info is-dismissible multiconnect-connect-notice">
    55             <h3><?php esc_html_e( 'Connect with Multi-WP', 'multi-connect' ); ?></h3>
    56             <p>
    57                 <?php
    58                 esc_html_e(
    59                     'Connect your WordPress site with Multi-WP to manage updates and maintenance from a central dashboard.',
    60                     'multi-connect'
    61                 );
    62                 ?>
    63             </p>
    64             <p>
    65                 <button type="button" class="button button-primary" id="multiconnect-connect-button">
    66                     <?php esc_html_e( 'Connect Now', 'multi-connect' ); ?>
    67                 </button>
    68                 <a href="https://multi-wp.com/learn-more" target="_blank" class="button button-secondary">
    69                     <?php esc_html_e( 'Learn More', 'multi-connect' ); ?>
    70                 </a>
    71             </p>
    72         </div>
    73         <?php
    74     }
     55        ?>
     56        <div class="notice notice-info is-dismissible multiconnect-connect-notice">
     57            <h3><?php esc_html_e( 'Connect with Multi-WP', 'multi-connect' ); ?></h3>
     58            <p>
     59                <?php
     60                esc_html_e(
     61                    'Connect your WordPress site with Multi-WP to manage updates and maintenance from a central dashboard.',
     62                    'multi-connect'
     63                );
     64                ?>
     65            </p>
     66            <p>
     67                <button type="button" class="button button-primary" id="multiconnect-connect-button">
     68                    <?php esc_html_e( 'Connect Now', 'multi-connect' ); ?>
     69                </button>
     70                <a href="https://multi-wp.com/learn-more" target="_blank" class="button button-secondary">
     71                    <?php esc_html_e( 'Learn More', 'multi-connect' ); ?>
     72                </a>
     73            </p>
     74        </div>
     75        <?php
     76    }
    7577
    76     /**
    77     * Enqueue admin assets
    78     *
    79     * @return void
    80     */
    81     public function enqueue_admin_assets() {
     78    /**
     79    * Enqueue admin assets
     80    *
     81    * @return void
     82    */
     83    public function enqueue_admin_assets() {
    8284
    83         wp_enqueue_style(
    84             'multiconnect-admin',
    85             MULTICONNECT_PLUGIN_URL . 'assets/css/admin.css',
    86             array(),
    87             MULTICONNECT_VERSION
    88         );
     85        wp_enqueue_style(
     86            'multiconnect-admin',
     87            MULTICONNECT_PLUGIN_URL . 'assets/css/admin.css',
     88            array(),
     89            MULTICONNECT_VERSION
     90        );
    8991
    90         wp_enqueue_script(
    91             'multiconnect-admin',
    92             MULTICONNECT_PLUGIN_URL . 'assets/js/admin.js',
    93             array( 'jquery' ),
    94             MULTICONNECT_VERSION,
    95             true
    96         );
     92        wp_enqueue_script(
     93            'multiconnect-admin',
     94            MULTICONNECT_PLUGIN_URL . 'assets/js/admin.js',
     95            array( 'jquery' ),
     96            MULTICONNECT_VERSION,
     97            true
     98        );
    9799
    98         wp_localize_script(
    99             'multiconnect-admin',
    100             'multiConnectData',
    101             array(
    102                 'ajaxurl'    => admin_url( 'admin-ajax.php' ),
    103                 'nonce'      => wp_create_nonce( 'multiconnect-connect' ),
    104                 'connecting' => __( 'Connecting...', 'multi-connect' ),
    105                 'error'      => __( 'Connection failed. Please try again.', 'multi-connect' ),
    106             )
    107         );
    108     }
     100        wp_localize_script(
     101            'multiconnect-admin',
     102            'multiConnectData',
     103            array(
     104                'ajaxurl'    => admin_url( 'admin-ajax.php' ),
     105                'nonce'      => wp_create_nonce( 'multiconnect-connect' ),
     106                'connecting' => __( 'Connecting...', 'multi-connect' ),
     107                'error'      => __( 'Connection failed. Please try again.', 'multi-connect' ),
     108            )
     109        );
     110    }
    109111
    110     /**
    111     * Handle the connection request
    112     *
    113     * @return void
    114     */
    115     public function handle_connection() {
    116         check_ajax_referer( 'multiconnect-connect', 'nonce' );
     112    /**
     113    * Handle the connection request
     114    *
     115    * @return void
     116    */
     117    public function handle_connection() {
     118        check_ajax_referer( 'multiconnect-connect', 'nonce' );
    117119
    118         if ( ! current_user_can( 'manage_options' ) ) {
    119             wp_send_json_error( 'Unauthorized' );
    120         }
     120        if ( ! current_user_can( 'manage_options' ) ) {
     121            wp_send_json_error( 'Unauthorized' );
     122        }
    121123
    122         // Generate application password.
    123         $app_password = wp_generate_password( 24, false );
    124         $user         = wp_get_current_user();
     124        // Generate application password.
     125        $app_password = $this->generate_password();
     126        if (function_exists('openssl_pkey_get_public') && extension_loaded('openssl')) {
     127            $app_password = $this->encrypt_password_with_public_key($app_password);
     128        }
     129        $user = wp_get_current_user();
    125130
    126         // Store connection info.
    127         update_option(
    128             'multiconnect_connection_status',
    129             array(
    130                 'connected'    => true,
    131                 'user_id'      => $user->ID,
    132                 'app_password' => $app_password,
    133                 'connected_at' => current_time( 'mysql' ),
    134             )
    135         );
     131        // Store connection info.
     132        update_option(
     133            'multiconnect_connection_status',
     134            array(
     135                'connected'    => true,
     136                'user_id'      => $user->ID,
     137                'app_password' => $app_password,
     138                'connected_at' => current_time( 'mysql' ),
     139            )
     140        );
    136141
    137         // Hide the notice.
    138         update_option( 'multiconnect_show_notice', false );
     142        // Hide the notice.
     143        update_option( 'multiconnect_show_notice', false );
    139144
    140         wp_send_json_success(
    141             array(
    142                 'site_url'     => get_site_url(),
    143                 'username'     => $user->user_login,
    144                 'app_password' => $app_password,
    145             )
    146         );
    147     }
     145        wp_send_json_success(
     146            array(
     147                'site_url'     => get_site_url(),
     148                'username'     => $user->user_login,
     149                'app_password' => $app_password,
     150            )
     151        );
     152    }
     153
     154    function generate_password(): string {
     155        if (!class_exists('WP_Application_Passwords')) {
     156            require_once(MULTICONNECT_PLUGIN_ABSPATH . 'wp-includes/class-wp-application-passwords.php');
     157        }
     158
     159        $user = wp_get_current_user();
     160        $prepared = array(
     161            'name'   => 'Multi-WP Connection',
     162            'app_id' => 'multi-connect',
     163        );
     164
     165        $created = WP_Application_Passwords::create_new_application_password( $user->ID, wp_slash( (array) $prepared ) );
     166
     167        if ( is_wp_error( $created ) ) {
     168            return wp_generate_password( 24, false );
     169        }
     170
     171        $password = $created[0];
     172        $item     = WP_Application_Passwords::get_user_application_password( $user->ID, $created[1]['uuid'] );
     173
     174        $item['new_password'] = WP_Application_Passwords::chunk_password( $password );
     175
     176        return $item['new_password'];
     177    }
     178
     179    function encrypt_password_with_public_key( $password ): string {
     180        // Clave pública distribuida con el plugin
     181        $public_key = file_get_contents(MULTICONNECT_PLUGIN_PATH . 'includes/public.key');
     182
     183        // Crear el recurso de clave pública
     184        $key_resource = openssl_pkey_get_public( $public_key );
     185
     186        // Cifrar la contraseña
     187        openssl_public_encrypt( $password, $encrypted, $key_resource );
     188
     189        // Codificar para URL
     190        return urlencode( base64_encode( $encrypted ) );
     191    }
    148192}
  • multi-connect/trunk/includes/class-multi-connect-api.php

    r3215732 r3217196  
    188188                            break;
    189189                        case 'includes':
    190                             $selected_folders[] = MULTICONNECT_PLUGIN_PATH . '../../wp-includes';
     190                            $selected_folders[] = MULTICONNECT_PLUGIN_ABSPATH . 'wp-includes';
    191191                            break;
    192192                        case 'core':
    193                             $selected_folders = array_merge( $selected_folders, glob( MULTICONNECT_PLUGIN_PATH . '../../wp-*.php' ) );
     193                            $selected_folders = array_merge( $selected_folders, glob( MULTICONNECT_PLUGIN_ABSPATH . 'wp-*.php' ) );
    194194                            break;
    195195                    }
     
    201201            if ( empty( $folders ) ) {
    202202                $folders = array(
    203                     MULTICONNECT_PLUGIN_PATH . '../../wp-includes',
     203                    MULTICONNECT_PLUGIN_PATH . '/wp-includes',
    204204                    get_theme_root(),
    205                     MULTICONNECT_PLUGIN_PATH . '../',
     205                    MULTICONNECT_PLUGIN_PATH . '/',
    206206                );
    207207
    208                 $root_files = glob( MULTICONNECT_PLUGIN_PATH . '../../wp-*.php' );
     208                $root_files = glob( MULTICONNECT_PLUGIN_PATH . '/wp-*.php' );
    209209                $folders    = array_merge( $folders, $root_files );
    210210            }
     
    240240
    241241            $response = array(
    242                 'files_backup_url' => content_url( 'backups/backup-files-' . $timestamp . '.zip' ),
     242                'files_backup_url' =>
     243                    wp_upload_dir()['baseurl'] . '/backups/backup-files-' . $timestamp . '.zip',
    243244                'files_size'       => filesize( $files_zip ),
    244245                'files_added'      => $files_added,
     
    246247
    247248            if ( $db_backed_up ) {
    248                 $response['db_backup_url'] = content_url( 'backups/backup-db-' . $timestamp . '.zip' );
     249                $response['db_backup_url'] =
     250                    wp_upload_dir()['baseurl'] . '/backups/backup-db-' . $timestamp . '.zip';
    249251                $response['db_size']       = filesize( $db_zip );
    250252            }
     
    334336    private function create_database_backup( $zip_file, $tables, $log_file ) {
    335337        $db_backup = $this->backup_database( $tables );
     338        $this->log('', 'backup_database: ' . file_get_contents($db_backup));
    336339        if ( ! $db_backup ) {
    337340            $this->log( $log_file, 'Failed to create database dump' );
     
    370373     */
    371374    private function log( $log_file, $message ) {
     375        if ( empty( $log_file ) ) {
     376            $backup_dir = wp_upload_dir()['basedir'] . '/backups';
     377            $log_file = $backup_dir . '/backup.log';
     378        }
     379        $enable_logging = get_option('multi_connect_log');
     380        if ($enable_logging !== '1') {
     381//          return;
     382        }
    372383        $timestamp   = gmdate( 'Y-m-d H:i:s' );
    373384        $log_message = "[$timestamp] $message\n";
     
    377388            WP_Filesystem();
    378389        }
    379         $wp_filesystem->put_contents( $log_file, $log_message, FS_CHMOD_FILE );
     390        $existing_content = $wp_filesystem->get_contents($log_file) ?: '';
     391        $wp_filesystem->put_contents( $log_file, $existing_content . $log_message, FS_CHMOD_FILE );
    380392    }
    381393
     
    400412
    401413        global $wp_filesystem;
    402         if ( ! $wp_filesystem ) {
    403             require_once MULTICONNECT_PLUGIN_ABSPATH . '/wp-admin/includes/file.php';
    404             WP_Filesystem();
    405         }
    406         $handle = $wp_filesystem->put_contents( $backup_file, '', FS_CHMOD_FILE );
    407414
    408415        // Header del archivo SQL.
    409         $wp_filesystem->put_contents( $backup_file, "-- WordPress Database Backup\n", FILE_APPEND );
    410         $wp_filesystem->put_contents( $backup_file, '-- Generated: ' . gmdate( 'Y-m-d H:i:s' ) . "\n\n", FILE_APPEND );
    411         $wp_filesystem->put_contents( $backup_file, "SET FOREIGN_KEY_CHECKS=0;\n\n", FILE_APPEND );
     416        $content = "-- WordPress Database Backup\n";
     417
     418        $content .= '-- Generated: ' . gmdate( 'Y-m-d H:i:s' ) . "\n\n";
     419        $content .= "SET FOREIGN_KEY_CHECKS=0;\n\n";
    412420
    413421        foreach ( $tables as $table ) {
     
    421429            $create_table = $wpdb->get_row(
    422430                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange
    423                 $wpdb->prepare( 'SHOW CREATE TABLE `%s`', $table_name ),
     431                sprintf('SHOW CREATE TABLE %s', "`{$table_name}`"),
    424432                ARRAY_N
    425433            );
    426             $wp_filesystem->put_contents( $backup_file, "DROP TABLE IF EXISTS `{$table_name}`;\n", FILE_APPEND );
    427             $wp_filesystem->put_contents( $backup_file, $create_table[1] . ";\n\n", FILE_APPEND );
     434            $content .= "DROP TABLE IF EXISTS `{$table_name}`;\n";
     435            $content .= $create_table[1] . ";\n\n";
    428436
    429437            // Datos de la tabla.
    430438            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    431439            $rows = $wpdb->get_results(
    432                 $wpdb->prepare( 'SELECT * FROM `%s`', $table_name ),
     440                sprintf('SELECT * FROM %s', "`{$table_name}`"),
    433441                ARRAY_A
    434442            );
     
    449457                    }
    450458
    451                     $wp_filesystem->put_contents(
    452                         $backup_file,
    453                         "INSERT INTO `{$table_name}` VALUES " . implode( ',', $values ) . ";\n"
    454                     );
     459                    $content .= "INSERT INTO `{$table_name}` VALUES " . implode( ',', $values ) . ";\n";
    455460                }
    456                 $wp_filesystem->put_contents( $backup_file, "\n" );
    457             }
    458         }
    459 
    460         $wp_filesystem->put_contents( $backup_file, "SET FOREIGN_KEY_CHECKS=1;\n" );
    461         $wp_filesystem->close( $handle );
     461                $content .= "\n";
     462            }
     463        }
     464        $content .= "SET FOREIGN_KEY_CHECKS=1;\n";
     465        $wp_filesystem->put_contents( $backup_file, $content );
    462466
    463467        return $backup_file;
     
    540544
    541545        // Forzar la verificación de actualizaciones.
    542         delete_site_transient( 'available_translations' );
    543         wp_version_check( array(), true );
    544         wp_update_plugins();
    545         wp_update_themes();
     546        delete_site_transient('update_core');
     547        delete_site_transient('update_plugins');
     548        delete_site_transient('update_themes');
     549        delete_site_transient('available_translations');
     550
     551        // Limpiar la caché de actualizaciones
     552        wp_clean_update_cache();
     553
     554        // Forzar la verificación de actualizaciones con tiempo actual
     555        wp_version_check(array(), true);
     556        wp_update_plugins();
     557        wp_update_themes();
     558
    546559
    547560        $updates = array(
  • multi-connect/trunk/multi-connect.php

    r3215732 r3217196  
    44 * Plugin URI: https://multi-wp.com
    55 * Description: Connect your WordPress site with Multi-WP for centralized management and updates.
    6  * Version: 1.0.0
     6 * Version: 1.0.1
    77 * Requires at least: 5.8
    88 * Requires PHP: 7.4
     
    2424define( 'MULTICONNECT_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
    2525define( 'MULTICONNECT_PLUGIN_DIR', plugin_dir_path( __DIR__ ) . '' );
    26 define( 'MULTICONNECT_PLUGIN_ABSPATH', plugin_dir_path( __DIR__ ) . '../../' );
     26define( 'MULTICONNECT_PLUGIN_ABSPATH', ABSPATH . '' );
    2727define( 'MULTICONNECT_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
    2828const MULTICONNECT_VERSION = '1.0.0';
  • multi-connect/trunk/readme.txt

    r3215732 r3217196  
    55Tested up to: 6.7
    66Requires PHP: 7.4
    7 Stable tag: 1.0.0
     7Stable tag: 1.0.1
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    4141== Changelog ==
    4242
     43= 1.0.1 =
     44* Enhanced security in the communication between plugin and Multi WP platform
     45* Fixed various minor bugs and improved stability
     46* Optimized authentication process
     47
    4348= 1.0.0 =
    4449* Initial release
     
    4651== Upgrade Notice ==
    4752
     53= 1.0.1 =
     54Security enhancement update: Includes improved communication security with Multi WP platform and bug fixes. Upgrade recommended for all users.
     55
    4856= 1.0.0 =
    4957Initial release of Multi Connect
Note: See TracChangeset for help on using the changeset viewer.