58 lines
1.4 KiB
PHP
58 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace App\Casts;
|
|
|
|
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
|
use Illuminate\Support\Facades\Crypt;
|
|
|
|
/**
|
|
* Encrypts a value using AES-256-CBC when writing to the database,
|
|
* and decrypts it when reading. Uses Laravel's APP_KEY cipher.
|
|
*
|
|
* Used for: phone_number, national_id, and any PII.
|
|
* NEVER log or expose encrypted fields.
|
|
*/
|
|
class Encryptable implements CastsAttributes
|
|
{
|
|
private const ALLOWED_HASH_CONTEXTS = ['search'];
|
|
|
|
/**
|
|
* @param \Illuminate\Database\Eloquent\Model $model
|
|
* @param string $key
|
|
* @param mixed $value
|
|
* @param array $attributes
|
|
* @return string|null
|
|
*/
|
|
public function get($model, $key, $value, $attributes)
|
|
{
|
|
if (is_null($value)) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return Crypt::decryptString($value);
|
|
} catch (\Throwable $e) {
|
|
report($e);
|
|
|
|
// If decryption fails, return masked value to prevent crash
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param \Illuminate\Database\Eloquent\Model $model
|
|
* @param string $key
|
|
* @param mixed $value
|
|
* @param array $attributes
|
|
* @return string|null
|
|
*/
|
|
public function set($model, $key, $value, $attributes)
|
|
{
|
|
if (is_null($value)) {
|
|
return null;
|
|
}
|
|
|
|
return Crypt::encryptString($value);
|
|
}
|
|
}
|