[SOLVED] Encrypt data on persistence (v12.4)

Hi everybody,

I extended the fe_user-model with some custom properties and want to encrypt the data (string) on persistence. Of course, the data should be decrypted on retrieval. I think a custom type converter is an option. I just can’t find how to apply the converter to my custom properties.

Or should this be done by hydrating / thawing? And how?

Thanks for any help, hint or (even better) example,
Arndt

With suggest a TypeConverter you will get all data - you might want to extend the defaut PersistentObjectConverter instead.
Alternatively, the AfterObjectThawedEvent could be a good choice - you can most likely touch only the single properties needed :ok_hand:

Working with encrypted data in the backend
If working from the backend with similar data, I have a field myself that I encrypt via a formevals like this

#ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals'][ApiCredential::class] = '';
#ApiCredential.php
final class ApiCredential
{
    public const OBFUSCATED_VALUE = '********';


    public function evaluateFieldValue(string $value): string
    {
        if ($value === self::OBFUSCATED_VALUE) {
            return $value;
        }

        return Credentials::encrypt($value);
    }

    /**
     * @param array{value: string} $parameters
     */
    public function deevaluateFieldValue(array $parameters): string
    {
        if ($parameters['value'] === '') {
            return '';
        }

        return self::OBFUSCATED_VALUE;
    }
}
# Configuration/TCA/<table>.php
        'api_secret' => [
            'label' => 'LLL:EXT:extension/Resources/Private/Language/TCA/table.xlf:columns.api_secret.label',
            'config' => [
                'type' => 'input',
                'required' => true,
                'eval' => ApiCredential::class
            ]
        ]

Thank you for hinting to the AfterObjectThawedEvent. This would make decrypting the data very easy. However, it seems, that a listener to this event can see but not manipulate the data.
I am not sure if this is a bug or intended, but the eventDispatcher doesn’t return any data:

I don’t need to obfuscate the data in the backend.

The event has a getRecord method - that allows you to retrieve and manipulate the record using it’s set* method.

Like

$encryptedValue = Encryptor::encrypt($event->getRecord()->getSecret());
$event->getRecord()->setSecret($encryptedValue)

Yes, you are right. Except that it is the getObject-method:

$user = $event->getObject();
if (method_exists($user, 'getSensitiveProp')) {
	$encryptedProp = $this->encryptionService->encrypt($user->getSensitiveProp());
	$user->setSensitiveProp($encryptedProp);
}

$event->getRecord() returns an array.

But how would I encrypt the sensitiveProp on persistence? Maybe with the event EntityAddedToPersistenceEvent?

Yep, I would go for them if your situation is receiving data:

TYPO3\CMS\Extbase\Event\Persistence\EntityAddedToPersistenceEvent
TYPO3\CMS\Extbase\Event\Persistence\EntityUpdatedInPersistenceEvent