PageSourceSearch

https://www.naccu.org/Scripts-fingerprintE17C6A6AA61ED09A55B25C2363089452/recaptchaEnterprise.js

js naccu.org collected 2026-09-26 04:50:45 UTC 7,228 bytes, 164 lines download raw bytes

1(function () {
2    const siteKey = window.__recaptchaEnterpriseSiteKey;
3    if (!siteKey || typeof grecaptcha === "undefined") return;
4
5    function captureRecaptchaEvent(eventName, props) {
6        try {
7            if (window.posthog && typeof window.posthog.capture === "function") {
8                window.posthog.capture(eventName, props);
9            }
10        } catch (err) {
11            // Never break submit for analytics failures.
12        }
13    }
14
15    function getOrCreateResponseInput(form) {
16        let input = form.querySelector('input[name="g-recaptcha-response"]');
17        if (!input) {
18            input = document.createElement('input');
19            input.type = 'hidden';
20            input.name = 'g-recaptcha-response';
21            form.appendChild(input);
22        }
23        return input;
24    }
25
26    // Button-driven flow (closest to Google's "add attributes to button" pattern)
27    // Use on a submit button with class="js-recaptcha-enterprise" and optional data-recaptcha-action.
28    document.addEventListener("click", function (e) {
29        const btn = e.target && e.target.closest ? e.target.closest(".js-recaptcha-enterprise") : null;
30        if (!btn) return;
31
32        const form = btn.form || (btn.closest ? btn.closest("form") : null);
33        if (!form || !(form instanceof HTMLFormElement)) return;
34
35        const isTrusted = e.isTrusted !== false;
36        const action = btn.dataset.recaptchaAction || form.dataset.recaptchaAction || "submit";
37
38        // If the form has client-side validation rules, run them first so we
39        // don't trigger reCAPTCHA for obviously invalid input.
40        let isValid = true;
41        try {
42            const jq = window.jQuery;
43            if (typeof jq !== "undefined") {
44                const $form = jq(form);
45                let validator = $form.data("validator");
46
47                // In some MVC setups, unobtrusive validation is parsed after load.
48                // Ensure rules are registered so `valid()` reflects field errors.
49                if (!validator && jq.validator && jq.validator.unobtrusive && typeof jq.validator.unobtrusive.parse === "function") {
50                    jq.validator.unobtrusive.parse(form);
51                    validator = $form.data("validator");
52                }
53
54                if (validator) {
55                    // `valid()` will also surface messages.
56                    isValid = $form.valid();
57                } else if (typeof form.checkValidity === "function") {
58                    isValid = form.checkValidity();
59                }
60            } else if (typeof form.checkValidity === "function") {
61                isValid = form.checkValidity();
62            }
63        } catch (err) {
64            // If validation integration fails for any reason, fall back to
65            // previous behavior (always trigger reCAPTCHA).
66            isValid = true;
67        }
68
69        if (!isValid) return;
70
71        // Prevent multiple token requests for the same click/submit.
72        // Always preventDefault so a second click cannot POST with a cleared token.
73        if (form.dataset.recaptchaProcessing === "true") {
74            e.preventDefault();
75            e.stopPropagation();
76            // Second click while a token was already in flight was blocked
77            captureRecaptchaEvent("recaptcha_enterprise_duplicate_submit_blocked", {
78                action: action,
79                isTrusted: isTrusted,
80                hasToken: false,
81                pathname: window.location && window.location.pathname
82            });
83            return;
84        }
85        form.dataset.recaptchaProcessing = "true";
86
87        const input = getOrCreateResponseInput(form);
88        input.value = "";
89
90        // Pause the click's default submit so we can inject the token first
91        e.preventDefault();
92
93        if (!isTrusted) {
94            // That click was untrusted (often password manager / scripted) — still proceeded
95            captureRecaptchaEvent("recaptcha_enterprise_untrusted_click", {
96                action: action,
97                isTrusted: false,
98                hasToken: false,
99                pathname: window.location && window.location.pathname
100            });
101        }
102
103        // Our handler took a valid submit click and started token fetch
104        captureRecaptchaEvent("recaptcha_enterprise_submit_intercepted", {
105            action: action,
106            isTrusted: isTrusted,
107            hasToken: false,
108            pathname: window.location && window.location.pathname
109        });
110
111        function submitFormWithToken() {
112            if (typeof form.requestSubmit === "function") {
113                form.requestSubmit(btn);
114            } else {
115                form.submit();
116            }
117        }
118
119        grecaptcha.enterprise.ready(function () {
120            grecaptcha.enterprise.execute(siteKey, { action: action })
121                .then(function (token) {
122                    const hasToken = !!(token && String(token).trim());
123                    input.value = token || "";
124                    delete form.dataset.recaptchaProcessing;
125
126                    // Always submit so the server can show the existing 807 message when the token is empty.
127                    if (!hasToken) {
128                        // Empty token or execute rejected; form still submitted (will likely hit 807)
129                        captureRecaptchaEvent("recaptcha_enterprise_token_failed", {
130                            action: action,
131                            isTrusted: isTrusted,
132                            hasToken: false,
133                            errorName: "empty_token",
134                            pathname: window.location && window.location.pathname
135                        });
136                    } else {
137                        // Google returned a non-empty token; form submitted
138                        captureRecaptchaEvent("recaptcha_enterprise_token_success", {
139                            action: action,
140                            isTrusted: isTrusted,
141                            hasToken: true,
142                            pathname: window.location && window.location.pathname
143                        });
144                    }
145
146                    submitFormWithToken();
147                })
148                .catch(function (err) {
149                    input.value = "";
150                    delete form.dataset.recaptchaProcessing;
151                    // Empty token or execute rejected; form still submitted (will likely hit 807)
152                    captureRecaptchaEvent("recaptcha_enterprise_token_failed", {
153                        action: action,
154                        isTrusted: isTrusted,
155                        hasToken: false,
156                        errorName: err && err.name ? String(err.name) : "execute_rejected",
157                        pathname: window.location && window.location.pathname
158                    });
159                    // Same 807 path as an empty token so the click is not silent.
160                    submitFormWithToken();
161                });
162        });
163    });
164})();

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.