Changeset 3217196
- Timestamp:
- 01/05/2025 01:35:48 PM (14 months ago)
- Location:
- multi-connect
- Files:
-
- 2 added
- 11 edited
- 1 copied
-
. (modified) (2 props)
-
tags/1.0.1 (copied) (copied from multi-connect/trunk)
-
tags/1.0.1/.editorconfig (modified) (1 diff)
-
tags/1.0.1/includes/class-admin.php (modified) (2 diffs)
-
tags/1.0.1/includes/class-multi-connect-api.php (modified) (11 diffs)
-
tags/1.0.1/includes/public.key (added)
-
tags/1.0.1/multi-connect.php (modified) (2 diffs)
-
tags/1.0.1/readme.txt (modified) (3 diffs)
-
trunk/.editorconfig (modified) (1 diff)
-
trunk/includes/class-admin.php (modified) (2 diffs)
-
trunk/includes/class-multi-connect-api.php (modified) (11 diffs)
-
trunk/includes/public.key (added)
-
trunk/multi-connect.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
multi-connect
-
Property
svn:global-ignores
set to
.idea
node_modules
.DS_Store
-
Property
svn:ignore
set to
.idea
-
Property
svn:global-ignores
set to
-
multi-connect/tags/1.0.1/.editorconfig
r3215732 r3217196 1 1 [*] 2 2 end_of_line = lf 3 charset = utf-8 4 trim_trailing_whitespace = true 5 indent_size = 4 6 indent_style = space 7 insert_final_newline = true -
multi-connect/tags/1.0.1/includes/class-admin.php
r3215732 r3217196 8 8 namespace MultiConnect; 9 9 10 use WP_Application_Passwords; 11 10 12 if ( ! defined( 'ABSPATH' ) ) { 11 // Exit if accessed directly.12 exit;13 // Exit if accessed directly. 14 exit; 13 15 } 14 16 … … 19 21 */ 20 22 class Admin { 21 /**22 * Constructor23 */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 } 30 32 31 /**32 * Check if the connection is established33 *34 * @return void35 */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 } 42 44 43 /**44 * Display the connection notice45 *46 * @return void47 */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 } 52 54 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 <?php58 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 <?php74 }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 } 75 77 76 /**77 * Enqueue admin assets78 *79 * @return void80 */81 public function enqueue_admin_assets() {78 /** 79 * Enqueue admin assets 80 * 81 * @return void 82 */ 83 public function enqueue_admin_assets() { 82 84 83 wp_enqueue_style(84 'multiconnect-admin',85 MULTICONNECT_PLUGIN_URL . 'assets/css/admin.css',86 array(),87 MULTICONNECT_VERSION88 );85 wp_enqueue_style( 86 'multiconnect-admin', 87 MULTICONNECT_PLUGIN_URL . 'assets/css/admin.css', 88 array(), 89 MULTICONNECT_VERSION 90 ); 89 91 90 wp_enqueue_script(91 'multiconnect-admin',92 MULTICONNECT_PLUGIN_URL . 'assets/js/admin.js',93 array( 'jquery' ),94 MULTICONNECT_VERSION,95 true96 );92 wp_enqueue_script( 93 'multiconnect-admin', 94 MULTICONNECT_PLUGIN_URL . 'assets/js/admin.js', 95 array( 'jquery' ), 96 MULTICONNECT_VERSION, 97 true 98 ); 97 99 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 } 109 111 110 /**111 * Handle the connection request112 *113 * @return void114 */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' ); 117 119 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 } 121 123 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(); 125 130 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 ); 136 141 137 // Hide the notice.138 update_option( 'multiconnect_show_notice', false );142 // Hide the notice. 143 update_option( 'multiconnect_show_notice', false ); 139 144 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 } 148 192 } -
multi-connect/tags/1.0.1/includes/class-multi-connect-api.php
r3215732 r3217196 188 188 break; 189 189 case 'includes': 190 $selected_folders[] = MULTICONNECT_PLUGIN_ PATH . '../../wp-includes';190 $selected_folders[] = MULTICONNECT_PLUGIN_ABSPATH . 'wp-includes'; 191 191 break; 192 192 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' ) ); 194 194 break; 195 195 } … … 201 201 if ( empty( $folders ) ) { 202 202 $folders = array( 203 MULTICONNECT_PLUGIN_PATH . ' ../../wp-includes',203 MULTICONNECT_PLUGIN_PATH . '/wp-includes', 204 204 get_theme_root(), 205 MULTICONNECT_PLUGIN_PATH . ' ../',205 MULTICONNECT_PLUGIN_PATH . '/', 206 206 ); 207 207 208 $root_files = glob( MULTICONNECT_PLUGIN_PATH . ' ../../wp-*.php' );208 $root_files = glob( MULTICONNECT_PLUGIN_PATH . '/wp-*.php' ); 209 209 $folders = array_merge( $folders, $root_files ); 210 210 } … … 240 240 241 241 $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', 243 244 'files_size' => filesize( $files_zip ), 244 245 'files_added' => $files_added, … … 246 247 247 248 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'; 249 251 $response['db_size'] = filesize( $db_zip ); 250 252 } … … 334 336 private function create_database_backup( $zip_file, $tables, $log_file ) { 335 337 $db_backup = $this->backup_database( $tables ); 338 $this->log('', 'backup_database: ' . file_get_contents($db_backup)); 336 339 if ( ! $db_backup ) { 337 340 $this->log( $log_file, 'Failed to create database dump' ); … … 370 373 */ 371 374 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 } 372 383 $timestamp = gmdate( 'Y-m-d H:i:s' ); 373 384 $log_message = "[$timestamp] $message\n"; … … 377 388 WP_Filesystem(); 378 389 } 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 ); 380 392 } 381 393 … … 400 412 401 413 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 );407 414 408 415 // 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"; 412 420 413 421 foreach ( $tables as $table ) { … … 421 429 $create_table = $wpdb->get_row( 422 430 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange 423 $wpdb->prepare( 'SHOW CREATE TABLE `%s`', $table_name),431 sprintf('SHOW CREATE TABLE %s', "`{$table_name}`"), 424 432 ARRAY_N 425 433 ); 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"; 428 436 429 437 // Datos de la tabla. 430 438 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 431 439 $rows = $wpdb->get_results( 432 $wpdb->prepare( 'SELECT * FROM `%s`', $table_name),440 sprintf('SELECT * FROM %s', "`{$table_name}`"), 433 441 ARRAY_A 434 442 ); … … 449 457 } 450 458 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"; 455 460 } 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 ); 462 466 463 467 return $backup_file; … … 540 544 541 545 // 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 546 559 547 560 $updates = array( -
multi-connect/tags/1.0.1/multi-connect.php
r3215732 r3217196 4 4 * Plugin URI: https://multi-wp.com 5 5 * Description: Connect your WordPress site with Multi-WP for centralized management and updates. 6 * Version: 1.0. 06 * Version: 1.0.1 7 7 * Requires at least: 5.8 8 8 * Requires PHP: 7.4 … … 24 24 define( 'MULTICONNECT_PLUGIN_PATH', plugin_dir_path( __FILE__ ) ); 25 25 define( 'MULTICONNECT_PLUGIN_DIR', plugin_dir_path( __DIR__ ) . '' ); 26 define( 'MULTICONNECT_PLUGIN_ABSPATH', plugin_dir_path( __DIR__ ) . '../../' );26 define( 'MULTICONNECT_PLUGIN_ABSPATH', ABSPATH . '' ); 27 27 define( 'MULTICONNECT_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); 28 28 const MULTICONNECT_VERSION = '1.0.0'; -
multi-connect/tags/1.0.1/readme.txt
r3215732 r3217196 5 5 Tested up to: 6.7 6 6 Requires PHP: 7.4 7 Stable tag: 1.0. 07 Stable tag: 1.0.1 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 41 41 == Changelog == 42 42 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 43 48 = 1.0.0 = 44 49 * Initial release … … 46 51 == Upgrade Notice == 47 52 53 = 1.0.1 = 54 Security enhancement update: Includes improved communication security with Multi WP platform and bug fixes. Upgrade recommended for all users. 55 48 56 = 1.0.0 = 49 57 Initial release of Multi Connect -
multi-connect/trunk/.editorconfig
r3215732 r3217196 1 1 [*] 2 2 end_of_line = lf 3 charset = utf-8 4 trim_trailing_whitespace = true 5 indent_size = 4 6 indent_style = space 7 insert_final_newline = true -
multi-connect/trunk/includes/class-admin.php
r3215732 r3217196 8 8 namespace MultiConnect; 9 9 10 use WP_Application_Passwords; 11 10 12 if ( ! defined( 'ABSPATH' ) ) { 11 // Exit if accessed directly.12 exit;13 // Exit if accessed directly. 14 exit; 13 15 } 14 16 … … 19 21 */ 20 22 class Admin { 21 /**22 * Constructor23 */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 } 30 32 31 /**32 * Check if the connection is established33 *34 * @return void35 */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 } 42 44 43 /**44 * Display the connection notice45 *46 * @return void47 */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 } 52 54 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 <?php58 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 <?php74 }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 } 75 77 76 /**77 * Enqueue admin assets78 *79 * @return void80 */81 public function enqueue_admin_assets() {78 /** 79 * Enqueue admin assets 80 * 81 * @return void 82 */ 83 public function enqueue_admin_assets() { 82 84 83 wp_enqueue_style(84 'multiconnect-admin',85 MULTICONNECT_PLUGIN_URL . 'assets/css/admin.css',86 array(),87 MULTICONNECT_VERSION88 );85 wp_enqueue_style( 86 'multiconnect-admin', 87 MULTICONNECT_PLUGIN_URL . 'assets/css/admin.css', 88 array(), 89 MULTICONNECT_VERSION 90 ); 89 91 90 wp_enqueue_script(91 'multiconnect-admin',92 MULTICONNECT_PLUGIN_URL . 'assets/js/admin.js',93 array( 'jquery' ),94 MULTICONNECT_VERSION,95 true96 );92 wp_enqueue_script( 93 'multiconnect-admin', 94 MULTICONNECT_PLUGIN_URL . 'assets/js/admin.js', 95 array( 'jquery' ), 96 MULTICONNECT_VERSION, 97 true 98 ); 97 99 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 } 109 111 110 /**111 * Handle the connection request112 *113 * @return void114 */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' ); 117 119 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 } 121 123 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(); 125 130 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 ); 136 141 137 // Hide the notice.138 update_option( 'multiconnect_show_notice', false );142 // Hide the notice. 143 update_option( 'multiconnect_show_notice', false ); 139 144 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 } 148 192 } -
multi-connect/trunk/includes/class-multi-connect-api.php
r3215732 r3217196 188 188 break; 189 189 case 'includes': 190 $selected_folders[] = MULTICONNECT_PLUGIN_ PATH . '../../wp-includes';190 $selected_folders[] = MULTICONNECT_PLUGIN_ABSPATH . 'wp-includes'; 191 191 break; 192 192 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' ) ); 194 194 break; 195 195 } … … 201 201 if ( empty( $folders ) ) { 202 202 $folders = array( 203 MULTICONNECT_PLUGIN_PATH . ' ../../wp-includes',203 MULTICONNECT_PLUGIN_PATH . '/wp-includes', 204 204 get_theme_root(), 205 MULTICONNECT_PLUGIN_PATH . ' ../',205 MULTICONNECT_PLUGIN_PATH . '/', 206 206 ); 207 207 208 $root_files = glob( MULTICONNECT_PLUGIN_PATH . ' ../../wp-*.php' );208 $root_files = glob( MULTICONNECT_PLUGIN_PATH . '/wp-*.php' ); 209 209 $folders = array_merge( $folders, $root_files ); 210 210 } … … 240 240 241 241 $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', 243 244 'files_size' => filesize( $files_zip ), 244 245 'files_added' => $files_added, … … 246 247 247 248 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'; 249 251 $response['db_size'] = filesize( $db_zip ); 250 252 } … … 334 336 private function create_database_backup( $zip_file, $tables, $log_file ) { 335 337 $db_backup = $this->backup_database( $tables ); 338 $this->log('', 'backup_database: ' . file_get_contents($db_backup)); 336 339 if ( ! $db_backup ) { 337 340 $this->log( $log_file, 'Failed to create database dump' ); … … 370 373 */ 371 374 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 } 372 383 $timestamp = gmdate( 'Y-m-d H:i:s' ); 373 384 $log_message = "[$timestamp] $message\n"; … … 377 388 WP_Filesystem(); 378 389 } 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 ); 380 392 } 381 393 … … 400 412 401 413 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 );407 414 408 415 // 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"; 412 420 413 421 foreach ( $tables as $table ) { … … 421 429 $create_table = $wpdb->get_row( 422 430 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange 423 $wpdb->prepare( 'SHOW CREATE TABLE `%s`', $table_name),431 sprintf('SHOW CREATE TABLE %s', "`{$table_name}`"), 424 432 ARRAY_N 425 433 ); 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"; 428 436 429 437 // Datos de la tabla. 430 438 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 431 439 $rows = $wpdb->get_results( 432 $wpdb->prepare( 'SELECT * FROM `%s`', $table_name),440 sprintf('SELECT * FROM %s', "`{$table_name}`"), 433 441 ARRAY_A 434 442 ); … … 449 457 } 450 458 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"; 455 460 } 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 ); 462 466 463 467 return $backup_file; … … 540 544 541 545 // 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 546 559 547 560 $updates = array( -
multi-connect/trunk/multi-connect.php
r3215732 r3217196 4 4 * Plugin URI: https://multi-wp.com 5 5 * Description: Connect your WordPress site with Multi-WP for centralized management and updates. 6 * Version: 1.0. 06 * Version: 1.0.1 7 7 * Requires at least: 5.8 8 8 * Requires PHP: 7.4 … … 24 24 define( 'MULTICONNECT_PLUGIN_PATH', plugin_dir_path( __FILE__ ) ); 25 25 define( 'MULTICONNECT_PLUGIN_DIR', plugin_dir_path( __DIR__ ) . '' ); 26 define( 'MULTICONNECT_PLUGIN_ABSPATH', plugin_dir_path( __DIR__ ) . '../../' );26 define( 'MULTICONNECT_PLUGIN_ABSPATH', ABSPATH . '' ); 27 27 define( 'MULTICONNECT_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); 28 28 const MULTICONNECT_VERSION = '1.0.0'; -
multi-connect/trunk/readme.txt
r3215732 r3217196 5 5 Tested up to: 6.7 6 6 Requires PHP: 7.4 7 Stable tag: 1.0. 07 Stable tag: 1.0.1 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 41 41 == Changelog == 42 42 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 43 48 = 1.0.0 = 44 49 * Initial release … … 46 51 == Upgrade Notice == 47 52 53 = 1.0.1 = 54 Security enhancement update: Includes improved communication security with Multi WP platform and bug fixes. Upgrade recommended for all users. 55 48 56 = 1.0.0 = 49 57 Initial release of Multi Connect
Note: See TracChangeset
for help on using the changeset viewer.