1/** 2 * Google reCAPTCHA v3 for WooCommerce â front-end token handling. 3 * 4 * Keeps a fresh token in every protected form's hidden field. reCAPTCHA v3 5 * tokens are valid for 2 minutes, so we mint on load, refresh on an interval, 6 * on window focus, and whenever WooCommerce rebuilds the checkout via AJAX. 7 * 8 * @package CZG_Recaptcha_WC 9 */ 10( function () { 11 'use strict'; 12 13 var cfg = window.czgRecaptchaWC || {}; 14 15 if ( ! cfg.siteKey ) { 16 return; 17 } 18 19 var FIELD_NAME = cfg.fieldName || 'czg_recaptcha_token'; 20 var DEFAULT_ACTION = cfg.defaultAction || 'submit'; 21 var REFRESH_MS = parseInt( cfg.refresh, 10 ) || 90000; 22 23 /** 24 * Runs a callback once the grecaptcha API is fully ready. 25 * 26 * @param {Function} cb Callback. 27 */ 28 function whenReady( cb ) { 29 if ( window.grecaptcha && typeof window.grecaptcha.execute === 'function' && typeof window.grecaptcha.ready === 'function' ) { 30 window.grecaptcha.ready( cb ); 31 } else { 32 window.setTimeout( function () { 33 whenReady( cb ); 34 }, 250 ); 35 } 36 } 37 38 /** 39 * Requests a token for an action and hands it to the callback. 40 * 41 * @param {string} action Action name. 42 * @param {Function} cb Receives the token string. 43 */ 44 function mintToken( action, cb ) { 45 whenReady( function () { 46 try { 47 window.grecaptcha.execute( cfg.siteKey, { action: action } ).then( 48 function ( token ) { 49 if ( token ) { 50 cb( token ); 51 } 52 }, 53 function () { /* swallow â a failed mint just leaves the old token */ } 54 ); 55 } catch ( e ) { /* grecaptcha not ready yet; the interval will retry */ } 56 } ); 57 } 58 59 /** 60 * Returns all hidden token fields currently in the DOM. 61 * 62 * @return {NodeList} 63 */ 64 function tokenFields() { 65 return document.querySelectorAll( 'input[name="' + FIELD_NAME + '"]' ); 66 } 67 68 /** 69 * Refreshes every token field with a freshly minted token. 70 */ 71 function refreshAll() { 72 var fields = tokenFields(); 73 74 for ( var i = 0; i < fields.length; i++ ) { 75 ( function ( field ) { 76 var action = field.getAttribute( 'data-action' ) || DEFAULT_ACTION; 77 mintToken( action, function ( token ) { 78 field.value = token; 79 } ); 80 } )( fields[ i ] ); 81 } 82 } 83 84 /** 85 * Boots the token lifecycle. 86 */ 87 function init() { 88 refreshAll(); 89 90 // Keep tokens fresh well within their 2-minute lifetime. 91 window.setInterval( refreshAll, REFRESH_MS ); 92 93 // A backgrounded tab throttles timers; top up when the user returns. 94 window.addEventListener( 'focus', refreshAll ); 95 document.addEventListener( 'visibilitychange', function () { 96 if ( ! document.hidden ) { 97 refreshAll(); 98 } 99 } ); 100 } 101 102 if ( 'loading' !== document.readyState ) { 103 init(); 104 } else { 105 document.addEventListener( 'DOMContentLoaded', init ); 106 } 107 108 // WooCommerce rebuilds the checkout review over AJAX; re-mint afterwards so 109 // any token field that lives inside the refreshed markup stays valid. 110 if ( window.jQuery ) { 111 window.jQuery( document.body ).on( 'updated_checkout payment_method_selected', refreshAll ); 112 } 113} )();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.