Compare commits

..

47 Commits

Author SHA1 Message Date
github-actions[bot]
d9c09fe566 Merge pull request #11562 from firefly-iii/release-1768885025
🤖 Automatically merge the PR into the develop branch.
2026-01-20 05:57:12 +01:00
JC5
0686d86ef8 🤖 Auto commit for release 'develop' on 2026-01-20 2026-01-20 05:57:05 +01:00
James Cole
7c2aea31fe Update jquery 2026-01-20 05:49:14 +01:00
James Cole
bb0af2396e Merge pull request #11551 from firefly-iii/dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-20 05:08:52 +01:00
mergify[bot]
4718ee9723 Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 19:24:23 +00:00
github-actions[bot]
55c762d55a Merge pull request #11558 from firefly-iii/release-1768850616
🤖 Automatically merge the PR into the develop branch.
2026-01-19 20:23:44 +01:00
JC5
734df18f4e 🤖 Auto commit for release 'develop' on 2026-01-19 2026-01-19 20:23:36 +01:00
mergify[bot]
11537c4922 Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 19:20:14 +00:00
James Cole
30205d828a Merge pull request #11552 from firefly-iii/dependabot/npm_and_yarn/develop/jquery-4.0.0
Bump jquery from 3.7.1 to 4.0.0
2026-01-19 20:19:30 +01:00
mergify[bot]
6b2d724a5b Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 19:18:17 +00:00
mergify[bot]
9c0eb8a028 Merge branch 'develop' into dependabot/npm_and_yarn/develop/jquery-4.0.0 2026-01-19 19:18:01 +00:00
James Cole
103a6d1b15 Expand events for #11544 2026-01-19 20:17:16 +01:00
mergify[bot]
99403ab9f6 Merge branch 'develop' into dependabot/npm_and_yarn/develop/jquery-4.0.0 2026-01-19 19:11:10 +00:00
mergify[bot]
5980ac0b64 Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 19:11:07 +00:00
James Cole
b9e5851e38 Remove unused class #11411 2026-01-19 20:09:53 +01:00
mergify[bot]
6da02065b7 Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 19:08:57 +00:00
mergify[bot]
eab18ed2f2 Merge branch 'develop' into dependabot/npm_and_yarn/develop/jquery-4.0.0 2026-01-19 19:08:53 +00:00
James Cole
67d18e4b62 Clean up latest MFA handler #11455 2026-01-19 20:08:15 +01:00
mergify[bot]
41da3a014f Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 19:02:51 +00:00
mergify[bot]
71774905b0 Merge branch 'develop' into dependabot/npm_and_yarn/develop/jquery-4.0.0 2026-01-19 19:02:47 +00:00
James Cole
48f886d17c Replace multiple failures alert #11544 2026-01-19 20:02:20 +01:00
James Cole
e28df272b5 Replace multiple failures alert #11544 2026-01-19 20:02:08 +01:00
mergify[bot]
c7f4c40435 Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 18:57:51 +00:00
mergify[bot]
95e98cfeca Merge branch 'develop' into dependabot/npm_and_yarn/develop/jquery-4.0.0 2026-01-19 18:57:47 +00:00
James Cole
095d31fbe1 Replace multiple failures alert #11544 2026-01-19 19:57:09 +01:00
mergify[bot]
8db08cc623 Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 18:50:19 +00:00
mergify[bot]
27044aeecf Merge branch 'develop' into dependabot/npm_and_yarn/develop/jquery-4.0.0 2026-01-19 18:50:15 +00:00
James Cole
8bd7752e2b Clean up more MFA event handlers #11544 2026-01-19 19:49:50 +01:00
James Cole
ee24d55554 Clean up more MFA event handlers #11544 2026-01-19 19:49:34 +01:00
mergify[bot]
8e8e0ab67d Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 18:43:54 +00:00
mergify[bot]
740a14972a Merge branch 'develop' into dependabot/npm_and_yarn/develop/jquery-4.0.0 2026-01-19 18:43:44 +00:00
James Cole
c6667c2293 Continued. #11544 2026-01-19 19:43:23 +01:00
James Cole
8327a3d670 Enabled MFA notifications #11544 2026-01-19 19:43:06 +01:00
mergify[bot]
4278d59d05 Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 18:37:08 +00:00
mergify[bot]
5534bedde0 Merge branch 'develop' into dependabot/npm_and_yarn/develop/jquery-4.0.0 2026-01-19 18:37:02 +00:00
James Cole
83fe7f6f6d MFA disabled #11544 2026-01-19 19:36:21 +01:00
mergify[bot]
669bb20228 Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 18:33:07 +00:00
mergify[bot]
e41dbdc3a7 Merge branch 'develop' into dependabot/npm_and_yarn/develop/jquery-4.0.0 2026-01-19 18:33:03 +00:00
James Cole
670f98eb66 Merge branch 'main' into develop 2026-01-19 19:32:21 +01:00
mergify[bot]
3229011035 Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 06:56:35 +00:00
mergify[bot]
7e02bee90b Merge branch 'develop' into dependabot/npm_and_yarn/develop/jquery-4.0.0 2026-01-19 06:56:31 +00:00
James Cole
d12fd40a57 Merge pull request #11554 from firefly-iii/JC5-patch-2
Update PHP version setup in release workflow
2026-01-19 07:52:00 +01:00
James Cole
4405b2ac8f Update PHP version setup in release workflow
Set default PHP version to 8.4 if not provided.

Signed-off-by: James Cole <james@firefly-iii.org>
2026-01-19 07:51:49 +01:00
mergify[bot]
cc99abefac Merge branch 'develop' into dependabot/npm_and_yarn/develop/i18next-chained-backend-5.0.0 2026-01-19 06:03:18 +00:00
mergify[bot]
bbbc8492db Merge branch 'develop' into dependabot/npm_and_yarn/develop/jquery-4.0.0 2026-01-19 06:03:13 +00:00
dependabot[bot]
edb8f811af Bump jquery from 3.7.1 to 4.0.0
Bumps [jquery](https://github.com/jquery/jquery) from 3.7.1 to 4.0.0.
- [Release notes](https://github.com/jquery/jquery/releases)
- [Changelog](https://github.com/jquery/jquery/blob/main/changelog.md)
- [Commits](https://github.com/jquery/jquery/compare/3.7.1...4.0.0)

---
updated-dependencies:
- dependency-name: jquery
  dependency-version: 4.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 04:09:35 +00:00
dependabot[bot]
d79d1a3317 Bump i18next-chained-backend from 4.6.3 to 5.0.0
Bumps [i18next-chained-backend](https://github.com/i18next/i18next-chained-backend) from 4.6.3 to 5.0.0.
- [Changelog](https://github.com/i18next/i18next-chained-backend/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next-chained-backend/compare/v4.6.3...v5.0.0)

---
updated-dependencies:
- dependency-name: i18next-chained-backend
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 04:09:22 +00:00
35 changed files with 896 additions and 628 deletions

View File

@@ -42,7 +42,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ github.event.inputs.phpversion }}
php-version: ${{ github.event.inputs.phpversion || '8.4' }}
extensions: mbstring, intl, zip, bcmath
- name: Switch and pull
run: |

View File

@@ -1,44 +0,0 @@
<?php
/*
* EnabledMFA.php
* Copyright (c) 2024 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/.
*/
declare(strict_types=1);
namespace FireflyIII\Events\Security;
use FireflyIII\Events\Event;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Queue\SerializesModels;
class MFAUsedBackupCode extends Event
{
use SerializesModels;
public User $user;
public function __construct(Authenticatable|User|null $user)
{
if ($user instanceof User) {
$this->user = $user;
}
}
}

View File

@@ -1,8 +1,9 @@
<?php
declare(strict_types=1);
/*
* UnknownUserAttemptedLogin.php
* Copyright (c) 2024 james@firefly-iii.org.
* UnknownUserTriedLogin.php
* Copyright (c) 2026 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -17,16 +18,14 @@
* 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/.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Events\Security;
namespace FireflyIII\Events\Security\System;
use Illuminate\Queue\SerializesModels;
class UnknownUserAttemptedLogin
class UnknownUserTriedLogin
{
use SerializesModels;

View File

@@ -1,8 +1,9 @@
<?php
declare(strict_types=1);
/*
* EnabledMFA.php
* Copyright (c) 2024 james@firefly-iii.org.
* UserFailedLoginAttempt.php
* Copyright (c) 2026 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -17,19 +18,18 @@
* 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/.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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 MFABackupNoLeft extends Event
class UserFailedLoginAttempt extends Event
{
use SerializesModels;
@@ -39,6 +39,10 @@ class MFABackupNoLeft extends Event
{
if ($user instanceof User) {
$this->user = $user;
return;
}
throw new InvalidArgumentException('User must be an instance of User.');
}
}

View File

@@ -1,8 +1,9 @@
<?php
declare(strict_types=1);
/*
* EnabledMFA.php
* Copyright (c) 2024 james@firefly-iii.org.
* UserHasDisabledMFA.php
* Copyright (c) 2026 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -17,19 +18,18 @@
* 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/.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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 EnabledMFA extends Event
class UserHasDisabledMFA extends Event
{
use SerializesModels;
@@ -39,6 +39,10 @@ class EnabledMFA extends Event
{
if ($user instanceof User) {
$this->user = $user;
return;
}
throw new InvalidArgumentException('User must be an instance of User.');
}
}

View File

@@ -1,8 +1,9 @@
<?php
declare(strict_types=1);
/*
* EnabledMFA.php
* Copyright (c) 2024 james@firefly-iii.org.
* UserHasEnabledMFA.php
* Copyright (c) 2026 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -17,19 +18,18 @@
* 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/.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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 DisabledMFA extends Event
class UserHasEnabledMFA extends Event
{
use SerializesModels;
@@ -39,6 +39,10 @@ class DisabledMFA extends Event
{
if ($user instanceof User) {
$this->user = $user;
return;
}
throw new InvalidArgumentException('User must be an instance of User.');
}
}

View File

@@ -1,8 +1,9 @@
<?php
declare(strict_types=1);
/*
* EnabledMFA.php
* Copyright (c) 2024 james@firefly-iii.org.
* UserHasFewMFABackupCodesLeft.php
* Copyright (c) 2026 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -17,19 +18,18 @@
* 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/.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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 MFABackupFewLeft extends Event
class UserHasFewMFABackupCodesLeft extends Event
{
use SerializesModels;
@@ -39,6 +39,10 @@ class MFABackupFewLeft extends Event
{
if ($user instanceof User) {
$this->user = $user;
return;
}
throw new InvalidArgumentException('User must be an instance of User.');
}
}

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
/*
* UserHasGeneratedNewBackupCodes.php
* Copyright (c) 2026 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\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.');
}
}

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
/*
* UserHasNoMFABackupCodesLeft.php
* Copyright (c) 2026 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\Security\User;
use FireflyIII\Events\Event;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Queue\SerializesModels;
use InvalidArgumentException;
class UserHasNoMFABackupCodesLeft 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.');
}
}

View File

@@ -1,8 +1,9 @@
<?php
declare(strict_types=1);
/*
* EnabledMFA.php
* Copyright (c) 2024 james@firefly-iii.org.
* UserHasUsedBackupCode.php
* Copyright (c) 2026 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -17,19 +18,18 @@
* 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/.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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 +39,10 @@ class MFANewBackupCodes extends Event
{
if ($user instanceof User) {
$this->user = $user;
return;
}
throw new InvalidArgumentException('User must be an instance of User.');
}
}

View File

@@ -1,8 +1,9 @@
<?php
declare(strict_types=1);
/*
* EnabledMFA.php
* Copyright (c) 2024 james@firefly-iii.org.
* UserKeepsFailingMFA.php
* Copyright (c) 2026 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -17,19 +18,18 @@
* 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/.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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 MFAManyFailedAttempts extends Event
class UserKeepsFailingMFA extends Event
{
use SerializesModels;
@@ -39,6 +39,10 @@ class MFAManyFailedAttempts extends Event
{
if ($user instanceof User) {
$this->user = $user;
return;
}
throw new InvalidArgumentException('User must be an instance of User.');
}
}

View File

@@ -1,44 +0,0 @@
<?php
/*
* UserAttemptedLogin.php
* Copyright (c) 2024 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/.
*/
declare(strict_types=1);
namespace FireflyIII\Events\Security;
use FireflyIII\Events\Event;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Queue\SerializesModels;
class UserAttemptedLogin extends Event
{
use SerializesModels;
public User $user;
public function __construct(Authenticatable|User|null $user)
{
if ($user instanceof User) {
$this->user = $user;
}
}
}

View File

@@ -26,18 +26,16 @@ namespace FireflyIII\Handlers\Events;
use Exception;
use FireflyIII\Events\Admin\InvitationCreated;
use FireflyIII\Events\NewVersionAvailable;
use FireflyIII\Events\Security\UnknownUserAttemptedLogin;
use FireflyIII\Events\Test\OwnerTestNotificationChannel;
use FireflyIII\Notifications\Admin\UnknownUserLoginAttempt;
use FireflyIII\Notifications\Admin\UserInvitation;
use FireflyIII\Notifications\Admin\VersionCheckResult;
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
use FireflyIII\Notifications\Test\OwnerTestNotificationEmail;
use FireflyIII\Notifications\Test\OwnerTestNotificationPushover;
use FireflyIII\Notifications\Test\OwnerTestNotificationSlack;
use FireflyIII\Support\Facades\FireflyConfig;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class AdminEventHandler.
@@ -70,28 +68,6 @@ class AdminEventHandler
}
}
public function sendLoginAttemptNotification(UnknownUserAttemptedLogin $event): void
{
try {
$owner = new OwnerNotifiable();
Notification::send($owner, new UnknownUserLoginAttempt($event->address));
} 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());
}
}
/**
* Send new version message to admin.
*/

View File

@@ -1,223 +0,0 @@
<?php
/*
* MFAHandler.php
* Copyright (c) 2024 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/.
*/
declare(strict_types=1);
namespace FireflyIII\Handlers\Events\Security;
use Exception;
use FireflyIII\Events\Security\DisabledMFA;
use FireflyIII\Events\Security\EnabledMFA;
use FireflyIII\Events\Security\MFABackupFewLeft;
use FireflyIII\Events\Security\MFABackupNoLeft;
use FireflyIII\Events\Security\MFAManyFailedAttempts;
use FireflyIII\Events\Security\MFANewBackupCodes;
use FireflyIII\Events\Security\MFAUsedBackupCode;
use FireflyIII\Notifications\Security\DisabledMFANotification;
use FireflyIII\Notifications\Security\EnabledMFANotification;
use FireflyIII\Notifications\Security\MFABackupFewLeftNotification;
use FireflyIII\Notifications\Security\MFABackupNoLeftNotification;
use FireflyIII\Notifications\Security\MFAManyFailedAttemptsNotification;
use FireflyIII\Notifications\Security\MFAUsedBackupCodeNotification;
use FireflyIII\Notifications\Security\NewBackupCodesNotification;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Log;
class MFAHandler
{
public function sendBackupFewLeftMail(MFABackupFewLeft $event): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$user = $event->user;
$count = $event->count;
try {
Notification::send($user, new MFABackupFewLeftNotification($user, $count));
} 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());
}
}
public function sendBackupNoLeftMail(MFABackupNoLeft $event): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$user = $event->user;
try {
Notification::send($user, new MFABackupNoLeftNotification($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());
}
}
public function sendMFADisabledMail(DisabledMFA $event): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$user = $event->user;
try {
Notification::send($user, new DisabledMFANotification($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());
}
}
public function sendMFAEnabledMail(EnabledMFA $event): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$user = $event->user;
try {
Notification::send($user, new EnabledMFANotification($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());
}
}
public function sendMFAFailedAttemptsMail(MFAManyFailedAttempts $event): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$user = $event->user;
$count = $event->count;
try {
Notification::send($user, new MFAManyFailedAttemptsNotification($user, $count));
} 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());
}
}
public function sendNewMFABackupCodesMail(MFANewBackupCodes $event): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$user = $event->user;
try {
Notification::send($user, new NewBackupCodesNotification($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());
}
}
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());
}
}
}

View File

@@ -32,7 +32,6 @@ 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\UserTestNotificationChannel;
use FireflyIII\Events\UserChangedEmail;
use FireflyIII\Exceptions\FireflyException;
@@ -43,7 +42,6 @@ use FireflyIII\Models\GroupMembership;
use FireflyIII\Models\UserGroup;
use FireflyIII\Models\UserRole;
use FireflyIII\Notifications\Admin\UserRegistration as AdminRegistrationNotification;
use FireflyIII\Notifications\Security\UserFailedLoginAttempt;
use FireflyIII\Notifications\Test\UserTestNotificationEmail;
use FireflyIII\Notifications\Test\UserTestNotificationPushover;
use FireflyIII\Notifications\Test\UserTestNotificationSlack;
@@ -51,13 +49,13 @@ use FireflyIII\Notifications\User\UserLogin;
use FireflyIII\Notifications\User\UserNewPassword;
use FireflyIII\Notifications\User\UserRegistration as UserRegistrationNotification;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Facades\Preferences;
use FireflyIII\User;
use Illuminate\Auth\Events\Login;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Notification;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class UserEventHandler.
@@ -298,27 +296,6 @@ class UserEventHandler
}
}
public function sendLoginAttemptNotification(UserAttemptedLogin $event): void
{
try {
Notification::send($event->user, new UserFailedLoginAttempt($event->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());
}
}
/**
* Send a new password to the user.
*/

View File

@@ -25,12 +25,13 @@ namespace FireflyIII\Http\Controllers\Auth;
use Carbon\Carbon;
use FireflyIII\Events\ActuallyLoggedIn;
use FireflyIII\Events\Security\UnknownUserAttemptedLogin;
use FireflyIII\Events\Security\UserAttemptedLogin;
use FireflyIII\Events\Security\System\UnknownUserTriedLogin;
use FireflyIII\Events\Security\User\UserFailedLoginAttempt;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Providers\RouteServiceProvider;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\User;
use Illuminate\Contracts\Foundation\Application;
@@ -50,7 +51,6 @@ use Illuminate\Validation\ValidationException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class LoginController
@@ -138,10 +138,10 @@ class LoginController extends Controller
$user = $this->repository->findByEmail($username);
if (!$user instanceof User) {
// send event to owner.
event(new UnknownUserAttemptedLogin($username));
event(new UnknownUserTriedLogin($username));
}
if ($user instanceof User) {
event(new UserAttemptedLogin($user));
event(new UserFailedLoginAttempt($user));
}
// Copied directly from AuthenticatesUsers, but with logging added:

View File

@@ -23,13 +23,13 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Auth;
use FireflyIII\Support\Facades\Preferences;
use Carbon\Carbon;
use FireflyIII\Events\Security\MFABackupFewLeft;
use FireflyIII\Events\Security\MFABackupNoLeft;
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;
use FireflyIII\User;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
@@ -54,7 +54,7 @@ class TwoFactorController extends Controller
/** @var User $user */
$user = auth()->user();
$siteOwner = config('firefly.site_owner');
$title = (string) trans('firefly.two_factor_forgot_title');
$title = (string)trans('firefly.two_factor_forgot_title');
return view('auth.lost-two-factor', ['user' => $user, 'siteOwner' => $siteOwner, 'title' => $title]);
}
@@ -67,7 +67,7 @@ class TwoFactorController extends Controller
{
/** @var array $mfaHistory */
$mfaHistory = Preferences::get('mfa_history', [])->data;
$mfaCode = (string) $request->get('one_time_password');
$mfaCode = (string)$request->get('one_time_password');
// is in history? then refuse to use it.
if ($this->inMFAHistory($mfaCode, $mfaHistory)) {
@@ -88,7 +88,7 @@ class TwoFactorController extends Controller
if (3 === $counter || 10 === $counter) {
// do not reset MFA failure counter, but DO send a warning to the user.
Log::channel('audit')->info(sprintf('User "%s" has had %d failed MFA attempts.', $user->email, $counter));
event(new MFAManyFailedAttempts($user, $counter));
event(new UserKeepsFailingMFA($user, $counter));
}
unset($user);
}
@@ -116,7 +116,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'));
}
@@ -168,7 +168,7 @@ class TwoFactorController extends Controller
private function addToMFAFailureCounter(): void
{
$preference = (int) Preferences::get('mfa_failure_count', 0)->data;
$preference = (int)Preferences::get('mfa_failure_count', 0)->data;
++$preference;
Log::channel('audit')->info(sprintf('MFA failure count is set to %d.', $preference));
Preferences::set('mfa_failure_count', $preference);
@@ -176,7 +176,7 @@ class TwoFactorController extends Controller
private function getMFAFailureCounter(): int
{
$value = (int) Preferences::get('mfa_failure_count', 0)->data;
$value = (int)Preferences::get('mfa_failure_count', 0)->data;
Log::channel('audit')->info(sprintf('MFA failure count is %d.', $value));
return $value;
@@ -230,13 +230,13 @@ class TwoFactorController extends Controller
if (count($newList) <= 3 && count($newList) > 0) {
$user = auth()->user();
Log::channel('audit')->info(sprintf('User "%s" has used a backup code. They have %d backup codes left.', $user->email, count($newList)));
event(new MFABackupFewLeft($user, count($newList)));
event(new UserHasFewMFABackupCodesLeft($user, count($newList)));
}
// if the list is empty, send notification
if (0 === count($newList)) {
$user = auth()->user();
Log::channel('audit')->info(sprintf('User "%s" has used their last backup code.', $user->email));
event(new MFABackupNoLeft($user));
event(new UserHasNoMFABackupCodesLeft($user));
}
Preferences::set('mfa_recovery', $newList);

View File

@@ -24,16 +24,16 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Profile;
use FireflyIII\Support\Facades\Preferences;
use Carbon\Carbon;
use FireflyIII\Events\Security\DisabledMFA;
use FireflyIII\Events\Security\EnabledMFA;
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;
use FireflyIII\Http\Requests\TokenFormRequest;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Support\Facades\Preferences;
use FireflyIII\User;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
@@ -71,7 +71,7 @@ class MfaController extends Controller
$this->middleware(
static function ($request, $next) {
app('view')->share('title', (string) trans('firefly.profile'));
app('view')->share('title', (string)trans('firefly.profile'));
app('view')->share('mainTitleIcon', 'fa-user');
return $next($request);
@@ -131,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]);
@@ -150,7 +150,7 @@ class MfaController extends Controller
return redirect(route('profile.index'));
}
$subTitle = (string) trans('firefly.mfa_index_title');
$subTitle = (string)trans('firefly.mfa_index_title');
$subTitleIcon = 'fa-calculator';
return view('profile.mfa.disable-mfa')->with(['subTitle' => $subTitle, 'subTitleIcon' => $subTitleIcon, 'enabledMFA' => $enabledMFA]);
@@ -178,8 +178,8 @@ class MfaController extends Controller
$repository->setMFACode($user, null);
Preferences::mark();
session()->flash('success', (string) trans('firefly.pref_two_factor_auth_disabled'));
session()->flash('info', (string) trans('firefly.pref_two_factor_auth_remove_it'));
session()->flash('success', (string)trans('firefly.pref_two_factor_auth_disabled'));
session()->flash('info', (string)trans('firefly.pref_two_factor_auth_remove_it'));
// also logout current 2FA tokens.
$cookieName = config('google2fa.cookie_name', 'google2fa_token');
@@ -187,7 +187,7 @@ class MfaController extends Controller
// send user notification.
Log::channel('audit')->info(sprintf('User "%s" has disabled MFA', $user->email));
event(new DisabledMFA($user));
event(new UserHasDisabledMFA($user));
return redirect(route('profile.index'));
}
@@ -210,7 +210,7 @@ class MfaController extends Controller
// If FF3 already has a secret, just set the two-factor auth enabled to 1,
// and let the user continue with the existing secret.
if ($enabledMFA) {
session()->flash('info', (string) trans('firefly.2fa_already_enabled'));
session()->flash('info', (string)trans('firefly.2fa_already_enabled'));
return redirect(route('profile.index'));
}
@@ -257,13 +257,13 @@ class MfaController extends Controller
if (is_array($secret)) {
$secret = null;
}
$secret = (string) $secret;
$secret = (string)$secret;
$repository->setMFACode($user, $secret);
Preferences::delete('temp-mfa-secret');
session()->flash('success', (string) trans('firefly.saved_preferences'));
session()->flash('success', (string)trans('firefly.saved_preferences'));
Preferences::mark();
// also save the code so replay attack is prevented.
@@ -280,7 +280,7 @@ class MfaController extends Controller
// send user notification.
Log::channel('audit')->info(sprintf('User "%s" has enabled MFA', $user->email));
event(new EnabledMFA($user));
event(new UserHasEnabledMFA($user));
return redirect(route('profile.mfa.backup-codes'));
}
@@ -335,7 +335,7 @@ class MfaController extends Controller
return redirect(route('profile.index'));
}
$subTitle = (string) trans('firefly.mfa_index_title');
$subTitle = (string)trans('firefly.mfa_index_title');
$subTitleIcon = 'fa-calculator';
$enabledMFA = null !== auth()->user()->mfa_secret;

View File

@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
/*
* NotifiesOwnerAboutUnknownUser.php
* Copyright (c) 2026 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\Listeners\Security\System;
use Exception;
use FireflyIII\Events\Security\System\UnknownUserTriedLogin;
use FireflyIII\Notifications\Admin\UnknownUserLoginAttempt;
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
class NotifiesOwnerAboutUnknownUser
{
public function handle(UnknownUserTriedLogin $event): void
{
try {
$owner = new OwnerNotifiable();
Notification::send($owner, new UnknownUserLoginAttempt($event->address));
} 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());
}
}
}

View File

@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
/*
* NotifiesUserAboutDisabledMFA.php
* Copyright (c) 2026 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\Listeners\Security\User;
use Exception;
use FireflyIII\Events\Security\User\UserHasDisabledMFA;
use FireflyIII\Notifications\Security\DisabledMFANotification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
class NotifiesUserAboutDisabledMFA implements ShouldQueue
{
public function handle(UserHasDisabledMFA $event): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$user = $event->user;
try {
Notification::send($user, new DisabledMFANotification($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());
}
}
}

View File

@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
/*
* NotifiesUserAboutEnabledMFA.php
* Copyright (c) 2026 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\Listeners\Security\User;
use Exception;
use FireflyIII\Events\Security\User\UserHasEnabledMFA;
use FireflyIII\Notifications\Security\EnabledMFANotification;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
class NotifiesUserAboutEnabledMFA
{
public function handle(UserHasEnabledMFA $event): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$user = $event->user;
try {
Notification::send($user, new EnabledMFANotification($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());
}
}
}

View File

@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
/*
* NotifiesUserAboutFailedLogin.php
* Copyright (c) 2026 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\Listeners\Security\User;
use Exception;
use FireflyIII\Events\Security\User\UserFailedLoginAttempt;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
class NotifiesUserAboutFailedLogin
{
public function handle(UserFailedLoginAttempt $event): void
{
try {
Notification::send($event->user, new \FireflyIII\Notifications\Security\UserFailedLoginAttempt($event->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());
}
}
}

View File

@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
/*
* NotifiesUserAboutFewCodesLeft.php
* Copyright (c) 2026 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\Listeners\Security\User;
use Exception;
use FireflyIII\Events\Security\User\UserHasFewMFABackupCodesLeft;
use FireflyIII\Notifications\Security\MFABackupFewLeftNotification;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
class NotifiesUserAboutFewCodesLeft
{
public function handle(UserHasFewMFABackupCodesLeft $event): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$user = $event->user;
$count = $event->count;
try {
Notification::send($user, new MFABackupFewLeftNotification($user, $count));
} 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());
}
}
}

View File

@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
/*
* NotifiesUserAboutNewBackupCodes.php
* Copyright (c) 2026 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\Listeners\Security\User;
use Exception;
use FireflyIII\Events\Security\User\UserHasGeneratedNewBackupCodes;
use FireflyIII\Notifications\Security\NewBackupCodesNotification;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
class NotifiesUserAboutNewBackupCodes
{
public function handle(UserHasGeneratedNewBackupCodes $event): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$user = $event->user;
try {
Notification::send($user, new NewBackupCodesNotification($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());
}
}
}

View File

@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
/*
* NotifiesUserAboutNoCodesLeft.php
* Copyright (c) 2026 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\Listeners\Security\User;
use Exception;
use FireflyIII\Events\Security\User\UserHasNoMFABackupCodesLeft;
use FireflyIII\Notifications\Security\MFABackupNoLeftNotification;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
class NotifiesUserAboutNoCodesLeft
{
public function handle(UserHasNoMFABackupCodesLeft $event): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$user = $event->user;
try {
Notification::send($user, new MFABackupNoLeftNotification($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());
}
}
}

View File

@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
/*
* NotifiesUserAboutRepeatedMFAFailures.php
* Copyright (c) 2026 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\Listeners\Security\User;
use Exception;
use FireflyIII\Events\Security\User\UserKeepsFailingMFA;
use FireflyIII\Notifications\Security\MFAManyFailedAttemptsNotification;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
class NotifiesUserAboutRepeatedMFAFailures
{
public function handle(UserKeepsFailingMFA $event): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$user = $event->user;
$count = $event->count;
try {
Notification::send($user, new MFAManyFailedAttemptsNotification($user, $count));
} 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());
}
}
}

View File

@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
/*
* NotifiesUserAboutUsedBackupCode.php
* Copyright (c) 2026 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\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());
}
}
}

View File

@@ -35,15 +35,6 @@ use FireflyIII\Events\RequestedNewPassword;
use FireflyIII\Events\RequestedReportOnJournals;
use FireflyIII\Events\RequestedSendWebhookMessages;
use FireflyIII\Events\RequestedVersionCheckStatus;
use FireflyIII\Events\Security\DisabledMFA;
use FireflyIII\Events\Security\EnabledMFA;
use FireflyIII\Events\Security\MFABackupFewLeft;
use FireflyIII\Events\Security\MFABackupNoLeft;
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;
@@ -74,9 +65,9 @@ class EventServiceProvider extends ServiceProvider
'FireflyIII\Handlers\Events\UserEventHandler@createGroupMembership',
'FireflyIII\Handlers\Events\UserEventHandler@createExchangeRates',
],
UserAttemptedLogin::class => [
'FireflyIII\Handlers\Events\UserEventHandler@sendLoginAttemptNotification',
],
// UserAttemptedLogin::class => [
// 'FireflyIII\Handlers\Events\UserEventHandler@sendLoginAttemptNotification',
// ],
// is a User related event.
Login::class => [
'FireflyIII\Handlers\Events\UserEventHandler@checkSingleUserIsAdmin',
@@ -118,9 +109,9 @@ class EventServiceProvider extends ServiceProvider
'FireflyIII\Handlers\Events\AdminEventHandler@sendInvitationNotification',
'FireflyIII\Handlers\Events\UserEventHandler@sendRegistrationInvite',
],
UnknownUserAttemptedLogin::class => [
'FireflyIII\Handlers\Events\AdminEventHandler@sendLoginAttemptNotification',
],
// UnknownUserAttemptedLogin::class => [
// 'FireflyIII\Handlers\Events\AdminEventHandler@sendLoginAttemptNotification',
// ],
// is a Transaction Journal related event.
StoredTransactionGroup::class => [
@@ -183,27 +174,27 @@ class EventServiceProvider extends ServiceProvider
// ],
// security related
EnabledMFA::class => [
'FireflyIII\Handlers\Events\Security\MFAHandler@sendMFAEnabledMail',
],
DisabledMFA::class => [
'FireflyIII\Handlers\Events\Security\MFAHandler@sendMFADisabledMail',
],
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',
],
// EnabledMFA::class => [
// 'FireflyIII\Handlers\Events\Security\MFAHandler@sendMFAEnabledMail',
// ],
// DisabledMFA::class => [
// 'FireflyIII\Handlers\Events\Security\MFAHandler@sendMFADisabledMail',
// ],
// 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',
// ],
// preferences
UserGroupChangedPrimaryCurrency::class => [
'FireflyIII\Handlers\Events\PreferencesEventHandler@resetPrimaryCurrencyAmounts',

22
composer.lock generated
View File

@@ -11302,11 +11302,11 @@
},
{
"name": "phpstan/phpstan",
"version": "2.1.33",
"version": "2.1.34",
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/9e800e6bee7d5bd02784d4c6069b48032d16224f",
"reference": "9e800e6bee7d5bd02784d4c6069b48032d16224f",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/070ba754a949fcade788e16e8dc5a5935b7cf2ee",
"reference": "070ba754a949fcade788e16e8dc5a5935b7cf2ee",
"shasum": ""
},
"require": {
@@ -11351,7 +11351,7 @@
"type": "github"
}
],
"time": "2025-12-05T10:24:31+00:00"
"time": "2026-01-19T19:52:16+00:00"
},
{
"name": "phpstan/phpstan-deprecation-rules",
@@ -11889,21 +11889,21 @@
},
{
"name": "rector/rector",
"version": "2.3.1",
"version": "2.3.2",
"source": {
"type": "git",
"url": "https://github.com/rectorphp/rector.git",
"reference": "9afc1bb43571b25629f353c61a9315b5ef31383a"
"reference": "07cbbe28bd60251b96b18d42e514779b0e2faa83"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/9afc1bb43571b25629f353c61a9315b5ef31383a",
"reference": "9afc1bb43571b25629f353c61a9315b5ef31383a",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/07cbbe28bd60251b96b18d42e514779b0e2faa83",
"reference": "07cbbe28bd60251b96b18d42e514779b0e2faa83",
"shasum": ""
},
"require": {
"php": "^7.4|^8.0",
"phpstan/phpstan": "^2.1.33"
"phpstan/phpstan": "^2.1.34"
},
"conflict": {
"rector/rector-doctrine": "*",
@@ -11937,7 +11937,7 @@
],
"support": {
"issues": "https://github.com/rectorphp/rector/issues",
"source": "https://github.com/rectorphp/rector/tree/2.3.1"
"source": "https://github.com/rectorphp/rector/tree/2.3.2"
},
"funding": [
{
@@ -11945,7 +11945,7 @@
"type": "github"
}
],
"time": "2026-01-13T15:13:58+00:00"
"time": "2026-01-20T01:11:51+00:00"
},
{
"name": "sebastian/cli-parser",

View File

@@ -78,8 +78,8 @@ return [
'running_balance_column' => (bool)envNonEmpty('USE_RUNNING_BALANCE', true), // this is only the default value, is not used.
// see cer.php for exchange rates feature flag.
],
'version' => 'develop/2026-01-19',
'build_time' => 1768805645,
'version' => 'develop/2026-01-20',
'build_time' => 1768884917,
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 28, // field is no longer used.

224
package-lock.json generated
View File

@@ -2606,9 +2606,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz",
"integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.2.tgz",
"integrity": "sha512-21J6xzayjy3O6NdnlO6aXi/urvSRjm6nCI6+nF6ra2YofKruGixN9kfT+dt55HVNwfDmpDHJcaS3JuP/boNnlA==",
"cpu": [
"arm"
],
@@ -2620,9 +2620,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz",
"integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.2.tgz",
"integrity": "sha512-eXBg7ibkNUZ+sTwbFiDKou0BAckeV6kIigK7y5Ko4mB/5A1KLhuzEKovsmfvsL8mQorkoincMFGnQuIT92SKqA==",
"cpu": [
"arm64"
],
@@ -2634,9 +2634,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz",
"integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.2.tgz",
"integrity": "sha512-UCbaTklREjrc5U47ypLulAgg4njaqfOVLU18VrCrI+6E5MQjuG0lSWaqLlAJwsD7NpFV249XgB0Bi37Zh5Sz4g==",
"cpu": [
"arm64"
],
@@ -2648,9 +2648,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz",
"integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.2.tgz",
"integrity": "sha512-dP67MA0cCMHFT2g5XyjtpVOtp7y4UyUxN3dhLdt11at5cPKnSm4lY+EhwNvDXIMzAMIo2KU+mc9wxaAQJTn7sQ==",
"cpu": [
"x64"
],
@@ -2662,9 +2662,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz",
"integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.2.tgz",
"integrity": "sha512-WDUPLUwfYV9G1yxNRJdXcvISW15mpvod1Wv3ok+Ws93w1HjIVmCIFxsG2DquO+3usMNCpJQ0wqO+3GhFdl6Fow==",
"cpu": [
"arm64"
],
@@ -2676,9 +2676,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz",
"integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.2.tgz",
"integrity": "sha512-Ng95wtHVEulRwn7R0tMrlUuiLVL/HXA8Lt/MYVpy88+s5ikpntzZba1qEulTuPnPIZuOPcW9wNEiqvZxZmgmqQ==",
"cpu": [
"x64"
],
@@ -2690,9 +2690,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz",
"integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.2.tgz",
"integrity": "sha512-AEXMESUDWWGqD6LwO/HkqCZgUE1VCJ1OhbvYGsfqX2Y6w5quSXuyoy/Fg3nRqiwro+cJYFxiw5v4kB2ZDLhxrw==",
"cpu": [
"arm"
],
@@ -2704,9 +2704,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz",
"integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.2.tgz",
"integrity": "sha512-ZV7EljjBDwBBBSv570VWj0hiNTdHt9uGznDtznBB4Caj3ch5rgD4I2K1GQrtbvJ/QiB+663lLgOdcADMNVC29Q==",
"cpu": [
"arm"
],
@@ -2718,9 +2718,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz",
"integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.2.tgz",
"integrity": "sha512-uvjwc8NtQVPAJtq4Tt7Q49FOodjfbf6NpqXyW/rjXoV+iZ3EJAHLNAnKT5UJBc6ffQVgmXTUL2ifYiLABlGFqA==",
"cpu": [
"arm64"
],
@@ -2732,9 +2732,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz",
"integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.2.tgz",
"integrity": "sha512-s3KoWVNnye9mm/2WpOZ3JeUiediUVw6AvY/H7jNA6qgKA2V2aM25lMkVarTDfiicn/DLq3O0a81jncXszoyCFA==",
"cpu": [
"arm64"
],
@@ -2746,9 +2746,9 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz",
"integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.2.tgz",
"integrity": "sha512-gi21faacK+J8aVSyAUptML9VQN26JRxe484IbF+h3hpG+sNVoMXPduhREz2CcYr5my0NE3MjVvQ5bMKX71pfVA==",
"cpu": [
"loong64"
],
@@ -2760,9 +2760,9 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-musl": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz",
"integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.2.tgz",
"integrity": "sha512-qSlWiXnVaS/ceqXNfnoFZh4IiCA0EwvCivivTGbEu1qv2o+WTHpn1zNmCTAoOG5QaVr2/yhCoLScQtc/7RxshA==",
"cpu": [
"loong64"
],
@@ -2774,9 +2774,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz",
"integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.2.tgz",
"integrity": "sha512-rPyuLFNoF1B0+wolH277E780NUKf+KoEDb3OyoLbAO18BbeKi++YN6gC/zuJoPPDlQRL3fIxHxCxVEWiem2yXw==",
"cpu": [
"ppc64"
],
@@ -2788,9 +2788,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-musl": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz",
"integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.2.tgz",
"integrity": "sha512-g+0ZLMook31iWV4PvqKU0i9E78gaZgYpSrYPed/4Bu+nGTgfOPtfs1h11tSSRPXSjC5EzLTjV/1A7L2Vr8pJoQ==",
"cpu": [
"ppc64"
],
@@ -2802,9 +2802,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz",
"integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.2.tgz",
"integrity": "sha512-i+sGeRGsjKZcQRh3BRfpLsM3LX3bi4AoEVqmGDyc50L6KfYsN45wVCSz70iQMwPWr3E5opSiLOwsC9WB4/1pqg==",
"cpu": [
"riscv64"
],
@@ -2816,9 +2816,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz",
"integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.2.tgz",
"integrity": "sha512-C1vLcKc4MfFV6I0aWsC7B2Y9QcsiEcvKkfxprwkPfLaN8hQf0/fKHwSF2lcYzA9g4imqnhic729VB9Fo70HO3Q==",
"cpu": [
"riscv64"
],
@@ -2830,9 +2830,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz",
"integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.2.tgz",
"integrity": "sha512-68gHUK/howpQjh7g7hlD9DvTTt4sNLp1Bb+Yzw2Ki0xvscm2cOdCLZNJNhd2jW8lsTPrHAHuF751BygifW4bkQ==",
"cpu": [
"s390x"
],
@@ -2844,9 +2844,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz",
"integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.2.tgz",
"integrity": "sha512-1e30XAuaBP1MAizaOBApsgeGZge2/Byd6wV4a8oa6jPdHELbRHBiw7wvo4dp7Ie2PE8TZT4pj9RLGZv9N4qwlw==",
"cpu": [
"x64"
],
@@ -2858,9 +2858,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz",
"integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.2.tgz",
"integrity": "sha512-4BJucJBGbuGnH6q7kpPqGJGzZnYrpAzRd60HQSt3OpX/6/YVgSsJnNzR8Ot74io50SeVT4CtCWe/RYIAymFPwA==",
"cpu": [
"x64"
],
@@ -2872,9 +2872,9 @@
]
},
"node_modules/@rollup/rollup-openbsd-x64": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz",
"integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.2.tgz",
"integrity": "sha512-cT2MmXySMo58ENv8p6/O6wI/h/gLnD3D6JoajwXFZH6X9jz4hARqUhWpGuQhOgLNXscfZYRQMJvZDtWNzMAIDw==",
"cpu": [
"x64"
],
@@ -2886,9 +2886,9 @@
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz",
"integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.2.tgz",
"integrity": "sha512-sZnyUgGkuzIXaK3jNMPmUIyJrxu/PjmATQrocpGA1WbCPX8H5tfGgRSuYtqBYAvLuIGp8SPRb1O4d1Fkb5fXaQ==",
"cpu": [
"arm64"
],
@@ -2900,9 +2900,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz",
"integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.2.tgz",
"integrity": "sha512-sDpFbenhmWjNcEbBcoTV0PWvW5rPJFvu+P7XoTY0YLGRupgLbFY0XPfwIbJOObzO7QgkRDANh65RjhPmgSaAjQ==",
"cpu": [
"arm64"
],
@@ -2914,9 +2914,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz",
"integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.2.tgz",
"integrity": "sha512-GvJ03TqqaweWCigtKQVBErw2bEhu1tyfNQbarwr94wCGnczA9HF8wqEe3U/Lfu6EdeNP0p6R+APeHVwEqVxpUQ==",
"cpu": [
"ia32"
],
@@ -2928,9 +2928,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz",
"integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.2.tgz",
"integrity": "sha512-KvXsBvp13oZz9JGe5NYS7FNizLe99Ny+W8ETsuCyjXiKdiGrcz2/J/N8qxZ/RSwivqjQguug07NLHqrIHrqfYw==",
"cpu": [
"x64"
],
@@ -2942,9 +2942,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz",
"integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.2.tgz",
"integrity": "sha512-xNO+fksQhsAckRtDSPWaMeT1uIM+JrDRXlerpnWNXhn1TdB3YZ6uKBMBTKP0eX9XtYEP978hHk1f8332i2AW8Q==",
"cpu": [
"x64"
],
@@ -7135,12 +7135,12 @@
}
},
"node_modules/i18next-chained-backend": {
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/i18next-chained-backend/-/i18next-chained-backend-4.6.3.tgz",
"integrity": "sha512-Yg4hAKg/98zRAMQs87vJSNevTzaPPrYF3Eb7Kpx+UEaaXLd3p69g7dulAL+hpmZQHeMQ/5gFqHVtdwva53mB0Q==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/i18next-chained-backend/-/i18next-chained-backend-5.0.1.tgz",
"integrity": "sha512-J2DZFvvJOrrfHPnTWMUm758+Da8J7JZXaOlo7dWgN+Vtkl4pH/0gy+i+iDFp+wkRVy6SbK6Ef57DQTbBBlOhaQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.23.2"
"@babel/runtime": "^7.28.4"
}
},
"node_modules/i18next-http-backend": {
@@ -7597,9 +7597,9 @@
}
},
"node_modules/jquery": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-4.0.0.tgz",
"integrity": "sha512-TXCHVR3Lb6TZdtw1l3RTLf8RBWVGexdxL6AC8/e0xZKEpBflBsjh9/8LXw+dkNFuOyW9B7iB3O1sP7hS0Kiacg==",
"dev": true,
"license": "MIT"
},
@@ -10089,9 +10089,9 @@
}
},
"node_modules/rollup": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz",
"integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==",
"version": "4.55.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.2.tgz",
"integrity": "sha512-PggGy4dhwx5qaW+CKBilA/98Ql9keyfnb7lh4SR6shQ91QQQi1ORJ1v4UinkdP2i87OBs9AQFooQylcrrRfIcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -10105,31 +10105,31 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.55.1",
"@rollup/rollup-android-arm64": "4.55.1",
"@rollup/rollup-darwin-arm64": "4.55.1",
"@rollup/rollup-darwin-x64": "4.55.1",
"@rollup/rollup-freebsd-arm64": "4.55.1",
"@rollup/rollup-freebsd-x64": "4.55.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.55.1",
"@rollup/rollup-linux-arm-musleabihf": "4.55.1",
"@rollup/rollup-linux-arm64-gnu": "4.55.1",
"@rollup/rollup-linux-arm64-musl": "4.55.1",
"@rollup/rollup-linux-loong64-gnu": "4.55.1",
"@rollup/rollup-linux-loong64-musl": "4.55.1",
"@rollup/rollup-linux-ppc64-gnu": "4.55.1",
"@rollup/rollup-linux-ppc64-musl": "4.55.1",
"@rollup/rollup-linux-riscv64-gnu": "4.55.1",
"@rollup/rollup-linux-riscv64-musl": "4.55.1",
"@rollup/rollup-linux-s390x-gnu": "4.55.1",
"@rollup/rollup-linux-x64-gnu": "4.55.1",
"@rollup/rollup-linux-x64-musl": "4.55.1",
"@rollup/rollup-openbsd-x64": "4.55.1",
"@rollup/rollup-openharmony-arm64": "4.55.1",
"@rollup/rollup-win32-arm64-msvc": "4.55.1",
"@rollup/rollup-win32-ia32-msvc": "4.55.1",
"@rollup/rollup-win32-x64-gnu": "4.55.1",
"@rollup/rollup-win32-x64-msvc": "4.55.1",
"@rollup/rollup-android-arm-eabi": "4.55.2",
"@rollup/rollup-android-arm64": "4.55.2",
"@rollup/rollup-darwin-arm64": "4.55.2",
"@rollup/rollup-darwin-x64": "4.55.2",
"@rollup/rollup-freebsd-arm64": "4.55.2",
"@rollup/rollup-freebsd-x64": "4.55.2",
"@rollup/rollup-linux-arm-gnueabihf": "4.55.2",
"@rollup/rollup-linux-arm-musleabihf": "4.55.2",
"@rollup/rollup-linux-arm64-gnu": "4.55.2",
"@rollup/rollup-linux-arm64-musl": "4.55.2",
"@rollup/rollup-linux-loong64-gnu": "4.55.2",
"@rollup/rollup-linux-loong64-musl": "4.55.2",
"@rollup/rollup-linux-ppc64-gnu": "4.55.2",
"@rollup/rollup-linux-ppc64-musl": "4.55.2",
"@rollup/rollup-linux-riscv64-gnu": "4.55.2",
"@rollup/rollup-linux-riscv64-musl": "4.55.2",
"@rollup/rollup-linux-s390x-gnu": "4.55.2",
"@rollup/rollup-linux-x64-gnu": "4.55.2",
"@rollup/rollup-linux-x64-musl": "4.55.2",
"@rollup/rollup-openbsd-x64": "4.55.2",
"@rollup/rollup-openharmony-arm64": "4.55.2",
"@rollup/rollup-win32-arm64-msvc": "4.55.2",
"@rollup/rollup-win32-ia32-msvc": "4.55.2",
"@rollup/rollup-win32-x64-gnu": "4.55.2",
"@rollup/rollup-win32-x64-msvc": "4.55.2",
"fsevents": "~2.3.2"
}
},
@@ -12448,7 +12448,7 @@
"bootstrap-sass": "^3",
"cross-env": "^10.0",
"font-awesome": "^4.7.0",
"jquery": "^3",
"jquery": "^4",
"laravel-mix": "^6.0",
"postcss": "^8.4.47",
"uiv": "^1.4",
@@ -12473,7 +12473,7 @@
"chartjs-chart-sankey": "^0.14.0",
"date-fns": "^4.0.0",
"i18next": "^25.0.1",
"i18next-chained-backend": "^4.6.2",
"i18next-chained-backend": "^5.0.0",
"i18next-http-backend": "^3.0.1",
"i18next-localstorage-backend": "^4.2.0",
"leaflet": "^1.9.4",

File diff suppressed because one or more lines are too long

View File

@@ -20,7 +20,7 @@
"bootstrap-sass": "^3",
"cross-env": "^10.0",
"font-awesome": "^4.7.0",
"jquery": "^3",
"jquery": "^4",
"laravel-mix": "^6.0",
"postcss": "^8.4.47",
"uiv": "^1.4",

View File

@@ -107,25 +107,25 @@
"multi_account_warning_withdrawal": "Keep in mind that the source account of subsequent splits will be overruled by whatever is defined in the first split of the withdrawal.",
"multi_account_warning_deposit": "Keep in mind that the destination account of subsequent splits will be overruled by whatever is defined in the first split of the deposit.",
"multi_account_warning_transfer": "Keep in mind that the source + destination account of subsequent splits will be overruled by whatever is defined in the first split of the transfer.",
"webhook_trigger_ANY": "After any event",
"webhook_trigger_STORE_TRANSACTION": "After transaction creation",
"webhook_trigger_UPDATE_TRANSACTION": "After transaction update",
"webhook_trigger_DESTROY_TRANSACTION": "After transaction delete",
"webhook_trigger_STORE_BUDGET": "After budget creation",
"webhook_trigger_UPDATE_BUDGET": "After budget update",
"webhook_trigger_DESTROY_BUDGET": "After budget delete",
"webhook_trigger_STORE_UPDATE_BUDGET_LIMIT": "After budgeted amount change",
"webhook_response_TRANSACTIONS": "Transaction details",
"webhook_response_RELEVANT": "Relevant details",
"webhook_response_ACCOUNTS": "Account details",
"webhook_response_NONE": "No details",
"webhook_trigger_ANY": "Setelah setiap peristiwa",
"webhook_trigger_STORE_TRANSACTION": "Setelah pembuatan transaksi",
"webhook_trigger_UPDATE_TRANSACTION": "Setelah pembaruan transaksi",
"webhook_trigger_DESTROY_TRANSACTION": "Setelah penghapusan transaksi",
"webhook_trigger_STORE_BUDGET": "Setelah pembuatan anggaran",
"webhook_trigger_UPDATE_BUDGET": "Setelah pembaruan anggaran",
"webhook_trigger_DESTROY_BUDGET": "Setelah penghapusan anggaran",
"webhook_trigger_STORE_UPDATE_BUDGET_LIMIT": "Setelah perubahan jumlah anggaran",
"webhook_response_TRANSACTIONS": "Detail transaksi",
"webhook_response_RELEVANT": "Detail relevan",
"webhook_response_ACCOUNTS": "Detail rekening",
"webhook_response_NONE": "Tidak ada detail",
"webhook_delivery_JSON": "JSON",
"actions": "Tindakan",
"meta_data": "Data meta",
"webhook_messages": "Webhook message",
"inactive": "Tidak-aktif",
"no_webhook_messages": "There are no webhook messages",
"inspect": "Inspect",
"no_webhook_messages": "Tidak ada pesan webhook.",
"inspect": "Periksa",
"create_new_webhook": "Create new webhook",
"webhooks": "Webhooks",
"webhook_trigger_form_help": "Indicate on what event the webhook will trigger",
@@ -134,7 +134,7 @@
"webhook_active_form_help": "The webhook must be active or it won't be called.",
"edit_webhook_js": "Edit webhook \"{title}\"",
"webhook_was_triggered": "The webhook was triggered on the indicated transaction. Please wait for results to appear.",
"view_message": "View message",
"view_message": "Lihat pesan",
"view_attempts": "Lihat upaya yang gagal",
"message_content_title": "Webhook message content",
"message_content_help": "This is the content of the message that was sent (or tried) using this webhook.",

View File

@@ -28,7 +28,7 @@
"chartjs-chart-sankey": "^0.14.0",
"date-fns": "^4.0.0",
"i18next": "^25.0.1",
"i18next-chained-backend": "^4.6.2",
"i18next-chained-backend": "^5.0.0",
"i18next-http-backend": "^3.0.1",
"i18next-localstorage-backend": "^4.2.0",
"leaflet": "^1.9.4",