PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.7.2
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.7.2
2.7.1 2.7.2 2.7.0 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 All 141 releases
← All changes | includes/class-metasync-connect-manager.php +41 -9 2.7.1 → 2.7.2 View file →
@@ -283,8 +283,15 @@
283 283 }
284 284
285 285 $sa_connect_url = $dashboard_domain . '/sso/wordpress?' . http_build_query($connect_args);
286 286
287 + // Consent-gated analytics: the denominator for searchatlas_connected.
288 + $existing_key = Metasync::get_searchatlas_api_key();
289 + Metasync_PostHog::feature('searchatlas_connect_started', array(
290 + 'is_reconnection' => is_string($existing_key) && $existing_key !== '',
291 + 'is_whitelabel' => (bool) Metasync::is_whitelabel_enabled(),
292 + ));
293 +
287 294 wp_send_json_success(array(
288 295 'connect_url' => $sa_connect_url,
289 296 'nonce_token' => $sa_connect_token,
290 297 'debug_info' => array(
@@ -459,8 +466,13 @@
459 466 } elseif ($pull['status'] === 'error') {
460 467 // Honest state: surface the real server error (e.g. "Domain not
461 468 // found for customer") instead of the silent 60s timeout. The
462 469 // existing JS branches on status_code (404/500/…) to render it.
470 + // Once per connect attempt, even if the poll repeats.
471 + Metasync_PostHog::feature_once('searchatlas_connect_failed', array(
472 + 'status_code' => $pull_status_code ?: 400,
473 + 'source' => 'pull',
474 + ), md5($nonce_token), 15 * MINUTE_IN_SECONDS);
463 475 wp_send_json_success(array(
464 476 'updated' => true,
465 477 'status_code' => $pull_status_code ?: 400,
466 478 'message' => isset($connect['message']) ? sanitize_text_field($connect['message']) : '',
@@ -1076,18 +1088,16 @@
1076 1088
1077 1089 $cleaned_tokens = $this->cleanup_searchatlas_nonce_tokens();
1078 1090 $cleared_data['sa_connect_nonce_tokens'] = 'none (simplified token system)';
1079 1091
1080 - delete_option(Metasync::option_name . '_whitelabel_user');
1081 - $cleared_data['whitelabel_user'] = 'removed';
1092 + // White-label identity is preserved across the authentication
1093 + // reset: the reseller's branding, logos, domains, custom OTTO
1094 + // name, visibility/access controls, password and recovery
1095 + // settings, and the dedicated whitelabel_user option must survive
1096 + // the disconnect. Only authentication tokens and credentials are
1097 + // cleared above. Do not delete the whitelabel blob or the
1098 + // whitelabel_user option here.
1082 1099
1083 - if (isset($options['whitelabel'])) {
1084 - $cleared_data['whitelabel_settings'] = 'removed';
1085 - unset($options['whitelabel']);
1086 -
1087 - $this->write_options_without_stored_merge($options);
1088 - }
1089 -
1090 1100 $this->clear_jwt_token_cache();
1091 1101 $this->revoke_mcp_jwt_tokens();
1092 1102 $cleared_data['jwt_token_cache'] = 'cleared';
1093 1103
@@ -1110,8 +1120,30 @@
1110 1120 $cleared_data['heartbeat_cache'] = 'cleared';
1111 1121 $cleared_data['last_known_connection_state'] = 'cleared';
1112 1122
1113 1123 Metasync_Heartbeat_Manager::instance()->unschedule_heartbeat_cron();
1124 +
1125 + // Consent-gated analytics: churn signal, the opposite of connected.
1126 + Metasync_PostHog::feature('searchatlas_disconnected', array(
1127 + 'method' => 'reset_auth',
1128 + 'was_connected' => isset($cleared_data['searchatlas_api_key']),
1129 + ));
1130 +
1131 + // Re-synchronise the branded plugin file headers so the WordPress
1132 + // plugin list and the plugin UI stay branded after the
1133 + // authentication reset. Only attempted when white-label branding
1134 + // exists, and a failed sync is logged as a warning, not reported
1135 + // as a reset failure: the credentials have already been cleared,
1136 + // and hosts with read-only plugin files would otherwise never see
1137 + // a successful reset.
1138 + if (Metasync::is_whitelabel_enabled()) {
1139 + if (!class_exists('Metasync_Activator')) {
1140 + require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-metasync-activator.php';
1141 + }
1142 + if (!Metasync_Activator::sync_plugin_file_headers()) {
1143 + error_log('MetaSync: failed to re-synchronise branded plugin file headers after the authentication reset.');
1144 + }
1145 + }
1114 1146
1115 1147 wp_send_json_success(array(
1116 1148 'message' => 'Authentication has been reset successfully. You can now connect a new account.',
1117 1149 'cleared_data' => $cleared_data,