Version 1.4.10 - security hardening, empty fallback, and reCAPTCHA improvements
- Harden XSS protection with escapeHtml on all rendered output values - Add empty_fallback support for empty cell display across all view types - Fix reCAPTCHA default action to 'submit' matching JS side - Move reCAPTCHA token generation from inline PHP to public.js - Lower default reCAPTCHA min score from 0.5 to 0.3 - Improve reCAPTCHA token age check and preload error handling - Add form submit handler for enter key support - Increase waitForRecaptcha timeout to 10 seconds - Show button/color settings only for button output types - Remove debug console.log and error_log statements - Bump version to 1.4.10
This commit is contained in:
@@ -306,6 +306,9 @@ jQuery(document).ready(function ($) {
|
|||||||
// Append the rendered HTML
|
// Append the rendered HTML
|
||||||
$(".result-value-output").html(html);
|
$(".result-value-output").html(html);
|
||||||
|
|
||||||
|
// Sync type-button-link visibility for initial render
|
||||||
|
$(".result-value-output .output-type").trigger("change");
|
||||||
|
|
||||||
// You can call other functions after the template is rendered
|
// You can call other functions after the template is rendered
|
||||||
append_fields_to_preview();
|
append_fields_to_preview();
|
||||||
},
|
},
|
||||||
|
|||||||
279
assets/public.js
279
assets/public.js
@@ -22,18 +22,12 @@ jQuery(document).ready(function ($) {
|
|||||||
var recaptchaToken = thisChecker.find('input[name="recaptcha_token"]').val();
|
var recaptchaToken = thisChecker.find('input[name="recaptcha_token"]').val();
|
||||||
if (recaptchaToken) {
|
if (recaptchaToken) {
|
||||||
baseData.recaptcha_token = recaptchaToken;
|
baseData.recaptcha_token = recaptchaToken;
|
||||||
console.log("Security: reCAPTCHA token added to request");
|
|
||||||
} else {
|
|
||||||
console.log("Security: No reCAPTCHA token found");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Turnstile token if present
|
// Add Turnstile token if present
|
||||||
var turnstileToken = thisChecker.find('input[name="turnstile_token"]').val();
|
var turnstileToken = thisChecker.find('input[name="turnstile_token"]').val();
|
||||||
if (turnstileToken) {
|
if (turnstileToken) {
|
||||||
baseData.turnstile_token = turnstileToken;
|
baseData.turnstile_token = turnstileToken;
|
||||||
console.log("Security: Turnstile token added to request");
|
|
||||||
} else {
|
|
||||||
console.log("Security: No Turnstile token found");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add honeypot field (should be empty)
|
// Add honeypot field (should be empty)
|
||||||
@@ -41,16 +35,13 @@ jQuery(document).ready(function ($) {
|
|||||||
if (hpInput.length) {
|
if (hpInput.length) {
|
||||||
baseData.honeypot_name = hpInput.attr('name');
|
baseData.honeypot_name = hpInput.attr('name');
|
||||||
baseData.honeypot_value = hpInput.val() || "";
|
baseData.honeypot_value = hpInput.val() || "";
|
||||||
console.log("Security: Honeypot field added (value: " + (hpInput.val() === "" ? "empty" : "filled") + ")");
|
|
||||||
} else {
|
} else {
|
||||||
var legacyHp = thisChecker.find('input[name="website_url_hp"]').val();
|
var legacyHp = thisChecker.find('input[name="website_url_hp"]').val();
|
||||||
if (typeof legacyHp !== 'undefined') {
|
if (typeof legacyHp !== 'undefined') {
|
||||||
baseData.website_url_hp = legacyHp || "";
|
baseData.website_url_hp = legacyHp || "";
|
||||||
console.log("Security: Honeypot field added (legacy value: " + (legacyHp === "" ? "empty" : "filled") + ")");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Security: AJAX data prepared", baseData);
|
|
||||||
return baseData;
|
return baseData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +208,6 @@ jQuery(document).ready(function ($) {
|
|||||||
tokenInput.val(token).attr('data-timestamp', Date.now().toString());
|
tokenInput.val(token).attr('data-timestamp', Date.now().toString());
|
||||||
resolve();
|
resolve();
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
console.error('reCAPTCHA refresh error:', error);
|
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -246,19 +236,33 @@ jQuery(document).ready(function ($) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ensureCaptchaReady(checkerId) {
|
function ensureCaptchaReady(checkerId) {
|
||||||
// If reCAPTCHA is configured, always refresh/generate a token (it will create the hidden input if missing)
|
var thisChecker = $("#checker-" + checkerId);
|
||||||
|
|
||||||
|
// If reCAPTCHA is configured, check if we need to refresh the token
|
||||||
if (window.checkerRecaptcha) {
|
if (window.checkerRecaptcha) {
|
||||||
|
var tokenInput = thisChecker.find('input[name="recaptcha_token"]');
|
||||||
|
var hasToken = tokenInput.length && tokenInput.val();
|
||||||
|
|
||||||
|
// Check token age
|
||||||
|
if (hasToken) {
|
||||||
|
var tokenAge = Date.now() - parseInt(tokenInput.attr('data-timestamp') || '0');
|
||||||
|
// Token is valid for 2 minutes, use it if it's less than 90 seconds old
|
||||||
|
if (tokenAge < 90000) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return waitForRecaptcha()
|
return waitForRecaptcha()
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return refreshRecaptchaToken(checkerId);
|
return refreshRecaptchaToken(checkerId);
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
return Promise.reject(err);
|
var errorMsg = err ? err.message : "reCAPTCHA verification failed";
|
||||||
|
return Promise.reject(new Error(errorMsg));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh Turnstile if stale
|
// Refresh Turnstile if stale
|
||||||
var thisChecker = $("#checker-" + checkerId);
|
|
||||||
var turnstileInput = thisChecker.find('input[name="turnstile_token"]');
|
var turnstileInput = thisChecker.find('input[name="turnstile_token"]');
|
||||||
if (turnstileInput.length && turnstileInput.val()) {
|
if (turnstileInput.length && turnstileInput.val()) {
|
||||||
var ts = parseInt(turnstileInput.attr("data-timestamp") || "0");
|
var ts = parseInt(turnstileInput.attr("data-timestamp") || "0");
|
||||||
@@ -271,19 +275,23 @@ jQuery(document).ready(function ($) {
|
|||||||
turnstileInput.val("");
|
turnstileInput.val("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
function waitForRecaptcha(timeoutMs = 5000) {
|
function waitForRecaptcha(timeoutMs = 10000) {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
var start = Date.now();
|
var start = Date.now();
|
||||||
|
|
||||||
(function check() {
|
(function check() {
|
||||||
if (typeof grecaptcha !== "undefined" && typeof grecaptcha.ready === "function") {
|
if (typeof grecaptcha !== "undefined" && typeof grecaptcha.ready === "function") {
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Date.now() - start > timeoutMs) {
|
if (Date.now() - start > timeoutMs) {
|
||||||
return reject(new Error("reCAPTCHA script not loaded"));
|
return reject(new Error("reCAPTCHA script failed to load. Please check your internet connection or try disabling reCAPTCHA."));
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(check, 200);
|
setTimeout(check, 200);
|
||||||
})();
|
})();
|
||||||
});
|
});
|
||||||
@@ -309,10 +317,9 @@ jQuery(document).ready(function ($) {
|
|||||||
loadAllData(checkerId, settings, true); // true = initial load
|
loadAllData(checkerId, settings, true); // true = initial load
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preload captcha tokens to surface badge and avoid first-click delays
|
// Preload reCAPTCHA token on page load (improves score by showing natural browsing behavior)
|
||||||
ensureCaptchaReady(checkerId).catch(function(err){
|
ensureCaptchaReady(checkerId).catch(function(){
|
||||||
console.warn("Captcha preload failed", err);
|
// Silently fail on preload - will retry on submit
|
||||||
showSecurityError(checkerId, checkerSecurity.i18n ? checkerSecurity.i18n.security_error : "Security validation failed.", false);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -585,10 +592,16 @@ jQuery(document).ready(function ($) {
|
|||||||
var button_text = escapeHtml(outputSetting.button_text || "Click");
|
var button_text = escapeHtml(outputSetting.button_text || "Click");
|
||||||
var bg_color = escapeHtml(outputSetting.bg_color || "#333333");
|
var bg_color = escapeHtml(outputSetting.bg_color || "#333333");
|
||||||
var text_color = escapeHtml(outputSetting.text_color || "#ffffff");
|
var text_color = escapeHtml(outputSetting.text_color || "#ffffff");
|
||||||
|
var empty_fallback = escapeHtml(outputSetting.empty_fallback || "");
|
||||||
var safeQ = escapeHtml(q);
|
var safeQ = escapeHtml(q);
|
||||||
var safeVal = escapeHtml(r);
|
var safeVal = escapeHtml(r);
|
||||||
|
var isEmpty = !r || String(r).trim() === "";
|
||||||
|
|
||||||
if (type == "link_button") {
|
if (isEmpty && empty_fallback) {
|
||||||
|
safeVal = empty_fallback;
|
||||||
|
} else if (isEmpty) {
|
||||||
|
safeVal = "";
|
||||||
|
} else if (type == "link_button") {
|
||||||
safeVal =
|
safeVal =
|
||||||
'<a href="' +
|
'<a href="' +
|
||||||
safeVal +
|
safeVal +
|
||||||
@@ -694,9 +707,15 @@ jQuery(document).ready(function ($) {
|
|||||||
var button_text = escapeHtml(outputSetting.button_text || "Click");
|
var button_text = escapeHtml(outputSetting.button_text || "Click");
|
||||||
var bg_color = escapeHtml(outputSetting.bg_color || "#333333");
|
var bg_color = escapeHtml(outputSetting.bg_color || "#333333");
|
||||||
var text_color = escapeHtml(outputSetting.text_color || "#ffffff");
|
var text_color = escapeHtml(outputSetting.text_color || "#ffffff");
|
||||||
|
var empty_fallback = escapeHtml(outputSetting.empty_fallback || "");
|
||||||
var safeVal = escapeHtml(r);
|
var safeVal = escapeHtml(r);
|
||||||
|
var isEmpty = !r || String(r).trim() === "";
|
||||||
|
|
||||||
if (type == "link_button") {
|
if (isEmpty && empty_fallback) {
|
||||||
|
safeVal = empty_fallback;
|
||||||
|
} else if (isEmpty) {
|
||||||
|
safeVal = "";
|
||||||
|
} else if (type == "link_button") {
|
||||||
safeVal =
|
safeVal =
|
||||||
'<a href="' +
|
'<a href="' +
|
||||||
safeVal +
|
safeVal +
|
||||||
@@ -824,10 +843,16 @@ jQuery(document).ready(function ($) {
|
|||||||
var button_text = escapeHtml(outputSetting.button_text || "Click");
|
var button_text = escapeHtml(outputSetting.button_text || "Click");
|
||||||
var bg_color = escapeHtml(outputSetting.bg_color || "#333333");
|
var bg_color = escapeHtml(outputSetting.bg_color || "#333333");
|
||||||
var text_color = escapeHtml(outputSetting.text_color || "#ffffff");
|
var text_color = escapeHtml(outputSetting.text_color || "#ffffff");
|
||||||
|
var empty_fallback = escapeHtml(outputSetting.empty_fallback || "");
|
||||||
var safeQ = escapeHtml(q);
|
var safeQ = escapeHtml(q);
|
||||||
var safeVal = escapeHtml(r);
|
var safeVal = escapeHtml(r);
|
||||||
|
var isEmpty = !r || String(r).trim() === "";
|
||||||
|
|
||||||
if (type == "link_button") {
|
if (isEmpty && empty_fallback) {
|
||||||
|
safeVal = empty_fallback;
|
||||||
|
} else if (isEmpty) {
|
||||||
|
safeVal = "";
|
||||||
|
} else if (type == "link_button") {
|
||||||
safeVal =
|
safeVal =
|
||||||
'<a href="' +
|
'<a href="' +
|
||||||
safeVal +
|
safeVal +
|
||||||
@@ -926,10 +951,16 @@ jQuery(document).ready(function ($) {
|
|||||||
var button_text = escapeHtml(outputSetting.button_text || "Click");
|
var button_text = escapeHtml(outputSetting.button_text || "Click");
|
||||||
var bg_color = escapeHtml(outputSetting.bg_color || "#333333");
|
var bg_color = escapeHtml(outputSetting.bg_color || "#333333");
|
||||||
var text_color = escapeHtml(outputSetting.text_color || "#ffffff");
|
var text_color = escapeHtml(outputSetting.text_color || "#ffffff");
|
||||||
|
var empty_fallback = escapeHtml(outputSetting.empty_fallback || "");
|
||||||
var safeQ = escapeHtml(q);
|
var safeQ = escapeHtml(q);
|
||||||
var safeVal = escapeHtml(r);
|
var safeVal = escapeHtml(r);
|
||||||
|
var isEmpty = !r || String(r).trim() === "";
|
||||||
|
|
||||||
if (type == "link_button") {
|
if (isEmpty && empty_fallback) {
|
||||||
|
safeVal = empty_fallback;
|
||||||
|
} else if (isEmpty) {
|
||||||
|
safeVal = "";
|
||||||
|
} else if (type == "link_button") {
|
||||||
safeVal =
|
safeVal =
|
||||||
'<a href="' +
|
'<a href="' +
|
||||||
safeVal +
|
safeVal +
|
||||||
@@ -1085,6 +1116,11 @@ jQuery(document).ready(function ($) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(".dw-checker-form").on("submit", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
$(this).find(".search-button").trigger("click");
|
||||||
|
});
|
||||||
|
|
||||||
$(".search-button").on("click", function (e) {
|
$(".search-button").on("click", function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
@@ -1255,49 +1291,76 @@ jQuery(document).ready(function ($) {
|
|||||||
var prefix = "";
|
var prefix = "";
|
||||||
var type = "";
|
var type = "";
|
||||||
var button_text = "";
|
var button_text = "";
|
||||||
|
var empty_fallback = "";
|
||||||
var hidden = "no";
|
var hidden = "no";
|
||||||
|
var bg_color = "#333333";
|
||||||
|
var text_color = "#ffffff";
|
||||||
$.each(res.output, function (o, p) {
|
$.each(res.output, function (o, p) {
|
||||||
if (q == p.key) {
|
if (q == p.key) {
|
||||||
prefix = p.prefix;
|
prefix = p.prefix;
|
||||||
type = p.type;
|
type = p.type;
|
||||||
button_text = p.button_text;
|
button_text = p.button_text;
|
||||||
|
if ("empty_fallback" in p) {
|
||||||
|
empty_fallback = p.empty_fallback;
|
||||||
|
}
|
||||||
if ("hide" in p) {
|
if ("hide" in p) {
|
||||||
hidden = p.hide;
|
hidden = p.hide;
|
||||||
}
|
}
|
||||||
|
if ("bg_color" in p) {
|
||||||
|
bg_color = p.bg_color;
|
||||||
|
}
|
||||||
|
if ("text_color" in p) {
|
||||||
|
text_color = p.text_color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (hidden == "yes") {
|
if (hidden == "yes") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type == "link_button") {
|
var isEmpty = !r || String(r).trim() === "";
|
||||||
|
if (isEmpty && empty_fallback) {
|
||||||
|
r = escapeHtml(empty_fallback);
|
||||||
|
} else if (isEmpty) {
|
||||||
|
r = "";
|
||||||
|
} else if (type == "link_button") {
|
||||||
r =
|
r =
|
||||||
'<a href="' +
|
'<a href="' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||||
id +
|
id +
|
||||||
'" target="_blank" rel="noopener">' +
|
'" target="_blank" rel="noopener" style="background-color: ' +
|
||||||
button_text +
|
escapeHtml(bg_color) +
|
||||||
|
"; color: " +
|
||||||
|
escapeHtml(text_color) +
|
||||||
|
';">' +
|
||||||
|
escapeHtml(button_text) +
|
||||||
"</a>";
|
"</a>";
|
||||||
} else if (type == "whatsapp_button") {
|
} else if (type == "whatsapp_button") {
|
||||||
r =
|
r =
|
||||||
'<a href="https://wa.me/' +
|
'<a href="https://wa.me/' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||||
id +
|
id +
|
||||||
'" target="_blank" rel="noopener">' +
|
'" target="_blank" rel="noopener" style="background-color: ' +
|
||||||
button_text +
|
escapeHtml(bg_color) +
|
||||||
|
"; color: " +
|
||||||
|
escapeHtml(text_color) +
|
||||||
|
';">' +
|
||||||
|
escapeHtml(button_text) +
|
||||||
"</a>";
|
"</a>";
|
||||||
} else if (type == "image") {
|
} else if (type == "image") {
|
||||||
r =
|
r =
|
||||||
'<img src="' +
|
'<img src="' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" class="dw-checker-image dw-checker-img-' +
|
'" class="dw-checker-image dw-checker-img-' +
|
||||||
id +
|
id +
|
||||||
'" style="max-width: 150px; height: auto; cursor: pointer;" onclick="openImageLightbox(this)" data-fullsize="' +
|
'" style="max-width: 150px; height: auto; cursor: pointer;" onclick="openImageLightbox(this)" data-fullsize="' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" alt="' +
|
'" alt="' +
|
||||||
q +
|
escapeHtml(q) +
|
||||||
'" />';
|
'" />';
|
||||||
|
} else if (type == "text") {
|
||||||
|
r = escapeHtml(r);
|
||||||
}
|
}
|
||||||
resultDiv += "<tr>";
|
resultDiv += "<tr>";
|
||||||
resultDiv +=
|
resultDiv +=
|
||||||
@@ -1308,7 +1371,7 @@ jQuery(document).ready(function ($) {
|
|||||||
'px;"><span class="dw-checker-result-header" style="color:' +
|
'px;"><span class="dw-checker-result-header" style="color:' +
|
||||||
header_color +
|
header_color +
|
||||||
'">' +
|
'">' +
|
||||||
q +
|
escapeHtml(q) +
|
||||||
"</span></th>";
|
"</span></th>";
|
||||||
resultDiv +=
|
resultDiv +=
|
||||||
'<td style="border-color: ' +
|
'<td style="border-color: ' +
|
||||||
@@ -1318,7 +1381,7 @@ jQuery(document).ready(function ($) {
|
|||||||
'px;"><span class="dw-checker-result-value" style="color:' +
|
'px;"><span class="dw-checker-result-value" style="color:' +
|
||||||
value_color +
|
value_color +
|
||||||
'">' +
|
'">' +
|
||||||
prefix +
|
escapeHtml(prefix || "") +
|
||||||
r +
|
r +
|
||||||
"</span></td>";
|
"</span></td>";
|
||||||
resultDiv += "</tr>";
|
resultDiv += "</tr>";
|
||||||
@@ -1358,49 +1421,76 @@ jQuery(document).ready(function ($) {
|
|||||||
var prefix = "";
|
var prefix = "";
|
||||||
var type = "";
|
var type = "";
|
||||||
var button_text = "";
|
var button_text = "";
|
||||||
|
var empty_fallback = "";
|
||||||
var hidden = "no";
|
var hidden = "no";
|
||||||
|
var bg_color = "#333333";
|
||||||
|
var text_color = "#ffffff";
|
||||||
$.each(res.output, function (o, p) {
|
$.each(res.output, function (o, p) {
|
||||||
if (q == p.key) {
|
if (q == p.key) {
|
||||||
prefix = p.prefix;
|
prefix = p.prefix;
|
||||||
type = p.type;
|
type = p.type;
|
||||||
button_text = p.button_text;
|
button_text = p.button_text;
|
||||||
|
if ("empty_fallback" in p) {
|
||||||
|
empty_fallback = p.empty_fallback;
|
||||||
|
}
|
||||||
if ("hide" in p) {
|
if ("hide" in p) {
|
||||||
hidden = p.hide;
|
hidden = p.hide;
|
||||||
}
|
}
|
||||||
|
if ("bg_color" in p) {
|
||||||
|
bg_color = p.bg_color;
|
||||||
|
}
|
||||||
|
if ("text_color" in p) {
|
||||||
|
text_color = p.text_color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (hidden == "yes") {
|
if (hidden == "yes") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type == "link_button") {
|
var isEmpty = !r || String(r).trim() === "";
|
||||||
|
if (isEmpty && empty_fallback) {
|
||||||
|
r = escapeHtml(empty_fallback);
|
||||||
|
} else if (isEmpty) {
|
||||||
|
r = "";
|
||||||
|
} else if (type == "link_button") {
|
||||||
r =
|
r =
|
||||||
'<a href="' +
|
'<a href="' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||||
id +
|
id +
|
||||||
'" target="_blank" rel="noopener">' +
|
'" target="_blank" rel="noopener" style="background-color: ' +
|
||||||
button_text +
|
escapeHtml(bg_color) +
|
||||||
|
"; color: " +
|
||||||
|
escapeHtml(text_color) +
|
||||||
|
';">' +
|
||||||
|
escapeHtml(button_text) +
|
||||||
"</a>";
|
"</a>";
|
||||||
} else if (type == "whatsapp_button") {
|
} else if (type == "whatsapp_button") {
|
||||||
r =
|
r =
|
||||||
'<a href="https://wa.me/' +
|
'<a href="https://wa.me/' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||||
id +
|
id +
|
||||||
'" target="_blank" rel="noopener">' +
|
'" target="_blank" rel="noopener" style="background-color: ' +
|
||||||
button_text +
|
escapeHtml(bg_color) +
|
||||||
|
"; color: " +
|
||||||
|
escapeHtml(text_color) +
|
||||||
|
';">' +
|
||||||
|
escapeHtml(button_text) +
|
||||||
"</a>";
|
"</a>";
|
||||||
} else if (type == "image") {
|
} else if (type == "image") {
|
||||||
r =
|
r =
|
||||||
'<img src="' +
|
'<img src="' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" class="dw-checker-image dw-checker-img-' +
|
'" class="dw-checker-image dw-checker-img-' +
|
||||||
id +
|
id +
|
||||||
'" style="max-width: 150px; height: auto; cursor: pointer;" onclick="openImageLightbox(this)" data-fullsize="' +
|
'" style="max-width: 150px; height: auto; cursor: pointer;" onclick="openImageLightbox(this)" data-fullsize="' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" alt="' +
|
'" alt="' +
|
||||||
q +
|
escapeHtml(q) +
|
||||||
'" />';
|
'" />';
|
||||||
|
} else if (type == "text") {
|
||||||
|
r = escapeHtml(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
resultDiv +=
|
resultDiv +=
|
||||||
@@ -1413,13 +1503,13 @@ jQuery(document).ready(function ($) {
|
|||||||
'<div class="result-header"><span class="dw-checker-result-header" style="color:' +
|
'<div class="result-header"><span class="dw-checker-result-header" style="color:' +
|
||||||
header_color +
|
header_color +
|
||||||
';">' +
|
';">' +
|
||||||
q +
|
escapeHtml(q) +
|
||||||
"</span></div>";
|
"</span></div>";
|
||||||
resultDiv +=
|
resultDiv +=
|
||||||
'<div class="result-value"><span class="dw-checker-result-value" style="color:' +
|
'<div class="result-value"><span class="dw-checker-result-value" style="color:' +
|
||||||
value_color +
|
value_color +
|
||||||
';">' +
|
';">' +
|
||||||
prefix +
|
escapeHtml(prefix || "") +
|
||||||
r +
|
r +
|
||||||
"</span></div>";
|
"</span></div>";
|
||||||
resultDiv += "</div>";
|
resultDiv += "</div>";
|
||||||
@@ -1466,49 +1556,76 @@ jQuery(document).ready(function ($) {
|
|||||||
var prefix = "";
|
var prefix = "";
|
||||||
var type = "";
|
var type = "";
|
||||||
var button_text = "";
|
var button_text = "";
|
||||||
|
var empty_fallback = "";
|
||||||
var hidden = "no";
|
var hidden = "no";
|
||||||
|
var bg_color = "#333333";
|
||||||
|
var text_color = "#ffffff";
|
||||||
$.each(res.output, function (o, p) {
|
$.each(res.output, function (o, p) {
|
||||||
if (q == p.key) {
|
if (q == p.key) {
|
||||||
prefix = p.prefix;
|
prefix = p.prefix;
|
||||||
type = p.type;
|
type = p.type;
|
||||||
button_text = p.button_text;
|
button_text = p.button_text;
|
||||||
|
if ("empty_fallback" in p) {
|
||||||
|
empty_fallback = p.empty_fallback;
|
||||||
|
}
|
||||||
if ("hide" in p) {
|
if ("hide" in p) {
|
||||||
hidden = p.hide;
|
hidden = p.hide;
|
||||||
}
|
}
|
||||||
|
if ("bg_color" in p) {
|
||||||
|
bg_color = p.bg_color;
|
||||||
|
}
|
||||||
|
if ("text_color" in p) {
|
||||||
|
text_color = p.text_color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (hidden == "yes") {
|
if (hidden == "yes") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type == "link_button") {
|
var isEmpty = !r || String(r).trim() === "";
|
||||||
|
if (isEmpty && empty_fallback) {
|
||||||
|
r = escapeHtml(empty_fallback);
|
||||||
|
} else if (isEmpty) {
|
||||||
|
r = "";
|
||||||
|
} else if (type == "link_button") {
|
||||||
r =
|
r =
|
||||||
'<a href="' +
|
'<a href="' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||||
id +
|
id +
|
||||||
'" target="_blank" rel="noopener">' +
|
'" target="_blank" rel="noopener" style="background-color: ' +
|
||||||
button_text +
|
escapeHtml(bg_color) +
|
||||||
|
"; color: " +
|
||||||
|
escapeHtml(text_color) +
|
||||||
|
';">' +
|
||||||
|
escapeHtml(button_text) +
|
||||||
"</a>";
|
"</a>";
|
||||||
} else if (type == "whatsapp_button") {
|
} else if (type == "whatsapp_button") {
|
||||||
r =
|
r =
|
||||||
'<a href="https://wa.me/' +
|
'<a href="https://wa.me/' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||||
id +
|
id +
|
||||||
'" target="_blank" rel="noopener">' +
|
'" target="_blank" rel="noopener" style="background-color: ' +
|
||||||
button_text +
|
escapeHtml(bg_color) +
|
||||||
|
"; color: " +
|
||||||
|
escapeHtml(text_color) +
|
||||||
|
';">' +
|
||||||
|
escapeHtml(button_text) +
|
||||||
"</a>";
|
"</a>";
|
||||||
} else if (type == "image") {
|
} else if (type == "image") {
|
||||||
r =
|
r =
|
||||||
'<img src="' +
|
'<img src="' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" class="dw-checker-image dw-checker-img-' +
|
'" class="dw-checker-image dw-checker-img-' +
|
||||||
id +
|
id +
|
||||||
'" style="max-width: 150px; height: auto; cursor: pointer;" onclick="openImageLightbox(this)" data-fullsize="' +
|
'" style="max-width: 150px; height: auto; cursor: pointer;" onclick="openImageLightbox(this)" data-fullsize="' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" alt="' +
|
'" alt="' +
|
||||||
q +
|
escapeHtml(q) +
|
||||||
'" />';
|
'" />';
|
||||||
|
} else if (type == "text") {
|
||||||
|
r = escapeHtml(r);
|
||||||
}
|
}
|
||||||
resultDiv +=
|
resultDiv +=
|
||||||
'<td style="border-color: ' +
|
'<td style="border-color: ' +
|
||||||
@@ -1518,7 +1635,7 @@ jQuery(document).ready(function ($) {
|
|||||||
'px;"><span class="dw-checker-result-value" style="color:' +
|
'px;"><span class="dw-checker-result-value" style="color:' +
|
||||||
value_color +
|
value_color +
|
||||||
'">' +
|
'">' +
|
||||||
prefix +
|
escapeHtml(prefix || "") +
|
||||||
r +
|
r +
|
||||||
"</span></td>";
|
"</span></td>";
|
||||||
});
|
});
|
||||||
@@ -1614,6 +1731,7 @@ jQuery(document).ready(function ($) {
|
|||||||
var prefix = "";
|
var prefix = "";
|
||||||
var type = "";
|
var type = "";
|
||||||
var button_text = "";
|
var button_text = "";
|
||||||
|
var empty_fallback = "";
|
||||||
var hidden = "no";
|
var hidden = "no";
|
||||||
var bg_color = "#cccccc";
|
var bg_color = "#cccccc";
|
||||||
var text_color = "#000000";
|
var text_color = "#000000";
|
||||||
@@ -1622,6 +1740,9 @@ jQuery(document).ready(function ($) {
|
|||||||
prefix = p.prefix;
|
prefix = p.prefix;
|
||||||
type = p.type;
|
type = p.type;
|
||||||
button_text = p.button_text;
|
button_text = p.button_text;
|
||||||
|
if ("empty_fallback" in p) {
|
||||||
|
empty_fallback = p.empty_fallback;
|
||||||
|
}
|
||||||
if ("hide" in p) {
|
if ("hide" in p) {
|
||||||
hidden = p.hide;
|
hidden = p.hide;
|
||||||
}
|
}
|
||||||
@@ -1636,35 +1757,42 @@ jQuery(document).ready(function ($) {
|
|||||||
if (hidden == "yes") {
|
if (hidden == "yes") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type == "link_button") {
|
var isEmpty = !r || String(r).trim() === "";
|
||||||
|
if (isEmpty && empty_fallback) {
|
||||||
|
r = escapeHtml(empty_fallback);
|
||||||
|
} else if (isEmpty) {
|
||||||
|
r = "";
|
||||||
|
} else if (type == "link_button") {
|
||||||
r =
|
r =
|
||||||
'<a href="' +
|
'<a href="' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||||
id +
|
id +
|
||||||
'" target="_blank" rel="noopener">' +
|
'" target="_blank" rel="noopener">' +
|
||||||
button_text +
|
escapeHtml(button_text) +
|
||||||
"</a>";
|
"</a>";
|
||||||
} else if (type == "whatsapp_button") {
|
} else if (type == "whatsapp_button") {
|
||||||
r =
|
r =
|
||||||
'<a href="https://wa.me/' +
|
'<a href="https://wa.me/' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||||
id +
|
id +
|
||||||
'" target="_blank" rel="noopener">' +
|
'" target="_blank" rel="noopener">' +
|
||||||
button_text +
|
escapeHtml(button_text) +
|
||||||
"</a>";
|
"</a>";
|
||||||
} else if (type == "image") {
|
} else if (type == "image") {
|
||||||
r =
|
r =
|
||||||
'<img src="' +
|
'<img src="' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" class="dw-checker-image dw-checker-img-' +
|
'" class="dw-checker-image dw-checker-img-' +
|
||||||
id +
|
id +
|
||||||
'" style="max-width: 100%; height: auto; cursor: pointer;" onclick="openImageLightbox(this)" data-fullsize="' +
|
'" style="max-width: 100%; height: auto; cursor: pointer;" onclick="openImageLightbox(this)" data-fullsize="' +
|
||||||
r +
|
escapeHtml(r) +
|
||||||
'" alt="' +
|
'" alt="' +
|
||||||
q +
|
escapeHtml(q) +
|
||||||
'" />';
|
'" />';
|
||||||
|
} else if (type == "text") {
|
||||||
|
r = escapeHtml(r);
|
||||||
}
|
}
|
||||||
resultDiv +=
|
resultDiv +=
|
||||||
`<div class="dw-checker-single-card" style="background-color: ` +
|
`<div class="dw-checker-single-card" style="background-color: ` +
|
||||||
@@ -1679,12 +1807,12 @@ jQuery(document).ready(function ($) {
|
|||||||
<span class="dw-checker-card-header" style="color:` +
|
<span class="dw-checker-card-header" style="color:` +
|
||||||
text_color +
|
text_color +
|
||||||
`">` +
|
`">` +
|
||||||
q +
|
escapeHtml(q) +
|
||||||
`</span>
|
`</span>
|
||||||
<span class="dw-checker-card-value" style="color:` +
|
<span class="dw-checker-card-value" style="color:` +
|
||||||
text_color +
|
text_color +
|
||||||
`">` +
|
`">` +
|
||||||
prefix +
|
escapeHtml(prefix || "") +
|
||||||
r +
|
r +
|
||||||
`</span>
|
`</span>
|
||||||
</div>`;
|
</div>`;
|
||||||
@@ -1706,11 +1834,20 @@ jQuery(document).ready(function ($) {
|
|||||||
|
|
||||||
ensureCaptchaReady($id)
|
ensureCaptchaReady($id)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
|
// Double-check that reCAPTCHA token exists before proceeding
|
||||||
|
if (window.checkerRecaptcha) {
|
||||||
|
var tokenInput = this_checker.find('input[name="recaptcha_token"]');
|
||||||
|
if (!tokenInput.val()) {
|
||||||
|
showSecurityError($id, checkerSecurity.i18n ? checkerSecurity.i18n.recaptcha_failed : "reCAPTCHA verification failed. Please try again.", false);
|
||||||
|
$this.text($this.attr("data-btn-text")).prop("disabled", false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
performSearch();
|
performSearch();
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(function() {
|
||||||
console.error("Captcha refresh failed", err);
|
showSecurityError($id, checkerSecurity.i18n ? checkerSecurity.i18n.recaptcha_failed : "reCAPTCHA verification failed. Please try again.", false);
|
||||||
showSecurityError($id, checkerSecurity.i18n ? checkerSecurity.i18n.security_error : "Security validation failed.", false);
|
$this.text($this.attr("data-btn-text")).prop("disabled", false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
/**
|
/**
|
||||||
* Plugin Name: Sheet Data Checker Pro
|
* Plugin Name: Sheet Data Checker Pro
|
||||||
* Description: Check data from Google Sheet with customizable filter form
|
* Description: Check data from Google Sheet with customizable filter form
|
||||||
* Version: 1.4.5
|
* Version: 1.4.10
|
||||||
* Plugin URI: https://dwindi.com/sheet-data-checker
|
* Plugin URI: https://dwindi.com/sheet-data-checker
|
||||||
* Author: Dwindi Ramadhana
|
* Author: Dwindi Ramadhana
|
||||||
* Author URI: https://facebook.com/dwindi.ramadhana
|
* Author URI: https://facebook.com/dwindi.ramadhana
|
||||||
@@ -35,7 +35,7 @@ if ( ! defined( 'SHEET_CHECKER_PRO_BASENAME' ) ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( ! defined( 'SHEET_CHECKER_PRO_VERSION' ) ) {
|
if ( ! defined( 'SHEET_CHECKER_PRO_VERSION' ) ) {
|
||||||
define( 'SHEET_CHECKER_PRO_VERSION', '1.4.5' );
|
define( 'SHEET_CHECKER_PRO_VERSION', '1.4.10' );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! defined( 'SHEET_CHECKER_PRO_URL' ) ) {
|
if ( ! defined( 'SHEET_CHECKER_PRO_URL' ) ) {
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ class CHECKER_SECURITY {
|
|||||||
$secret_key_raw = isset($checker['security']['recaptcha']['secret_key']) ? $checker['security']['recaptcha']['secret_key'] : '';
|
$secret_key_raw = isset($checker['security']['recaptcha']['secret_key']) ? $checker['security']['recaptcha']['secret_key'] : '';
|
||||||
$secret_key = trim((string) $secret_key_raw);
|
$secret_key = trim((string) $secret_key_raw);
|
||||||
|
|
||||||
$min_score_raw = isset($checker['security']['recaptcha']['min_score']) ? $checker['security']['recaptcha']['min_score'] : 0.5;
|
$min_score_raw = isset($checker['security']['recaptcha']['min_score']) ? $checker['security']['recaptcha']['min_score'] : 0.3;
|
||||||
if (is_string($min_score_raw)) {
|
if (is_string($min_score_raw)) {
|
||||||
$min_score_raw = str_replace(',', '.', $min_score_raw);
|
$min_score_raw = str_replace(',', '.', $min_score_raw);
|
||||||
}
|
}
|
||||||
@@ -199,16 +199,13 @@ class CHECKER_SECURITY {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($score < $min_score) {
|
if ($score < $min_score) {
|
||||||
error_log("Sheet Data Checker: reCAPTCHA score too low - Score: {$score}, Min: {$min_score}");
|
|
||||||
return [
|
return [
|
||||||
'success' => false,
|
'success' => false,
|
||||||
'score' => $score,
|
'score' => $score,
|
||||||
'message' => 'reCAPTCHA score too low. Please try again.'
|
'message' => "reCAPTCHA score too low ({$score}). Please try again."
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
error_log("Sheet Data Checker: reCAPTCHA verification SUCCESS - Score: {$score}, Action: {$response_action}");
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'success' => true,
|
'success' => true,
|
||||||
'score' => $score
|
'score' => $score
|
||||||
|
|||||||
@@ -504,6 +504,7 @@ class SHEET_DATA_CHECKER_PRO
|
|||||||
'type' => isset($checker['output'][$id]['type']) ? $checker['output'][$id]['type'] : 'text',
|
'type' => isset($checker['output'][$id]['type']) ? $checker['output'][$id]['type'] : 'text',
|
||||||
'button_text' => isset($checker['output'][$id]['button_text']) ? $checker['output'][$id]['button_text'] : '',
|
'button_text' => isset($checker['output'][$id]['button_text']) ? $checker['output'][$id]['button_text'] : '',
|
||||||
'prefix' => isset($checker['output'][$id]['prefix']) ? $checker['output'][$id]['prefix'] : '',
|
'prefix' => isset($checker['output'][$id]['prefix']) ? $checker['output'][$id]['prefix'] : '',
|
||||||
|
'empty_fallback' => isset($checker['output'][$id]['empty_fallback']) ? $checker['output'][$id]['empty_fallback'] : '',
|
||||||
'bg_color' => isset($checker['output'][$id]['bg_color']) ? $checker['output'][$id]['bg_color'] : '#cccccc',
|
'bg_color' => isset($checker['output'][$id]['bg_color']) ? $checker['output'][$id]['bg_color'] : '#cccccc',
|
||||||
'text_color' => isset($checker['output'][$id]['text_color']) ? $checker['output'][$id]['text_color'] : '#000000',
|
'text_color' => isset($checker['output'][$id]['text_color']) ? $checker['output'][$id]['text_color'] : '#000000',
|
||||||
'display' => isset($checker['result']['display']) && $checker['result']['display'] == 'card'
|
'display' => isset($checker['result']['display']) && $checker['result']['display'] == 'card'
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ class CHECKER_CAPTCHA_HELPER {
|
|||||||
}
|
}
|
||||||
} elseif ($recaptcha_enabled) {
|
} elseif ($recaptcha_enabled) {
|
||||||
$site_key = $checker['security']['recaptcha']['site_key'] ?? '';
|
$site_key = $checker['security']['recaptcha']['site_key'] ?? '';
|
||||||
$action = $checker['security']['recaptcha']['action'] ?? 'checker_validate';
|
// Default action must match JavaScript default ('submit') to avoid score penalties
|
||||||
|
$action = $checker['security']['recaptcha']['action'] ?? 'submit';
|
||||||
$hide_badge = $checker['security']['recaptcha']['hide_badge'] ?? 'no';
|
$hide_badge = $checker['security']['recaptcha']['hide_badge'] ?? 'no';
|
||||||
|
|
||||||
if ($site_key) {
|
if ($site_key) {
|
||||||
@@ -87,101 +88,31 @@ class CHECKER_CAPTCHA_HELPER {
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
// Pass settings to JavaScript
|
// Pass settings to JavaScript - let public.js handle token generation
|
||||||
wp_add_inline_script(
|
wp_add_inline_script(
|
||||||
'google-recaptcha-v3',
|
'google-recaptcha-v3',
|
||||||
'
|
'
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
console.log("[CAPTCHA Debug] DOMContentLoaded - checking for grecaptcha...");
|
|
||||||
console.log("[CAPTCHA Debug] grecaptcha available:", typeof grecaptcha !== "undefined");
|
|
||||||
|
|
||||||
if (typeof grecaptcha !== "undefined") {
|
if (typeof grecaptcha !== "undefined") {
|
||||||
console.log("[CAPTCHA Debug] reCAPTCHA v3 detected, initializing...");
|
// Store reCAPTCHA settings globally for public.js to use
|
||||||
|
|
||||||
// Store reCAPTCHA settings globally
|
|
||||||
window.checkerRecaptcha = {
|
window.checkerRecaptcha = {
|
||||||
siteKey: "' . esc_js($site_key) . '",
|
siteKey: "' . esc_js($site_key) . '",
|
||||||
action: "' . esc_js($action) . '"
|
action: "' . esc_js($action) . '"
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("[CAPTCHA Debug] reCAPTCHA settings:", window.checkerRecaptcha);
|
|
||||||
|
|
||||||
' . ($hide_badge ? '
|
' . ($hide_badge ? '
|
||||||
// Hide reCAPTCHA badge
|
// Hide reCAPTCHA badge
|
||||||
var style = document.createElement("style");
|
var style = document.createElement("style");
|
||||||
style.innerHTML = ".grecaptcha-badge { display: none !important; }";
|
style.innerHTML = ".grecaptcha-badge { display: none !important; }";
|
||||||
document.head.appendChild(style);
|
document.head.appendChild(style);
|
||||||
console.log("[CAPTCHA Debug] reCAPTCHA badge hidden");
|
|
||||||
' : '
|
' : '
|
||||||
// Ensure badge is visible
|
// Ensure badge is visible
|
||||||
var style = document.createElement("style");
|
var style = document.createElement("style");
|
||||||
style.innerHTML = ".grecaptcha-badge { visibility: visible !important; opacity: 1 !important; display: block !important; }";
|
style.innerHTML = ".grecaptcha-badge { visibility: visible !important; opacity: 1 !important; display: block !important; }";
|
||||||
document.head.appendChild(style);
|
document.head.appendChild(style);
|
||||||
') . '
|
') . '
|
||||||
|
|
||||||
// Initialize reCAPTCHA for all checker forms
|
|
||||||
initRecaptchaForForms();
|
|
||||||
console.log("[CAPTCHA Debug] reCAPTCHA initialization complete");
|
|
||||||
} else {
|
|
||||||
console.error("[CAPTCHA Debug] grecaptcha NOT available - script may not have loaded");
|
|
||||||
}
|
}
|
||||||
});
|
});'
|
||||||
|
|
||||||
function initRecaptchaForForms() {
|
|
||||||
var forms = document.querySelectorAll(".dw-checker-container form");
|
|
||||||
forms.forEach(function(form) {
|
|
||||||
var searchButton = form.querySelector(".search-button");
|
|
||||||
if (!searchButton) return;
|
|
||||||
|
|
||||||
// Generate token when search button is clicked
|
|
||||||
searchButton.addEventListener("click", function(e) {
|
|
||||||
var tokenInput = form.querySelector("input[name=recaptcha_token]");
|
|
||||||
|
|
||||||
// If token already exists and is recent (less than 2 minutes old), don\'t regenerate
|
|
||||||
if (tokenInput && tokenInput.value && tokenInput.dataset.timestamp) {
|
|
||||||
var tokenAge = Date.now() - parseInt(tokenInput.dataset.timestamp);
|
|
||||||
if (tokenAge < 120000) { // 2 minutes
|
|
||||||
console.log("reCAPTCHA: Using existing token (age: " + Math.floor(tokenAge/1000) + "s)");
|
|
||||||
return; // Let the click proceed with existing token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent default to wait for token generation
|
|
||||||
var hasToken = tokenInput && tokenInput.value;
|
|
||||||
if (!hasToken) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopImmediatePropagation();
|
|
||||||
|
|
||||||
console.log("reCAPTCHA: Generating new token...");
|
|
||||||
|
|
||||||
// Generate new token
|
|
||||||
grecaptcha.ready(function() {
|
|
||||||
grecaptcha.execute(
|
|
||||||
window.checkerRecaptcha.siteKey,
|
|
||||||
{action: window.checkerRecaptcha.action}
|
|
||||||
).then(function(token) {
|
|
||||||
console.log("reCAPTCHA: Token generated successfully");
|
|
||||||
// Add or update token in hidden input
|
|
||||||
if (!tokenInput) {
|
|
||||||
tokenInput = document.createElement("input");
|
|
||||||
tokenInput.type = "hidden";
|
|
||||||
tokenInput.name = "recaptcha_token";
|
|
||||||
form.appendChild(tokenInput);
|
|
||||||
}
|
|
||||||
tokenInput.value = token;
|
|
||||||
tokenInput.dataset.timestamp = Date.now().toString();
|
|
||||||
|
|
||||||
// Trigger the search button click again
|
|
||||||
searchButton.click();
|
|
||||||
}).catch(function(error) {
|
|
||||||
console.error("reCAPTCHA error:", error);
|
|
||||||
alert("reCAPTCHA verification failed. Please refresh the page.");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, true); // Use capture phase to run before other click handlers
|
|
||||||
});
|
|
||||||
}'
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,8 +139,6 @@ class CHECKER_CAPTCHA_HELPER {
|
|||||||
'cloudflare-turnstile',
|
'cloudflare-turnstile',
|
||||||
'
|
'
|
||||||
window.onloadTurnstileCallback = function() {
|
window.onloadTurnstileCallback = function() {
|
||||||
console.log("[CAPTCHA Debug] Turnstile callback triggered");
|
|
||||||
|
|
||||||
// Store Turnstile settings globally
|
// Store Turnstile settings globally
|
||||||
window.checkerTurnstile = {
|
window.checkerTurnstile = {
|
||||||
siteKey: "' . esc_js($site_key) . '",
|
siteKey: "' . esc_js($site_key) . '",
|
||||||
@@ -217,16 +146,10 @@ class CHECKER_CAPTCHA_HELPER {
|
|||||||
size: "' . esc_js($size) . '"
|
size: "' . esc_js($size) . '"
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("[CAPTCHA Debug] Turnstile settings:", window.checkerTurnstile);
|
|
||||||
|
|
||||||
// Initialize Turnstile for all checker forms
|
// Initialize Turnstile for all checker forms
|
||||||
initTurnstileForForms();
|
initTurnstileForForms();
|
||||||
console.log("[CAPTCHA Debug] Turnstile initialization complete");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Also log when script loads
|
|
||||||
console.log("[CAPTCHA Debug] Turnstile script loading...");
|
|
||||||
|
|
||||||
function initTurnstileForForms() {
|
function initTurnstileForForms() {
|
||||||
var forms = document.querySelectorAll(".dw-checker-container form");
|
var forms = document.querySelectorAll(".dw-checker-container form");
|
||||||
forms.forEach(function(form) {
|
forms.forEach(function(form) {
|
||||||
@@ -244,7 +167,6 @@ class CHECKER_CAPTCHA_HELPER {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render Turnstile widget
|
// Render Turnstile widget
|
||||||
console.log("Turnstile: Initializing widget");
|
|
||||||
turnstile.render(container, {
|
turnstile.render(container, {
|
||||||
sitekey: window.checkerTurnstile.siteKey,
|
sitekey: window.checkerTurnstile.siteKey,
|
||||||
theme: window.checkerTurnstile.theme,
|
theme: window.checkerTurnstile.theme,
|
||||||
@@ -264,10 +186,10 @@ class CHECKER_CAPTCHA_HELPER {
|
|||||||
console.log("Turnstile: Token stored in form");
|
console.log("Turnstile: Token stored in form");
|
||||||
},
|
},
|
||||||
"error-callback": function(error) {
|
"error-callback": function(error) {
|
||||||
console.error("Turnstile error:", error);
|
// Silently handle errors
|
||||||
},
|
},
|
||||||
"expired-callback": function() {
|
"expired-callback": function() {
|
||||||
console.warn("Turnstile: Token expired, please complete challenge again");
|
// Reset expired token
|
||||||
var input = form.querySelector("input[name=turnstile_token]");
|
var input = form.querySelector("input[name=turnstile_token]");
|
||||||
if (input) {
|
if (input) {
|
||||||
input.value = "";
|
input.value = "";
|
||||||
|
|||||||
@@ -23,32 +23,36 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-2 type-button-link" {{#ifCond type '==' 'text'}}style="display:none;"{{/ifCond}}>
|
<div class="row mb-2 type-button-link">
|
||||||
<div class="col-3"><label class="form-label fw-bold mb-0">Button Text</label></div>
|
<div class="col-3"><label class="form-label fw-bold mb-0">Button Text</label></div>
|
||||||
<div class="col-9">
|
<div class="col-9">
|
||||||
<input type="text" id="output-buttontext-{{id}}" name="checker[output][{{id}}][button_text]" value="{{button_text}}" class="w-100"/>
|
<input type="text" id="output-buttontext-{{id}}" name="checker[output][{{id}}][button_text]" value="{{button_text}}" class="w-100"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-2 type-button-link">
|
||||||
|
<div class="col-3"><label class="form-label fw-bold mb-0">BG Color</label></div>
|
||||||
|
<div class="col-9">
|
||||||
|
<input type="color" id="output-bg_color-{{id}}" name="checker[output][{{id}}][bg_color]" value="{{bg_color}}" class="w-100"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-2 type-button-link">
|
||||||
|
<div class="col-3"><label class="form-label fw-bold mb-0">Text Color</label></div>
|
||||||
|
<div class="col-9">
|
||||||
|
<input type="color" id="output-text_color-{{id}}" name="checker[output][{{id}}][text_color]" value="{{text_color}}" class="w-100"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<div class="col-3"><label class="form-label fw-bold mb-0">Prefix</label></div>
|
<div class="col-3"><label class="form-label fw-bold mb-0">Prefix</label></div>
|
||||||
<div class="col-9">
|
<div class="col-9">
|
||||||
<input type="text" id="output-prefix-{{id}}" name="checker[output][{{id}}][prefix]" value="{{prefix}}" class="w-100"/>
|
<input type="text" id="output-prefix-{{id}}" name="checker[output][{{id}}][prefix]" value="{{prefix}}" class="w-100"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{#if display}}
|
|
||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<div class="col-3"><label class="form-label fw-bold mb-0">BG Color</label></div>
|
<div class="col-3"><label class="form-label fw-bold mb-0">Empty Fallback</label></div>
|
||||||
<div class="col-9">
|
<div class="col-9">
|
||||||
<input type="color" id="output-bg_color-{{id}}" name="checker[output][{{id}}][bg_color]" value="{{bg_color}}" class="w-100"/>
|
<input type="text" id="output-empty_fallback-{{id}}" name="checker[output][{{id}}][empty_fallback]" value="{{empty_fallback}}" class="w-100" placeholder="e.g. N/A, —, Not available"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
|
||||||
<div class="col-3"><label class="form-label fw-bold mb-0">Text Color</label></div>
|
|
||||||
<div class="col-9">
|
|
||||||
<input type="color" id="output-text_color-{{id}}" name="checker[output][{{id}}][text_color]" value="{{text_color}}" class="w-100"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|||||||
Reference in New Issue
Block a user