diff --git a/app/Events/Security/UserAttemptedLogin.php b/app/Events/Security/UserAttemptedLogin.php new file mode 100644 index 0000000000..8457a5ecc3 --- /dev/null +++ b/app/Events/Security/UserAttemptedLogin.php @@ -0,0 +1,42 @@ +user = $user; + } + } +} diff --git a/app/Handlers/Events/UserEventHandler.php b/app/Handlers/Events/UserEventHandler.php index aaac2ca8d5..91b63b4e18 100644 --- a/app/Handlers/Events/UserEventHandler.php +++ b/app/Handlers/Events/UserEventHandler.php @@ -31,6 +31,7 @@ use FireflyIII\Events\Admin\InvitationCreated; use FireflyIII\Events\DetectedNewIPAddress; use FireflyIII\Events\RegisteredUser; use FireflyIII\Events\RequestedNewPassword; +use FireflyIII\Events\Security\UserAttemptedLogin; use FireflyIII\Events\Test\OwnerTestNotificationChannel; use FireflyIII\Events\Test\UserTestNotificationChannel; use FireflyIII\Events\UserChangedEmail; @@ -435,6 +436,26 @@ class UserEventHandler } } + public function sendLoginAttemptNotification(UserAttemptedLogin $event): void { + try { + Notification::send($event->user, new UserFailedLoginAttempt($event->user)); + } catch (\Exception $e) { // @phpstan-ignore-line + $message = $e->getMessage(); + if (str_contains($message, 'Bcc')) { + app('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')) { + app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + + return; + } + app('log')->error($e->getMessage()); + app('log')->error($e->getTraceAsString()); + } + } + /** * Sends a test message to an administrator. */ diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 9ec43cb780..6558e626de 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -127,10 +127,14 @@ class LoginController extends Controller } app('log')->warning('Login attempt failed.'); $username = (string) $request->get($this->username()); - if (null === $this->repository->findByEmail($username)) { + $user = $this->repository->findByEmail($username); + if (null === $user) { // send event to owner. event(new UnknownUserAttemptedLogin($username)); } + if(null !== $user) { + event(new UserAttemptedLogin($user)); + } // Copied directly from AuthenticatesUsers, but with logging added: // If the login attempt was unsuccessful we will increment the number of attempts diff --git a/app/Notifications/Admin/UnknownUserLoginAttempt.php b/app/Notifications/Admin/UnknownUserLoginAttempt.php index 4632a06e7e..6ee20a56e9 100644 --- a/app/Notifications/Admin/UnknownUserLoginAttempt.php +++ b/app/Notifications/Admin/UnknownUserLoginAttempt.php @@ -39,21 +39,12 @@ class UnknownUserLoginAttempt extends Notification use Queueable; private string $address; - /** - * Create a new notification instance. - */ public function __construct(string $address) { $this->address = $address; } /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toArray(OwnerNotifiable $notifiable) @@ -63,8 +54,6 @@ class UnknownUserLoginAttempt extends Notification } /** - * Get the mail representation of the notification. - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toMail(OwnerNotifiable $notifiable): MailMessage @@ -76,8 +65,6 @@ class UnknownUserLoginAttempt extends Notification } /** - * Get the Slack representation of the notification. - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toSlack(OwnerNotifiable $notifiable): SlackMessage @@ -87,6 +74,9 @@ class UnknownUserLoginAttempt extends Notification ); } + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ public function toPushover(OwnerNotifiable $notifiable): PushoverMessage { return PushoverMessage::create((string) trans('email.unknown_user_message', ['address' => $this->address])) @@ -94,6 +84,9 @@ class UnknownUserLoginAttempt extends Notification ; } + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ public function toNtfy(OwnerNotifiable $notifiable): Message { $settings = ReturnsSettings::getSettings('ntfy', 'owner', null); @@ -106,8 +99,6 @@ class UnknownUserLoginAttempt extends Notification } /** - * Get the notification's delivery channels. - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function via(OwnerNotifiable $notifiable) diff --git a/app/Notifications/Admin/UserInvitation.php b/app/Notifications/Admin/UserInvitation.php index 761d410f4c..a9d40ab9b0 100644 --- a/app/Notifications/Admin/UserInvitation.php +++ b/app/Notifications/Admin/UserInvitation.php @@ -46,9 +46,7 @@ class UserInvitation extends Notification private InvitedUser $invitee; private OwnerNotifiable $owner; - /** - * Create a new notification instance. - */ + public function __construct(OwnerNotifiable $owner, InvitedUser $invitee) { $this->invitee = $invitee; @@ -56,12 +54,6 @@ class UserInvitation extends Notification } /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toArray(OwnerNotifiable $notifiable) @@ -71,12 +63,6 @@ class UserInvitation extends Notification } /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toMail(OwnerNotifiable $notifiable) @@ -88,12 +74,6 @@ class UserInvitation extends Notification } /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toSlack(OwnerNotifiable $notifiable) @@ -102,7 +82,9 @@ class UserInvitation extends Notification (string) trans('email.invitation_created_body', ['email' => $this->invitee->user->email, 'invitee' => $this->invitee->email]) ); } - + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ public function toPushover(OwnerNotifiable $notifiable): PushoverMessage { Log::debug('Now in toPushover() for UserInvitation'); @@ -111,7 +93,9 @@ class UserInvitation extends Notification ->title((string) trans('email.invitation_created_subject')) ; } - + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ public function toNtfy(OwnerNotifiable $notifiable): Message { Log::debug('Now in toNtfy() for UserInvitation'); @@ -125,12 +109,6 @@ class UserInvitation extends Notification } /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function via(OwnerNotifiable $notifiable) diff --git a/app/Notifications/Admin/UserRegistration.php b/app/Notifications/Admin/UserRegistration.php index 5745ca9e6d..e28e1ca239 100644 --- a/app/Notifications/Admin/UserRegistration.php +++ b/app/Notifications/Admin/UserRegistration.php @@ -46,9 +46,7 @@ class UserRegistration extends Notification private OwnerNotifiable $owner; private User $user; - /** - * Create a new notification instance. - */ + public function __construct(OwnerNotifiable $owner, User $user) { $this->user = $user; @@ -56,8 +54,6 @@ class UserRegistration extends Notification } /** - * Get the array representation of the notification. - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toArray(OwnerNotifiable $notifiable) @@ -67,12 +63,6 @@ class UserRegistration extends Notification } /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toMail(OwnerNotifiable $notifiable) @@ -84,19 +74,15 @@ class UserRegistration extends Notification } /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toSlack(OwnerNotifiable $notifiable) { return (new SlackMessage())->content((string) trans('email.admin_new_user_registered', ['email' => $this->user->email, 'id' => $this->user->id])); } - + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ public function toPushover(OwnerNotifiable $notifiable): PushoverMessage { Log::debug('Now in toPushover() for UserRegistration'); @@ -105,7 +91,9 @@ class UserRegistration extends Notification ->title((string) trans('email.registered_subject_admin')) ; } - + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ public function toNtfy(OwnerNotifiable $notifiable): Message { Log::debug('Now in toNtfy() for (Admin) UserRegistration'); @@ -119,12 +107,6 @@ class UserRegistration extends Notification } /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function via(OwnerNotifiable $notifiable) diff --git a/app/Notifications/Admin/VersionCheckResult.php b/app/Notifications/Admin/VersionCheckResult.php index 001c9c838f..68e28475d9 100644 --- a/app/Notifications/Admin/VersionCheckResult.php +++ b/app/Notifications/Admin/VersionCheckResult.php @@ -44,21 +44,13 @@ class VersionCheckResult extends Notification private string $message; - /** - * Create a new notification instance. - */ + public function __construct(string $message) { $this->message = $message; } /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toArray(OwnerNotifiable $notifiable) @@ -68,12 +60,6 @@ class VersionCheckResult extends Notification } /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toMail(OwnerNotifiable $notifiable) @@ -85,12 +71,6 @@ class VersionCheckResult extends Notification } /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toSlack(OwnerNotifiable $notifiable) @@ -101,7 +81,9 @@ class VersionCheckResult extends Notification }) ; } - + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ public function toPushover(OwnerNotifiable $notifiable): PushoverMessage { Log::debug('Now in toPushover() for VersionCheckResult'); @@ -110,7 +92,9 @@ class VersionCheckResult extends Notification ->title((string) trans('email.new_version_email_subject')) ; } - + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ public function toNtfy(OwnerNotifiable $notifiable): Message { Log::debug('Now in toNtfy() for VersionCheckResult'); @@ -124,12 +108,6 @@ class VersionCheckResult extends Notification } /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function via(OwnerNotifiable $notifiable) diff --git a/app/Notifications/Security/DisabledMFANotification.php b/app/Notifications/Security/DisabledMFANotification.php index f0efecf0cb..48dc9462a8 100644 --- a/app/Notifications/Security/DisabledMFANotification.php +++ b/app/Notifications/Security/DisabledMFANotification.php @@ -42,21 +42,11 @@ class DisabledMFANotification extends Notification private User $user; - /** - * Create a new notification instance. - */ public function __construct(User $user) { $this->user = $user; } - /** - * Get the array representation of the notification. - * - * @param User $notifiable - * - * @return array - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toArray(User $notifiable) @@ -66,12 +56,6 @@ class DisabledMFANotification extends Notification } /** - * Get the mail representation of the notification. - * - * @param User $notifiable - * - * @return MailMessage - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toMail(User $notifiable) @@ -80,14 +64,7 @@ class DisabledMFANotification extends Notification return (new MailMessage())->markdown('emails.security.disabled-mfa', ['user' => $this->user])->subject($subject); } - /** - * Get the Slack representation of the notification. - * - * @param User $notifiable - * - * @return SlackMessage - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function toSlack(User $notifiable) @@ -96,7 +73,9 @@ class DisabledMFANotification extends Notification return (new SlackMessage())->content($message); } - + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ public function toPushover(User $notifiable): PushoverMessage { Log::debug('Now in (user) toPushover()'); @@ -104,6 +83,9 @@ class DisabledMFANotification extends Notification return PushoverMessage::create((string) trans('email.disabled_mfa_slack', ['email' => $this->user->email])) ->title((string)trans('email.disabled_mfa_subject')); } + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ public function toNtfy(User $user): Message { $settings = ReturnsSettings::getSettings('ntfy', 'user', $user); @@ -116,12 +98,6 @@ class DisabledMFANotification extends Notification } /** - * Get the notification's delivery channels. - * - * @param User $notifiable - * - * @return array - * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function via(User $notifiable) diff --git a/app/Notifications/Security/EnabledMFANotification.php b/app/Notifications/Security/EnabledMFANotification.php index cfe5cf0e6d..fc927be354 100644 --- a/app/Notifications/Security/EnabledMFANotification.php +++ b/app/Notifications/Security/EnabledMFANotification.php @@ -37,38 +37,20 @@ class EnabledMFANotification extends Notification private User $user; - /** - * Create a new notification instance. - */ + public function __construct(User $user) { $this->user = $user; } - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toMail($notifiable) { $subject = (string)trans('email.enabled_mfa_subject'); @@ -76,15 +58,7 @@ class EnabledMFANotification extends Notification return (new MailMessage())->markdown('emails.security.enabled-mfa', ['user' => $this->user])->subject($subject); } - /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toSlack($notifiable) { $message = (string)trans('email.enabled_mfa_slack', ['email' => $this->user->email]); @@ -92,15 +66,7 @@ class EnabledMFANotification extends Notification return (new SlackMessage())->content($message); } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { /** @var null|User $user */ diff --git a/app/Notifications/Security/MFABackupFewLeftNotification.php b/app/Notifications/Security/MFABackupFewLeftNotification.php index d01925686f..c4e7209bb6 100644 --- a/app/Notifications/Security/MFABackupFewLeftNotification.php +++ b/app/Notifications/Security/MFABackupFewLeftNotification.php @@ -38,39 +38,21 @@ class MFABackupFewLeftNotification extends Notification private User $user; private int $count; - /** - * Create a new notification instance. - */ + public function __construct(User $user, int $count) { $this->user = $user; $this->count = $count; } - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toMail($notifiable) { $subject = (string)trans('email.mfa_few_backups_left_subject', ['count' => $this->count]); @@ -78,15 +60,7 @@ class MFABackupFewLeftNotification extends Notification return (new MailMessage())->markdown('emails.security.few-backup-codes', ['user' => $this->user, 'count' => $this->count])->subject($subject); } - /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toSlack($notifiable) { $message = (string)trans('email.mfa_few_backups_left_slack', ['email' => $this->user->email, 'count' => $this->count]); @@ -94,15 +68,7 @@ class MFABackupFewLeftNotification extends Notification return (new SlackMessage())->content($message); } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { /** @var null|User $user */ diff --git a/app/Notifications/Security/MFABackupNoLeftNotification.php b/app/Notifications/Security/MFABackupNoLeftNotification.php index 91a98c1101..5e0199c079 100644 --- a/app/Notifications/Security/MFABackupNoLeftNotification.php +++ b/app/Notifications/Security/MFABackupNoLeftNotification.php @@ -37,38 +37,20 @@ class MFABackupNoLeftNotification extends Notification private User $user; - /** - * Create a new notification instance. - */ + public function __construct(User $user) { $this->user = $user; } - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toMail($notifiable) { $subject = (string)trans('email.mfa_no_backups_left_subject'); @@ -76,15 +58,7 @@ class MFABackupNoLeftNotification extends Notification return (new MailMessage())->markdown('emails.security.no-backup-codes', ['user' => $this->user])->subject($subject); } - /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toSlack($notifiable) { $message = (string)trans('email.mfa_no_backups_left_slack', ['email' => $this->user->email]); @@ -92,15 +66,7 @@ class MFABackupNoLeftNotification extends Notification return (new SlackMessage())->content($message); } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { /** @var null|User $user */ diff --git a/app/Notifications/Security/MFAManyFailedAttemptsNotification.php b/app/Notifications/Security/MFAManyFailedAttemptsNotification.php index b8926e58e8..d7d78863fe 100644 --- a/app/Notifications/Security/MFAManyFailedAttemptsNotification.php +++ b/app/Notifications/Security/MFAManyFailedAttemptsNotification.php @@ -38,39 +38,21 @@ class MFAManyFailedAttemptsNotification extends Notification private User $user; private int $count; - /** - * Create a new notification instance. - */ + public function __construct(User $user, int $count) { $this->user = $user; $this->count = $count; } - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toMail($notifiable) { $subject = (string)trans('email.mfa_many_failed_subject', ['count' => $this->count]); @@ -78,15 +60,7 @@ class MFAManyFailedAttemptsNotification extends Notification return (new MailMessage())->markdown('emails.security.many-failed-attempts', ['user' => $this->user, 'count' => $this->count])->subject($subject); } - /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toSlack($notifiable) { $message = (string)trans('email.mfa_many_failed_slack', ['email' => $this->user->email, 'count' => $this->count]); @@ -94,15 +68,7 @@ class MFAManyFailedAttemptsNotification extends Notification return (new SlackMessage())->content($message); } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { /** @var null|User $user */ diff --git a/app/Notifications/Security/MFAUsedBackupCodeNotification.php b/app/Notifications/Security/MFAUsedBackupCodeNotification.php index 2179dd2357..5aac05099d 100644 --- a/app/Notifications/Security/MFAUsedBackupCodeNotification.php +++ b/app/Notifications/Security/MFAUsedBackupCodeNotification.php @@ -37,38 +37,20 @@ class MFAUsedBackupCodeNotification extends Notification private User $user; - /** - * Create a new notification instance. - */ + public function __construct(User $user) { $this->user = $user; } - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toMail($notifiable) { $subject = (string)trans('email.used_backup_code_subject'); @@ -76,15 +58,7 @@ class MFAUsedBackupCodeNotification extends Notification return (new MailMessage())->markdown('emails.security.used-backup-code', ['user' => $this->user])->subject($subject); } - /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toSlack($notifiable) { $message = (string)trans('email.used_backup_code_slack', ['email' => $this->user->email]); @@ -92,15 +66,7 @@ class MFAUsedBackupCodeNotification extends Notification return (new SlackMessage())->content($message); } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { /** @var null|User $user */ diff --git a/app/Notifications/Security/NewBackupCodesNotification.php b/app/Notifications/Security/NewBackupCodesNotification.php index eeaac3b0ac..8973242e02 100644 --- a/app/Notifications/Security/NewBackupCodesNotification.php +++ b/app/Notifications/Security/NewBackupCodesNotification.php @@ -37,38 +37,20 @@ class NewBackupCodesNotification extends Notification private User $user; - /** - * Create a new notification instance. - */ + public function __construct(User $user) { $this->user = $user; } - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toMail($notifiable) { $subject = (string)trans('email.new_backup_codes_subject'); @@ -76,15 +58,7 @@ class NewBackupCodesNotification extends Notification return (new MailMessage())->markdown('emails.security.new-backup-codes', ['user' => $this->user])->subject($subject); } - /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toSlack($notifiable) { $message = (string)trans('email.new_backup_codes_slack', ['email' => $this->user->email]); @@ -92,15 +66,7 @@ class NewBackupCodesNotification extends Notification return (new SlackMessage())->content($message); } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { /** @var null|User $user */ diff --git a/app/Notifications/Security/UserFailedLoginAttempt.php b/app/Notifications/Security/UserFailedLoginAttempt.php new file mode 100644 index 0000000000..51a4462dc7 --- /dev/null +++ b/app/Notifications/Security/UserFailedLoginAttempt.php @@ -0,0 +1,82 @@ +user = $user; + } + + + public function toArray($notifiable) + { + return [ + ]; + } + + + public function toMail($notifiable) + { + $subject = (string)trans('email.new_backup_codes_subject'); + + return (new MailMessage())->markdown('emails.security.new-backup-codes', ['user' => $this->user])->subject($subject); + } + + + public function toSlack($notifiable) + { + $message = (string)trans('email.new_backup_codes_slack', ['email' => $this->user->email]); + + return (new SlackMessage())->content($message); + } + + + public function via($notifiable) + { + /** @var null|User $user */ + $user = auth()->user(); + $slackUrl = null === $user ? '' : app('preferences')->getForUser(auth()->user(), 'slack_webhook_url', '')->data; + if (is_array($slackUrl)) { + $slackUrl = ''; + } + if (UrlValidator::isValidWebhookURL((string)$slackUrl)) { + return ['mail', 'slack']; + } + + return ['mail']; + } +} diff --git a/app/Notifications/Test/OwnerTestNotificationEmail.php b/app/Notifications/Test/OwnerTestNotificationEmail.php index 9ac18ed14b..ed74b12537 100644 --- a/app/Notifications/Test/OwnerTestNotificationEmail.php +++ b/app/Notifications/Test/OwnerTestNotificationEmail.php @@ -38,9 +38,7 @@ class OwnerTestNotificationEmail extends Notification private OwnerNotifiable $owner; - /** - * Create a new notification instance. - */ + public function __construct(OwnerNotifiable $owner) { $this->owner = $owner; diff --git a/app/Notifications/Test/OwnerTestNotificationNtfy.php b/app/Notifications/Test/OwnerTestNotificationNtfy.php index d06594d542..d6ec326625 100644 --- a/app/Notifications/Test/OwnerTestNotificationNtfy.php +++ b/app/Notifications/Test/OwnerTestNotificationNtfy.php @@ -42,9 +42,7 @@ class OwnerTestNotificationNtfy extends Notification public OwnerNotifiable $owner; - /** - * Create a new notification instance. - */ + public function __construct(OwnerNotifiable $owner) { $this->owner = $owner; diff --git a/app/Notifications/Test/OwnerTestNotificationPushover.php b/app/Notifications/Test/OwnerTestNotificationPushover.php index 4d71f095ab..f5fdf1a032 100644 --- a/app/Notifications/Test/OwnerTestNotificationPushover.php +++ b/app/Notifications/Test/OwnerTestNotificationPushover.php @@ -42,9 +42,7 @@ class OwnerTestNotificationPushover extends Notification private OwnerNotifiable $owner; - /** - * Create a new notification instance. - */ + public function __construct(OwnerNotifiable $owner) { $this->owner = $owner; diff --git a/app/Notifications/Test/OwnerTestNotificationSlack.php b/app/Notifications/Test/OwnerTestNotificationSlack.php index 55dce8f62a..ea3dbab6d7 100644 --- a/app/Notifications/Test/OwnerTestNotificationSlack.php +++ b/app/Notifications/Test/OwnerTestNotificationSlack.php @@ -40,9 +40,7 @@ class OwnerTestNotificationSlack extends Notification private OwnerNotifiable $owner; - /** - * Create a new notification instance. - */ + public function __construct(OwnerNotifiable $owner) { $this->owner = $owner; diff --git a/app/Notifications/Test/UserTestNotificationEmail.php b/app/Notifications/Test/UserTestNotificationEmail.php index d617756849..25463f8789 100644 --- a/app/Notifications/Test/UserTestNotificationEmail.php +++ b/app/Notifications/Test/UserTestNotificationEmail.php @@ -39,9 +39,7 @@ class UserTestNotificationEmail extends Notification private User $user; - /** - * Create a new notification instance. - */ + public function __construct(User $user) { $this->user = $user; diff --git a/app/Notifications/Test/UserTestNotificationNtfy.php b/app/Notifications/Test/UserTestNotificationNtfy.php index 73877acd4a..5891701ed2 100644 --- a/app/Notifications/Test/UserTestNotificationNtfy.php +++ b/app/Notifications/Test/UserTestNotificationNtfy.php @@ -42,9 +42,7 @@ class UserTestNotificationNtfy extends Notification public User $user; - /** - * Create a new notification instance. - */ + public function __construct(User $user) { $this->user = $user; diff --git a/app/Notifications/Test/UserTestNotificationPushover.php b/app/Notifications/Test/UserTestNotificationPushover.php index 3acb2cf8aa..d694ae00ed 100644 --- a/app/Notifications/Test/UserTestNotificationPushover.php +++ b/app/Notifications/Test/UserTestNotificationPushover.php @@ -43,9 +43,7 @@ class UserTestNotificationPushover extends Notification private User $user; - /** - * Create a new notification instance. - */ + public function __construct(User $user) { $this->user = $user; diff --git a/app/Notifications/Test/UserTestNotificationSlack.php b/app/Notifications/Test/UserTestNotificationSlack.php index 759c06a318..0d935bccce 100644 --- a/app/Notifications/Test/UserTestNotificationSlack.php +++ b/app/Notifications/Test/UserTestNotificationSlack.php @@ -40,9 +40,7 @@ class UserTestNotificationSlack extends Notification private OwnerNotifiable $owner; - /** - * Create a new notification instance. - */ + public function __construct(OwnerNotifiable $owner) { $this->owner = $owner; diff --git a/app/Notifications/User/BillReminder.php b/app/Notifications/User/BillReminder.php index 36d93b84e6..5b2cb849b9 100644 --- a/app/Notifications/User/BillReminder.php +++ b/app/Notifications/User/BillReminder.php @@ -43,9 +43,7 @@ class BillReminder extends Notification private int $diff; private string $field; - /** - * Create a new notification instance. - */ + public function __construct(Bill $bill, string $field, int $diff) { $this->bill = $bill; @@ -53,30 +51,14 @@ class BillReminder extends Notification $this->diff = $diff; } - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toMail($notifiable) { $subject = (string)trans(sprintf('email.bill_warning_subject_%s', $this->field), ['diff' => $this->diff, 'name' => $this->bill->name]); @@ -90,15 +72,7 @@ class BillReminder extends Notification ; } - /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toSlack($notifiable) { $message = (string)trans(sprintf('email.bill_warning_subject_%s', $this->field), ['diff' => $this->diff, 'name' => $this->bill->name]); @@ -117,15 +91,7 @@ class BillReminder extends Notification ; } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { /** @var null|User $user */ diff --git a/app/Notifications/User/NewAccessToken.php b/app/Notifications/User/NewAccessToken.php index b32192d089..126bc2f8c7 100644 --- a/app/Notifications/User/NewAccessToken.php +++ b/app/Notifications/User/NewAccessToken.php @@ -38,35 +38,17 @@ class NewAccessToken extends Notification { use Queueable; - /** - * Create a new notification instance. - */ + public function __construct() {} - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toMail($notifiable) { return (new MailMessage()) @@ -75,29 +57,13 @@ class NewAccessToken extends Notification ; } - /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toSlack($notifiable) { return (new SlackMessage())->content((string)trans('email.access_token_created_body')); } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { /** @var null|User $user */ diff --git a/app/Notifications/User/RuleActionFailed.php b/app/Notifications/User/RuleActionFailed.php index 669d8b8e7b..35ea148b1e 100644 --- a/app/Notifications/User/RuleActionFailed.php +++ b/app/Notifications/User/RuleActionFailed.php @@ -43,9 +43,7 @@ class RuleActionFailed extends Notification private string $ruleLink; private string $ruleTitle; - /** - * Create a new notification instance. - */ + public function __construct(array $params) { [$mainMessage, $groupTitle, $groupLink, $ruleTitle, $ruleLink] = $params; @@ -56,30 +54,14 @@ class RuleActionFailed extends Notification $this->ruleLink = $ruleLink; } - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toSlack($notifiable) { $groupTitle = $this->groupTitle; @@ -94,15 +76,7 @@ class RuleActionFailed extends Notification }); } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { /** @var null|User $user */ diff --git a/app/Notifications/User/TransactionCreation.php b/app/Notifications/User/TransactionCreation.php index fcf9f95fc0..61e2626d8a 100644 --- a/app/Notifications/User/TransactionCreation.php +++ b/app/Notifications/User/TransactionCreation.php @@ -37,38 +37,20 @@ class TransactionCreation extends Notification private array $collection; - /** - * Create a new notification instance. - */ + public function __construct(array $collection) { $this->collection = $collection; } - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toMail($notifiable) { return (new MailMessage()) @@ -77,15 +59,7 @@ class TransactionCreation extends Notification ; } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { return ['mail']; diff --git a/app/Notifications/User/UserLogin.php b/app/Notifications/User/UserLogin.php index e7fc4e8a53..3107748de0 100644 --- a/app/Notifications/User/UserLogin.php +++ b/app/Notifications/User/UserLogin.php @@ -41,38 +41,20 @@ class UserLogin extends Notification private string $ip; - /** - * Create a new notification instance. - */ + public function __construct(string $ip) { $this->ip = $ip; } - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toMail($notifiable) { $time = now(config('app.timezone'))->isoFormat((string)trans('config.date_time_js')); @@ -94,15 +76,7 @@ class UserLogin extends Notification ; } - /** - * Get the Slack representation of the notification. - * - * @param mixed $notifiable - * - * @return SlackMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toSlack($notifiable) { $host = ''; @@ -120,15 +94,7 @@ class UserLogin extends Notification return (new SlackMessage())->content((string)trans('email.slack_login_from_new_ip', ['host' => $host, 'ip' => $this->ip])); } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { /** @var null|User $user */ diff --git a/app/Notifications/User/UserNewPassword.php b/app/Notifications/User/UserNewPassword.php index e4090984d5..e75861add3 100644 --- a/app/Notifications/User/UserNewPassword.php +++ b/app/Notifications/User/UserNewPassword.php @@ -37,38 +37,20 @@ class UserNewPassword extends Notification private string $url; - /** - * Create a new notification instance. - */ + public function __construct(string $url) { $this->url = $url; } - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toMail($notifiable) { return (new MailMessage()) @@ -77,15 +59,7 @@ class UserNewPassword extends Notification ; } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { return ['mail']; diff --git a/app/Notifications/User/UserRegistration.php b/app/Notifications/User/UserRegistration.php index 50aae568a3..bde33969f6 100644 --- a/app/Notifications/User/UserRegistration.php +++ b/app/Notifications/User/UserRegistration.php @@ -35,35 +35,17 @@ class UserRegistration extends Notification { use Queueable; - /** - * Create a new notification instance. - */ + public function __construct() {} - /** - * Get the array representation of the notification. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toArray($notifiable) { return [ ]; } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * - * @return MailMessage - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function toMail($notifiable) { return (new MailMessage()) @@ -72,15 +54,7 @@ class UserRegistration extends Notification ; } - /** - * Get the notification's delivery channels. - * - * @param mixed $notifiable - * - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ + public function via($notifiable) { return ['mail']; diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index d6931d1da6..9ce9cef6b0 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -47,6 +47,7 @@ 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; use FireflyIII\Events\StoredTransactionGroup; use FireflyIII\Events\Test\OwnerTestNotificationChannel; @@ -109,6 +110,9 @@ class EventServiceProvider extends ServiceProvider 'FireflyIII\Handlers\Events\UserEventHandler@createGroupMembership', 'FireflyIII\Handlers\Events\UserEventHandler@createExchangeRates', ], + UserAttemptedLogin::class => [ + 'FireflyIII\Handlers\Events\UserEventHandler@sendLoginAttemptNotification', + ], // is a User related event. Login::class => [ 'FireflyIII\Handlers\Events\UserEventHandler@checkSingleUserIsAdmin',