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:
299
assets/public.js
299
assets/public.js
@@ -22,35 +22,26 @@ jQuery(document).ready(function ($) {
|
||||
var recaptchaToken = thisChecker.find('input[name="recaptcha_token"]').val();
|
||||
if (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
|
||||
var turnstileToken = thisChecker.find('input[name="turnstile_token"]').val();
|
||||
if (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)
|
||||
var hpInput = thisChecker.find('input[data-hp-field="1"]');
|
||||
if (hpInput.length) {
|
||||
baseData.honeypot_name = hpInput.attr('name');
|
||||
baseData.honeypot_value = hpInput.val() || "";
|
||||
console.log("Security: Honeypot field added (value: " + (hpInput.val() === "" ? "empty" : "filled") + ")");
|
||||
} else {
|
||||
var legacyHp = thisChecker.find('input[name="website_url_hp"]').val();
|
||||
if (typeof legacyHp !== 'undefined') {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -62,18 +53,18 @@ jQuery(document).ready(function ($) {
|
||||
function handleAjaxError(xhr, checkerId) {
|
||||
var thisChecker = $("#checker-" + checkerId);
|
||||
var response = xhr.responseJSON;
|
||||
|
||||
|
||||
// WordPress wp_send_json_error format: {success: false, data: {message: "...", type: "..."}}
|
||||
if (response && response.data) {
|
||||
var errorType = response.data.type || 'error';
|
||||
var errorMessage = response.data.message || 'An error occurred';
|
||||
|
||||
|
||||
// Handle nonce expiry - prompt page refresh
|
||||
if (errorType === 'nonce_expired') {
|
||||
showSecurityError(checkerId, errorMessage, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Handle CAPTCHA errors
|
||||
if (errorType === 'recaptcha' || errorType === 'turnstile') {
|
||||
showSecurityError(checkerId, errorMessage, false);
|
||||
@@ -81,19 +72,19 @@ jQuery(document).ready(function ($) {
|
||||
resetCaptchaWidget(checkerId, errorType);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Handle rate limit with enhanced message
|
||||
if (errorType === 'rate_limit') {
|
||||
showSecurityError(checkerId, errorMessage, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Handle honeypot trigger (silent fail for bots)
|
||||
if (errorType === 'honeypot') {
|
||||
showSecurityError(checkerId, errorMessage, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Generic error
|
||||
showSecurityError(checkerId, errorMessage, false);
|
||||
} else if (response && response.message) {
|
||||
@@ -199,12 +190,12 @@ jQuery(document).ready(function ($) {
|
||||
function refreshRecaptchaToken(checkerId) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var thisChecker = $("#checker-" + checkerId);
|
||||
|
||||
|
||||
if (typeof grecaptcha === 'undefined' || !window.checkerRecaptcha) {
|
||||
resolve(); // No reCAPTCHA configured
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
grecaptcha.ready(function() {
|
||||
grecaptcha.execute(window.checkerRecaptcha.siteKey, {
|
||||
action: window.checkerRecaptcha.action || 'submit'
|
||||
@@ -217,7 +208,6 @@ jQuery(document).ready(function ($) {
|
||||
tokenInput.val(token).attr('data-timestamp', Date.now().toString());
|
||||
resolve();
|
||||
}).catch(function(error) {
|
||||
console.error('reCAPTCHA refresh error:', error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
@@ -246,19 +236,33 @@ jQuery(document).ready(function ($) {
|
||||
}
|
||||
|
||||
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) {
|
||||
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()
|
||||
.then(function() {
|
||||
return refreshRecaptchaToken(checkerId);
|
||||
})
|
||||
.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
|
||||
var thisChecker = $("#checker-" + checkerId);
|
||||
var turnstileInput = thisChecker.find('input[name="turnstile_token"]');
|
||||
if (turnstileInput.length && turnstileInput.val()) {
|
||||
var ts = parseInt(turnstileInput.attr("data-timestamp") || "0");
|
||||
@@ -271,19 +275,23 @@ jQuery(document).ready(function ($) {
|
||||
turnstileInput.val("");
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
function waitForRecaptcha(timeoutMs = 5000) {
|
||||
function waitForRecaptcha(timeoutMs = 10000) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var start = Date.now();
|
||||
|
||||
(function check() {
|
||||
if (typeof grecaptcha !== "undefined" && typeof grecaptcha.ready === "function") {
|
||||
return resolve();
|
||||
}
|
||||
|
||||
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);
|
||||
})();
|
||||
});
|
||||
@@ -309,10 +317,9 @@ jQuery(document).ready(function ($) {
|
||||
loadAllData(checkerId, settings, true); // true = initial load
|
||||
}
|
||||
|
||||
// Preload captcha tokens to surface badge and avoid first-click delays
|
||||
ensureCaptchaReady(checkerId).catch(function(err){
|
||||
console.warn("Captcha preload failed", err);
|
||||
showSecurityError(checkerId, checkerSecurity.i18n ? checkerSecurity.i18n.security_error : "Security validation failed.", false);
|
||||
// Preload reCAPTCHA token on page load (improves score by showing natural browsing behavior)
|
||||
ensureCaptchaReady(checkerId).catch(function(){
|
||||
// Silently fail on preload - will retry on submit
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -585,10 +592,16 @@ jQuery(document).ready(function ($) {
|
||||
var button_text = escapeHtml(outputSetting.button_text || "Click");
|
||||
var bg_color = escapeHtml(outputSetting.bg_color || "#333333");
|
||||
var text_color = escapeHtml(outputSetting.text_color || "#ffffff");
|
||||
var empty_fallback = escapeHtml(outputSetting.empty_fallback || "");
|
||||
var safeQ = escapeHtml(q);
|
||||
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 =
|
||||
'<a href="' +
|
||||
safeVal +
|
||||
@@ -694,9 +707,15 @@ jQuery(document).ready(function ($) {
|
||||
var button_text = escapeHtml(outputSetting.button_text || "Click");
|
||||
var bg_color = escapeHtml(outputSetting.bg_color || "#333333");
|
||||
var text_color = escapeHtml(outputSetting.text_color || "#ffffff");
|
||||
var empty_fallback = escapeHtml(outputSetting.empty_fallback || "");
|
||||
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 =
|
||||
'<a href="' +
|
||||
safeVal +
|
||||
@@ -824,10 +843,16 @@ jQuery(document).ready(function ($) {
|
||||
var button_text = escapeHtml(outputSetting.button_text || "Click");
|
||||
var bg_color = escapeHtml(outputSetting.bg_color || "#333333");
|
||||
var text_color = escapeHtml(outputSetting.text_color || "#ffffff");
|
||||
var empty_fallback = escapeHtml(outputSetting.empty_fallback || "");
|
||||
var safeQ = escapeHtml(q);
|
||||
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 =
|
||||
'<a href="' +
|
||||
safeVal +
|
||||
@@ -926,10 +951,16 @@ jQuery(document).ready(function ($) {
|
||||
var button_text = escapeHtml(outputSetting.button_text || "Click");
|
||||
var bg_color = escapeHtml(outputSetting.bg_color || "#333333");
|
||||
var text_color = escapeHtml(outputSetting.text_color || "#ffffff");
|
||||
var empty_fallback = escapeHtml(outputSetting.empty_fallback || "");
|
||||
var safeQ = escapeHtml(q);
|
||||
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 =
|
||||
'<a href="' +
|
||||
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) {
|
||||
e.preventDefault();
|
||||
var $this = $(this);
|
||||
@@ -1255,49 +1291,76 @@ jQuery(document).ready(function ($) {
|
||||
var prefix = "";
|
||||
var type = "";
|
||||
var button_text = "";
|
||||
var empty_fallback = "";
|
||||
var hidden = "no";
|
||||
var bg_color = "#333333";
|
||||
var text_color = "#ffffff";
|
||||
$.each(res.output, function (o, p) {
|
||||
if (q == p.key) {
|
||||
prefix = p.prefix;
|
||||
type = p.type;
|
||||
button_text = p.button_text;
|
||||
if ("empty_fallback" in p) {
|
||||
empty_fallback = p.empty_fallback;
|
||||
}
|
||||
if ("hide" in p) {
|
||||
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") {
|
||||
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 =
|
||||
'<a href="' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||
id +
|
||||
'" target="_blank" rel="noopener">' +
|
||||
button_text +
|
||||
'" target="_blank" rel="noopener" style="background-color: ' +
|
||||
escapeHtml(bg_color) +
|
||||
"; color: " +
|
||||
escapeHtml(text_color) +
|
||||
';">' +
|
||||
escapeHtml(button_text) +
|
||||
"</a>";
|
||||
} else if (type == "whatsapp_button") {
|
||||
r =
|
||||
'<a href="https://wa.me/' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||
id +
|
||||
'" target="_blank" rel="noopener">' +
|
||||
button_text +
|
||||
'" target="_blank" rel="noopener" style="background-color: ' +
|
||||
escapeHtml(bg_color) +
|
||||
"; color: " +
|
||||
escapeHtml(text_color) +
|
||||
';">' +
|
||||
escapeHtml(button_text) +
|
||||
"</a>";
|
||||
} else if (type == "image") {
|
||||
r =
|
||||
'<img src="' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" class="dw-checker-image dw-checker-img-' +
|
||||
id +
|
||||
'" style="max-width: 150px; height: auto; cursor: pointer;" onclick="openImageLightbox(this)" data-fullsize="' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" alt="' +
|
||||
q +
|
||||
escapeHtml(q) +
|
||||
'" />';
|
||||
} else if (type == "text") {
|
||||
r = escapeHtml(r);
|
||||
}
|
||||
resultDiv += "<tr>";
|
||||
resultDiv +=
|
||||
@@ -1308,7 +1371,7 @@ jQuery(document).ready(function ($) {
|
||||
'px;"><span class="dw-checker-result-header" style="color:' +
|
||||
header_color +
|
||||
'">' +
|
||||
q +
|
||||
escapeHtml(q) +
|
||||
"</span></th>";
|
||||
resultDiv +=
|
||||
'<td style="border-color: ' +
|
||||
@@ -1318,7 +1381,7 @@ jQuery(document).ready(function ($) {
|
||||
'px;"><span class="dw-checker-result-value" style="color:' +
|
||||
value_color +
|
||||
'">' +
|
||||
prefix +
|
||||
escapeHtml(prefix || "") +
|
||||
r +
|
||||
"</span></td>";
|
||||
resultDiv += "</tr>";
|
||||
@@ -1358,49 +1421,76 @@ jQuery(document).ready(function ($) {
|
||||
var prefix = "";
|
||||
var type = "";
|
||||
var button_text = "";
|
||||
var empty_fallback = "";
|
||||
var hidden = "no";
|
||||
var bg_color = "#333333";
|
||||
var text_color = "#ffffff";
|
||||
$.each(res.output, function (o, p) {
|
||||
if (q == p.key) {
|
||||
prefix = p.prefix;
|
||||
type = p.type;
|
||||
button_text = p.button_text;
|
||||
if ("empty_fallback" in p) {
|
||||
empty_fallback = p.empty_fallback;
|
||||
}
|
||||
if ("hide" in p) {
|
||||
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") {
|
||||
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 =
|
||||
'<a href="' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||
id +
|
||||
'" target="_blank" rel="noopener">' +
|
||||
button_text +
|
||||
'" target="_blank" rel="noopener" style="background-color: ' +
|
||||
escapeHtml(bg_color) +
|
||||
"; color: " +
|
||||
escapeHtml(text_color) +
|
||||
';">' +
|
||||
escapeHtml(button_text) +
|
||||
"</a>";
|
||||
} else if (type == "whatsapp_button") {
|
||||
r =
|
||||
'<a href="https://wa.me/' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||
id +
|
||||
'" target="_blank" rel="noopener">' +
|
||||
button_text +
|
||||
'" target="_blank" rel="noopener" style="background-color: ' +
|
||||
escapeHtml(bg_color) +
|
||||
"; color: " +
|
||||
escapeHtml(text_color) +
|
||||
';">' +
|
||||
escapeHtml(button_text) +
|
||||
"</a>";
|
||||
} else if (type == "image") {
|
||||
r =
|
||||
'<img src="' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" class="dw-checker-image dw-checker-img-' +
|
||||
id +
|
||||
'" style="max-width: 150px; height: auto; cursor: pointer;" onclick="openImageLightbox(this)" data-fullsize="' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" alt="' +
|
||||
q +
|
||||
escapeHtml(q) +
|
||||
'" />';
|
||||
} else if (type == "text") {
|
||||
r = escapeHtml(r);
|
||||
}
|
||||
|
||||
resultDiv +=
|
||||
@@ -1413,13 +1503,13 @@ jQuery(document).ready(function ($) {
|
||||
'<div class="result-header"><span class="dw-checker-result-header" style="color:' +
|
||||
header_color +
|
||||
';">' +
|
||||
q +
|
||||
escapeHtml(q) +
|
||||
"</span></div>";
|
||||
resultDiv +=
|
||||
'<div class="result-value"><span class="dw-checker-result-value" style="color:' +
|
||||
value_color +
|
||||
';">' +
|
||||
prefix +
|
||||
escapeHtml(prefix || "") +
|
||||
r +
|
||||
"</span></div>";
|
||||
resultDiv += "</div>";
|
||||
@@ -1466,49 +1556,76 @@ jQuery(document).ready(function ($) {
|
||||
var prefix = "";
|
||||
var type = "";
|
||||
var button_text = "";
|
||||
var empty_fallback = "";
|
||||
var hidden = "no";
|
||||
var bg_color = "#333333";
|
||||
var text_color = "#ffffff";
|
||||
$.each(res.output, function (o, p) {
|
||||
if (q == p.key) {
|
||||
prefix = p.prefix;
|
||||
type = p.type;
|
||||
button_text = p.button_text;
|
||||
if ("empty_fallback" in p) {
|
||||
empty_fallback = p.empty_fallback;
|
||||
}
|
||||
if ("hide" in p) {
|
||||
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") {
|
||||
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 =
|
||||
'<a href="' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||
id +
|
||||
'" target="_blank" rel="noopener">' +
|
||||
button_text +
|
||||
'" target="_blank" rel="noopener" style="background-color: ' +
|
||||
escapeHtml(bg_color) +
|
||||
"; color: " +
|
||||
escapeHtml(text_color) +
|
||||
';">' +
|
||||
escapeHtml(button_text) +
|
||||
"</a>";
|
||||
} else if (type == "whatsapp_button") {
|
||||
r =
|
||||
'<a href="https://wa.me/' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||
id +
|
||||
'" target="_blank" rel="noopener">' +
|
||||
button_text +
|
||||
'" target="_blank" rel="noopener" style="background-color: ' +
|
||||
escapeHtml(bg_color) +
|
||||
"; color: " +
|
||||
escapeHtml(text_color) +
|
||||
';">' +
|
||||
escapeHtml(button_text) +
|
||||
"</a>";
|
||||
} else if (type == "image") {
|
||||
r =
|
||||
'<img src="' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" class="dw-checker-image dw-checker-img-' +
|
||||
id +
|
||||
'" style="max-width: 150px; height: auto; cursor: pointer;" onclick="openImageLightbox(this)" data-fullsize="' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" alt="' +
|
||||
q +
|
||||
escapeHtml(q) +
|
||||
'" />';
|
||||
} else if (type == "text") {
|
||||
r = escapeHtml(r);
|
||||
}
|
||||
resultDiv +=
|
||||
'<td style="border-color: ' +
|
||||
@@ -1518,7 +1635,7 @@ jQuery(document).ready(function ($) {
|
||||
'px;"><span class="dw-checker-result-value" style="color:' +
|
||||
value_color +
|
||||
'">' +
|
||||
prefix +
|
||||
escapeHtml(prefix || "") +
|
||||
r +
|
||||
"</span></td>";
|
||||
});
|
||||
@@ -1614,6 +1731,7 @@ jQuery(document).ready(function ($) {
|
||||
var prefix = "";
|
||||
var type = "";
|
||||
var button_text = "";
|
||||
var empty_fallback = "";
|
||||
var hidden = "no";
|
||||
var bg_color = "#cccccc";
|
||||
var text_color = "#000000";
|
||||
@@ -1622,6 +1740,9 @@ jQuery(document).ready(function ($) {
|
||||
prefix = p.prefix;
|
||||
type = p.type;
|
||||
button_text = p.button_text;
|
||||
if ("empty_fallback" in p) {
|
||||
empty_fallback = p.empty_fallback;
|
||||
}
|
||||
if ("hide" in p) {
|
||||
hidden = p.hide;
|
||||
}
|
||||
@@ -1636,35 +1757,42 @@ jQuery(document).ready(function ($) {
|
||||
if (hidden == "yes") {
|
||||
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 =
|
||||
'<a href="' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||
id +
|
||||
'" target="_blank" rel="noopener">' +
|
||||
button_text +
|
||||
escapeHtml(button_text) +
|
||||
"</a>";
|
||||
} else if (type == "whatsapp_button") {
|
||||
r =
|
||||
'<a href="https://wa.me/' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" class="button dw-checker-value-button dw-checker-btn-' +
|
||||
id +
|
||||
'" target="_blank" rel="noopener">' +
|
||||
button_text +
|
||||
escapeHtml(button_text) +
|
||||
"</a>";
|
||||
} else if (type == "image") {
|
||||
r =
|
||||
'<img src="' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" class="dw-checker-image dw-checker-img-' +
|
||||
id +
|
||||
'" style="max-width: 100%; height: auto; cursor: pointer;" onclick="openImageLightbox(this)" data-fullsize="' +
|
||||
r +
|
||||
escapeHtml(r) +
|
||||
'" alt="' +
|
||||
q +
|
||||
escapeHtml(q) +
|
||||
'" />';
|
||||
} else if (type == "text") {
|
||||
r = escapeHtml(r);
|
||||
}
|
||||
resultDiv +=
|
||||
`<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:` +
|
||||
text_color +
|
||||
`">` +
|
||||
q +
|
||||
escapeHtml(q) +
|
||||
`</span>
|
||||
<span class="dw-checker-card-value" style="color:` +
|
||||
text_color +
|
||||
`">` +
|
||||
prefix +
|
||||
escapeHtml(prefix || "") +
|
||||
r +
|
||||
`</span>
|
||||
</div>`;
|
||||
@@ -1706,11 +1834,20 @@ jQuery(document).ready(function ($) {
|
||||
|
||||
ensureCaptchaReady($id)
|
||||
.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();
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.error("Captcha refresh failed", err);
|
||||
showSecurityError($id, checkerSecurity.i18n ? checkerSecurity.i18n.security_error : "Security validation failed.", false);
|
||||
.catch(function() {
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user