Add PRV_Key_Store (resolver), PRV_Crypto_Helper (libsodium/OpenSSL), PRV_Key_Manager_Renderer (write-only Settings card), PRV_Key_Test_Ajax. Key resolver: PRV_OPENROUTER_API_KEY constant > prv_provider_key_enc option > none. All probe + test paths read key through PRV_Key_Store::get_key(). Security: - Ciphertext only in prv_provider_key_enc (hex nonce:hex ciphertext). - Enc key from SHA-256(AUTH_KEY+SECURE_AUTH_KEY) — never stored. - Plaintext never in options, logs, exceptions, page source, REST, or JS. - manage_options + nonce on set/remove/test. wp-config precedence enforced. - write-only UI: password input always renders empty; status text only. - uninstall.php prv_ wildcard DELETE covers prv_provider_key_enc. Files: 4 new (all ≤300 lines), 14 modified. Tests: test-key-store.php (encrypt/decrypt round-trip, wrong-key fails silently, resolver precedence, write-only render, Remove, constant wins). ARCHITECTURE/CONVENTIONS/CONTEXT/ CHANGELOG all updated in this commit. Agent-Session: 2026-06-15-pr-vision-v0.2.3-api-key-ui
53 lines
2.3 KiB
PHP
53 lines
2.3 KiB
PHP
<?php
|
|
/**
|
|
* PR Vision -- full data teardown on uninstall.
|
|
*
|
|
* Drops the custom prv_ai_visibility table and deletes every wp_options
|
|
* row whose name starts with "prv_". WP-Cron events are already cleared
|
|
* by PRV_Deactivator on deactivation; this runs after that.
|
|
*
|
|
* v0.2.0 additions: prv_models_schema_version, prv_config_versions,
|
|
* prv_active_config_version, prv_api_key_status, prv_api_key_last_check,
|
|
* prv_last_run_at, prv_last_run_counts, prv_last_run_truncated,
|
|
* prv_last_run_truncated_at -- all purged by the prv_ wildcard DELETE below.
|
|
*
|
|
* v0.2.3 addition: prv_provider_key_enc (encrypted API key) -- also purged
|
|
* by the prv_ wildcard DELETE below. No plaintext is stored.
|
|
*
|
|
* @see ARCHITECTURE.md -- Section Uninstall specification.
|
|
* @see class-prv-deactivator.php -- Clears cron on deactivation.
|
|
* @see class-prv-key-store.php -- Encrypted key storage (prv_provider_key_enc).
|
|
* @package PrVision
|
|
*/
|
|
|
|
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
|
exit;
|
|
}
|
|
|
|
global $wpdb;
|
|
|
|
/* ── 1. Drop the custom table ─────────────────────────────────────── */
|
|
|
|
$table = $wpdb->prefix . 'prv_ai_visibility';
|
|
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching
|
|
$wpdb->query( "DROP TABLE IF EXISTS {$table}" );
|
|
|
|
/* ── 2. Delete all prv_ prefixed options (v0.1, v0.2, v0.2.3) ───── */
|
|
|
|
// Covers prv_provider_key_enc (v0.2.3) along with all prior option keys.
|
|
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
|
$wpdb->query(
|
|
"DELETE FROM {$wpdb->options} WHERE option_name LIKE 'prv\_%'"
|
|
);
|
|
|
|
/* ── 3. Delete prv_ transients ────────────────────────────────────── */
|
|
|
|
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
|
$wpdb->query(
|
|
"DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_prv\_%' OR option_name LIKE '_transient_timeout_prv\_%'"
|
|
);
|
|
|
|
/* ── 4. Clear any remaining scheduled cron events ─────────────────── */
|
|
|
|
wp_clear_scheduled_hook( 'prv_weekly_probe' );
|