sagautam5/laravel-email-blocker

Rule Based email blocking on laravel application

Installs: 6

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/sagautam5/laravel-email-blocker

v1.0.0 2025-12-28 18:27 UTC

This package is auto-updated.

Last update: 2025-12-28 18:29:27 UTC


README

Build Latest Stable Version Total Downloads Issues Stars License Forks Twitter

🚀 Introduction

Laravel Email Blocker is a lightweight and extensible package that allows you to control, block, log, and analyze outgoing emails using configurable, rule-based logic.

It is especially useful for:

  • 🧪 Local, testing, and staging environments
  • 🏢 Multi-tenant or enterprise systems
  • 📜 Compliance-sensitive applications
  • 🚨 Preventing accidental emails to real users

The package integrates seamlessly with Laravel’s mail system and introduces minimal overhead.

📑 Table of Contents

✨ Features

  • 🚫 Rule-based email blocking
  • 🧩 Pluggable & extensible rule architecture
  • 📝 Persistent logging of blocked emails
  • 📊 Built-in insights & metrics
  • 🧪 Pest PHP–friendly test setup
  • ⚙️ Zero changes required to existing mail code

📋 Requirements

  • PHP 8.2 or higher
  • Laravel 11.x or higher

📦 Installation

Install via Composer:

composer require sagautam5/laravel-email-blocker

The package supports Laravel auto-discovery.

🔧 Configuration

Publish Configuration File

php artisan vendor:publish --provider="Sagautam5\EmailBlocker\EmailBlockerServiceProvider --tag="config"

This will create:

config/email-blocker.php

Default Configuration

<?php

use Sagautam5\EmailBlocker\Rules\BlockByDomainRule;
use Sagautam5\EmailBlocker\Rules\BlockByEmailRule;
use Sagautam5\EmailBlocker\Rules\BlockByEnvironmentRule;
use Sagautam5\EmailBlocker\Rules\BlockByGlobalRule;
use Sagautam5\EmailBlocker\Rules\BlockByMailableRule;
use Sagautam5\EmailBlocker\Rules\BlockByTimeWindowRule;

return [

    // Master switch for the package
    'block_enabled' => env('EMAIL_BLOCK_ENABLED', true),

    // Enable database logging of blocked emails
    'log_enabled' => env('EMAIL_BLOCK_LOG_ENABLED', false),

    // Database table for logs
    'log_table' => 'blocked_emails',

    // Applied rules (executed in order)
    'rules' => [
        BlockByGlobalRule::class,
        BlockByEnvironmentRule::class,
        BlockByDomainRule::class,
        BlockByMailableRule::class,
        BlockByTimeWindowRule::class,
        BlockByEmailRule::class,

        // App\Rules\CustomEmailBlockRule::class,
    ],

    // Rule-specific settings
    'settings' => [

        'global_block' => env('GLOBAL_EMAIL_BLOCK_ENABLED', false),

        'blocked_environments' => [
            // 'local',
            // 'staging',
        ],

        'blocked_domains' => [
            // 'example.com',
        ],

        'blocked_mailables' => [
            // App\Mail\WelcomeMail::class,
        ],

        'blocked_emails' => [
            // 'user@example.com',
        ],

        'time_window' => [
            'from' => null, // '09:00'
            'to' => null,   // '18:00'
            'timezone' => null, // 'Asia/Kathmandu'
        ],
    ],
];

Validate Configuration

After executing vendor:publish to publish configuration file, you can adjust things as well as add new rules. To validate that your configuration is valid, you can just run following console command:

php artisan email-blocker:validate

If correct then,

✔ Email Blocker configuration is valid.

otherwise, you could see something like this in console:

✖ Email Blocker configuration is invalid.

email-blocker: 'settings.blocked_environments' must be an array of strings.

🧪 Usage Guide

Disable Email Blocking Completely

To disable email blocking entirely, set the following environment variable to false in your .env file:

EMAIL_BLOCK_ENABLED=false

This disables all rules and logging. By default, email block is enabled.

Disable Specific Rules

Simply remove the rule class from the rules array in config/email-blocker.php.

🧱 Built-in Blocking Rules

1️⃣ Global Block

Blocks all outgoing emails.

GLOBAL_EMAIL_BLOCK_ENABLED=true

or

'global_block' => true,

By default, it's not enabled.

2️⃣ Environment Block

Blocks emails in selected environments.

'blocked_environments' => [
    'local',
    'testing',
],

By default, emails are not blocked in any environments.

3️⃣ Domain Block

Blocks emails sent to specific domains.

'blocked_domains' => [
    'example.com',
],

By default, emails are not blocked in any domains

4️⃣ Mailable Block

Blocks email sent via specific Mailable classes.

'blocked_mailables' => [
    'App\Mail\WelcomeMail',
],

By default, emails sent via all mailable classes are not blocked.

5️⃣ Time Window Block

Blocks email addresses during a defined time range.

'time_window' => [
    'from' => '09:00',
    'to' => '18:00',
    'timezone' => 'Asia/Kathmandu',
],
  • Uses 24-hour format
  • Timezone-aware ( By default, config('app.timezone') value is used)

6️⃣ Email Block

Blocks specific recipient email addresses.

'blocked_emails' => [
    'user@ample.com',
],

By default, no email addresses are blocked.

📊 Insights & Metrics

When logging is enabled, the package provides ready-to-use metrics to analyze email blocking behavior.

Available Metrics

Metric Class Description
CountBlockedEmailsMetric Total number of blocked emails
BlockedByRuleMetric Emails blocked per rule
BlockedByMailableMetric Emails blocked per mailable
BlockedOverTimeMetric Blocking trends over time
ReceiverTypeDistributionMetric Distribution by receiver type
TopBlockedRecipientMetric Most frequently blocked recipients
TopBlockedSenderMetric Senders triggering most blocks
TopMailableRulePairsMetric Most common mailable–rule combinations

Common Filters

Most metrics support:

[
    'start_date' => '2025-12-01',
    'end_date' => '2025-12-24',
    'limit' => 5,
]

Example Usage

use Sagautam5\EmailBlocker\Insights\Metrics\BlockedByMailableMetric;

$metric = new BlockedByMailableMetric();

$result = $metric->calculate([
    'start_date' => '2025-12-01',
    'end_date' => '2025-12-24',
    'limit' => 5,
]);

Example Output

[
    [
        'mailable' => 'App\Mail\WelcomeMail',
        'total' => 10,
    ],
    [
        'mailable' => 'App\Mail\OrderConfirmationMail',
        'total' => 9,
    ],
]

🧩 Customization

You can create custom blocking rules or custom metrics by extending the provided base classes:

  • BaseRule

  • BaseMetric

This allows deep customization without modifying the core package.

Example Custom Rule

namespace App\Custom\Rules;

use Closure;
use App\Models\BlackList;
use Sagautam5\EmailBlocker\Abstracts\BaseRule;

class BlockEmailsInBlackListRule extends BaseRule
{
    /**
     * @param  array<string>  $emails
     * @return Closure|array<string>
     */
    public function handle(array $emails, Closure $next): Closure|array
    {
        $blockedEmails = BlackList::whereIn('emails', $emails)->pluck('emails')->toArray();
        
        if (!empty($blockedEmails)) {
            $this->handleLog($blockedEmails);

            return [];
        }

        return $next($emails);
    }

    public function getReason(): string
    {
        return 'Email is present on black list.';
    }
}

To enable this block rule, we need to add this into rules array inside config file

use App\Custom\Rules\BlockEmailsInBlackListRule;

'rules' => [
    // Other Builtin Rules

    BlockEmailsInBlackListRule::class,
],

After this, all emails will be checked by this rule.

Example Custom Metric

namespace App\Insights\Metrics;

use Illuminate\Database\Eloquent\Builder;
use Sagautam5\EmailBlocker\Abstracts\BaseMetric;
use Sagautam5\EmailBlocker\Models\BlockedEmail;
use Sagautam5\EmailBlocker\Enums\ReceiverType;

class TotalBlockedPrimaryEmails extends BaseMetric
{
    public function getName(): string
    {
        return 'Total Blocked Primary Emails';
    }

    /**
     * @param  array<string>  $filters
     * @return array<mixed>
     */
    public function calculate(array $filters = []): array
    {
        /**
         * @var Builder<BlockedEmail> $query
         */
        $query = BlockedEmail::query()->where('receiver_type', ReceiverType::CC);

        $query = $this->applyDateFilters($query, $filters);

        return [
            'count' => $query->count(),
        ];
    }
}
Usage
use App\Insights\Metrics\TotalBlockedPrimaryEmails;

$metric = new TotalBlockedPrimaryEmails();

$totalBlocked = $metric->calculate([
    'start_date' => '2025-06-01',
    'end_date' => '2025-12-31'
]);
Output
[ 
    'count' => 10
];

Testing

composer test

🔐 Security

Please review our security policy on how to report security vulnerabilities.

🤝 Contributing

Please see CONTRIBUTING for details.

⚖️ Code of Conduct

In order to ensure that the this community is welcoming to all, please review and abide by the Code of Conduct.

👥 Credits

⭐ Support

If this package helps you:

  • ⭐ Star the repository
  • 🐛 Report issues
  • 💡 Suggest improvements

Your support is appreciated !

📄 License

This package is open-sourced software licensed under the MIT license.

See the full license here: LICENSE