mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-05 04:03:26 +00:00
Code for #3712
This commit is contained in:
49
app/Events/DetectedNewIPAddress.php
Normal file
49
app/Events/DetectedNewIPAddress.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/*
|
||||
* DetectedNewIPAddress.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class DetectedNewIPAddress
|
||||
*/
|
||||
class DetectedNewIPAddress extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public string $ipAddress;
|
||||
public User $user;
|
||||
|
||||
/**
|
||||
* Create a new event instance. This event is triggered when a new user registers.
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $ipAddress
|
||||
*/
|
||||
public function __construct(User $user, string $ipAddress)
|
||||
{
|
||||
$this->ipAddress = $ipAddress;
|
||||
$this->user = $user;
|
||||
}
|
||||
}
|
@@ -23,11 +23,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Events\DetectedNewIPAddress;
|
||||
use FireflyIII\Events\RegisteredUser;
|
||||
use FireflyIII\Events\RequestedNewPassword;
|
||||
use FireflyIII\Events\UserChangedEmail;
|
||||
use FireflyIII\Mail\ConfirmEmailChangeMail;
|
||||
use FireflyIII\Mail\NewIPAddressWarningMail;
|
||||
use FireflyIII\Mail\RegisteredUser as RegisteredUserMail;
|
||||
use FireflyIII\Mail\RequestedNewPassword as RequestedNewPasswordMail;
|
||||
use FireflyIII\Mail\UndoEmailChangeMail;
|
||||
@@ -125,6 +128,78 @@ class UserEventHandler
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Login $event
|
||||
*/
|
||||
public function storeUserIPAddress(Login $event): void
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $event->user;
|
||||
/** @var array $preference */
|
||||
$preference = app('preferences')->getForUser($user, 'login_ip_history', [])->data;
|
||||
$inArray = false;
|
||||
$ip = request()->ip();
|
||||
Log::debug(sprintf('User logging in from IP address %s', $ip));
|
||||
|
||||
// update array if in array
|
||||
foreach ($preference as $index => $row) {
|
||||
if ($row['ip'] === $ip) {
|
||||
Log::debug('Found IP in array, refresh time.');
|
||||
$preference[$index]['time'] = now(config('app.timezone'))->format('Y-m-d H:i:s');
|
||||
$inArray = true;
|
||||
}
|
||||
// clean up old entries (6 months)
|
||||
$carbon = Carbon::createFromFormat('Y-m-d H:i:s', $preference[$index]['time']);
|
||||
if ($carbon->diffInMonths(today()) > 6) {
|
||||
Log::debug(sprintf('Entry for %s is very old, remove it.', $row['ip']));
|
||||
unset($preference[$index]);
|
||||
}
|
||||
}
|
||||
// add to array if not the case:
|
||||
if (false === $inArray) {
|
||||
$preference[] = [
|
||||
'ip' => $ip,
|
||||
'time' => now(config('app.timezone'))->format('Y-m-d H:i:s'),
|
||||
'notified' => false,
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
$preference = array_values($preference);
|
||||
app('preferences')->setForUser($user, 'login_ip_history', $preference);
|
||||
|
||||
if (false === $inArray) {
|
||||
event(new DetectedNewIPAddress($user, $ip));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DetectedNewIPAddress $event
|
||||
*/
|
||||
public function notifyNewIPAddress(DetectedNewIPAddress $event): void
|
||||
{
|
||||
$user = $event->user;
|
||||
$email = $user->email;
|
||||
$ipAddress = $event->ipAddress;
|
||||
$list = app('preferences')->getForUser($user, 'login_ip_history', [])->data;
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($list as $index => $entry) {
|
||||
if (false === $entry['notified']) {
|
||||
try {
|
||||
Mail::to($email)->send(new NewIPAddressWarningMail($ipAddress));
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
}
|
||||
$list[$index]['notified'] = true;
|
||||
}
|
||||
|
||||
app('preferences')->setForUser($user, 'login_ip_history', $list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email to confirm email change.
|
||||
*
|
||||
@@ -167,7 +242,7 @@ class UserEventHandler
|
||||
$ipAddress = $event->ipAddress;
|
||||
$token = app('preferences')->getForUser($user, 'email_change_undo_token', 'invalid');
|
||||
$hashed = hash('sha256', sprintf('%s%s', (string) config('app.key'), $oldEmail));
|
||||
$uri = route('profile.undo-email-change', [$token->data,$hashed]);
|
||||
$uri = route('profile.undo-email-change', [$token->data, $hashed]);
|
||||
try {
|
||||
Mail::to($oldEmail)->send(new UndoEmailChangeMail($newEmail, $oldEmail, $uri, $ipAddress));
|
||||
// @codeCoverageIgnoreStart
|
||||
|
59
app/Mail/NewIPAddressWarningMail.php
Normal file
59
app/Mail/NewIPAddressWarningMail.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/*
|
||||
* NewIPAddressWarningMail.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Mail;
|
||||
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Laravel\Passport\Client;
|
||||
|
||||
/**
|
||||
* Class NewIPAddressWarningMail
|
||||
*/
|
||||
class NewIPAddressWarningMail extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public string $ipAddress;
|
||||
|
||||
/**
|
||||
* OAuthTokenCreatedMail constructor.
|
||||
*
|
||||
* @param string $ipAddress
|
||||
*/
|
||||
public function __construct(string $ipAddress)
|
||||
{
|
||||
$this->ipAddress = $ipAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build(): self
|
||||
{
|
||||
return $this->view('emails.new-ip-html')->text('emails.new-ip-text')
|
||||
->subject((string) trans('email.login_from_new_ip'));
|
||||
}
|
||||
}
|
@@ -24,6 +24,7 @@ namespace FireflyIII\Providers;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Events\AdminRequestedTestMessage;
|
||||
use FireflyIII\Events\DetectedNewIPAddress;
|
||||
use FireflyIII\Events\RegisteredUser;
|
||||
use FireflyIII\Events\RequestedNewPassword;
|
||||
use FireflyIII\Events\RequestedReportOnJournals;
|
||||
@@ -67,6 +68,10 @@ class EventServiceProvider extends ServiceProvider
|
||||
Login::class => [
|
||||
'FireflyIII\Handlers\Events\UserEventHandler@checkSingleUserIsAdmin',
|
||||
'FireflyIII\Handlers\Events\UserEventHandler@demoUserBackToEnglish',
|
||||
'FireflyIII\Handlers\Events\UserEventHandler@storeUserIPAddress',
|
||||
],
|
||||
DetectedNewIPAddress::class => [
|
||||
'FireflyIII\Handlers\Events\UserEventHandler@notifyNewIPAddress',
|
||||
],
|
||||
RequestedVersionCheckStatus::class => [
|
||||
'FireflyIII\Handlers\Events\VersionCheckEventHandler@checkForUpdates',
|
||||
|
@@ -51,7 +51,6 @@ class RemoteUserGuard implements Guard
|
||||
*/
|
||||
public function __construct(UserProvider $provider, Application $app)
|
||||
{
|
||||
Log::debug('Constructed RemoteUserGuard');
|
||||
$this->application = $app;
|
||||
$this->provider = $provider;
|
||||
$this->user = null;
|
||||
|
Reference in New Issue
Block a user