From 67d18e4b6297f46084d7b2501d5e5039ad8b8cc9 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 19 Jan 2026 20:08:15 +0100 Subject: [PATCH] Clean up latest MFA handler #11455 --- .../User/UserHasGeneratedNewBackupCodes.php | 44 +++++++++++++++ .../UserHasUsedBackupCode.php} | 16 +++--- .../Controllers/Auth/TwoFactorController.php | 3 +- .../Controllers/Profile/MfaController.php | 3 +- .../User/NotifiesUserAboutNewBackupCodes.php} | 45 +++------------ .../User/NotifiesUserAboutUsedBackupCode.php | 55 +++++++++++++++++++ app/Providers/EventServiceProvider.php | 19 +++---- 7 files changed, 127 insertions(+), 58 deletions(-) create mode 100644 app/Events/Security/User/UserHasGeneratedNewBackupCodes.php rename app/Events/Security/{MFANewBackupCodes.php => User/UserHasUsedBackupCode.php} (74%) rename app/{Handlers/Events/Security/MFAHandler.php => Listeners/Security/User/NotifiesUserAboutNewBackupCodes.php} (54%) create mode 100644 app/Listeners/Security/User/NotifiesUserAboutUsedBackupCode.php diff --git a/app/Events/Security/User/UserHasGeneratedNewBackupCodes.php b/app/Events/Security/User/UserHasGeneratedNewBackupCodes.php new file mode 100644 index 0000000000..cebe68efde --- /dev/null +++ b/app/Events/Security/User/UserHasGeneratedNewBackupCodes.php @@ -0,0 +1,44 @@ +. + */ + +namespace FireflyIII\Events\Security\User; + +use FireflyIII\Events\Event; +use FireflyIII\User; +use Illuminate\Contracts\Auth\Authenticatable; +use Illuminate\Queue\SerializesModels; +use InvalidArgumentException; + +class UserHasGeneratedNewBackupCodes extends Event +{ + use SerializesModels; + + public User $user; + + public function __construct(Authenticatable|User|null $user) + { + if ($user instanceof User) { + $this->user = $user; + return; + } + throw new InvalidArgumentException('User must be an instance of User.'); + } +} diff --git a/app/Events/Security/MFANewBackupCodes.php b/app/Events/Security/User/UserHasUsedBackupCode.php similarity index 74% rename from app/Events/Security/MFANewBackupCodes.php rename to app/Events/Security/User/UserHasUsedBackupCode.php index b07878c1d6..dfdad7ab0a 100644 --- a/app/Events/Security/MFANewBackupCodes.php +++ b/app/Events/Security/User/UserHasUsedBackupCode.php @@ -1,8 +1,7 @@ . */ -declare(strict_types=1); - -namespace FireflyIII\Events\Security; +namespace FireflyIII\Events\Security\User; use FireflyIII\Events\Event; use FireflyIII\User; use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Queue\SerializesModels; +use InvalidArgumentException; -class MFANewBackupCodes extends Event +class UserHasUsedBackupCode extends Event { use SerializesModels; @@ -39,6 +37,8 @@ class MFANewBackupCodes extends Event { if ($user instanceof User) { $this->user = $user; + return; } + throw new InvalidArgumentException('User must be an instance of User.'); } } diff --git a/app/Http/Controllers/Auth/TwoFactorController.php b/app/Http/Controllers/Auth/TwoFactorController.php index fbe21d6e81..b699790ca6 100644 --- a/app/Http/Controllers/Auth/TwoFactorController.php +++ b/app/Http/Controllers/Auth/TwoFactorController.php @@ -28,6 +28,7 @@ use FireflyIII\Events\Security\MFAManyFailedAttempts; use FireflyIII\Events\Security\MFAUsedBackupCode; use FireflyIII\Events\Security\User\UserHasFewMFABackupCodesLeft; use FireflyIII\Events\Security\User\UserHasNoMFABackupCodesLeft; +use FireflyIII\Events\Security\User\UserHasUsedBackupCode; use FireflyIII\Events\Security\User\UserKeepsFailingMFA; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Support\Facades\Preferences; @@ -117,7 +118,7 @@ class TwoFactorController extends Controller // send user notification. $user = auth()->user(); Log::channel('audit')->info(sprintf('User "%s" has used a backup code.', $user->email)); - event(new MFAUsedBackupCode($user)); + event(new UserHasUsedBackupCode($user)); return redirect(route('home')); } diff --git a/app/Http/Controllers/Profile/MfaController.php b/app/Http/Controllers/Profile/MfaController.php index f97774d7f9..2d1e54eae6 100644 --- a/app/Http/Controllers/Profile/MfaController.php +++ b/app/Http/Controllers/Profile/MfaController.php @@ -28,6 +28,7 @@ use Carbon\Carbon; use FireflyIII\Events\Security\MFANewBackupCodes; use FireflyIII\Events\Security\User\UserHasDisabledMFA; use FireflyIII\Events\Security\User\UserHasEnabledMFA; +use FireflyIII\Events\Security\User\UserHasGeneratedNewBackupCodes; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Middleware\IsDemoUser; use FireflyIII\Http\Requests\ExistingTokenFormRequest; @@ -130,7 +131,7 @@ class MfaController extends Controller // send user notification. $user = auth()->user(); Log::channel('audit')->info(sprintf('User "%s" has generated new backup codes.', $user->email)); - event(new MFANewBackupCodes($user)); + event(new UserHasGeneratedNewBackupCodes($user)); return view('profile.mfa.backup-codes-post')->with(['codes' => $codes]); diff --git a/app/Handlers/Events/Security/MFAHandler.php b/app/Listeners/Security/User/NotifiesUserAboutNewBackupCodes.php similarity index 54% rename from app/Handlers/Events/Security/MFAHandler.php rename to app/Listeners/Security/User/NotifiesUserAboutNewBackupCodes.php index 63817e157b..815ec8213e 100644 --- a/app/Handlers/Events/Security/MFAHandler.php +++ b/app/Listeners/Security/User/NotifiesUserAboutNewBackupCodes.php @@ -1,8 +1,7 @@ . */ -declare(strict_types=1); - -namespace FireflyIII\Handlers\Events\Security; +namespace FireflyIII\Listeners\Security\User; use Exception; -use FireflyIII\Events\Security\MFANewBackupCodes; -use FireflyIII\Events\Security\MFAUsedBackupCode; -use FireflyIII\Notifications\Security\MFAUsedBackupCodeNotification; +use FireflyIII\Events\Security\User\UserHasGeneratedNewBackupCodes; use FireflyIII\Notifications\Security\NewBackupCodesNotification; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Notification; -class MFAHandler +class NotifiesUserAboutNewBackupCodes { - - public function sendNewMFABackupCodesMail(MFANewBackupCodes $event): void - { + public function handle(UserHasGeneratedNewBackupCodes $event): void { Log::debug(sprintf('Now in %s', __METHOD__)); $user = $event->user; @@ -60,28 +53,4 @@ class MFAHandler } } - public function sendUsedBackupCodeMail(MFAUsedBackupCode $event): void - { - Log::debug(sprintf('Now in %s', __METHOD__)); - - $user = $event->user; - - try { - Notification::send($user, new MFAUsedBackupCodeNotification($user)); - } catch (Exception $e) { - $message = $e->getMessage(); - if (str_contains($message, 'Bcc')) { - Log::warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); - - return; - } - if (str_contains($message, 'RFC 2822')) { - Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); - - return; - } - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); - } - } } diff --git a/app/Listeners/Security/User/NotifiesUserAboutUsedBackupCode.php b/app/Listeners/Security/User/NotifiesUserAboutUsedBackupCode.php new file mode 100644 index 0000000000..6b2f1e001b --- /dev/null +++ b/app/Listeners/Security/User/NotifiesUserAboutUsedBackupCode.php @@ -0,0 +1,55 @@ +. + */ + +namespace FireflyIII\Listeners\Security\User; + +use Exception; +use FireflyIII\Events\Security\User\UserHasUsedBackupCode; +use FireflyIII\Notifications\Security\MFAUsedBackupCodeNotification; +use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Notification; + +class NotifiesUserAboutUsedBackupCode +{ +public function handle(UserHasUsedBackupCode $event): void { + Log::debug(sprintf('Now in %s', __METHOD__)); + + $user = $event->user; + + try { + Notification::send($user, new MFAUsedBackupCodeNotification($user)); + } catch (Exception $e) { + $message = $e->getMessage(); + if (str_contains($message, 'Bcc')) { + Log::warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + + return; + } + if (str_contains($message, 'RFC 2822')) { + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + + return; + } + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); + } +} +} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index e82d556da3..f585c883e0 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -37,7 +37,6 @@ use FireflyIII\Events\RequestedSendWebhookMessages; use FireflyIII\Events\RequestedVersionCheckStatus; use FireflyIII\Events\Security\MFAManyFailedAttempts; use FireflyIII\Events\Security\MFANewBackupCodes; -use FireflyIII\Events\Security\MFAUsedBackupCode; use FireflyIII\Events\Security\UnknownUserAttemptedLogin; use FireflyIII\Events\Security\UserAttemptedLogin; use FireflyIII\Events\StoredAccount; @@ -185,21 +184,21 @@ class EventServiceProvider extends ServiceProvider // DisabledMFA::class => [ // 'FireflyIII\Handlers\Events\Security\MFAHandler@sendMFADisabledMail', // ], - MFANewBackupCodes::class => [ - 'FireflyIII\Handlers\Events\Security\MFAHandler@sendNewMFABackupCodesMail', - ], - MFAUsedBackupCode::class => [ - 'FireflyIII\Handlers\Events\Security\MFAHandler@sendUsedBackupCodeMail', - ], + // MFANewBackupCodes::class => [ + // 'FireflyIII\Handlers\Events\Security\MFAHandler@sendNewMFABackupCodesMail', + // ], + // MFAUsedBackupCode::class => [ + // 'FireflyIII\Handlers\Events\Security\MFAHandler@sendUsedBackupCodeMail', + // ], // MFABackupFewLeft::class => [ // 'FireflyIII\Handlers\Events\Security\MFAHandler@sendBackupFewLeftMail', // ], // MFABackupNoLeft::class => [ // 'FireflyIII\Handlers\Events\Security\MFAHandler@sendBackupNoLeftMail', // ], -// MFAManyFailedAttempts::class => [ -// 'FireflyIII\Handlers\Events\Security\MFAHandler@sendMFAFailedAttemptsMail', -// ], + // MFAManyFailedAttempts::class => [ + // 'FireflyIII\Handlers\Events\Security\MFAHandler@sendMFAFailedAttemptsMail', + // ], // preferences UserGroupChangedPrimaryCurrency::class => [ 'FireflyIII\Handlers\Events\PreferencesEventHandler@resetPrimaryCurrencyAmounts',