HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/ai.naniguide.com/resources/views/recaptcha/script.blade.php
@if (isset($errors) && $errors->has('recaptcha_invalid'))
    <span class="help-block text-danger">
        <strong>{{ $errors->first('recaptcha_invalid') }}</strong>
    </span>
@endif

{{--
    Standard reCAPTCHA v3 (NOT Enterprise).

    Behaviour: always submit the form, even when the captcha lib fails to load
    or `execute()` rejects. The server-side fail-open path
    (`App\Library\Tool::verifyCaptchaOrAlert`) treats Google rejections as a
    config alert (admins get a bell-dropdown notification) and lets the request
    through. This avoids locking everyone out of login when Google revokes the
    site_key, the user has JS off, an ad blocker eats `api.js`, etc.

    Past failure modes guarded against (each one previously broke prod login):
      • jQuery missing in refactor auth layout → reference error → no submit
        binding → empty token submit. Fixed by going vanilla JS here.
      • Enterprise `enterprise.js` loaded for v3 keys → undefined namespace →
        throw before preventDefault → empty submit. Fixed by using `api.js`.
      • `api.js?render=KEY` returns 4xx (key revoked / invalid) → grecaptcha
        never defined → submit handler crashed. Fixed by `<script onerror>` +
        always-submit fallback below.
--}}

<input type="hidden" name="g-recaptcha-response" value="" />

<script>
    window.__captchaUnreachable = false;
</script>
<script
    src="https://www.google.com/recaptcha/api.js?render={{ App\Model\Setting::get('recaptcha_site_key') }}"
    onerror="window.__captchaUnreachable = true;"
></script>
<script>
    (function() {
        var siteKey = @json(App\Model\Setting::get('recaptcha_site_key'));
        var tokenInput = document.querySelector('input[name="g-recaptcha-response"]');
        if (!tokenInput) return;
        var form = tokenInput.closest('form');
        if (!form) return;

        function submitNatively() {
            // Use form.submit() (NOT requestSubmit). requestSubmit dispatches a
            // new submit event; when called from inside our own submit handler
            // some browsers swallow the recursive dispatch and the form never
            // actually POSTs. form.submit() bypasses event listeners entirely
            // and does an immediate native submission, which is what we want
            // here — we already passed the captcha gate, no other handler
            // should re-prevent the navigation.
            form.removeEventListener('submit', onSubmit);
            form.submit();
        }

        function onSubmit(e) {
            // Token already populated (re-entry after async fetch) — let it through.
            if (tokenInput.value !== '') return;

            // Always intercept first so any later failure can't accidentally
            // trigger a native submit before we've had a chance to react.
            e.preventDefault();

            // api.js failed to load (network blocked, key revoked → 4xx, etc.)
            // → submit anyway with empty token; server fail-open will alert admins.
            if (window.__captchaUnreachable || typeof grecaptcha === 'undefined' || !grecaptcha.ready) {
                submitNatively();
                return;
            }

            grecaptcha.ready(function() {
                grecaptcha.execute(siteKey, { action: 'LOGIN' }).then(function(token) {
                    tokenInput.value = token;
                    submitNatively();
                }).catch(function() {
                    // execute() rejected (domain not allowed, key revoked,
                    // quota exceeded, …) — submit with empty token; server
                    // fail-open path takes over.
                    submitNatively();
                });
            });
        }

        form.addEventListener('submit', onSubmit);
    })();
</script>