From 7e0bcba919b0bb27f8131f3a9acc0cc2bd2e5764 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 17 Aug 2022 12:38:44 +0200 Subject: [Google Forms] Support forms with reCAPTCHA --- .../google-forms-hacktcha.js | 63 ++++++++++++++++++++++ src/docs-google-com-fix-forms/google_forms.js | 15 +++++- src/docs-google-com-fix-forms/index.json | 21 +++++++- 3 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 src/docs-google-com-fix-forms/google-forms-hacktcha.js diff --git a/src/docs-google-com-fix-forms/google-forms-hacktcha.js b/src/docs-google-com-fix-forms/google-forms-hacktcha.js new file mode 100644 index 0000000..e37f095 --- /dev/null +++ b/src/docs-google-com-fix-forms/google-forms-hacktcha.js @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: CC0-1.0 + * + * Code to run Hacktcha on Google forms. + * + * Copyright (C) 2022 Wojtek Kosior + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the CC0 1.0 Universal License as published by + * the Creative Commons Corporation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * CC0 1.0 Universal License for more details. + */ + +"use strict"; + +(async () => { + const recaptcha_div = document.getElementById("recaptcha"); + + if (recaptcha_div === null) + return; + + recaptcha_div.style.display = "block"; + + const site_key = recaptcha_div.getAttribute("data-sitekey"); + + const token_field = document.createElement("textarea"); + token_field.name = "g-recaptcha-response"; + token_field.style.display = "none"; + recaptcha_div.before(token_field); + + let authenticated = false; + + /* Function called from google_forms.js. */ + window.hacktcha_completed = function() { + return authenticated; + } + + const submit_buttons = [...document.querySelectorAll('[jsname=M2UYVd]')]; + + for (const button of submit_buttons) { + button._color_orig = getComputedStyle(button)["background-color"]; + button.style.backgroundColor = "lightgray"; + } + + for await (const token of HCHA.run(recaptcha_div, site_key)) { + if (token === null) { + authenticated = false; + + for (const button of submit_buttons) + button.style.backgroundColor = "lightgray"; + } else { + authenticated = true; + + for (const button of submit_buttons) + button.style.backgroundColor = button._color_orig; + + token_field.value = token; + } + } +})(); diff --git a/src/docs-google-com-fix-forms/google_forms.js b/src/docs-google-com-fix-forms/google_forms.js index 4652426..73d6840 100644 --- a/src/docs-google-com-fix-forms/google_forms.js +++ b/src/docs-google-com-fix-forms/google_forms.js @@ -82,7 +82,19 @@ document.querySelectorAll('[jsname=LwH6nd]').forEach(n => n.remove()); /* Enable the form sumbission button (if any). */ for (const submit_but of document.querySelectorAll('[jsname=M2UYVd]')) - submit_but.addEventListener("click", () => form.submit()); + submit_but.addEventListener("click", () => { + /* + * hacktcha_completed() will be defined by google-forms-hacktcha.js but only + * if we have the actual captcha support enabled. It will return true if + * we're already authenticated. + */ + if (typeof window.hacktcha_completed === "function") { + if (!window.hacktcha_completed()) + return; + } + + form.submit() + }); /* Enable the "next page" button (if any). */ function goToNext() @@ -109,6 +121,5 @@ for (const warning of * support dropdown inputs * support "other" radio buttons and "other" checkbox buttons, in which the user types text in addition to selecting the "other" box - * support reCAPTCHA integration * support displaying public analytics ("viewanalytics" instead of "viewform") */ diff --git a/src/docs-google-com-fix-forms/index.json b/src/docs-google-com-fix-forms/index.json index c74688a..5aad90d 100644 --- a/src/docs-google-com-fix-forms/index.json +++ b/src/docs-google-com-fix-forms/index.json @@ -17,7 +17,7 @@ "identifier": "docs-google-com-fix-forms", "long_name": "Google Forms submission fix", "uuid": "23f51630-6118-4ef2-9709-2a1dba7ebb52", - "version": [2022, 8, 16], + "version": [2022, 8, 17], "revision": 1, "description": "Enable filling and submitting of Google Forms without relying on site-served JavaScript.", "dependencies": [], @@ -32,6 +32,25 @@ "identifier": "docs-google-com-fix-forms" } } + }, { + "type": "mapping_and_resource", + "identifier": "docs-google-com-fix-forms-hacktcha", + "long_name": "Google Forms submission fix (with reCAPTCHA/Hacktcha support)", + "uuid": "a8433924-102b-482a-9958-f7e8880f539e", + "version": [2022, 8, 17], + "revision": 1, + "description": "Enable filling and submitting of Google Forms without relying on site-served JavaScript. Also submit forms with reCAPTCHA challenge.", + "dependencies": [{"identifier": "hacktcha"}, {"identifier": "docs-google-com-fix-forms"}], + "scripts": [{"file": "google-forms-hacktcha.js"}], + "payloads": { + // same as above + "https://docs.google.com/forms/d/**": { + "identifier": "docs-google-com-fix-forms-hacktcha" + }, + "https://docs.google.com/forms/u/1/d/**": { + "identifier": "docs-google-com-fix-forms-hacktcha" + } + } }, { "type": "mapping", "identifier": "google-forms-fix", -- cgit v1.2.3