Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions inc/cleantalk-common.php
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,8 @@ function apbct_exclusions_check__url()
*/
// case for admin-ajax routes, may contain get params(!)
$is_admin_ajax_like = stripos(Server::getString('REQUEST_URI'), '/wp-admin/admin-ajax.php') === 0;
// case for woocommerce-ajax routes, may contain get params(!)
$is_wc_ajax_like = stripos(Server::getString('REQUEST_URI'), '/?wc-ajax=') === 0;
// case for wp-json paths
$is_wp_json_like = stripos(Server::getString('REQUEST_URI'), '/wp-json/') === 0;
// case for rest paths
Expand All @@ -446,6 +448,7 @@ function apbct_exclusions_check__url()
Server::getString('HTTP_REFERER') &&
(
$is_admin_ajax_like ||
$is_wc_ajax_like ||
$is_wp_json_like ||
$is_rest_only_path
)
Expand Down
2 changes: 1 addition & 1 deletion js/apbct-public-bundle.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/apbct-public-bundle_ext-protection.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/apbct-public-bundle_ext-protection_gathering.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/apbct-public-bundle_full-protection.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/apbct-public-bundle_full-protection_gathering.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/apbct-public-bundle_gathering.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/apbct-public-bundle_int-protection.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/apbct-public-bundle_int-protection_gathering.min.js

Large diffs are not rendered by default.

199 changes: 147 additions & 52 deletions js/prebuild/apbct-public-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -2818,7 +2818,7 @@ class ApbctHandler {
cronFormsHandler(cronStartTimeout = 2000) {
setTimeout(function() {
setInterval(function() {
if (!+ctPublic.settings__data__bot_detector_enabled) {
if (!+ctPublic.settings__data__bot_detector_enabled && typeof ApbctGatheringData !== 'undefined') {
new ApbctGatheringData().restartFieldsListening();
}
new ApbctEventTokenTransport().restartBotDetectorEventTokenAttach();
Expand Down Expand Up @@ -2928,6 +2928,68 @@ class ApbctHandler {
}
}

/**
* Catch Iframe fetch request
* @return {void}
*/
catchIframeFetchRequest() {
setTimeout(function() {
try {
// Give next gen iframe
const foundIframe = Array.from(document.querySelectorAll('iframe')).find(
(iframe) => iframe.src?.includes('givewp-route'),
);

if (!foundIframe) {
return;
}

// Cross origin access check
let contentWindow;
try {
contentWindow = foundIframe.contentWindow;
if (!contentWindow || !contentWindow.fetch) {
return;
}
} catch (securityError) {
// access denied
return;
}

// Save original iframe fetch
const originalIframeFetch = contentWindow.fetch;

// Intercept and add fields to body
contentWindow.fetch = async function(...args) {
try {
// is body and boddy has append func
if (args && args[1] && args[1].body) {
if (
args[1].body instanceof FormData || (typeof args[1].body.append === 'function')
) {
if (+ctPublic.settings__data__bot_detector_enabled) {
args[1].body.append(
'ct_bot_detector_event_token',
apbctLocalStorage.get('bot_detector_event_token'),
);
} else {
args[1].body.append('ct_no_cookie_hidden_field', getNoCookieData());
}
}
}
} catch (e) {
// do nothing due fields add error
}

// run origin fetch
return originalIframeFetch.apply(contentWindow, args);
};
} catch (error) {
// do nothing on unexpected error
}
}, 1000);
}

/**
* Catch fetch request
* @return {void}
Expand Down Expand Up @@ -2967,95 +3029,127 @@ class ApbctHandler {
})
)
) {
/**
* Select key/value pair depending on botDetectorEnabled flag
* @param {bool} botDetectorEnabled
* @return {{key: string, value: string}|false} False on empty gained data.
*/
const selectFieldsData = function(botDetectorEnabled) {
const result = {
'key': null,
'value': null,
};
if (botDetectorEnabled) {
result.key = 'ct_bot_detector_event_token';
result.value = apbctLocalStorage.get('bot_detector_event_token');
} else {
result.key = 'ct_no_cookie_hidden_field';
result.value = getNoCookieData();
};
return result.key && result.value ? result : false;
};

/**
*
* @param {string} body Fetch request data body.
* @param {object|bool} fieldPair Key value to inject.
* @return {string} Modified body.
*/
const attachFieldsToBody = function(body, fieldPair = false) {
if (fieldPair) {
if (body instanceof FormData || typeof body.append === 'function') {
body.append(fieldPair.key, fieldPair.value);
} else {
let bodyObj = JSON.parse(body);
if (!bodyObj.hasOwnProperty(fieldPair.key)) {
bodyObj[fieldPair.key] = fieldPair.value;
body = JSON.stringify(bodyObj);
}
}
}
return body;
};

let preventOriginalFetch = false;

window.fetch = async function(...args) {
// if no data set provided - exit
if (
!args ||
!args[0] ||
!args[1] ||
!args[1].body
) {
return defaultFetch.apply(window, args);
}

// Metform block
if (
Array.from(document.forms).some((form) => form.classList.contains('metform-form-content')) &&
args &&
args[0] &&
typeof args[0].includes === 'function' &&
(args[0].includes('/wp-json/metform/') ||
(ctPublicFunctions._rest_url && (() => {
try {
return args[0].includes(new URL(ctPublicFunctions._rest_url).pathname + 'metform/');
} catch (e) {
return false;
return defaultFetch.apply(window, args);
}
})())
)
) {
if (args && args[1] && args[1].body) {
if (+ctPublic.settings__data__bot_detector_enabled) {
args[1].body.append(
'ct_bot_detector_event_token',
apbctLocalStorage.get('bot_detector_event_token'),
);
} else {
args[1].body.append('ct_no_cookie_hidden_field', getNoCookieData());
}
try {
args[1].body = attachFieldsToBody(
args[1].body,
selectFieldsData(+ctPublic.settings__data__bot_detector_enabled),
);
} catch (e) {
return defaultFetch.apply(window, args);
}
}

// WP Recipe Maker block
if (
Array.from(document.forms).some(
(form) => form.classList.contains('wprm-user-ratings-modal-stars-container'),
) &&
args &&
args[0] &&
typeof args[0].includes === 'function' &&
args[0].includes('/wp-json/wp-recipe-maker/')
) {
if (args[1] && args[1].body) {
if (typeof args[1].body === 'string') {
let bodyObj;
try {
bodyObj = JSON.parse(args[1].body);
} catch (e) {
bodyObj = {};
}
if (+ctPublic.settings__data__bot_detector_enabled) {
bodyObj.ct_bot_detector_event_token =
apbctLocalStorage.get('bot_detector_event_token');
} else {
bodyObj.ct_no_cookie_hidden_field = getNoCookieData();
}
args[1].body = JSON.stringify(bodyObj);
}
try {
args[1].body = attachFieldsToBody(
args[1].body,
selectFieldsData(+ctPublic.settings__data__bot_detector_enabled),
);
} catch (e) {
return defaultFetch.apply(window, args);
}
}

// WooCommerce add to cart request, like:
// /index.php?rest_route=/wc/store/v1/cart/add-item
if (args && args[0] &&
args[0].includes('/wc/store/v1/cart/add-item') &&
args && args[1] && args[1].body
if (
typeof args[0].includes === 'function' &&
args[0].includes('/wc/store/v1/cart/add-item')
) {
if (
+ctPublic.settings__data__bot_detector_enabled &&
+ctPublic.settings__forms__wc_add_to_cart
) {
try {
let bodyObj = JSON.parse(args[1].body);
if (!bodyObj.hasOwnProperty('ct_bot_detector_event_token')) {
bodyObj.ct_bot_detector_event_token =
apbctLocalStorage.get('bot_detector_event_token');
args[1].body = JSON.stringify(bodyObj);
}
} catch (e) {
return false;
try {
if (
+ctPublic.settings__forms__wc_add_to_cart
) {
args[1].body = attachFieldsToBody(
args[1].body,
selectFieldsData(+ctPublic.settings__data__bot_detector_enabled),
);
}
} else {
args[1].body.append('ct_no_cookie_hidden_field', getNoCookieData());
} catch (e) {
return defaultFetch.apply(window, args);
}
}

// bitrix24 EXTERNAL form
if (+ctPublic.settings__forms__check_external &&
args && args[0] &&
typeof args[0].includes === 'function' &&
args[0].includes('bitrix/services/main/ajax.php?action=crm.site.form.fill') &&
args[1] && args[1].body && args[1].body instanceof FormData
args[1].body instanceof FormData
) {
const currentTargetForm = document.querySelector('.b24-form form');
let data = {
Expand Down Expand Up @@ -3720,7 +3814,7 @@ function apbct_ready() {
handler.detectForcedAltCookiesForms();

// Gathering data when bot detector is disabled
if (!+ctPublic.settings__data__bot_detector_enabled) {
if (!+ctPublic.settings__data__bot_detector_enabled && typeof ApbctGatheringData !== 'undefined') {
const gatheringData = new ApbctGatheringData();
gatheringData.setSessionId();
gatheringData.writeReferrersToSessionStorage();
Expand Down Expand Up @@ -3772,6 +3866,7 @@ function apbct_ready() {

handler.catchXmlHttpRequest();
handler.catchFetchRequest();
handler.catchIframeFetchRequest();
handler.catchJqueryAjax();
handler.catchWCRestRequestAsMiddleware();

Expand Down
Loading