Skip to content

Commit

Permalink
tell firewall that too many emails were sent
Browse files Browse the repository at this point in the history
  • Loading branch information
denisdulici committed Mar 25, 2023
1 parent fd8b6c1 commit 70ab665
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 99 deletions.
15 changes: 15 additions & 0 deletions app/Events/Email/TooManyEmailsSent.php
@@ -0,0 +1,15 @@
<?php

namespace App\Events\Email;

use App\Abstracts\Event;

class TooManyEmailsSent extends Event
{
public $user_id;

public function __construct(int $user_id)
{
$this->user_id = $user_id;
}
}
14 changes: 14 additions & 0 deletions app/Listeners/Email/ReportTooManyEmailsSent.php
@@ -0,0 +1,14 @@
<?php

namespace App\Listeners\Email;

use App\Exceptions\Common\TooManyEmailsSent;
use App\Events\Email\TooManyEmailsSent as Event;

class ReportTooManyEmailsSent
{
public function handle(Event $event): void
{
report(new TooManyEmailsSent('Too many emails sent!'));
}
}
72 changes: 72 additions & 0 deletions app/Listeners/Email/TellFirewallTooManyEmailsSent.php
@@ -0,0 +1,72 @@
<?php

namespace App\Listeners\Email;

use Akaunting\Firewall\Events\AttackDetected;
use Akaunting\Firewall\Traits\Helper;
use App\Events\Email\TooManyEmailsSent as Event;
use Illuminate\Support\Facades\Config;

class TellFirewallTooManyEmailsSent
{
use Helper;

public function handle(Event $event): void
{
$this->request = request();
$this->middleware = 'too_many_emails_sent';
$this->user_id = $event->user_id;

$this->loadConfig();

if ($this->skip($event)) {
return;
}

$log = $this->log();

event(new AttackDetected($log));
}

public function loadConfig(): void
{
$config = array_merge_recursive(
Config::get('firewall'),
[
'middleware' => [
$this->middleware => [
'enabled' => env('FIREWALL_MIDDLEWARE_' . strtoupper($this->middleware) . '_ENABLED', env('FIREWALL_ENABLED', true)),

'methods' => ['post'],

'routes' => [
'only' => [], // i.e. 'contact'
'except' => [], // i.e. 'admin/*'
],

'auto_block' => [
'attempts' => env('FIREWALL_MIDDLEWARE_' . strtoupper($this->middleware) . '_AUTO_BLOCK_ATTEMPTS', 20),
'frequency' => 1 * 60, // 1 minute
'period' => 30 * 60, // 30 minutes
],
],
],
]
);

Config::set('firewall', $config);
}

public function skip($event): bool
{
if ($this->isDisabled()) {
return true;
}

if ($this->isWhitelist()) {
return true;
}

return false;
}
}
4 changes: 4 additions & 0 deletions app/Providers/Event.php
Expand Up @@ -104,6 +104,10 @@ class Event extends Provider
'App\Events\Setting\CategoryDeleted' => [
'App\Listeners\Setting\DeleteCategoryDeletedSubCategories',
],
'App\Events\Email\TooManyEmailsSent' => [
'App\Listeners\Email\ReportTooManyEmailsSent',
'App\Listeners\Email\TellFirewallTooManyEmailsSent',
],
];

/**
Expand Down
18 changes: 7 additions & 11 deletions app/Traits/Emails.php
Expand Up @@ -3,7 +3,7 @@
namespace App\Traits;

use App\Abstracts\Job;
use App\Exceptions\Common\TooManyEmailsSent;
use App\Events\Email\TooManyEmailsSent;
use App\Traits\Jobs;
use Illuminate\Support\Facades\RateLimiter;

Expand All @@ -14,15 +14,15 @@ trait Emails
public function sendEmail(Job $job): array
{
// Check if the user has reached the limit of emails per month
$key_per_month = 'email-month:' . user()->id;
$key_per_month = 'email-month:' . user_id();
$limit_per_month = config('app.throttles.email.month');
$decay_per_month = 60 * 60 * 24 * 30;

$can_send = RateLimiter::attempt($key_per_month, $limit_per_month, fn() => null, $decay_per_month);

if ($can_send) {
// Check if the user has reached the limit of emails per minute
$key_per_minute = 'email-minute:' . user()->id;
$key_per_minute = 'email-minute:' . user_id();
$limit_per_minute = config('app.throttles.email.minute');

$can_send = RateLimiter::attempt($key_per_minute, $limit_per_minute, fn() => null);
Expand All @@ -31,25 +31,21 @@ public function sendEmail(Job $job): array
if ($can_send) {
$this->dispatch($job);

$response = [
return [
'success' => true,
'error' => false,
'data' => '',
'message' => '',
];

return $response;
}

$response = [
event(new TooManyEmailsSent(user_id()));

return [
'success' => false,
'error' => true,
'data' => null,
'message' => 'Too many emails sent!',
];

report(new TooManyEmailsSent('Too many emails sent!'));

return $response;
}
}

0 comments on commit 70ab665

Please sign in to comment.