Skip to content

Commit

Permalink
fixes (#421)
Browse files Browse the repository at this point in the history
  • Loading branch information
iruzevic authored May 16, 2024
1 parent 0ad6a7f commit 36d31ab
Show file tree
Hide file tree
Showing 14 changed files with 93 additions and 41 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.

This projects adheres to [Semantic Versioning](https://semver.org/) and [Keep a CHANGELOG](https://keepachangelog.com/).

## [3.1.10]

### Fixed
- Airtable integration now supports multiple select fields.
- Moments form validation of input fields limiting the number of characters to 1000.
- Calculator will no longer break reCaptcha validation.
- Single submit with global msg disabled will no longer output the empty success message.
- Single submit now supports input type number.

### Added
- Security feature now supports calculator rate limiting separate setting.

## [3.1.9]

### Removed
Expand Down Expand Up @@ -356,6 +368,7 @@ This projects adheres to [Semantic Versioning](https://semver.org/) and [Keep a

- Initial production release.

[3.1.10]: https://github.com/infinum/eightshift-forms/compare/3.1.9...3.1.10
[3.1.9]: https://github.com/infinum/eightshift-forms/compare/3.1.8...3.1.9
[3.1.8]: https://github.com/infinum/eightshift-forms/compare/3.1.7...3.1.8
[3.1.7]: https://github.com/infinum/eightshift-forms/compare/3.1.6...3.1.7
Expand Down
34 changes: 17 additions & 17 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion eightshift-forms.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Description: Eightshift Forms is a complete form builder plugin that utilizes modern Block editor features with multiple third-party integrations, bringing your project to a new level.
* Author: WordPress team @Infinum
* Author URI: https://eightshift.com/
* Version: 3.1.9
* Version: 3.1.10
* Text Domain: eightshift-forms
*
* @package EightshiftForms
Expand Down
2 changes: 1 addition & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ parameters:
# Block templates
- '#^Variable \$attributes might not be defined\.#'
- '#^Variable \$innerBlockContent might not be defined\.#'
checkGenericClassInNonGenericObjectType: false
- identifier: missingType.generics
4 changes: 2 additions & 2 deletions src/Blocks/components/form/assets/captcha.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class Captcha {
}

if (this.state.getStateCaptchaIsEnterprise()) {
grecaptcha?.enterprise.ready(async () => {
grecaptcha?.enterprise?.ready(async () => {
try {
const token = await grecaptcha?.enterprise?.execute(siteKey, {action: actionName});

Expand Down Expand Up @@ -128,7 +128,7 @@ export class Captcha {
return;
}

document.querySelector('body').setAttribute(this.state.getStateAttribute('hideCaptchaBadge'), this.state.getStateCaptchaHideBadge());
document?.body?.setAttribute(this.state.getStateAttribute('hideCaptchaBadge'), this.state.getStateCaptchaHideBadge());
}

////////////////////////////////////////////////////////////////
Expand Down
4 changes: 3 additions & 1 deletion src/Blocks/components/form/assets/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,8 @@ export class Form {

if (
(this.state.getStateConfigIsAdmin() && this.state.getStateElementIsSingleSubmit(name, formId)) ||
(this.state.getStateFormConfigUseSingleSubmit(formId) && (this.state.getStateElementTypeCustom(name, formId) === 'range'))
(this.state.getStateFormConfigUseSingleSubmit(formId) && (this.state.getStateElementTypeCustom(name, formId) === 'range')) ||
(this.state.getStateFormConfigUseSingleSubmit(formId) && (this.state.getStateElementTypeCustom(name, formId) === 'number'))
) {
input.addEventListener('input', debounce(this.onInputEvent, 300));
} else {
Expand Down Expand Up @@ -1705,6 +1706,7 @@ export class Form {
!this.state.getStateConfigIsAdmin() &&
this.state.getStateFormConfigUseSingleSubmit(formId) && (
this.state.getStateElementTypeCustom(name, formId) === 'range' ||
this.state.getStateElementTypeCustom(name, formId) === 'number' ||
this.state.getStateElementTypeCustom(name, formId) === 'checkbox' ||
this.state.getStateElementTypeCustom(name, formId) === 'radio'
)
Expand Down
9 changes: 6 additions & 3 deletions src/Blocks/components/form/assets/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,15 @@ export class Utils {
return;
}

messageContainer?.classList?.add(this.state.getStateSelector('isActive'));
messageContainer.dataset.status = status;

// Scroll to msg if the condition is matched.
if (status === 'success') {
if (this.state.getStateFormGlobalMsgHideOnSuccess(formId)) {
return;
}

messageContainer?.classList?.add(this.state.getStateSelector('isActive'));
messageContainer.dataset.status = status;

if (!this.state.getStateSettingsDisableScrollToGlobalMsgOnSuccess(formId)) {
this.scrollToGlobalMsg(formId);
}
Expand All @@ -293,6 +293,9 @@ export class Utils {
messageContainer.innerHTML = `<div><span>${msg}</span></div>`;
}
} else {
messageContainer?.classList?.add(this.state.getStateSelector('isActive'));
messageContainer.dataset.status = status;

const headingError = this.state.getStateFormGlobalMsgHeadingError(formId);

if (headingError) {
Expand Down
2 changes: 1 addition & 1 deletion src/Integrations/Airtable/AirtableClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ private function prepareParams(array $params, string $formId): array
break;
case 'dynamicSelect':
if (!\is_array($value)) {
$value = [$value];
$value = \explode(UtilsConfig::DELIMITER, $value);
}
break;
default:
Expand Down
6 changes: 3 additions & 3 deletions src/Integrations/Hubspot/HubspotClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,9 @@ public function postApplication(string $itemId, array $params, array $files, str
$body = [
'context' => [
'ipAddress' => $this->security->getIpAddress(),
'hutk' => $params[UtilsHelper::getStateParam('hubspotCookie')]['value'],
'pageUri' => UtilsGeneralHelper::cleanPageUrl($params[UtilsHelper::getStateParam('hubspotPageUrl')]['value']),
'pageName' => $params[UtilsHelper::getStateParam('hubspotPageName')]['value'],
'hutk' => $params[UtilsHelper::getStateParam('hubspotCookie')]['value'] ?? '',
'pageUri' => UtilsGeneralHelper::cleanPageUrl($params[UtilsHelper::getStateParam('hubspotPageUrl')]['value'] ?? ''),
'pageName' => $params[UtilsHelper::getStateParam('hubspotPageName')]['value'] ?? '',
],
];

Expand Down
4 changes: 3 additions & 1 deletion src/Integrations/Moments/MomentsClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -429,12 +429,14 @@ private function prepareParams(array $params, string $formId): array
switch ($type) {
case 'select':
$explode = \explode(UtilsConfig::DELIMITER, $value);

$value = \count($explode) > 1 ? $explode : $value;
break;
case 'checkbox':
$value = \explode(UtilsConfig::DELIMITER, $value);
break;
case 'input':
$value = \substr($value, 0, 1000);
break;
case 'phone':
$value = \filter_var($value, \FILTER_SANITIZE_NUMBER_INT);
$value = \ltrim($value, '0');
Expand Down
7 changes: 4 additions & 3 deletions src/Rest/Routes/AbstractFormSubmit.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use EightshiftForms\Captcha\CaptchaInterface; // phpcs:ignore SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse
use EightshiftForms\Entries\EntriesHelper;
use EightshiftForms\Entries\SettingsEntries;
use EightshiftForms\Integrations\Calculator\SettingsCalculator;
use EightshiftForms\Labels\LabelsInterface; // phpcs:ignore SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse
use EightshiftFormsVendor\EightshiftFormsUtils\Helpers\UtilsApiHelper;
use EightshiftForms\Rest\Routes\Integrations\Mailer\FormSubmitMailerInterface; // phpcs:ignore SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse
Expand Down Expand Up @@ -204,7 +205,7 @@ public function routeCallback(WP_REST_Request $request)

// Validate allowed number of requests.
// We don't want to limit any custom requests like files, settings, steps, etc.
if (!$this->getSecurity()->isRequestValid()) {
if (!$this->getSecurity()->isRequestValid($formDetails[UtilsConfig::FD_TYPE])) {
throw new UnverifiedRequestException(
$this->getValidatorLabels()->getLabel('validationSecurity'),
[
Expand All @@ -230,7 +231,7 @@ public function routeCallback(WP_REST_Request $request)
}

// Validate captcha.
if (\apply_filters(SettingsCaptcha::FILTER_SETTINGS_GLOBAL_IS_VALID_NAME, false)) {
if (\apply_filters(SettingsCaptcha::FILTER_SETTINGS_GLOBAL_IS_VALID_NAME, false) && $formDetails[UtilsConfig::FD_TYPE] !== SettingsCalculator::SETTINGS_TYPE_KEY) {
$captchaParams = $formDetails[UtilsConfig::FD_CAPTCHA] ?? [];

if (!$captchaParams) {
Expand Down Expand Up @@ -299,11 +300,11 @@ public function routeCallback(WP_REST_Request $request)
[
'exception' => $e,
'request' => $request,
'formDetails' => $formDetails,
self::VALIDATION_ERROR_CODE => \esc_html($e->getData()[self::VALIDATION_ERROR_CODE] ?? ''),
self::VALIDATION_ERROR_MSG => \esc_html($e->getMessage()),
self::VALIDATION_ERROR_OUTPUT => $e->getData()[self::VALIDATION_ERROR_OUTPUT] ?? '',
self::VALIDATION_ERROR_DATA => $e->getData()[self::VALIDATION_ERROR_DATA] ?? '',
'formDetails' => $formDetails,
]
)
);
Expand Down
20 changes: 15 additions & 5 deletions src/Security/Security.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace EightshiftForms\Security;

use EightshiftForms\Integrations\Calculator\SettingsCalculator;
use EightshiftForms\Misc\SettingsCloudflare;
use EightshiftFormsVendor\EightshiftFormsUtils\Helpers\UtilsSettingsHelper;
use EightshiftFormsVendor\EightshiftLibs\Helpers\Components;
Expand All @@ -36,18 +37,19 @@ class Security implements SecurityInterface
/**
* Detect if the request is valid using rate limiting.
*
* @param string $formType Form type.
*
* @return boolean
*/
public function isRequestValid(): bool
public function isRequestValid(string $formType): bool
{
// Bailout if this feature is not enabled.
if (!\apply_filters(SettingsSecurity::FILTER_SETTINGS_IS_VALID_NAME, [])) {
return true;
}

$key = SettingsSecurity::SETTINGS_SECURITY_DATA_KEY;
$keyName = UtilsSettingsHelper::getOptionName($key);
$data = UtilsSettingsHelper::getOptionValueGroup($key);
$keyName = UtilsSettingsHelper::getOptionName(SettingsSecurity::SETTINGS_SECURITY_DATA_KEY);
$data = UtilsSettingsHelper::getOptionValueGroup(SettingsSecurity::SETTINGS_SECURITY_DATA_KEY);
$ip = $this->getIpAddress();
$time = \time();

Expand Down Expand Up @@ -85,7 +87,15 @@ public function isRequestValid(): bool
}

// Check if the request count exceeds the rate limit.
if ($count >= \intval(UtilsSettingsHelper::getOptionValueWithFallback(SettingsSecurity::SETTINGS_SECURITY_RATE_LIMIT_KEY, (string) self::RATE_LIMIT))) {
$rateLimitGeneral = UtilsSettingsHelper::getOptionValueWithFallback(SettingsSecurity::SETTINGS_SECURITY_RATE_LIMIT_KEY, (string) self::RATE_LIMIT);
$rateLimitCalculator = UtilsSettingsHelper::getOptionValue(SettingsSecurity::SETTINGS_SECURITY_RATE_LIMIT_CALCULATOR_KEY);

// Different rate limit for calculator.
if ($rateLimitCalculator && $formType === SettingsCalculator::SETTINGS_TYPE_KEY) {
$rateLimitGeneral = $rateLimitCalculator;
}

if ($count >= \intval($rateLimitGeneral)) {
return false;
}

Expand Down
4 changes: 3 additions & 1 deletion src/Security/SecurityInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ interface SecurityInterface
/**
* Detect if the request is valid using rate limiting.
*
* @param string $formType Form type.
*
* @return boolean
*/
public function isRequestValid(): bool;
public function isRequestValid(string $formType): bool;

/**
* Get users Ip address.
Expand Down
23 changes: 21 additions & 2 deletions src/Security/SettingsSecurity.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ class SettingsSecurity implements UtilsSettingGlobalInterface, ServiceInterface
*/
public const SETTINGS_SECURITY_RATE_LIMIT_KEY = 'security-rate-limit';

/**
* Rate limit calculator key.
*/
public const SETTINGS_SECURITY_RATE_LIMIT_CALCULATOR_KEY = 'security-rate-limit-calculator';

/**
* Rate limit window key.
*/
Expand Down Expand Up @@ -118,8 +123,8 @@ public function getSettingsGlobalData(): array
[
'component' => 'input',
'inputName' => UtilsSettingsHelper::getOptionName(self::SETTINGS_SECURITY_RATE_LIMIT_KEY),
'inputFieldLabel' => \__('Number of requests', 'eightshift-forms'),
'inputFieldHelp' => \__('Define the maximum number of requests a user can make in the given time period.', 'eightshift-forms'),
'inputFieldLabel' => \__('Number of requests general', 'eightshift-forms'),
'inputFieldHelp' => \__('Define the maximum number of requests a user can make in the given time period for all forms.', 'eightshift-forms'),
'inputType' => 'number',
'inputMin' => 1,
'inputMax' => 300,
Expand All @@ -129,6 +134,20 @@ public function getSettingsGlobalData(): array
'inputFieldInlineBeforeAfterContent' => true,
'inputValue' => UtilsSettingsHelper::getOptionValue(self::SETTINGS_SECURITY_RATE_LIMIT_KEY),
],
[
'component' => 'input',
'inputName' => UtilsSettingsHelper::getOptionName(self::SETTINGS_SECURITY_RATE_LIMIT_CALCULATOR_KEY),
'inputFieldLabel' => \__('Number of requests for calculator', 'eightshift-forms'),
'inputFieldHelp' => \__('Define the maximum number of requests a user can make in the given time period for calculator forms with single submit.', 'eightshift-forms'),
'inputType' => 'number',
'inputMin' => 1,
'inputMax' => 300,
'inputStep' => 1,
'inputPlaceholder' => Security::RATE_LIMIT,
'inputFieldAfterContent' => \__('per min', 'eightshift-forms'),
'inputFieldInlineBeforeAfterContent' => true,
'inputValue' => UtilsSettingsHelper::getOptionValue(self::SETTINGS_SECURITY_RATE_LIMIT_CALCULATOR_KEY),
],
[
'component' => 'input',
'inputName' => UtilsSettingsHelper::getOptionName(self::SETTINGS_SECURITY_RATE_LIMIT_WINDOW_KEY),
Expand Down

0 comments on commit 36d31ab

Please sign in to comment.