Skip to content

Commit

Permalink
Merge pull request #2 from veeqtoh/Document-app-for-initial-release
Browse files Browse the repository at this point in the history
Document package for initial release
  • Loading branch information
veeqtoh authored Jun 15, 2024
2 parents c5b2052 + c7788f9 commit 64f94a4
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Changelog
154 changes: 153 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,154 @@
# laravel-active-email
Disposable email address validator rule for Laravel apps

## Table of Contents

- [Overview](#overview)
- [Key Features](#key-features)
- [Installation](#installation)
- [Requirements](#requirements)
- [Install the Package](#install-the-package)
- [Publish the Config](#publish-the-config)
- [Usage](#usage)
- [Validator Approach](#validator-approach)
- [Class Approach](#class-approach)
- [Customization](#customization)
- [Strict Mode](#strict-mode)
- [Black List](#black-list)
- [Grey List](#grey-list)
- [White List](#white-list)
- [Testing](#testing)
- [To do](#to-do)
- [Security](#security)
- [Contribution](#contribution)
- [Changelog](#changelog)
- [Upgrading](#upgrading)
- [License](#license)

## Overview

This package provides a library of disposable domains and adds a validator to Laravel apps to check that a given email address isn't coming from a disposable email service such as `Mailinator`, `Guerillamail`, `Fastmail` considering all their possible wildcards.

### Key Features

- You can add your own preferred domains to the [black list](#black-list).
- You can [white list](#white-list) a domain to bye pass the blacklist. This can be useful in development environment.
- With [strict mode](#strict-mode), you can control the strictness of the validator, thereby allowing or preventing domains that are not necessarily disposable, but have been classified as disposable.
- Case-aware.
- Wildcard-aware.

## Installation


### Requirements

The package has been developed and tested to work with the following minimum requirements:

- PHP 8.x
- Laravel 10.x, 11.x

### Install the Package

You can install the package via Composer. The service provider is discovered automatically.

```bash
composer require veeqtoh/laravel-active-email
```

### Publish the Config

You can then publish the package's config file and update it as you'd prefer:
```bash
php artisan vendor:publish --provider="Veeqtoh\ActiveEmail\Providers\ActiveEmailProvider"
```

## Usage

### Validator Approach

Add the `notblacklisted` validator to your email validation rules array (or string) to ensure that the domain for a given email address is not blacklisted. I'd recommend you add it after the email validator to make sure a valid email is passed through:
```php
'emailField' => 'email|notblacklisted',
```

or

```php
'emailField' => ['email', 'notblacklisted'],
```

### Class Approach

Instantiate the `NotBlackListedEmail` Class as part of your email validation rules array to ensure that the domain for a given email address is not blacklisted. Again, I'd recommend you add it after the email validator to make sure a valid email is passed through:

```php
use Veeqtoh\ActiveEmail\Rules\NotBlackListedEmail;

'emailField' => ['email', new NotBlackListedEmail()],
```

### Customization

The package is highly customizable from the config file with the following features:

#### Strict Mode

This value determines the strictness level of this feature. when set to `true`, domains in the [grey list](#grey-list) are also blacklisted.

It is turned on by default, but can be set in your .env file as follows:

```php
DISPOSABLE_EMAIL_STRICT_MODE=true,
```

#### Black List

This is a list of base domains with or without the TLD that are blacklisted by default. Add a domain to this list to blacklist it.

#### Grey List

This is a list of base domains with or without the TLD that aren't blacklisted by default except when in strict mode. Add a domain to this list to whitelist it when the feature is not set to strict mode. Ensure that the domain is not on the [black list](#black-list).

#### White List

This is a list of base domains with or without the TLD that are blacklisted by default but you want them to be bye passed.

## To Do

There's always something that can be done to improve this package. I'd keep updating this list as I think of them.

- Crawl the web to grab an updated list of disposable domains.
- Maybe setup a schedule for it..

## Testing

To run the package's unit tests, run the following command:

``` bash
vendor/bin/pest
```

## Security

If you find any security related issues, please contact me directly at [[email protected]](mailto:[email protected]) to report it.

## Contribution

If you wish to make any changes or improvements to the package, feel free to make a pull request.

Note: A contribution guide will be added soon.

## Changelog

Check the [CHANGELOG](CHANGELOG.md) to get more information about the latest changes.

## Upgrading

Check the [UPGRADE](UPGRADE.md) guide to get more information on how to update this library to newer versions.

## License

The MIT License (MIT). Please see [License File](LICENSE) for more information.

## Support Me

If you've found this package useful, please consider sponsoring this project. It will encourage me to keep maintaining it.
1 change: 1 addition & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Upgrade
34 changes: 24 additions & 10 deletions config/active-email.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,46 @@

/*
|--------------------------------------------------------------------------
| Blacklist
| Black List
|--------------------------------------------------------------------------
|
| This is a list of base domains without the TLD that are blacklisted by
| default. Add a domain to this list to blacklist it.
| This is a list of base domains with or without the TLD that are
| blacklisted by default. Add a domain to this list to blacklist it.
|
*/

'blacklist' => [
//
//
],

/*
|--------------------------------------------------------------------------
| Greylist
| Grey List
|--------------------------------------------------------------------------
|
| This is a list of base domains without the TLD that aren't blacklisted by
| default except when in strict mode. Add a domain to this list to whitelist
| it when the feature is not set to strict mode. Ensure that the domain is not
| on the blacklist above.
| This is a list of base domains with or without the TLD that aren't
| blacklisted by default except when in strict mode. Add a domain to this
| list to whitelist it when the feature is not set to strict mode.
| Ensure that the domain is not on the blacklist above.
|
*/

'greylist' => [
//
//
],

/*
|--------------------------------------------------------------------------
| White List
|--------------------------------------------------------------------------
|
| This is a list of base domains with or without the TLD that are
| blacklisted by default but you want them to be bye passed.
|
*/

'whitelist' => [
//
],

];
4 changes: 3 additions & 1 deletion src/DisposableEmail.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
*/
class DisposableEmail
{
/**
/**
* Retrieve a list of base domains without the TLDs that are blacklisted by default.
*
* @return array
*/
public function getBlacklist() : array
{
Expand Down
3 changes: 1 addition & 2 deletions src/Providers/ActiveEmailProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@ public function boot() : void
__DIR__ . '/../../config/active-email.php' => config_path('active-email.php'),
], 'config');

// Register the custom validation rule
// Register the custom validation rule.
Validator::extend('notblacklisted', function ($attribute, $value, $parameters, $validator) {
$rule = new NotBlacklistedEmail();

// Create a Closure for the fail method
$fail = function($message) use ($attribute, $validator) {
$validator->errors()->add($attribute, $message);
};
Expand Down
20 changes: 13 additions & 7 deletions src/Rules/NotBlacklistedEmail.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ public function __construct()

/**
* Run the validation rule.
*
*
* @param string $attribute The name of the attribute being validated.
* @param mixed $value The value of the attribute being validated.
* @param \Closure(mixed): \Illuminate\Translation\PotentiallyTranslatedString $fail
* @param \Closure(mixed): \Illuminate\Translation\PotentiallyTranslatedString $fail
* The callback that should be used to report validation failures.
*
*
* @return void
*/
public function validate(string $attribute, mixed $value, Closure $fail) : void
Expand All @@ -41,11 +41,17 @@ public function validate(string $attribute, mixed $value, Closure $fail) : void
$domain = $this->getDomainName('@', $value, 1);
$domainName = $this->getDomainName('.', $domain, 0);

$mergedBlackLists = array_merge(config('active-email.blacklist'), $disposableEmail->getBlacklist());
$blackListedDomainNames = array_unique($mergedBlackLists);
$blackListedDomainNames = array_unique(array_merge(config('active-email.blacklist'), $disposableEmail->getBlacklist()));
$greyListedDomainNames = array_unique(array_merge(config('active-email.greylist'), $disposableEmail->getGreyList()));
$whiteListedDomainNames = array_unique(config('active-email.whitelist'));

foreach ($whiteListedDomainNames as $whiteListedDomainName) {
$byePass = $this->getDomainName('.', $whiteListedDomainName, 0);

$mergedGreyLists = array_merge(config('active-email.greylist'), $disposableEmail->getGreyList());
$greyListedDomainNames = array_unique($mergedGreyLists);
if ($domainName === $byePass) {
return;
}
}

if (config('active-email.strict_mode')) {
$blackListedDomainNames = array_merge($blackListedDomainNames, $greyListedDomainNames);
Expand Down
64 changes: 64 additions & 0 deletions tests/Unit/ActiveEmailTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,67 @@
expect($validator->fails())->toBeTrue();
}
});

it('validates that domains can be whitelisted - class instantiation', function () {
$rule = ['email' => [new NotBlacklistedEmail]];

// Valid email addresses (not blacklisted).
$validEmails = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
];

foreach ($validEmails as $email) {
$validator = Validator::make(['email' => $email], $rule);
expect($validator->passes())->toBeTrue();
}

// Invalid email addresses (blacklisted domains).
$invalidEmails = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
];

foreach ($invalidEmails as $email) {
$validator = Validator::make(['email' => $email], $rule);
expect($validator->fails())->toBeTrue();
}
});

it('validates that domains can be whitelisted - alias', function () {
$rule = ['email' => 'notblacklisted'];

// Valid email addresses (not blacklisted).
$validEmails = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
];

foreach ($validEmails as $email) {
$validator = Validator::make(['email' => $email], $rule);
expect($validator->passes())->toBeTrue();
}

// Invalid email addresses (blacklisted domains).
$invalidEmails = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
];

foreach ($invalidEmails as $email) {
$validator = Validator::make(['email' => $email], $rule);
expect($validator->fails())->toBeTrue();
}
});
3 changes: 2 additions & 1 deletion tests/Unit/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ protected function getPackageAliases($app)
protected function getEnvironmentSetUp($app)
{
// Set up any necessary configurations here
$app['config']->set('active-email.blacklist', ['mailinator.com', 'tempmail.com', 'example.ltd', 'example.co', 'example.com.nh', 'example.co.uk']);
$app['config']->set('active-email.blacklist', ['mailinator.com', 'tempmail.com', 'example.ltd', 'example.co', 'example.com.nh', 'example.co.uk', '10minutemail']);
$app['config']->set('active-email.greylist', []);
$app['config']->set('active-email.whitelist', ['10minutemail']);
$app['config']->set('active-email.strict_mode', false);
}
}

0 comments on commit 64f94a4

Please sign in to comment.