=== SMSTunnel === Contributors: narcisbodea, nicunarcisbodea Tags: sms, gateway, two-factor authentication, 2fa, notifications Requires at least: 5.0 Tested up to: 6.9 Requires PHP: 7.4 Stable tag: 1.0.9 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Send SMS messages directly from WordPress using your own Android phone as the SMS gateway. == Description == SMSTunnel transforms your Android phone into a powerful SMS gateway for WordPress. = Key Features = * Use Your Own Phone - No third-party SMS gateway costs * Two-Factor Authentication - Secure WordPress login with SMS 2FA * End-to-End Encryption - Messages encrypted with RSA keys * Quick Setup - Scan QR code from the mobile app == Installation == 1. Upload the plugin to /wp-content/plugins/ 2. Activate the plugin 3. Install the SMSTunnel app on your Android phone from https://smstunnel.io/integrations/android-app 4. Go to SMSTunnel > Quick Setup and scan the QR code with the app == Emergency 2FA recovery == When SMS 2FA is required and the "server fallback" option is OFF (the secure default), a total SMS outage would lock every admin out of wp-login - and the fallback option can only be changed while logged in. To recover, edit wp-config.php over FTP/SSH (or use WP-CLI) and add this line above the "That's all, stop editing" comment: define('SMSTUNNEL_2FA_EMERGENCY_BYPASS', true); While this constant is true, admins can log in without entering a 2FA code. Every use is recorded in the PHP error log. Remove the line as soon as SMS delivery is restored. Advanced users can instead hook the 'smstunnel_2fa_emergency_bypass' filter and return true. == External Services == This plugin connects to external services to provide certain functionality. Below are the details of each service: = SMSTunnel API = * **Purpose**: Core service that enables the plugin to communicate with the SMSTunnel mobile app for sending SMS messages from your phone * **When data is sent**: During Quick Setup (when pairing via QR code), when sending SMS messages, and when verifying API connections * **Data sent**: * During setup: Site URL, site token (random identifier), admin email (for account creation) * When sending SMS: Phone number, message content (encrypted if E2E is enabled), API key for authentication * **Service provider**: SMSTunnel.io (NARBOWEB SRL) * **Privacy Policy**: https://smstunnel.io/privacy * **Terms of Service**: https://smstunnel.io/terms = SMSTunnel Authentication = * **Purpose**: Optional sign-in via Google, Facebook, or email to link your SMSTunnel account with WordPress * **When data is sent**: Only when the admin uses the "Connect with Google/Facebook/Email" options on the plugin settings page * **Data sent**: * Google/Facebook: Redirects to smstunnel.io/auth/google or smstunnel.io/auth/facebook with a callback URL and CSRF state token * Email login: Email and password sent to smstunnel.io/api/v1/auth/login * After authentication: Fetches user profile from smstunnel.io/auth/me and creates an API key via smstunnel.io/api/v1/api-keys * **Service provider**: SMSTunnel.io (NARBOWEB SRL) * **Privacy Policy**: https://smstunnel.io/privacy * **Terms of Service**: https://smstunnel.io/terms **Note**: QR codes are generated locally using an embedded JavaScript library (qrcode.min.js). No external QR code generation services are used. All SMS messages are sent through your own Android phone - the SMSTunnel server only acts as a relay to connect WordPress with your phone. == Screenshots == 1. Connect SMSTunnel to your account using multiple sign-in methods - API key, Google, or Facebook - right from the plugin settings page 2. Advanced settings panel featuring Two-Factor Authentication for WordPress login, interface language selection, end-to-end encryption toggle, and one-click connection testing 3. Send a test SMS directly from the admin panel to verify your configuration works end-to-end 4. Quick Setup wizard - scan the QR code with the SMSTunnel mobile app to pair your WordPress site in seconds == Changelog == = 1.0.9 = * Security: Added an emergency break-glass bypass for 2FA so admins are not permanently locked out of wp-login during a total SMS outage (fail-closed fallback). Enable by adding define('SMSTUNNEL_2FA_EMERGENCY_BYPASS', true); to wp-config.php (see "Emergency 2FA recovery" in Installation), then remove it once access is restored. Every activation is written to the PHP error log. * Fix: API validation errors returned by the server as an array (NestJS class-validator) are now flattened to a readable string instead of storing the literal "Array" (PHP 8 "Array to string conversion"). * Fix: The read endpoints (connection test, usage, message status, received messages) now handle HTTP 429 rate-limit responses consistently with the send endpoints. * Fix: The login 2FA code request is now idempotent - reloading the login page reuses the existing code instead of resending an SMS and burning a rate-limit slot. * Fix: Uninstall now also removes the locally generated RSA key pair (smstunnel_public_key, smstunnel_private_key) so no key material is left orphaned. = 1.0.8 = * Added: Optional hybrid end-to-end encryption (v2) using AES-256-GCM for the message payload plus RSA-OAEP for the AES key, removing the ~245 byte size limit of legacy RSA encryption for long SMS messages * Added: "Use hybrid encryption (v2)" toggle in End-to-End Encryption settings (default OFF; requires an up-to-date SMSTunnel app that advertises v2 support) * Added: Pairing now stores the device's advertised E2E version so the encryptor only uses v2 for capable devices; falls back to v1 otherwise * Compatibility: When the hybrid toggle is OFF (default), encryption behaviour is unchanged (RSA PKCS#1 v1.5), so existing paired devices keep working = 1.0.7 = * Security: Added rate limiting to public (nopriv) 2FA SMS endpoints to prevent SMS bombing (3 codes / 15 min per IP on login, 60s cooldown + 5/hour on phone-setup verification) * Security: Added brute-force lockout on 2FA code verification (max 5 wrong attempts, then the code is invalidated) and switched to constant-time comparison (hash_equals) * Security: 2FA server fallback ("login without 2FA when SMS unavailable") now defaults to OFF to avoid fail-open authentication * Security: Client IP detection now relies solely on REMOTE_ADDR (validated) and no longer trusts spoofable proxy headers * Security: REST /setup-callback site token now compared in constant time (hash_equals) * Security: Hardened admin-settings.js E2E pairing UI to use .text() for dynamic/i18n values (DOM XSS) * Security: Added rate-limit (HTTP 429) handling for the SMS API client * Security: Strict in_array() comparisons for role checks * Fix: Synchronized uninstall cleanup with the option keys actually used by the plugin * Added: Shared recipient validation helpers (smstunnel_validate_e164, smstunnel_is_premium_number, smstunnel_sanitize_recipient) for satellite form plugins = 1.0.6 = * Security: Added nonce validation (check_ajax_referer) to all nopriv AJAX endpoints including 2FA login and phone setup * Security: Fixed DOM XSS in quick-setup.js, social-login.js, and admin-settings.js - all server/URL data now uses .text() instead of .html() * Security: Escaped all remaining unescaped outputs in SMS history table * Security: API key verification now uses X-API-Key header and configurable server URL (consistent with rest of plugin) * Fix: Corrected AJAX action name mismatch for API key verification * Documentation: Added SMSTunnel Authentication section to External Services (auth endpoints) = 1.0.5 = * Security: Moved all inline JavaScript to external files using wp_enqueue_script and wp_localize_script * Security: Added OAuth state parameter validation to prevent CSRF attacks on OAuth callback * Security: REST API /setup-callback now validates site_token in permission_callback instead of callback body * Security: Removed all wp_add_inline_script calls - all scripts now in external .js files * Code: Added $request parameter to all REST API permission_callback methods for PHP 8+ compatibility = 1.0.4 = * Documentation: Updated External Services section with complete service documentation = 1.0.3 = * Security: Replaced __return_true with documented custom permission_callback methods = 1.0.2 = * Security: Replaced inline scripts with wp_add_inline_script for proper enqueueing * Security: Fixed XSS vulnerabilities by using textContent instead of innerHTML for server responses * Security: Removed external QR code generation services (Google Charts, QR Server API) - all QR codes now generated locally * Security: Improved escaping for all JavaScript strings using esc_js() * Documentation: Updated External Services section to accurately reflect service usage = 1.0.1 = * Security: Added sanitization callbacks for all settings * Security: Fixed escape output for translatable strings * Security: Database queries now use prepared statements * Security: Changed wp_redirect to wp_safe_redirect * Security: Changed mt_rand to wp_rand * Compatibility: Tested up to WordPress 6.7.1 = 1.0.0 = * Initial release == Upgrade Notice == = 1.0.2 = Security update - removed external QR services, fixed XSS vulnerabilities, improved script enqueueing. = 1.0.1 = Security update with improved input sanitization and output escaping.