Created
June 30, 2026 17:16
-
-
Save odony/4fb16418a20c32c1527474e9885dd5d3 to your computer and use it in GitHub Desktop.
fix_turnstile_june2026.patch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git addons/website_cf_turnstile/static/src/interactions/turnstile.js addons/website_cf_turnstile/static/src/interactions/turnstile.js | |
| index 8008f9bb38df..c63fc0b912d1 100644 | |
| --- addons/website_cf_turnstile/static/src/interactions/turnstile.js | |
| +++ addons/website_cf_turnstile/static/src/interactions/turnstile.js | |
| @@ -3,16 +3,23 @@ import { session } from "@web/session"; | |
| export class TurnStile { | |
| static turnstileURL = "https://challenges.cloudflare.com/turnstile/v0/api.js"; | |
| + static nextId = 0; | |
| constructor(action) { | |
| const cf = new URLSearchParams(window.location.search).get("cf"); | |
| const mode = cf == "show" ? "always" : "interaction-only"; | |
| + | |
| + // unique per-widget callback names to support multiple widgets on same page | |
| + const id = TurnStile.nextId++; | |
| + const successCbName = `turnstileSuccess_${id}`; | |
| + const becomeVisibleCbName = `turnstileBecomeVisible_${id}`; | |
| + | |
| const turnstileContainer = renderToElement("website_cf_turnstile.turnstile_container", { | |
| action: action, | |
| appearance: mode, | |
| - beforeInteractiveGlobalCallback: "turnstileBecomeVisible", | |
| + beforeInteractiveGlobalCallback: becomeVisibleCbName, | |
| errorGlobalCallback: "throwTurnstileErrorCode", | |
| - executeGlobalCallback: "turnstileSuccess", | |
| + executeGlobalCallback: successCbName, | |
| sitekey: session.turnstile_site_key, | |
| style: "display: none;", | |
| }); | |
| @@ -24,9 +31,9 @@ export class TurnStile { | |
| error.code = code; | |
| throw error; | |
| }; | |
| - // `this` is bound to the turnstile widget calling the callback | |
| - globalThis.turnstileSuccess = function () { | |
| - const form = this.wrapper.closest("form") || this.wrapper.parentElement.parentElement; | |
| + globalThis[successCbName] = function (token) { | |
| + const form = turnstileContainer.closest("form") | |
| + || turnstileContainer.parentElement?.parentElement; | |
| const buttons = form.querySelectorAll(".cf_form_disabled"); | |
| for (const button of buttons) { | |
| button.classList.remove("disabled", "cf_form_disabled"); | |
| @@ -38,8 +45,7 @@ export class TurnStile { | |
| inputValidation.required = false; | |
| }; | |
| // unhide if interaction is needed | |
| - globalThis.turnstileBecomeVisible = function () { | |
| - const turnstileContainer = this.wrapper.parentElement; | |
| + globalThis[becomeVisibleCbName] = function () { | |
| turnstileContainer.style.display = ""; | |
| }; | |
| // avoid modifying shape of return, for stable compatibility |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment