Changeset 3469288
- Timestamp:
- 02/25/2026 09:59:52 AM (5 weeks ago)
- Location:
- authyo-otp-for-met-form/trunk
- Files:
-
- 6 edited
-
assets/css/style.css (modified) (1 diff)
-
assets/js/frontend.js (modified) (5 diffs)
-
authyo-otp-for-met-form.php (modified) (3 diffs)
-
includes/class-authyo-api.php (modified) (1 diff)
-
includes/class-authyo-frontend.php (modified) (3 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
authyo-otp-for-met-form/trunk/assets/css/style.css
r3466257 r3469288 316 316 pointer-events: none !important; 317 317 } 318 319 /* === Fallback UI === */ 320 .authyo-fallback { 321 background: #f0fff4; 322 border: 1px solid #00d084; 323 border-left: 4px solid #00d084; 324 padding: 15px; 325 border-radius: 4px; 326 margin-top: 15px; 327 } 328 329 .authyo-fallback-message { 330 font-size: 14px; 331 margin-bottom: 12px; 332 color: #333; 333 font-weight: 600; 334 margin-top: 0; 335 } 336 337 .authyo-fallback-buttons { 338 display: flex; 339 gap: 10px; 340 flex-wrap: wrap; 341 } 342 343 .authyo-fallback-btn { 344 flex: 1; 345 min-width: 100px; 346 display: flex; 347 align-items: center; 348 justify-content: center; 349 gap: 8px; 350 padding: 8px 12px; 351 border: 1px solid #00d084; 352 border-radius: 4px; 353 background: #fff; 354 cursor: pointer; 355 font-size: 13px; 356 color: #333; 357 font-weight: 600; 358 transition: all 0.2s; 359 } 360 361 .authyo-fallback-btn:hover:not(:disabled) { 362 background: #e6fff0; 363 border-color: #00a368; 364 } 365 366 .authyo-fallback-btn:disabled { 367 opacity: 0.5; 368 cursor: not-allowed; 369 background: #f5f5f5; 370 border-color: #ddd; 371 color: #888; 372 } 373 374 .authyo-fallback-btn.active { 375 border-style: dashed; 376 } 377 378 .authyo-fallback-btn .dashicons { 379 font-size: 16px; 380 width: 16px; 381 height: 16px; 382 color: #666; 383 } -
authyo-otp-for-met-form/trunk/assets/js/frontend.js
r3466376 r3469288 271 271 }, 272 272 273 startFallbackTimer: function ($wrap, seconds) { 274 const self = this; 275 this.clearFallbackTimer($wrap); 276 let sec = seconds; 277 278 const interval = setInterval(function () { 279 sec--; 280 if (sec <= 0) { 281 self.clearFallbackTimer($wrap); 282 self.showFallbackUI($wrap); 283 } 284 }, 1000); 285 $wrap.data('authyo-fallback-interval', interval); 286 }, 287 288 clearFallbackTimer: function ($wrap) { 289 const interval = $wrap.data('authyo-fallback-interval'); 290 if (interval) clearInterval(interval); 291 }, 292 293 showFallbackUI: function ($wrap) { 294 const self = this; 295 const $fallback = $wrap.find('.authyo-fallback'); 296 if (!$fallback.length) return; 297 298 const $btnContainer = $fallback.find('.authyo-fallback-buttons'); 299 $btnContainer.empty(); 300 301 const currentChannel = $wrap.data('current-channel'); 302 const channels = Config.channels || { sms: 1 }; 303 const enabledMethods = []; 304 if (channels.sms) enabledMethods.push('sms'); 305 if (channels.whatsapp) enabledMethods.push('whatsapp'); 306 if (channels.voicecall) enabledMethods.push('voicecall'); 307 308 const labels = { sms: 'SMS', whatsapp: 'WhatsApp', voicecall: 'Voice Call' }; 309 const icons = { sms: 'email-alt', whatsapp: 'whatsapp', voicecall: 'phone' }; 310 311 enabledMethods.forEach(m => { 312 const $btn = $(`<button type="button" class="authyo-fallback-btn button" data-method="${m}"> 313 <span class="dashicons dashicons-${icons[m] || 'email-alt'}"></span> 314 ${labels[m]} 315 </button>`); 316 317 if (m === currentChannel) { 318 $btn.prop('disabled', true).addClass('active').attr('title', 'Already tried this method'); 319 } 320 321 $btn.on('click', function () { 322 const method = $(this).data('method'); 323 $fallback.hide(); 324 325 // Find input reference for sendOTP 326 const $group = $(this).closest('.authyo-otp-group'); 327 const $input = $group.prev('.mf-input-wrapper, .elementor-widget-container').find('input.authyo-phone-field'); 328 const formId = $group.closest('.metform-form-content').data('form-id') || $group.closest('form').data('metform-form-id'); 329 330 self.sendOTP(null, $input, formId, method); 331 }); 332 333 $btnContainer.append($btn); 334 }); 335 336 $fallback.slideDown(); 337 }, 338 273 339 clearCountdown: function ($wrap) { 274 340 const interval = $wrap.data('authyo-interval'); … … 355 421 <button type="button" class="authyo-btn-verify">${Config.i18n.verify || 'Verify'}</button> 356 422 </div> 423 424 <!-- Fallback UI container --> 425 <div class="authyo-fallback" style="display:none; margin-top: 15px;"> 426 <p class="authyo-fallback-message">${Config.i18n.fallback_prompt || "Didn't receive OTP? Try another method:"}</p> 427 <div class="authyo-fallback-buttons"></div> 428 </div> 429 357 430 <div class="authyo-msg"></div> 358 431 </div> … … 478 551 $group.data('current-channel', channel); 479 552 553 // Clear any existing fallback timer 554 self.clearFallbackTimer($group); 555 480 556 if (res.bypass) { 481 557 self.onVerified($btn, $input, token); … … 494 570 const cooldown = (Config.defaults && Config.defaults.resend_cooldown) || 30; 495 571 self.startCountdown($group, cooldown); 572 573 // Start Fallback Timer for Phone Channels 574 if (channel !== 'email') { 575 const fallbackTime = (Config.defaults && Config.defaults.fallback_timer) || 30; 576 self.startFallbackTimer($group, fallbackTime); 577 } 496 578 }, 497 579 error: function (xhr) { … … 544 626 $group.find('.authyo-btn-send').hide(); 545 627 $group.find('.authyo-method-selector').hide(); 628 $group.find('.authyo-fallback').hide(); 629 self.clearFallbackTimer($group); 546 630 547 631 // Hide Input Wrapper (MetForm specific) - SOFT HIDE -
authyo-otp-for-met-form/trunk/authyo-otp-for-met-form.php
r3468450 r3469288 4 4 * Plugin URI: https://authyo.io 5 5 * Description: Integrates Authyo OTP Verification (Email, SMS, WhatsApp, Voice) into MetForm forms. 6 * Version: 1.0. 26 * Version: 1.0.3 7 7 * Author: Authyo 8 8 * Text Domain: authyo-otp-for-met-form … … 16 16 } 17 17 18 define( 'AUTHYO_OTP_MF_VERSION', '1.0. 2' );18 define( 'AUTHYO_OTP_MF_VERSION', '1.0.3' ); 19 19 define( 'AUTHYO_OTP_MF_PATH', plugin_dir_path( __FILE__ ) ); 20 20 define( 'AUTHYO_OTP_MF_URL', plugin_dir_url( __FILE__ ) ); … … 76 76 function authyo_otp_mf_activation() { 77 77 require_once plugin_dir_path( __FILE__ ) . 'includes/class-authyo-api.php'; 78 79 // Initialize default settings if they don't exist 80 $existing = get_option('authyo_otp_mf_settings'); 81 if (empty($existing)) { 82 $default_settings = [ 83 'app_id' => '', 84 'client_id' => '', 85 'client_secret' => '', 86 'channels' => [ 87 'email' => 1, 88 'sms' => 1, 89 'whatsapp' => 1, 90 'voicecall' => 1, 91 ], 92 'defaults' => [ 93 'otp_length' => 6, 94 'expiry_minutes' => 5, 95 'resend_cooldown' => 30, 96 'max_resends' => 3, 97 'primary_phone_method' => 'sms', 98 'fallback_timer' => 30, 99 'allow_visitor_method_choice' => 0, 100 ], 101 'forms' => [], 102 'country_config' => [ 103 'display_mode' => 'all' 104 ], 105 ]; 106 update_option('authyo_otp_mf_settings', $default_settings); 107 108 // Also update the flat option for compatibility 109 update_option('authyo_otp_mf_form_settings', []); 110 } 111 78 112 $api = new Authyo_OTP_MF_API(); 79 113 $api->refresh_country_list(); -
authyo-otp-for-met-form/trunk/includes/class-authyo-api.php
r3466257 r3469288 72 72 $body = json_decode( $body_raw, true ); 73 73 74 if ( $code >= 200 && $code < 300 && ! empty( $body['data']['results'][0]['maskId'] ) ) { 75 return [ 76 'success' => true, 77 'maskId' => sanitize_text_field( $body['data']['results'][0]['maskId'] ), 78 'http' => [ 'status' => $code ], 79 'raw' => $body ?: $body_raw, 80 ]; 74 if ( $code >= 200 && $code < 300 ) { 75 if ( ! empty( $body['data']['results'][0]['maskId'] ) ) { 76 return [ 77 'success' => true, 78 'maskId' => sanitize_text_field( $body['data']['results'][0]['maskId'] ), 79 'http' => [ 'status' => $code ], 80 'raw' => $body ?: $body_raw, 81 ]; 82 } 83 84 // Handle wallet empty or other success:false cases within 200 OK 85 if ( isset( $body['success'] ) && false === $body['success'] ) { 86 $msg = $body['message'] ?? $body['data']['results'][0]['message'] ?? __( 'Failed to send OTP', 'authyo-otp-for-met-form' ); 87 return new WP_Error( 88 'authyo_send_failed', 89 $msg, 90 [ 91 'status' => $code, 92 'body' => $body ?: $body_raw, 93 'request' => [ 'url' => $url ], 94 ] 95 ); 96 } 81 97 } 82 98 -
authyo-otp-for-met-form/trunk/includes/class-authyo-frontend.php
r3466376 r3469288 44 44 'enter_phone' => __('Please enter phone number', 'authyo-otp-for-met-form'), 45 45 'sending' => __('Sending...', 'authyo-otp-for-met-form'), 46 'verified_bypass' => __(' Verified successfully (Bypass)', 'authyo-otp-for-met-form'),46 'verified_bypass' => __('Auto-verified', 'authyo-otp-for-met-form'), 47 47 'resend_otp' => __('Resend OTP', 'authyo-otp-for-met-form'), 48 48 'sent' => __('Sent', 'authyo-otp-for-met-form'), … … 50 50 'verified_label' => __('verified:', 'authyo-otp-for-met-form'), 51 51 'search' => __('Search...', 'authyo-otp-for-met-form'), 52 'fallback_prompt' => __("Didn't receive OTP? Try another method:", 'authyo-otp-for-met-form'), 52 53 ) 53 54 ); … … 114 115 $result = $this->api->send_otp( $target, $channel, $otp_len, $expiry ); 115 116 116 // Wallet Exhausted Failsafe117 // Wallet Exhausted / API Failure Failsafe 117 118 if ( is_wp_error( $result ) ) { 118 119 $msg = $result->get_error_message(); 119 if ( stripos( $msg, 'wallet' ) !== false && stripos( $msg, 'low' ) !== false ) { 120 $should_bypass = false; 121 122 // Bypass if wallet is low or if API explicitly returned success: false 123 if ( stripos( $msg, 'wallet' ) !== false || stripos( $msg, 'balance' ) !== false ) { 124 $should_bypass = true; 125 } 126 127 if ( $should_bypass ) { 120 128 $verified_key = $token . ':' . $channel; 121 129 set_transient( 'authyo_otp_mf_verified_' . $verified_key, true, HOUR_IN_SECONDS ); 122 return rest_ensure_response([ 'success' => true, 'bypass' => true, 'channel' => $channel ]); 130 return rest_ensure_response([ 131 'success' => true, 132 'bypass' => true, 133 'channel' => $channel, 134 'message' => $msg 135 ]); 123 136 } 124 137 return $result; -
authyo-otp-for-met-form/trunk/readme.txt
r3468450 r3469288 4 4 Requires at least: 5.6 5 5 Tested up to: 6.9 6 Stable tag: 1.0. 26 Stable tag: 1.0.3 7 7 Requires PHP: 7.2 8 8 License: GPLv2 or later … … 53 53 == Changelog == 54 54 55 = 1.0.3 = 56 * New Feature: Added fallback OTP delivery methods (WhatsApp,SMS, Voice Call) for phone verification. 57 * UI Improvement: Added a countdown-based fallback option for alternative methods. 58 55 59 = 1.0.2 = 56 60 * Performance improvements.
Note: See TracChangeset
for help on using the changeset viewer.