Changeset 3717600
- Timestamp:
- 09/28/2026 04:41:30 PM (3 weeks ago)
- Location:
- destino-access-audit/trunk
- Files:
-
- 2 edited
-
destino-access-audit.php (modified) (16 diffs)
-
readme.txt (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
destino-access-audit/trunk/destino-access-audit.php
r3636849 r3717600 4 4 * Plugin URI: https://destinoexterior.com 5 5 * Description: Security audit dashboard: lists the site's active Application Passwords (with AJAX revoke and CSV export) and shows the connection status of the installed remote management tools (UpdraftPlus/UpdraftCentral, MainWP Child, ManageWP Worker, InfiniteWP Client, Wordfence Security, Elementor Site Management). 6 * Version: 1. 5.06 * Version: 1.6.0 7 7 * Requires at least: 5.6 8 8 * Requires PHP: 7.4 … … 16 16 * Changelog 17 17 * --------- 18 * 1.6.0 19 * - Connector block boxes (UpdraftPlus/UpdraftCentral, MainWP Child, ManageWP Worker, 20 * InfiniteWP Client, Wordfence Security, Elementor Site Management) restyled with a 21 * postbox-style header: title and Installed/Active badges in one line, right-aligned, 22 * separated from the body by a divider line (render_connector_box()). Every long 23 * explanatory paragraph (why a connection status can't be determined, UpdraftPlus's Lock 24 * Settings note) is now a small "?" icon whose explanation shows in a native HTML `title` 25 * tooltip (help_icon()) instead of always-visible body text -- tried with the plain `title` 26 * attribute first, since it needs no new CSS/JS; a custom-styled tooltip is the fallback if 27 * this doesn't read well in practice. 28 * - The connector boxes now sort themselves with installed plugins first (get_sorted_connectors()), 29 * instead of a fixed order. Sorting is a hand-rolled stable sort (decorate with the original 30 * index, sort, undecorate) rather than relying on usort()'s stability, which PHP only 31 * guarantees since 8.0 and this plugin supports 7.4+. 32 * - "Administrator Users" now renders before "Application Passwords". 33 * - ManageWP Worker: added a direct link to its own "Connection Management" panel 34 * (admin_url( 'plugins.php?showWorker=1' )), the same link its docblock already described but 35 * never rendered as an actual button. 36 * - Tested up to WordPress 7.1. 18 37 * 1.5.0 19 38 * - New blocks: Wordfence Security (installed/active only -- Wordfence Central's connection … … 109 128 } 110 129 111 define( 'DESTINO_ACCESS_AUDIT_VERSION', '1. 5.0' );130 define( 'DESTINO_ACCESS_AUDIT_VERSION', '1.6.0' ); 112 131 113 132 /** … … 284 303 .destino-access-audit-table-wrap { overflow-x:auto; } 285 304 @media (max-width: 900px) { .destino-access-audit-connectors { grid-template-columns:1fr; } } 305 .destino-access-audit-box-header { display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:6px 16px; margin:-1px -20px 16px; padding:14px 20px; border-bottom:1px solid #c3c4c7; } 306 .destino-access-audit-box-header h2 { margin:0; } 307 .destino-access-audit-box-badges { display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin:0; font-size:13px; } 308 .destino-access-audit-box-badge { display:inline-flex; align-items:center; gap:6px; white-space:nowrap; } 309 .destino-access-audit-box-body > *:last-child { margin-bottom:0; } 310 .destino-access-audit-help { display:inline-flex; align-items:center; justify-content:center; width:16px; height:16px; border-radius:50%; background:#f0f0f1; color:#50575e; font-size:11px; font-weight:700; line-height:1; cursor:help; vertical-align:middle; } 311 .destino-access-audit-help:focus { outline:2px solid #2271b1; outline-offset:1px; } 286 312 '; 287 313 } … … 377 403 378 404 <div class="destino-access-audit-section"> 405 <h2><?php esc_html_e( 'Administrator Users', 'destino-access-audit' ); ?></h2> 406 <?php self::render_administrators(); ?> 407 </div> 408 409 <div class="destino-access-audit-section"> 379 410 <h2><?php esc_html_e( 'Application Passwords', 'destino-access-audit' ); ?></h2> 380 411 <?php self::render_application_passwords(); ?> 381 412 </div> 382 413 383 <div class="destino-access-audit-section">384 <h2><?php esc_html_e( 'Administrator Users', 'destino-access-audit' ); ?></h2>385 <?php self::render_administrators(); ?>386 </div>387 388 414 <div class="destino-access-audit-connectors"> 389 <div class="destino-access-audit-section"> 390 <h2><?php echo esc_html( self::PRODUCT_UPDRAFTPLUS . ' / ' . self::PRODUCT_UPDRAFTCENTRAL ); ?></h2> 391 <?php self::render_updraftplus_status(); ?> 392 </div> 393 394 <div class="destino-access-audit-section"> 395 <h2><?php echo esc_html( self::PRODUCT_MAINWP_CHILD ); ?></h2> 396 <?php self::render_mainwp_status(); ?> 397 </div> 398 399 <div class="destino-access-audit-section"> 400 <h2><?php echo esc_html( self::PRODUCT_MANAGEWP_WORKER ); ?></h2> 401 <?php self::render_managewp_status(); ?> 402 </div> 403 404 <div class="destino-access-audit-section"> 405 <h2><?php echo esc_html( self::PRODUCT_INFINITEWP_CLIENT ); ?></h2> 406 <?php self::render_infinitewp_status(); ?> 407 </div> 408 409 <div class="destino-access-audit-section"> 410 <h2><?php echo esc_html( self::PRODUCT_WORDFENCE ); ?></h2> 411 <?php self::render_wordfence_status(); ?> 412 </div> 413 414 <div class="destino-access-audit-section"> 415 <h2><?php echo esc_html( self::PRODUCT_ELEMENTOR_MANAGE ); ?></h2> 416 <?php self::render_elementor_status(); ?> 417 </div> 415 <?php foreach ( self::get_sorted_connectors() as $connector ) : ?> 416 <?php self::render_connector_box( $connector['file'], $connector['label'], $connector['body'] ); ?> 417 <?php endforeach; ?> 418 418 </div> 419 419 </div> 420 420 <?php 421 } 422 423 /** 424 * The six connector blocks, sorted so installed plugins render first and the rest after 425 * (stable sort: within each group, the original order below is preserved -- PHP's usort() 426 * only guarantees stability since 8.0, and this plugin supports 7.4+, so the tie-break on 427 * original index below is done by hand rather than relying on that). 428 * 429 * @return array<int, array{file: string, label: string, body: callable}> 430 */ 431 private static function get_sorted_connectors() { 432 self::ensure_plugin_functions(); 433 434 $connectors = array( 435 array( 436 'file' => 'updraftplus/updraftplus.php', 437 'label' => self::PRODUCT_UPDRAFTPLUS . ' / ' . self::PRODUCT_UPDRAFTCENTRAL, 438 'body' => array( __CLASS__, 'render_updraftplus_body' ), 439 ), 440 array( 441 'file' => 'mainwp-child/mainwp-child.php', 442 'label' => self::PRODUCT_MAINWP_CHILD, 443 'body' => array( __CLASS__, 'render_mainwp_body' ), 444 ), 445 array( 446 'file' => 'worker/init.php', 447 'label' => self::PRODUCT_MANAGEWP_WORKER, 448 'body' => array( __CLASS__, 'render_managewp_body' ), 449 ), 450 array( 451 'file' => 'iwp-client/init.php', 452 'label' => self::PRODUCT_INFINITEWP_CLIENT, 453 'body' => array( __CLASS__, 'render_infinitewp_body' ), 454 ), 455 array( 456 'file' => 'wordfence/wordfence.php', 457 'label' => self::PRODUCT_WORDFENCE, 458 'body' => array( __CLASS__, 'render_wordfence_body' ), 459 ), 460 array( 461 'file' => 'manage/manage.php', 462 'label' => self::PRODUCT_ELEMENTOR_MANAGE, 463 'body' => array( __CLASS__, 'render_elementor_body' ), 464 ), 465 ); 466 467 $decorated = array(); 468 foreach ( $connectors as $i => $connector ) { 469 $installed = file_exists( WP_PLUGIN_DIR . '/' . $connector['file'] ); 470 $decorated[] = array( $installed ? 0 : 1, $i, $connector ); 471 } 472 473 usort( 474 $decorated, 475 static function ( $a, $b ) { 476 return ( $a[0] !== $b[0] ) ? ( $a[0] <=> $b[0] ) : ( $a[1] <=> $b[1] ); 477 } 478 ); 479 480 return array_map( 481 static function ( $item ) { 482 return $item[2]; 483 }, 484 $decorated 485 ); 486 } 487 488 /** 489 * Shared "postbox"-style wrapper for a connector block: a header strip (product name + 490 * Installed/Active badges, right-aligned, separated from the body by a divider line) and, 491 * only when the plugin is active, the block-specific body. 492 * 493 * @param string $file Plugin file relative to WP_PLUGIN_DIR, used for the installed/active check. 494 * @param string $label Product name shown as the box title. 495 * @param callable $body Called with no arguments to render the active-only body. 496 */ 497 private static function render_connector_box( $file, $label, $body ) { 498 self::ensure_plugin_functions(); 499 500 $installed = file_exists( WP_PLUGIN_DIR . '/' . $file ); 501 $active = is_plugin_active( $file ); 502 ?> 503 <div class="destino-access-audit-section"> 504 <div class="destino-access-audit-box-header"> 505 <h2><?php echo esc_html( $label ); ?></h2> 506 <p class="destino-access-audit-box-badges"> 507 <?php echo wp_kses_post( '<span class="destino-access-audit-box-badge">' . esc_html__( 'Installed:', 'destino-access-audit' ) . ' ' . self::badge( $installed ) . '</span>' ); ?> 508 <?php echo wp_kses_post( '<span class="destino-access-audit-box-badge">' . esc_html__( 'Active:', 'destino-access-audit' ) . ' ' . self::badge( $active ) . '</span>' ); ?> 509 </p> 510 </div> 511 <?php if ( $active ) : ?> 512 <div class="destino-access-audit-box-body"> 513 <?php call_user_func( $body ); ?> 514 </div> 515 <?php endif; ?> 516 </div> 517 <?php 518 } 519 520 /** 521 * A small "?" help icon whose full explanation is a native browser tooltip (the HTML 522 * `title` attribute) rather than always-visible body text. Tried first because it needs no 523 * new CSS/JS at all; if it doesn't read well in practice, a custom-styled tooltip is the 524 * fallback. 525 * 526 * @param string $text Already-translated explanation text (plain text, no HTML). 527 * @return string Escaped HTML. 528 */ 529 private static function help_icon( $text ) { 530 return ' <span class="destino-access-audit-help" tabindex="0" title="' . esc_attr( $text ) . '">?</span>'; 421 531 } 422 532 … … 746 856 * Application Passwords. 747 857 */ 748 private static function render_updraftplus_status() { 749 self::ensure_plugin_functions(); 750 751 $plugin_file = 'updraftplus/updraftplus.php'; 752 $installed = file_exists( WP_PLUGIN_DIR . '/' . $plugin_file ); 753 $active = is_plugin_active( $plugin_file ); 754 755 echo wp_kses_post( '<p>' . esc_html__( 'Installed:', 'destino-access-audit' ) . ' ' . self::badge( $installed ) . '</p>' ); 756 echo wp_kses_post( '<p>' . esc_html__( 'Active:', 'destino-access-audit' ) . ' ' . self::badge( $active ) . '</p>' ); 757 758 if ( ! $active ) { 759 return; 760 } 761 858 private static function render_updraftplus_body() { 762 859 echo '<p><a class="button button-secondary" href="' . esc_url( admin_url( 'options-general.php?page=updraftplus' ) ) . '">' . esc_html( 763 860 sprintf( … … 771 868 $locked = ! empty( $adminlock ) && is_array( $adminlock ) && ! empty( $adminlock['password'] ); 772 869 773 echo wp_kses_post( '<p>' . esc_html__( 'Settings screen protected by a lock password:', 'destino-access-audit' ) . ' ' . self::badge( $locked ) . '</p>' );774 775 if ( $locked ) {776 echo '<p class="description destino-access-audit-note">' . esc_html(777 sprintf(778 /* translators: %1$s: name of the third-party plugin (repeated) whose own password lock is being described. Always a product name, never translate it. */ 779 __( '%1$s\'s own "Lock Settings" feature (Advanced Tools tab) is hiding its settings behind a password. To review or remove it without knowing that password: temporarily add define( \'UPDRAFTPLUS_NOADMINLOCK\', true ); to wp-config.php, reload the %1$s settings page, change or remove the lock from its Advanced Tools tab, then remove that line again. If you do know the password, you can change or remove the lock directly from that same tab.', 'destino-access-audit' ),780 self::PRODUCT_UPDRAFTPLUS781 )782 ) . '</p>';783 }870 $lock_explanation = sprintf( 871 /* translators: %1$s: name of the third-party plugin (repeated) whose own password lock is being described. Always a product name, never translate it. */ 872 __( '%1$s\'s own "Lock Settings" feature (Advanced Tools tab) is hiding its settings behind a password. To review or remove it without knowing that password: temporarily add define( \'UPDRAFTPLUS_NOADMINLOCK\', true ); to wp-config.php, reload the %1$s settings page, change or remove the lock from its Advanced Tools tab, then remove that line again. If you do know the password, you can change or remove the lock directly from that same tab.', 'destino-access-audit' ), 873 self::PRODUCT_UPDRAFTPLUS 874 ); 875 876 echo wp_kses_post( 877 '<p>' . esc_html__( 'Settings screen protected by a lock password:', 'destino-access-audit' ) . ' ' . self::badge( $locked ) 878 . ( $locked ? self::help_icon( $lock_explanation ) : '' ) 879 . '</p>' 880 ); 784 881 785 882 $keys = get_option( 'updraft_central_localkeys' ); … … 853 950 * hook_activated_plugin() and plugin_settings_link()). 854 951 */ 855 private static function render_mainwp_status() { 856 self::ensure_plugin_functions(); 857 858 $plugin_file = 'mainwp-child/mainwp-child.php'; 859 $installed = file_exists( WP_PLUGIN_DIR . '/' . $plugin_file ); 860 $active = is_plugin_active( $plugin_file ); 861 862 echo wp_kses_post( '<p>' . esc_html__( 'Installed:', 'destino-access-audit' ) . ' ' . self::badge( $installed ) . '</p>' ); 863 echo wp_kses_post( '<p>' . esc_html__( 'Active:', 'destino-access-audit' ) . ' ' . self::badge( $active ) . '</p>' ); 864 865 if ( ! $active ) { 866 return; 867 } 868 952 private static function render_mainwp_body() { 869 953 echo '<p><a class="button button-secondary" href="' . esc_url( admin_url( 'options-general.php?page=mainwp_child_tab' ) ) . '">' . esc_html( 870 954 sprintf( … … 929 1013 * shows under its name on wp-admin → Plugins, or the ManageWP dashboard. 930 1014 */ 931 private static function render_managewp_status() { 932 self::ensure_plugin_functions(); 933 934 $plugin_file = 'worker/init.php'; 935 $installed = file_exists( WP_PLUGIN_DIR . '/' . $plugin_file ); 936 $active = is_plugin_active( $plugin_file ); 937 938 echo wp_kses_post( '<p>' . esc_html__( 'Installed:', 'destino-access-audit' ) . ' ' . self::badge( $installed ) . '</p>' ); 939 echo wp_kses_post( '<p>' . esc_html__( 'Active:', 'destino-access-audit' ) . ' ' . self::badge( $active ) . '</p>' ); 940 941 if ( ! $active ) { 942 return; 943 } 1015 private static function render_managewp_body() { 1016 echo '<p><a class="button button-secondary" href="' . esc_url( admin_url( 'plugins.php?showWorker=1' ) ) . '">' . esc_html( 1017 sprintf( 1018 /* translators: %s: name of the third-party plugin whose connection-management panel this links to. Always a product name, never translate it. */ 1019 __( 'View %s connection details', 'destino-access-audit' ), 1020 self::PRODUCT_MANAGEWP_WORKER 1021 ) 1022 ) . '</a></p>'; 1023 1024 $pairing_explanation = sprintf( 1025 /* translators: %s: name of the third-party plugin whose remote panel this pairs with. Always a product name, never translate it. */ 1026 __( 'This plugin pairs the site with the remote panel through an OpenSSL key exchange, without exposing a readable "connected" option/meta. Check the connection from the "Connection Management" link under the plugin\'s name on wp-admin → Plugins, or from your %s panel.', 'destino-access-audit' ), 1027 self::PRODUCT_MANAGEWP 1028 ); 944 1029 945 1030 echo wp_kses_post( … … 950 1035 self::PRODUCT_MANAGEWP 951 1036 ) 952 ) . ' ' . self::badge( null ) . '</p>' 953 ); 954 echo '<p class="description destino-access-audit-note">' . esc_html( 955 sprintf( 956 /* translators: %s: name of the third-party plugin whose remote panel this pairs with. Always a product name, never translate it. */ 957 __( 'This plugin pairs the site with the remote panel through an OpenSSL key exchange, without exposing a readable "connected" option/meta. Check the connection from the "Connection Management" link under the plugin\'s name on wp-admin → Plugins, or from your %s panel.', 'destino-access-audit' ), 958 self::PRODUCT_MANAGEWP 959 ) 960 ) . '</p>'; 1037 ) . ' ' . self::badge( null ) . self::help_icon( $pairing_explanation ) . '</p>' 1038 ); 961 1039 } 962 1040 … … 973 1051 * inventing a state. 974 1052 */ 975 private static function render_infinitewp_status() { 976 self::ensure_plugin_functions(); 977 978 $plugin_file = 'iwp-client/init.php'; 979 $installed = file_exists( WP_PLUGIN_DIR . '/' . $plugin_file ); 980 $active = is_plugin_active( $plugin_file ); 981 982 echo wp_kses_post( '<p>' . esc_html__( 'Installed:', 'destino-access-audit' ) . ' ' . self::badge( $installed ) . '</p>' ); 983 echo wp_kses_post( '<p>' . esc_html__( 'Active:', 'destino-access-audit' ) . ' ' . self::badge( $active ) . '</p>' ); 984 985 if ( ! $active ) { 986 return; 987 } 1053 private static function render_infinitewp_body() { 1054 $pairing_explanation = sprintf( 1055 /* translators: %s: name of the third-party remote-management panel this verifies requests from. Always a product name, never translate it. */ 1056 __( 'This plugin verifies every request from the remote panel using OpenSSL signatures, without exposing a readable "connected" option/meta. Check the connection from the %s panel itself (the added-sites section).', 'destino-access-audit' ), 1057 self::PRODUCT_INFINITEWP 1058 ); 988 1059 989 1060 echo wp_kses_post( … … 994 1065 self::PRODUCT_INFINITEWP 995 1066 ) 996 ) . ' ' . self::badge( null ) . '</p>' 997 ); 998 echo '<p class="description destino-access-audit-note">' . esc_html( 999 sprintf( 1000 /* translators: %s: name of the third-party remote-management panel this verifies requests from. Always a product name, never translate it. */ 1001 __( 'This plugin verifies every request from the remote panel using OpenSSL signatures, without exposing a readable "connected" option/meta. Check the connection from the %s panel itself (the added-sites section).', 'destino-access-audit' ), 1002 self::PRODUCT_INFINITEWP 1003 ) 1004 ) . '</p>'; 1067 ) . ' ' . self::badge( null ) . self::help_icon( $pairing_explanation ) . '</p>' 1068 ); 1005 1069 } 1006 1070 … … 1021 1085 * (lib/wfConfig.php, lib/wfCentralAPI.php, lib/menu_wordfence_central.php). 1022 1086 */ 1023 private static function render_wordfence_status() { 1024 self::ensure_plugin_functions(); 1025 1026 $plugin_file = 'wordfence/wordfence.php'; 1027 $installed = file_exists( WP_PLUGIN_DIR . '/' . $plugin_file ); 1028 $active = is_plugin_active( $plugin_file ); 1029 1030 echo wp_kses_post( '<p>' . esc_html__( 'Installed:', 'destino-access-audit' ) . ' ' . self::badge( $installed ) . '</p>' ); 1031 echo wp_kses_post( '<p>' . esc_html__( 'Active:', 'destino-access-audit' ) . ' ' . self::badge( $active ) . '</p>' ); 1032 1033 if ( ! $active ) { 1034 return; 1035 } 1036 1087 private static function render_wordfence_body() { 1037 1088 echo '<p><a class="button button-secondary" href="' . esc_url( admin_url( 'admin.php?page=Wordfence' ) ) . '">' . esc_html( 1038 1089 sprintf( … … 1043 1094 ) . '</a></p>'; 1044 1095 1096 $connection_explanation = sprintf( 1097 /* translators: %1$s: name of the remote panel/service (repeated); %2$s: name of the third-party plugin it belongs to. Both are always product names, never translate them. */ 1098 __( 'This plugin stores its %1$s connection state in a custom database table rather than a WordPress option, so it cannot be read here without depending on %2$s\'s internal, undocumented API. Check the connection from the %1$s tab in the plugin\'s own settings page.', 'destino-access-audit' ), 1099 self::PRODUCT_WORDFENCE_CENTRAL, 1100 self::PRODUCT_WORDFENCE 1101 ); 1102 1045 1103 echo wp_kses_post( 1046 1104 '<p class="destino-access-audit-note">' . esc_html( … … 1050 1108 self::PRODUCT_WORDFENCE_CENTRAL 1051 1109 ) 1052 ) . ' ' . self::badge( null ) . '</p>' 1053 ); 1054 echo '<p class="description destino-access-audit-note">' . esc_html( 1055 sprintf( 1056 /* translators: %1$s: name of the remote panel/service (repeated); %2$s: name of the third-party plugin it belongs to. Both are always product names, never translate them. */ 1057 __( 'This plugin stores its %1$s connection state in a custom database table rather than a WordPress option, so it cannot be read here without depending on %2$s\'s internal, undocumented API. Check the connection from the %1$s tab in the plugin\'s own settings page.', 'destino-access-audit' ), 1058 self::PRODUCT_WORDFENCE_CENTRAL, 1059 self::PRODUCT_WORDFENCE 1060 ) 1061 ) . '</p>'; 1110 ) . ' ' . self::badge( null ) . self::help_icon( $connection_explanation ) . '</p>' 1111 ); 1062 1112 } 1063 1113 … … 1078 1128 * (modules/settings/components/page.php). 1079 1129 */ 1080 private static function render_elementor_status() { 1081 self::ensure_plugin_functions(); 1082 1083 $plugin_file = 'manage/manage.php'; 1084 $installed = file_exists( WP_PLUGIN_DIR . '/' . $plugin_file ); 1085 $active = is_plugin_active( $plugin_file ); 1086 1087 echo wp_kses_post( '<p>' . esc_html__( 'Installed:', 'destino-access-audit' ) . ' ' . self::badge( $installed ) . '</p>' ); 1088 echo wp_kses_post( '<p>' . esc_html__( 'Active:', 'destino-access-audit' ) . ' ' . self::badge( $active ) . '</p>' ); 1089 1090 if ( ! $active ) { 1091 return; 1092 } 1093 1130 private static function render_elementor_body() { 1094 1131 echo '<p><a class="button button-secondary" href="' . esc_url( admin_url( 'admin.php?page=manage-settings' ) ) . '">' . esc_html( 1095 1132 sprintf( -
destino-access-audit/trunk/readme.txt
r3636849 r3717600 3 3 Tags: security, audit, application passwords, mainwp, updraftplus 4 4 Requires at least: 5.6 5 Tested up to: 7. 05 Tested up to: 7.1 6 6 Requires PHP: 7.4 7 Stable tag: 1. 5.07 Stable tag: 1.6.0 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 23 23 * **UpdraftPlus / UpdraftCentral** — whether UpdraftPlus is installed/active, a direct link to its settings screen, whether it is connected to an UpdraftCentral dashboard (including *which* WordPress user made that connection), and whether UpdraftPlus's own password-protected "Lock Settings" feature is currently hiding that screen. 24 24 * **MainWP Child** — whether MainWP Child is installed/active, a direct link to its settings screen, whether it is paired with a MainWP Dashboard, and *which* WordPress user established that pairing. 25 * **ManageWP Worker** — installed/active status . ManageWP Worker pairs with its dashboard through an OpenSSL key exchange with no locally readable "connected" flag, so this block documents that limitation instead of guessing.25 * **ManageWP Worker** — installed/active status, plus a direct link to its own "Connection Management" panel. ManageWP Worker pairs with its dashboard through an OpenSSL key exchange with no locally readable "connected" flag, so this block documents that limitation instead of guessing. 26 26 * **InfiniteWP Client** — installed/active status, with the same honest limitation note as ManageWP Worker. 27 27 * **Wordfence Security** — installed/active status. Wordfence Central's connection state lives in Wordfence's own proprietary database table, not a readable WordPress option, so this block documents that limitation instead of guessing, the same as ManageWP Worker and InfiniteWP Client. 28 28 * **Elementor Site Management** — whether the "Manage" plugin by Elementor.com is installed/active, a direct link to its settings screen, and whether it is connected to my.elementor.com. 29 29 30 The connector blocks above lay out as a 2-column grid on desktop, so they're easier to scan at a glance;Application Passwords and Administrator Users stay full-width since they contain data tables.30 The connector blocks above lay out as a 2-column grid on desktop, installed plugins first, so they're easier to scan at a glance; each box header shows its Installed/Active status inline, with longer explanations tucked behind a small "?" tooltip instead of always-visible paragraphs. Application Passwords and Administrator Users stay full-width since they contain data tables. 31 31 32 32 **Security notes** … … 69 69 == Changelog == 70 70 71 = 1.6.0 = 72 * Connector block boxes (UpdraftPlus/UpdraftCentral, MainWP Child, ManageWP Worker, InfiniteWP Client, Wordfence Security, Elementor Site Management) restyled with a postbox-style header: title and Installed/Active badges in one line, separated from the body by a divider. Every long explanatory paragraph (why a connection status can't be determined, UpdraftPlus's Lock Settings note) is now a small "?" icon with the explanation in a tooltip instead of always-visible text. 73 * The connector boxes now sort themselves with installed plugins first, instead of a fixed order. 74 * Administrator Users now appears before Application Passwords. 75 * ManageWP Worker: added a direct link to its own "Connection Management" panel (`plugins.php?showWorker=1`). 76 * Tested up to WordPress 7.1. 77 71 78 = 1.5.0 = 72 79 * New blocks: Wordfence Security (installed/active only — Wordfence Central's connection state lives in a proprietary database table, not a readable WordPress option) and Elementor Site Management (the separate "Manage" plugin by Elementor.com — installed/active plus a reliable connection badge).
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)