Example of Custom validation rules in HDInnovations/UNIT3D-Community-Edition

File app/Validators/EmailBlacklistValidator.php (link to Github)
use App\Helpers\EmailBlacklistUpdater;
use Illuminate\Support\Str;
use Psr\SimpleCache\InvalidArgumentException;

class EmailBlacklistValidator
{
    private $domains = [];

    public function message($message, $attribute, $rule, $parameters)
    {
        return \sprintf('%s domain is not allowed. Throwaway email providers are blacklisted.', $attribute);
    }

    public function validate($attribute, $value, $parameters)
    {
        $this->refresh();

        $domain = Str::after(\strtolower($value), '@');

        return ! \in_array($domain, $this->domains, true);
    }

    public function refresh()
    {
        $this->shouldUpdate();
        $this->domains = \cache()->get(\config('email-blacklist.cache-key'));
        $this->appendCustomDomains();
    }

    protected function shouldUpdate()
    {
        $autoupdate = \config('email-blacklist.auto-update');

        try {
            if ($autoupdate && ! \cache()->has(\config('email-blacklist.cache-key'))) {
                EmailBlacklistUpdater::update();
            }
        } catch (InvalidArgumentException) {
        }
    }

    protected function appendCustomDomains()
    {
        $appendList = \config('email-blacklist.append');
        if ($appendList === null) {
            return;
        }
        $appendDomains = \explode('|', \strtolower($appendList));
        $this->domains = \array_merge($this->domains, $appendDomains);
    }
}
File app/Providers/EmailBlacklistServiceProvider.php (link to Github)
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider;

class EmailBlacklistServiceProvider extends ServiceProvider
{
    ///
    public function boot()
    {
        Validator::extend('blacklist', "App\Validators\EmailBlacklistValidator@validate");

        Validator::replacer('blacklist', "App\Validators\EmailBlacklistValidator@message");
    }
}
File config/email-blacklist.php (link to Github)
return [
    'enabled'     => true,
    'source'      => 'https://cdn.jsdelivr.net/gh/andreis/disposable-email-domains@master/domains.json',
    'cache-key'   => 'email.domains.blacklist',
    'auto-update' => true,
    'append'      => null,
];
File app/Http/Controllers/Auth/ApplicationController.php (link to Github)
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class ApplicationController extends Controller
{
    //
    public function store(Request $request)
    {
        $application = \resolve(Application::class);
        $application->type = $request->input('type');
        $application->email = $request->input('email');
        $application->referrer = $request->input('referrer');

        if (\config('email-blacklist.enabled') == true) {
            if (\config('captcha.enabled') == false) {
                $v = \validator($request->all(), [
                    'type'     => 'required',
                    'email'    => 'required|string|email|max:70|blacklist|unique:invites|unique:users|unique:applications',
                    'referrer' => 'required',
                    'images.*' => 'filled',
                    'images'   => 'min:2',
                    'links.*'  => 'filled',
                    'links'    => 'min:2',
                ]);
           } else {
                $v = \validator($request->all(), [
                    'type'     => 'required',
                    'email'    => 'required|string|email|max:70|blacklist|unique:invites|unique:users|unique:applications',
                    'referrer' => 'required',
                    'images.*' => 'filled',
                    'images'   => 'min:2',
                    'links.*'  => 'filled',
                    'links'    => 'min:2',
                    'captcha'  => 'hiddencaptcha',
                ]);
            }
        }
        //
    }
    //
}
File app/Helpers/EmailBlacklistUpdater.php (link to Github)
use Carbon\Carbon;

class EmailBlacklistUpdater
{
    public static function update()
    {
        $url = \config('email-blacklist.source');
        if ($url === null) {
            return false;
        }
        // Define parameters for the cache
        $key = \config('email-blacklist.cache-key');
        $duration = Carbon::now()->addMonth();

        $domains = \json_decode(\file_get_contents($url), true, 512, JSON_THROW_ON_ERROR);
        $count = \is_countable($domains) ? \count($domains) : 0;

        // Retrieve blacklisted domains
        \cache()->put($key, $domains, $duration);

        return $count;
    }
}
File config/app.php (link to Github)
return [
    //
    'providers' => [
        //
        App\Providers\EmailBlacklistServiceProvider::class,
        //
    ],
    //
];

Additional resources on custom validation rules: