1if (window.recaptchaV3) { 2 3 // Check for reCAPTCHA config. 4 if ( 5 window.recaptchaV3.siteKey == 'undefined' || 6 window.recaptchaV3.siteKey == '' 7 ) { 8 console.warn('A RECAPTCHA_V3_SITE_KEY has not been set in .env') 9 } 10 11 // reCAPTCHA v3 12 const recaptchaScript = document.createElement('script') 13 document.head.appendChild(recaptchaScript) 14 recaptchaScript.type = 'text/javascript' 15 recaptchaScript.src = '//www.google.com/recaptcha/api.js?render=' + window.recaptchaV3.siteKey 16 recaptchaScript.onload = initRecaptcha 17 18 // Axios.js 19 if (typeof axios == 'undefined') { 20 const axiosScript = document.createElement('script') 21 document.head.appendChild(axiosScript) 22 axiosScript.type = 'text/javascript' 23 axiosScript.src = '//cdnjs.cloudflare.com/ajax/libs/axios/1.6.7/axios.min.js' 24 } 25 26 // reCAPTCHA is ready. 27 function initRecaptcha() { 28 grecaptcha.ready(function() { 29 const verifyUrl = '/!/statamic-recaptcha/verify-recaptcha-v3-token' 30 31 if (! window.recaptchaV3.verifyOnPageLoad) { 32 attachRecaptchaToForms() 33 34 // Verify on page load, and remove forms from the DOM if the verification failed. 35 } else { 36 grecaptcha.execute(window.recaptchaV3.siteKey, {action: 'pageload/' + window.recaptchaV3.action}) 37 .then(function(token) { 38 39 axios.post(verifyUrl, {token: token, action: 'pageload/' + window.recaptchaV3.action}) 40 .then(function(response) { 41 attachRecaptchaToForms() 42 }) 43 .catch(function(error) { 44 const forms = document.querySelectorAll('form:not(.nocaptcha)') 45 let errorMessage 46 47 // Remove forms from the DOM and replace with an error message. 48 for (let i = 0; i < forms.length; ++i) { 49 errorMessage = document.createElement('div') 50 errorMessage.className = 'alert alert-danger p-2 rounded bg-red-500' 51 errorMessage.setAttribute('role', 'alert') 52 errorMessage.innerHTML = error.response?.data?.error || 'Sorry, but you look like a robot.' 53 54 forms[i].parentNode.replaceChild(errorMessage, forms[i]) 55 } 56 }) 57 }) 58 } 59 }) 60 } 61 62 // Attach the reCAPTCHA token and action to each form. 63 function attachRecaptchaToForms() { 64 const forms = document.querySelectorAll('form:not(.nocaptcha)') 65 66 for (let i = 0; i < forms.length; ++i) { 67 grecaptcha.execute(window.recaptchaV3.siteKey, {action: 'formsubmission/' + window.recaptchaV3.action}) 68 .then(function(token) { 69 70 const tokenInput = document.createElement('input') 71 tokenInput.type = 'hidden' 72 tokenInput.name = 'captcha_token' 73 tokenInput.value = token 74 forms[i].appendChild(tokenInput) 75 76 const actionInput = document.createElement('input') 77 actionInput.type = 'hidden' 78 actionInput.name = 'captcha_action' 79 actionInput.value = 'formsubmission/' + window.recaptchaV3.action 80 forms[i].appendChild(actionInput) 81 }) 82 } 83 } 84}
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.