Compare commits

..

20 Commits

Author SHA1 Message Date
github-actions[bot]
705138aa27 Merge pull request #11885 from firefly-iii/release-1772775428
🤖 Automatically merge the PR into the develop branch.
2026-03-06 06:37:15 +01:00
JC5
36d20137b2 🤖 Auto commit for release 'develop' on 2026-03-06 2026-03-06 06:37:08 +01:00
James Cole
7f08a3f594 Use safe function. 2026-03-06 06:21:36 +01:00
James Cole
a897229958 Add changelog for v6.5.4 2026-03-06 06:12:15 +01:00
James Cole
1fa4632be5 Fix transaction search. 2026-03-06 06:03:12 +01:00
James Cole
221a00a23b Add debug info to track available budget creation. 2026-03-06 05:36:05 +01:00
James Cole
09c3318408 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2026-03-05 20:50:32 +01:00
Sander Dorigo
25ba87babb Better validation for webhook URLs 2026-03-05 10:11:09 +01:00
James Cole
d7e9a42f58 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2026-03-04 20:24:25 +01:00
James Cole
8fd6d99c11 Fix date issues in piggy banks for #11873 2026-03-04 20:21:12 +01:00
github-actions[bot]
463ae00ec2 Merge pull request #11876 from firefly-iii/release-1772642273
🤖 Automatically merge the PR into the develop branch.
2026-03-04 17:38:02 +01:00
JC5
969460d271 🤖 Auto commit for release 'develop' on 2026-03-04 2026-03-04 17:37:53 +01:00
James Cole
8ecfa4b619 Fix #11873 2026-03-04 17:31:42 +01:00
James Cole
55ae86ad62 Merge branch 'main' into develop 2026-03-04 17:28:57 +01:00
James Cole
7315825475 Update CI workflow to manage environment file
Copy .env.example to .env before running CI and remove .env afterward.

Signed-off-by: James Cole <james@firefly-iii.org>
2026-03-04 10:55:56 +01:00
James Cole
eea23ed756 Update composer update command in CI workflow
Removed the '--no-plugins' option from composer update command.

Signed-off-by: James Cole <james@firefly-iii.org>
2026-03-04 10:42:51 +01:00
James Cole
04875728b4 Remove staticMethod.notFound from ignoreErrors
Signed-off-by: James Cole <james@firefly-iii.org>
2026-03-04 10:42:22 +01:00
James Cole
1fa51a92c6 Ignore staticMethod.notFound error in PHPStan
Signed-off-by: James Cole <james@firefly-iii.org>
2026-03-04 10:24:47 +01:00
James Cole
9b5cf09cc0 Update release.yml to enforce error handling
Removed '|| true' from Mago format, PHPCS, and lint commands to ensure they fail the workflow if errors occur.

Signed-off-by: James Cole <james@firefly-iii.org>
2026-03-04 09:26:08 +01:00
github-actions[bot]
268377ad3a Merge pull request #11870 from firefly-iii/develop
🤖 Automatically merge the PR into the main branch.
2026-03-04 07:52:49 +01:00
21 changed files with 178 additions and 84 deletions

View File

@@ -174,22 +174,24 @@ jobs:
uses: nhedger/setup-mago@v1
- name: Run CI
run: |
cp .env.example .env
# install all packages etc.
rm -rf vendor composer.lock
composer update --no-scripts --no-plugins -q
composer update --no-scripts -q
# format code.
echo "Will now run Mago Format"
mago format || true
mago format
sudo chown -R runner:docker resources/lang
echo "Will now run PHPCS"
.ci/phpcs.sh || true
.ci/phpcs.sh
# lint and check
echo "Will now run Mago Lint"
mago lint || true
mago lint
echo "Will now run PHPstan"
.ci/phpstan.sh || true
.ci/phpstan.sh
rm .env
- name: Calculate variables
run: |

View File

@@ -68,7 +68,7 @@ final class TransactionController extends Controller
$description = (string) $request->attributes->get('description');
Log::debug(sprintf('Include deleted? %s', var_export($includeDeleted, true)));
if ('' !== $externalId) {
$count += $this->repository->countByMeta('external_identifier', $externalId, $includeDeleted);
$count += $this->repository->countByMeta('external_id', $externalId, $includeDeleted);
Log::debug(sprintf('Search for transactions with external_identifier "%s", count is now %d', $externalId, $count));
}
if ('' !== $internalRef) {

View File

@@ -27,6 +27,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Webhook;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Webhook;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\Webhook\IsValidWebhookUrl;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
@@ -83,7 +84,7 @@ class CreateRequest extends FormRequest
'delivery' => 'prohibited',
'deliveries' => 'required|array|min:1|max:1',
'deliveries.*' => sprintf('required|in:%s', $deliveries),
'url' => ['required', sprintf('url:%s', $validProtocols)],
'url' => ['required', sprintf('url:%s', $validProtocols), new IsValidWebhookUrl()],
];
}
}

View File

@@ -27,6 +27,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Webhook;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Webhook;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\Webhook\IsValidWebhookUrl;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
@@ -87,7 +88,7 @@ class UpdateRequest extends FormRequest
'delivery' => 'prohibited',
'deliveries' => 'required|array|min:1|max:1',
'deliveries.*' => sprintf('required|in:%s', $deliveries),
'url' => [sprintf('url:%s', $validProtocols), sprintf('uniqueExistingWebhook:%d', $webhook->id)],
'url' => [sprintf('url:%s', $validProtocols), sprintf('uniqueExistingWebhook:%d', $webhook->id), new IsValidWebhookUrl()],
];
}
}

View File

@@ -27,6 +27,7 @@ namespace FireflyIII\Events\Model\BudgetLimit;
use FireflyIII\Events\Event;
use FireflyIII\Models\BudgetLimit;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class CreatedBudgetLimit extends Event
{
@@ -35,5 +36,7 @@ class CreatedBudgetLimit extends Event
public function __construct(
public BudgetLimit $budgetLimit,
public bool $createWebhookMessages
) {}
) {
Log::debug(sprintf('CreatedNewBudgetLimit(#%d) Event', $budgetLimit->id));
}
}

View File

@@ -29,6 +29,7 @@ use FireflyIII\Events\Event;
use FireflyIII\Models\Budget;
use FireflyIII\User;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class DestroyedBudgetLimit extends Event
{
@@ -40,5 +41,7 @@ class DestroyedBudgetLimit extends Event
public Carbon $start,
public Carbon $end,
public bool $createWebhookMessages
) {}
) {
Log::debug(sprintf('DestroyedBudgetLimit(#%d) Event', $budget->id));
}
}

View File

@@ -27,6 +27,7 @@ namespace FireflyIII\Events\Model\BudgetLimit;
use FireflyIII\Events\Event;
use FireflyIII\Models\BudgetLimit;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class UpdatedBudgetLimit extends Event
{
@@ -35,5 +36,7 @@ class UpdatedBudgetLimit extends Event
public function __construct(
public BudgetLimit $budgetLimit,
public bool $createWebhookMessages
) {}
) {
Log::debug(sprintf('UpdatedBudgetLimit(#%d) Event', $budgetLimit->id));
}
}

View File

@@ -69,7 +69,7 @@ final class AmountController extends Controller
public function add(PiggyBank $piggyBank): Factory|\Illuminate\Contracts\View\View
{
/** @var Carbon $date */
$date = session('end', today(config('app.timezone')));
$date = now(config('app.timezone'));
$accounts = [];
$total = '0';
$totalSaved = $this->piggyRepos->getCurrentAmount($piggyBank);
@@ -109,7 +109,7 @@ final class AmountController extends Controller
public function addMobile(PiggyBank $piggyBank): Factory|\Illuminate\Contracts\View\View
{
/** @var Carbon $date */
$date = session('end', today(config('app.timezone')));
$date = now(config('app.timezone'));
$accounts = [];
$total = '0';
$totalSaved = $this->piggyRepos->getCurrentAmount($piggyBank);

View File

@@ -81,16 +81,6 @@ final class IndexController extends Controller
$this->piggyRepos->resetOrder();
$collection = $this->piggyRepos->getPiggyBanks();
session('end', today(config('app.timezone'))->endOfMonth());
// transform piggies using the transformer:
// $parameters = new ParameterBag();
// $parameters->set('end', $end);
// /** @var AccountTransformer $accountTransformer */
// $accountTransformer = app(AccountTransformer::class);
// $accountTransformer->setParameters($parameters);
// data
$piggyBanks = $this->groupPiggyBanks($collection);
$accounts = $this->collectAccounts($collection);
@@ -107,8 +97,8 @@ final class IndexController extends Controller
*/
public function setOrder(Request $request, PiggyBank $piggyBank): JsonResponse
{
$objectGroupTitle = (string) $request->get('objectGroupTitle');
$newOrder = (int) $request->get('order');
$objectGroupTitle = (string) $request->input('objectGroupTitle');
$newOrder = (int) $request->input('order');
$this->piggyRepos->setOrder($piggyBank, $newOrder);
if ('' !== $objectGroupTitle) {
$this->piggyRepos->setObjectGroup($piggyBank, $objectGroupTitle);
@@ -122,21 +112,15 @@ final class IndexController extends Controller
private function collectAccounts(Collection $collection): array
{
/** @var Carbon $end */
$end = session('end', today(config('app.timezone'))->endOfMonth());
// transform piggies using the transformer:
$parameters = new ParameterBag();
$parameters->set('end', $end);
$now = Carbon::now();
/** @var AccountTransformer $accountTransformer */
$accountTransformer = app(AccountTransformer::class);
$accountTransformer->setParameters($parameters);
// enrich each account.
$enrichment = new AccountEnrichment();
$enrichment->setUser(auth()->user());
$enrichment->setDate($end);
$enrichment->setDate($now);
$return = [];
/** @var PiggyBank $piggy */

View File

@@ -41,7 +41,7 @@ class ProcessesBudgetLimits implements ShouldQueue
{
public function handle(CreatedBudgetLimit|DestroyedBudgetLimit|UpdatedBudgetLimit $event): void
{
Log::debug(sprintf('Now in handle for event %s', get_class($event)));
Log::debug(sprintf('Now in ProcessesBudgetLimits::handle for event %s', get_class($event)));
if ($event instanceof DestroyedBudgetLimit && null !== $event->user) {
// need to recalculate all available budgets for this user.
$calculator = new AvailableBudgetCalculator();
@@ -70,6 +70,7 @@ class ProcessesBudgetLimits implements ShouldQueue
// do webhooks:
if ($event->createWebhookMessages) {
Log::debug('Event says to create webhook messages');
$this->createWebhookMessages($event->budgetLimit->budget->user, $event->budgetLimit->budget, WebhookTrigger::STORE_UPDATE_BUDGET_LIMIT);
}
}

View File

@@ -126,6 +126,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface, UserGroup
$user = $budgetLimit->budget->user;
$start = $budgetLimit->start_date->clone();
$end = $budgetLimit->end_date->clone();
Log::debug(sprintf('Send event for DestroyedBudgetLimit (limit #%d, budget #%d)', $budgetLimit->id, $budgetLimit->budget_id));
event(new DestroyedBudgetLimit($user, $budgetLimit->budget, $start, $end, true));
$budgetLimit->delete();
event(new WebhookMessagesRequestSending());
@@ -399,6 +400,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface, UserGroup
if (array_key_exists('notes', $data)) {
$this->setNoteText($budgetLimit, (string) $data['notes']);
}
Log::debug(sprintf('Updated budget limit with ID #%d', $budgetLimit->id));
$generateMessages = $data['fire_webhooks'] ?? true;
event(new UpdatedBudgetLimit($budgetLimit, $generateMessages));
event(new WebhookMessagesRequestSending());

View File

@@ -143,7 +143,13 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface, UserGroupInte
$amount = '' === $amount ? '0' : $amount;
$sum = bcadd($sum, $amount);
}
Log::debug(sprintf('Current amount in piggy bank #%d ("%s") is %s', $piggyBank->id, $piggyBank->name, $sum));
Log::debug(sprintf(
'Current amount (at %s) in piggy bank #%d ("%s") is %s',
now(config('app.timezone'))->toW3cString(),
$piggyBank->id,
$piggyBank->name,
$sum
));
return $sum;
}

View File

@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace FireflyIII\Rules\Webhook;
use Closure;
use FireflyIII\Support\Facades\FireflyConfig;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\IpUtils;
use function Safe\parse_url;
class IsValidWebhookUrl implements ValidationRule
{
/**
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
$value = (string) $value;
$resolved = gethostbyname(parse_url($value, PHP_URL_HOST));
Log::debug(sprintf('Now validating URL "%s" with IP "%s".', $value, $resolved));
// IPv4 is allowed to be in 127 range.
if (filter_var($resolved, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && IpUtils::checkIp4($resolved, '127.0.0.0/8')) {
Log::debug(sprintf('Local IP "%s" is allowed', $resolved));
return;
}
if (false === filter_var($resolved, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)) {
Log::error(sprintf('The resolved IP address "%s" is invalid.', $resolved));
$fail('validation.no_reserved_ip')->translate();
}
$validProtocols = FireflyConfig::get('valid_url_protocols', config('firefly.valid_url_protocols'))->data;
$parts = explode(',', $validProtocols);
$valid = false;
foreach ($parts as $part) {
if (str_starts_with($value, $part)) {
$valid = true;
}
}
if (false === $valid) {
$fail('validation.bad_url_prefix')->translate();
}
}
}

View File

@@ -28,11 +28,13 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Webhook\SignatureGeneratorInterface;
use FireflyIII\Models\WebhookAttempt;
use FireflyIII\Models\WebhookMessage;
use FireflyIII\Rules\Webhook\IsValidWebhookUrl;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use JsonException;
use function Safe\json_encode;
@@ -63,6 +65,16 @@ class StandardWebhookSender implements WebhookSenderInterface
$this->message->sent = true;
$this->message->save();
// validate the webhook URL.
$data = [
'url' => $this->message->webhook->url,
];
$rules = [
'url' => [new IsValidWebhookUrl()],
];
$res = Validator::make($data, $rules)->validate();
Log::debug('Result of res', $res);
try {
$signature = $signatureGenerator->generate($this->message);
} catch (FireflyException $e) {

View File

@@ -48,6 +48,11 @@ class AvailableBudgetCalculator
private AvailableBudgetRepositoryInterface $abRepository;
private BudgetLimitRepositoryInterface $blRepository;
public function __construct()
{
Log::debug('Created new AvailableBudgetCalculator');
}
public function recalculateByRange(): void
{
Log::debug(sprintf('Now in recalculateByRange(%s, %s)', $this->start->format('Y-m-d'), $this->start->format('Y-m-d')));

View File

@@ -3,6 +3,26 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## 6.5.4 - 2026-03-06
### Added
- Add some debug info to find
### Fixed
- [Issue 11873](https://github.com/firefly-iii/firefly-iii/issues/11873) (Piggy bank +/- sometimes sends 0.00 and fails with “Cannot add 0 because canAddAmount returned false”) reported by @ralle06
- Transaction count would search for the wrong meta field.
### Security
- Published security advisory https://github.com/firefly-iii/firefly-iii/security/advisories/GHSA-5q8v-j673-m5v4 found and reported by @lighthousekeeper1212
- It's possible to submit webhook URLs that point to internal IP addresses. This will still be the case in the future, though some reserved ranges are no blocked. Let me know if this impacts you.
### API
- Initial release.
## 6.5.3 - 2026-03-05
This release fixes some sloppy coding on my part, but good news everyone! A new linter is in place that should prevent that from happening. Turns out I had disabled it in the past :(.

52
composer.lock generated
View File

@@ -2561,16 +2561,16 @@
},
{
"name": "league/commonmark",
"version": "2.8.0",
"version": "2.8.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
"reference": "4efa10c1e56488e658d10adf7b7b7dcd19940bfb"
"reference": "84b1ca48347efdbe775426f108622a42735a6579"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/4efa10c1e56488e658d10adf7b7b7dcd19940bfb",
"reference": "4efa10c1e56488e658d10adf7b7b7dcd19940bfb",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/84b1ca48347efdbe775426f108622a42735a6579",
"reference": "84b1ca48347efdbe775426f108622a42735a6579",
"shasum": ""
},
"require": {
@@ -2595,9 +2595,9 @@
"phpstan/phpstan": "^1.8.2",
"phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0",
"scrutinizer/ocular": "^1.8.1",
"symfony/finder": "^5.3 | ^6.0 | ^7.0",
"symfony/process": "^5.4 | ^6.0 | ^7.0",
"symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0",
"symfony/finder": "^5.3 | ^6.0 | ^7.0 || ^8.0",
"symfony/process": "^5.4 | ^6.0 | ^7.0 || ^8.0",
"symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0 || ^8.0",
"unleashedtech/php-coding-standard": "^3.1.1",
"vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0"
},
@@ -2664,7 +2664,7 @@
"type": "tidelift"
}
],
"time": "2025-11-26T21:48:24+00:00"
"time": "2026-03-05T21:37:03+00:00"
},
{
"name": "league/config",
@@ -10115,16 +10115,16 @@
},
{
"name": "barryvdh/reflection-docblock",
"version": "v2.4.0",
"version": "v2.4.1",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/ReflectionDocBlock.git",
"reference": "d103774cbe7e94ddee7e4870f97f727b43fe7201"
"reference": "4f5ba70c30c81f2ce03a16a9965832cfcc31ed3b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/d103774cbe7e94ddee7e4870f97f727b43fe7201",
"reference": "d103774cbe7e94ddee7e4870f97f727b43fe7201",
"url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/4f5ba70c30c81f2ce03a16a9965832cfcc31ed3b",
"reference": "4f5ba70c30c81f2ce03a16a9965832cfcc31ed3b",
"shasum": ""
},
"require": {
@@ -10161,9 +10161,9 @@
}
],
"support": {
"source": "https://github.com/barryvdh/ReflectionDocBlock/tree/v2.4.0"
"source": "https://github.com/barryvdh/ReflectionDocBlock/tree/v2.4.1"
},
"time": "2025-07-17T06:07:30+00:00"
"time": "2026-03-05T20:09:01+00:00"
},
{
"name": "cloudcreativity/json-api-testing",
@@ -10373,16 +10373,16 @@
},
{
"name": "driftingly/rector-laravel",
"version": "2.1.9",
"version": "2.1.11",
"source": {
"type": "git",
"url": "https://github.com/driftingly/rector-laravel.git",
"reference": "aee9d4a1d489e7ec484fc79f33137f8ee051b3f7"
"reference": "84ea7e03f4a2d9d33e303559ed7e3280bfdb8d01"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/aee9d4a1d489e7ec484fc79f33137f8ee051b3f7",
"reference": "aee9d4a1d489e7ec484fc79f33137f8ee051b3f7",
"url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/84ea7e03f4a2d9d33e303559ed7e3280bfdb8d01",
"reference": "84ea7e03f4a2d9d33e303559ed7e3280bfdb8d01",
"shasum": ""
},
"require": {
@@ -10403,9 +10403,9 @@
"description": "Rector upgrades rules for Laravel Framework",
"support": {
"issues": "https://github.com/driftingly/rector-laravel/issues",
"source": "https://github.com/driftingly/rector-laravel/tree/2.1.9"
"source": "https://github.com/driftingly/rector-laravel/tree/2.1.11"
},
"time": "2025-12-25T23:31:36+00:00"
"time": "2026-03-05T19:46:28+00:00"
},
{
"name": "fakerphp/faker",
@@ -11140,16 +11140,16 @@
},
{
"name": "php-debugbar/php-debugbar",
"version": "v3.4.1",
"version": "v3.5.1",
"source": {
"type": "git",
"url": "https://github.com/php-debugbar/php-debugbar.git",
"reference": "ee9c718797a4c1fdf6c4d980cb3edcc1eeeddcc7"
"reference": "486b32fd98efe9a3c10f0b24c0caabc187f78f04"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/ee9c718797a4c1fdf6c4d980cb3edcc1eeeddcc7",
"reference": "ee9c718797a4c1fdf6c4d980cb3edcc1eeeddcc7",
"url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/486b32fd98efe9a3c10f0b24c0caabc187f78f04",
"reference": "486b32fd98efe9a3c10f0b24c0caabc187f78f04",
"shasum": ""
},
"require": {
@@ -11226,7 +11226,7 @@
],
"support": {
"issues": "https://github.com/php-debugbar/php-debugbar/issues",
"source": "https://github.com/php-debugbar/php-debugbar/tree/v3.4.1"
"source": "https://github.com/php-debugbar/php-debugbar/tree/v3.5.1"
},
"funding": [
{
@@ -11238,7 +11238,7 @@
"type": "github"
}
],
"time": "2026-02-26T11:40:30+00:00"
"time": "2026-03-05T20:37:33+00:00"
},
{
"name": "php-debugbar/symfony-bridge",

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-03-04',
'build_time' => 1772634704,
'version' => 'develop/2026-03-06',
'build_time' => 1772775247,
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 28, // field is no longer used.

40
package-lock.json generated
View File

@@ -2969,16 +2969,6 @@
"win32"
]
},
"node_modules/@trysound/sax": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/@types/babel__core": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
@@ -3246,9 +3236,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "25.3.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz",
"integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==",
"version": "25.3.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.5.tgz",
"integrity": "sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3273,9 +3263,9 @@
"license": "MIT"
},
"node_modules/@types/qs": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
"integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
"version": "6.15.0",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.0.tgz",
"integrity": "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==",
"dev": true,
"license": "MIT"
},
@@ -10284,6 +10274,16 @@
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/sax": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz",
"integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==",
"dev": true,
"license": "BlueOak-1.0.0",
"engines": {
"node": ">=11.0.0"
}
},
"node_modules/schema-utils": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
@@ -10968,18 +10968,18 @@
}
},
"node_modules/svgo": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
"integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==",
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.2.tgz",
"integrity": "sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@trysound/sax": "0.2.0",
"commander": "^7.2.0",
"css-select": "^4.1.3",
"css-tree": "^1.1.3",
"csso": "^4.2.0",
"picocolors": "^1.0.0",
"sax": "^1.5.0",
"stable": "^0.1.8"
},
"bin": {

View File

@@ -30,7 +30,7 @@
---
<p>
<img align="left" src=".github/assets/img/europe.png" alt="Flag of Europe" height="50"> Billionaires and fascists are breaking democracies and international alliances. Their profits are costing us our safety. (Digital) sovereignty is more important than ever. <strong>Firefly III</strong> is free open source software and lives in the European Union.
<img align="left" src=".github/assets/img/europe.png" alt="Flag of Europe" height="50"> Billionaires and fascists are breaking democracies and international alliances. Their profits are costing us our safety. (Digital) sovereignty is more important than ever. <strong>Firefly III</strong> is free open source software and originates from, and lives in the European Union (🇳🇱).
</p>
---

View File

@@ -139,6 +139,8 @@ return [
'in' => 'The selected :attribute is invalid.',
'integer' => 'The :attribute must be an integer.',
'ip' => 'The :attribute must be a valid IP address.',
'no_reserved_ip' => 'The URL must point to a valid IP address.',
'bad_url_prefix' => 'This URL is invalid.',
'json' => 'The :attribute must be a valid JSON string.',
'max.numeric' => 'The :attribute may not be greater than :max.',
'max.file' => 'The :attribute may not be greater than :max kilobytes.',