ifabula/sevola-interceptor-helper

Laravel database interceptor for automatic field encryption/decryption using Sevola SDK

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Forks: 0

pkg:composer/ifabula/sevola-interceptor-helper

v0.1.0 2025-11-09 01:37 UTC

This package is not auto-updated.

Last update: 2025-11-10 09:49:53 UTC


README

Laravel database interceptor for automatic field encryption/decryption using Sevola SDK.

Features

  • 🔐 Automatic encryption/decryption of database fields
  • 🎯 Configuration-driven (database table defines what to encrypt)
  • 🚀 Easy integration with Laravel Eloquent models
  • ⚡ Caching for performance
  • 🔍 Support for FF1 format-preserving encryption
  • 📝 Comprehensive logging for debugging

Installation

1. Install via Composer

composer require ifabula/sevola-interceptor-helper

2. Install Sevola SDK

composer require ifabula/sevola-sdk-php

3. Publish Configuration (Optional)

php artisan vendor:publish --tag=sevola-config

This creates config/sevola.php in your Laravel project.

4. Configure Environment Variables

Add to your .env file:

SEVOLA_API_KEY=your-api-key-here
SEVOLA_BASE_URL=http://localhost:8082
SEVOLA_CONFIG_DATABASE=amplio_encrypt_dev
SEVOLA_CONFIG_TABLE=mst_encryption_config
SEVOLA_LOGGING=true
SEVOLA_DEBUG=false

5. Register Service Provider (Laravel 10 and below)

For Laravel 11+, the service provider is auto-discovered. For older versions, add to config/app.php:

'providers' => [
    // ...
    Ifabula\SevolaInterceptor\SevolaServiceProvider::class,
],

Usage

Method 1: Using the HasEncryption Trait (Recommended)

Add the trait to your Eloquent models:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Ifabula\SevolaInterceptor\Traits\HasEncryption;

class User extends Model
{
    use HasEncryption;

    protected $table = 'mst_user_cms';
    
    protected $fillable = [
        'name',
        'email',
        'ROLE_NAME',
        'MERCHANT_CODE',
    ];
}

That's it! Now when you save or retrieve users:

// Encryption happens automatically on save
$user = new User();
$user->name = 'John Doe';
$user->ROLE_NAME = 'Admin';  // This will be encrypted based on config
$user->MERCHANT_CODE = '12345';  // This will be encrypted based on config
$user->save();

// Decryption happens automatically on retrieval
$user = User::find(1);
echo $user->ROLE_NAME;  // Automatically decrypted
echo $user->MERCHANT_CODE;  // Automatically decrypted

Method 2: Manual Encryption/Decryption

If you need more control, use the services directly:

use Ifabula\SevolaInterceptor\Services\ConfigService;
use Ifabula\SevolaInterceptor\Services\EncryptionService;

// Get the services
$configService = app(ConfigService::class);
$encryptionService = app(EncryptionService::class);

// Check if encryption is configured for a table
if ($configService->hasEncryption('amplio_encrypt_dev', 'mst_user_cms')) {
    // Get the config
    $config = $configService->getConfig('amplio_encrypt_dev', 'mst_user_cms');
    
    // Encrypt data
    $data = [
        'name' => 'John Doe',
        'ROLE_NAME' => 'Admin',
        'MERCHANT_CODE' => '12345',
    ];
    
    $encrypted = $encryptionService->encryptData($data, $config);
    
    // Decrypt data
    $decrypted = $encryptionService->decryptData($encrypted, $config);
}

Configuration Table Schema

The interceptor reads configuration from a database table with this structure:

CREATE TABLE mst_encryption_config (
    id INT PRIMARY KEY AUTO_INCREMENT,
    config_name VARCHAR(255),
    database_name VARCHAR(255),
    table_name VARCHAR(255),
    encrypted_columns JSON,  -- Example: ["ROLE_NAME", "MERCHANT_CODE"]
    status VARCHAR(50),  -- 'ACTIVE' or 'INACTIVE'
    encryption_algorithm VARCHAR(50),  -- 'FF1', 'AES-GCM', etc.
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);

Example configuration:

{
    "id": 1,
    "config_name": "User CMS Encryption",
    "database_name": "amplio_encrypt_dev",
    "table_name": "mst_user_cms",
    "encrypted_columns": "[\"ROLE_NAME\",\"MERCHANT_CODE\"]",
    "status": "ACTIVE",
    "encryption_algorithm": "FF1"
}

How It Works

For INSERT/UPDATE (Encryption)

  1. When you save a model with HasEncryption trait, it triggers the saving event
  2. The interceptor checks the config table to see if the table has encryption configured
  3. If configured and active, it encrypts the specified columns using Sevola SDK
  4. The encrypted data is then saved to the database

For SELECT (Decryption)

  1. When you retrieve a model with HasEncryption trait, it triggers the retrieved event
  2. The interceptor checks the config table to see if the table has encryption configured
  3. If configured and active, it decrypts the specified columns using Sevola SDK
  4. The decrypted data is returned to your application

Caching

  • Configuration is cached for 5 minutes (configurable via SEVOLA_CACHE_TTL)
  • This prevents excessive database queries to the config table
  • Cache is automatically cleared when you update the config

Advanced Usage

Clear Configuration Cache

use Ifabula\SevolaInterceptor\Services\ConfigService;

$configService = app(ConfigService::class);

// Clear cache for specific table
$configService->clearCache('amplio_encrypt_dev', 'mst_user_cms');

// Clear all config cache
$configService->clearCache();

Get All Active Configs

use Ifabula\SevolaInterceptor\Services\ConfigService;

$configService = app(ConfigService::class);
$configs = $configService->getAllActiveConfigs();

foreach ($configs as $config) {
    echo "Table: {$config->tableName}, Columns: " . implode(', ', $config->encryptedColumns);
}

Query Builder (Without Eloquent)

For raw queries or query builder, you'll need to handle encryption manually:

use Illuminate\Support\Facades\DB;
use Ifabula\SevolaInterceptor\Services\ConfigService;
use Ifabula\SevolaInterceptor\Services\EncryptionService;

$configService = app(ConfigService::class);
$encryptionService = app(EncryptionService::class);

$config = $configService->getConfig('amplio_encrypt_dev', 'mst_user_cms');

if ($config) {
    // Encrypt before insert
    $data = ['ROLE_NAME' => 'Admin', 'MERCHANT_CODE' => '12345'];
    $encrypted = $encryptionService->encryptData($data, $config);
    
    DB::table('mst_user_cms')->insert($encrypted);
    
    // Decrypt after select
    $rows = DB::table('mst_user_cms')->get();
    foreach ($rows as $row) {
        $decrypted = $encryptionService->decryptData((array)$row, $config);
        // Use $decrypted...
    }
}

Troubleshooting

Encryption Not Working

  1. Check if SEVOLA_API_KEY is set in .env
  2. Verify the config table has an ACTIVE entry for your database and table
  3. Enable logging: SEVOLA_LOGGING=true and SEVOLA_DEBUG=true
  4. Check Laravel logs: tail -f storage/logs/laravel.log

Performance Issues

  1. Increase cache TTL: SEVOLA_CACHE_TTL=600 (10 minutes)
  2. Ensure your config table is indexed on database_name and table_name
  3. Use Redis for caching instead of file cache

Column Not Being Encrypted

  1. Verify the column name matches exactly (case-sensitive) in the config table
  2. Check that the config status is 'ACTIVE'
  3. Ensure the model uses the HasEncryption trait

Requirements

  • PHP 8.2 or higher
  • Laravel 11.0 or higher (or Laravel 12.0)
  • Sevola SDK PHP
  • Database with encryption config table

License

MIT License

Support

For issues and questions, please open an issue on GitLab.