diff --git a/CHANGELOG.md b/CHANGELOG.md index c32939c..3da921f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,19 @@ # Changelog -- Tested up to: WordPress 6.3.2 +- Tested up to: WordPress 6.4.2 + +## v1.2 + +### Feat + +- Use decrypted value of prepopulated fields containing a BSN number when hook 'owc_prefill_gravityforms_use_value_bsn_decrypted' is used and set to true. ## v1.1 ### Feat - Prefill all advanced date fields. -- Small clean-up/refactoring & run composer format script. +- Small clean-up/refactoring & run composer format script. ## v1.0.17 diff --git a/README.md b/README.md new file mode 100644 index 0000000..cf02aa4 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# BRP Prefill Gravity Forms + +This plug-in facilitates editors to configure form completion by establishing a link between form fields and BRP API data. When prefilling fields with a BSN number, the value is saved encrypted in the database, ensuring the security of stored data. Consequently, both the list and detail pages displaying form entries utilize encrypted values. The behavior can be adjusted using the 'owc_prefill_gravityforms_use_value_bsn_decrypted' filter by setting the return value to true. By using this filter the encrypted values are displayed decrypted. The value is always saved encrypted in the database! + +## Example + +``` +add_filter('owc_prefill_gravityforms_use_value_bsn_decrypted', '__return_true'); +``` diff --git a/prefill-gravity-forms.php b/prefill-gravity-forms.php index c6b30c0..bb2dfff 100644 --- a/prefill-gravity-forms.php +++ b/prefill-gravity-forms.php @@ -4,7 +4,7 @@ * Plugin Name: Yard | BRP Prefill GravityForms * Plugin URI: https://www.openwebconcept.nl/ * Description: Prefill GravityForms fields, based on the dutch BSN number. Retrieve personal information and place these values in the corrensponding fields. - * Version: 1.1 + * Version: 1.2 * Author: Yard | Digital Agency * Author URI: https://www.yard.nl/ * License: GPL-3.0 @@ -20,7 +20,7 @@ die; } -define('PG_VERSION', '1.1'); +define('PG_VERSION', '1.2'); define('PG_DIR', basename(__DIR__)); define('PG_ROOT_PATH', __DIR__); define('PG_PLUGIN_SLUG', 'prefill-gravity-forms'); diff --git a/src/PrefillGravityForms/Controllers/BaseController.php b/src/PrefillGravityForms/Controllers/BaseController.php index fc4ccc9..6827c06 100644 --- a/src/PrefillGravityForms/Controllers/BaseController.php +++ b/src/PrefillGravityForms/Controllers/BaseController.php @@ -3,14 +3,13 @@ namespace OWC\PrefillGravityForms\Controllers; use DateTime; -use GF_Field; use Exception; +use GF_Field; +use function OWC\PrefillGravityForms\Foundation\Helpers\view; use OWC\PrefillGravityForms\Foundation\TeamsLogger; use OWC\PrefillGravityForms\GravityForms\GravityFormsSettings; - +use function Yard\DigiD\Foundation\Helpers\decrypt; use function Yard\DigiD\Foundation\Helpers\resolve; -use function OWC\PrefillGravityForms\Foundation\Helpers\view; -use function OWC\PrefillGravityForms\Foundation\Helpers\decrypt; abstract class BaseController { @@ -59,7 +58,7 @@ protected function supplementBSN(string $bsn): string $requiredLength = 9; $difference = $requiredLength - $bsnLength; - if ($difference < 1 || $difference > $requiredLength) { + if (1 > $difference || $difference > $requiredLength) { return $bsn; } @@ -83,13 +82,13 @@ protected function preFillFields(array $form, array $response): array continue; } - if ($field->type === 'text') { + if ('text' === $field->type) { $this->handleFieldText($field, $foundValue); continue; } - if ($field->type === 'date') { + if ('date' === $field->type) { $this->handleFieldDate($field, $foundValue); continue; @@ -118,7 +117,7 @@ public function explodeDotNotationValue(string $dotNotationString, array $respon $holder = []; foreach ($exploded as $key => $item) { - if ($key === 0) { + if (0 === $key) { // Place the wanted part of the response in $holder. $holder = $response[$item] ?? ''; @@ -178,7 +177,7 @@ protected function handleFieldDate(GF_Field $field, string $foundValue): void } // Field consists of 1 part. - if (empty($field->inputs) || $field->dateType === 'datepicker') { + if (empty($field->inputs) || 'datepicker' === $field->dateType) { $field->defaultValue = $date->format('d-m-Y'); $field->displayOnly = true; $field->cssClass = 'owc_prefilled'; @@ -187,7 +186,7 @@ protected function handleFieldDate(GF_Field $field, string $foundValue): void } // Field consists of 3 parts which are represented by the input attribute. - if (! empty($field->inputs) && ($field->dateType === 'datefield' || $field->dateType === 'datedropdown')) { + if (! empty($field->inputs) && ('datefield' === $field->dateType || 'datedropdown' === $field->dateType)) { $field->inputs[0]['defaultValue'] = $date->format('m'); $field->inputs[1]['defaultValue'] = $date->format('d'); $field->inputs[2]['defaultValue'] = $date->format('Y'); @@ -226,7 +225,7 @@ protected function getCurlHeaders(string $doelBinding = ''): array { $headers = [ 'x-doelbinding: ' . $doelBinding, - 'x-origin-oin: ' . $this->settings->getNumberOIN() + 'x-origin-oin: ' . $this->settings->getNumberOIN(), ]; if (! empty($this->settings->getAPIKey())) { @@ -265,7 +264,7 @@ protected function handleCurl(array $args): array return $decoded; } catch (\Exception $e) { return [ - 'status' => $e->getMessage() + 'status' => $e->getMessage(), ]; } } diff --git a/src/PrefillGravityForms/Foundation/Cryptor.php b/src/PrefillGravityForms/Foundation/Cryptor.php deleted file mode 100644 index 3c30955..0000000 --- a/src/PrefillGravityForms/Foundation/Cryptor.php +++ /dev/null @@ -1,52 +0,0 @@ -key = openssl_digest($key, 'SHA256', true); - } else { - $this->key = $key; - } - if ($method) { - if (! in_array(strtolower($method), openssl_get_cipher_methods())) { - throw new \Exception(__METHOD__ . ": unrecognised cipher method: {$method}"); - } - $this->method = $method; - } - } - - protected function ivBytes() - { - return openssl_cipher_iv_length($this->method); - } - - public function encrypt($data) - { - $iv = openssl_random_pseudo_bytes($this->ivBytes()); - - return bin2hex($iv) . openssl_encrypt($data, $this->method, $this->key, 0, $iv); - } - - // decrypt encrypted string - public function decrypt($data) - { - $iv_strlen = 2 * $this->ivBytes(); - if (preg_match("/^(.{" . $iv_strlen . "})(.+)$/", $data, $regs)) { - list(, $iv, $crypted_string) = $regs; - if (ctype_xdigit($iv) && 0 == strlen($iv) % 2) { - return openssl_decrypt($crypted_string, $this->method, $this->key, 0, hex2bin($iv)); - } - } - - return false; // failed to decrypt - } -} diff --git a/src/PrefillGravityForms/Foundation/Helpers.php b/src/PrefillGravityForms/Foundation/Helpers.php index 4b2445a..7e72dd7 100644 --- a/src/PrefillGravityForms/Foundation/Helpers.php +++ b/src/PrefillGravityForms/Foundation/Helpers.php @@ -24,34 +24,6 @@ function resolve($container, $arguments = []) return \OWC\PrefillGravityForms\Foundation\Plugin::getInstance()->getContainer()->get($container, $arguments); } -/** - * Encrypt a string. - */ -function encrypt($string): string -{ - try { - $encrypted = resolve(\OWC\PrefillGravityForms\Foundation\Cryptor::class)->encrypt($string); - } catch(\Exception $e) { - $encrypted = ''; - } - - return $encrypted; -} - -/** - * Decrypt a string. - */ -function decrypt($string): string -{ - try { - $decrypted = resolve(\OWC\PrefillGravityForms\Foundation\Cryptor::class)->decrypt($string); - } catch(\Exception $e) { - $decrypted = ''; - } - - return $decrypted ?: ''; -} - function config(string $setting, $default = '') { return resolve('config')->get($setting, $default); diff --git a/src/PrefillGravityForms/GravityForms/GravityForms.php b/src/PrefillGravityForms/GravityForms/GravityForms.php index d48aef1..6b24c25 100644 --- a/src/PrefillGravityForms/GravityForms/GravityForms.php +++ b/src/PrefillGravityForms/GravityForms/GravityForms.php @@ -2,11 +2,16 @@ namespace OWC\PrefillGravityForms\GravityForms; +use GF_Field; +use GFAPI; use function OWC\PrefillGravityForms\Foundation\Helpers\get_supplier; +use function Yard\DigiD\Foundation\Helpers\decrypt; +use function Yard\DigiD\Foundation\Helpers\encrypt; class GravityForms { protected string $supplier; + protected bool $shouldDecrypt; public function preRender(array $form): array { @@ -55,4 +60,65 @@ protected function getController(): object return new $controller(); } + + /** + * For security reasons, when populating/prefilling a field with a BSN number, the value is encrypted and securely stored. + */ + public function saveFieldValue(string $value, $lead, GF_Field $field, array $form): string + { + if ('burgerservicenummer' !== ($field->linkedFieldValue ?? '')) { + return $value; + } + + if (empty($value) || ! is_string($value)) { + return $value; + } + + return encrypt($value); + } + + /** + * Decrypts the value for display on the Entry list page, only for prepopulated fields containing a BSN number. + */ + public function modifyEntryValue(string $value, int $formID, int $fieldID): string + { + $field = GFAPI::get_field($formID, $fieldID); + + if (empty($field->linkedFieldValue) || 'burgerservicenummer' !== ($field->linkedFieldValue ?? '')) { + return $value; + } + + $shouldDecrypt = apply_filters('owc_prefill_gravityforms_use_value_bsn_decrypted', false); + + if ($shouldDecrypt) { + $value = $this->decryptEncryptedBSN($value); + } + + return esc_html($value); + } + + /** + * Decrypts the value for display on the Entry detail page, only for prepopulated fields containing a BSN number. + */ + public function modifyEntryValueDetail($value, $field, $lead, $form): string + { + if (empty($field->linkedFieldValue) || 'burgerservicenummer' !== ($field->linkedFieldValue ?? '')) { + return $value; + } + + $shouldDecrypt = apply_filters('owc_prefill_gravityforms_use_value_bsn_decrypted', false); + + if ($shouldDecrypt) { + $value = $this->decryptEncryptedBSN($value); + } + + return esc_html($value); + } + + private function decryptEncryptedBSN(string $value): string + { + $decrypted = decrypt($value); + + return $decrypted && is_string($decrypted) ? $decrypted : $value; + } } diff --git a/src/PrefillGravityForms/GravityForms/GravityFormsServiceProvider.php b/src/PrefillGravityForms/GravityForms/GravityFormsServiceProvider.php index 8790019..952dc1f 100644 --- a/src/PrefillGravityForms/GravityForms/GravityFormsServiceProvider.php +++ b/src/PrefillGravityForms/GravityForms/GravityFormsServiceProvider.php @@ -20,11 +20,15 @@ protected function loadHooks(): void { $gravityFormsFieldSettings = new GravityFormsFieldSettings(); $gravityFormsFormSettings = new GravityFormsFormSettings(); + $gravityForms = new GravityForms(); - $this->plugin->loader->addFilter('gform_pre_render', new GravityForms(), 'preRender'); + $this->plugin->loader->addFilter('gform_pre_render', $gravityForms, 'preRender'); $this->plugin->loader->addAction('gform_field_standard_settings', $gravityFormsFieldSettings, 'addSelect', 10, 2); $this->plugin->loader->addAction('gform_editor_js', $gravityFormsFieldSettings, 'addSelectScript', 10, 0); $this->plugin->loader->addFilter('gform_form_settings_fields', $gravityFormsFormSettings, 'addFormSettings', 9999, 2); + $this->plugin->loader->addAction('gform_save_field_value', $gravityForms, 'saveFieldValue', 10, 4); + $this->plugin->loader->addFilter('gform_entries_field_value', $gravityForms, 'modifyEntryValue', 10, 3); + $this->plugin->loader->addFilter('gform_entry_field_value', $gravityForms, 'modifyEntryValueDetail', 10, 4); } private function registerSettingsAddon(): void