'Insufficient permissions.' ) ); } $nonce = isset( $_POST['prv_nonce'] ) ? sanitize_text_field( wp_unslash( (string) $_POST['prv_nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, PRV_Settings_Page::NONCE_KEY_TEST ) ) { wp_send_json_error( array( 'message' => 'Security check failed.' ) ); } if ( false !== get_transient( self::RATE_LIMIT_TRANSIENT ) ) { wp_send_json_error( array( 'message' => 'Rate limited โ€” wait 30 s between tests.' ) ); } set_transient( self::RATE_LIMIT_TRANSIENT, 1, self::RATE_LIMIT_SECONDS ); $api_key = PRV_Key_Store::get_key(); if ( '' === $api_key ) { wp_send_json_error( array( 'message' => 'No API key configured.' ) ); } $start = microtime( true ); $provider = new PRV_OpenRouter_Provider( 'openai/gpt-4o-mini', null, null ); try { $provider->probe_with_key( self::PROBE_QUERY, $api_key ); $ms = (int) round( ( microtime( true ) - $start ) * 1000 ); wp_send_json_success( array( 'valid' => true, 'latency_ms' => $ms, 'message' => sprintf( 'Key valid ยท %d ms', $ms ), ) ); } catch ( \Exception $e ) { wp_send_json_error( array( 'valid' => false, 'message' => 'Key invalid or provider error โ€” check key and try again.', ) ); } } }