New numerical validation.

This commit is contained in:
James Cole 2024-01-02 14:33:17 +01:00
parent 85bde79fd1
commit 102da7b21e
No known key found for this signature in database
GPG Key ID: B49A324B7EAD6D80
32 changed files with 276 additions and 50 deletions

27
.ci/all.sh Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/env bash
#
# all.sh
# 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/>.
#
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
$SCRIPT_DIR/phpcs.sh
$SCRIPT_DIR/phpstan.sh
$SCRIPT_DIR/phpmd.sh

View File

@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Account;
use FireflyIII\Models\Location;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\UniqueAccountNumber;
use FireflyIII\Rules\UniqueIban;
use FireflyIII\Support\Request\AppendsLocationData;
@ -113,7 +114,7 @@ class StoreRequest extends FormRequest
'credit_card_type' => sprintf('nullable|in:%s|required_if:account_role,ccAsset', $ccPaymentTypes),
'monthly_payment_date' => 'nullable|date|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
'liability_type' => 'nullable|required_if:type,liability|required_if:type,liabilities|in:loan,debt,mortgage',
'liability_amount' => 'required_with:liability_start_date|min:0|numeric|max:1000000000',
'liability_amount' => ['required_with:liability_start_date', new IsValidPositiveAmount()],
'liability_start_date' => 'required_with:liability_amount|date',
'liability_direction' => 'nullable|required_if:type,liability|required_if:type,liabilities|in:credit,debit',
'interest' => 'between:0,100|numeric',

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\AvailableBudget;
use Carbon\Carbon;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -62,7 +63,7 @@ class Request extends FormRequest
return [
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'amount' => 'numeric|gt:0|max:1000000000',
'amount' => ['nullable', new IsValidPositiveAmount()],
'start' => 'date',
'end' => 'date',
];

View File

@ -25,6 +25,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Bill;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -72,8 +73,8 @@ class StoreRequest extends FormRequest
{
return [
'name' => 'between:1,255|uniqueObjectForUser:bills,name',
'amount_min' => 'numeric|gt:0|required|max:1000000000',
'amount_max' => 'numeric|gt:0|required|max:1000000000',
'amount_min' => ['required', new IsValidPositiveAmount()],
'amount_max' => ['required', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'date' => 'date|required',

View File

@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Bill;
use FireflyIII\Models\Bill;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -75,8 +76,8 @@ class UpdateRequest extends FormRequest
return [
'name' => sprintf('between:1,255|uniqueObjectForUser:bills,name,%d', $bill->id),
'amount_min' => 'numeric|gt:0|max:1000000000',
'amount_max' => 'numeric|gt:0|max:1000000000',
'amount_min' => ['nullable', new IsValidPositiveAmount()],
'amount_max' => ['nullable', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'date' => 'date',

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Budget;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
@ -74,7 +75,7 @@ class StoreRequest extends FormRequest
'notes' => 'nullable|between:1,65536',
// auto budget info
'auto_budget_type' => 'in:reset,rollover,adjusted,none',
'auto_budget_amount' => 'numeric|min:0|max:1000000000|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover|required_if:auto_budget_type,adjusted',
'auto_budget_amount' => ['required_if:auto_budget_type,reset', 'required_if:auto_budget_type,rollover', 'required_if:auto_budget_type,adjusted', new IsValidPositiveAmount()],
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover|required_if:auto_budget_type,adjusted',
];
}

View File

@ -25,6 +25,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Budget;
use FireflyIII\Models\Budget;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
@ -86,7 +87,7 @@ class UpdateRequest extends FormRequest
'auto_budget_type' => 'in:reset,rollover,adjusted,none',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
'auto_budget_currency_code' => 'exists:transaction_currencies,code',
'auto_budget_amount' => 'min:0|max:1000000000',
'auto_budget_amount' => ['nullable', new IsValidPositiveAmount()],
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
];
}

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -57,7 +58,7 @@ class StoreRequest extends FormRequest
return [
'start' => 'required|before:end|date',
'end' => 'required|after:start|date',
'amount' => 'required|gt:0|max:1000000000',
'amount' => ['required', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
];

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit;
use Carbon\Carbon;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -61,7 +62,7 @@ class UpdateRequest extends FormRequest
return [
'start' => 'date',
'end' => 'date',
'amount' => 'gt:0|max:1000000000',
'amount' => ['nullable', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
];

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -64,11 +65,11 @@ class StoreRequest extends FormRequest
{
return [
'name' => 'required|between:1,255|uniquePiggyBankForUser',
'current_amount' => ['numeric', 'gte:0', 'lte:target_amount', 'max:1000000000'],
'current_amount' => ['nullable', new IsValidPositiveAmount()],
'account_id' => 'required|numeric|belongsToUser:accounts,id',
'object_group_id' => 'numeric|belongsToUser:object_groups,id',
'object_group_title' => 'between:1,255',
'target_amount' => ['numeric', 'gte:0', 'lte:target_amount', 'required', 'max:1000000000'],
'target_amount' => ['required', new IsValidPositiveAmount()],
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',
'notes' => 'max:65000',

View File

@ -25,6 +25,7 @@ namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Rules\IsAssetAccountId;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\LessThanPiggyTarget;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
@ -69,8 +70,8 @@ class UpdateRequest extends FormRequest
return [
'name' => 'between:1,255|uniquePiggyBankForUser:'.$piggyBank->id,
'current_amount' => ['numeric', 'gte:0', new LessThanPiggyTarget(), 'max:1000000000'],
'target_amount' => 'numeric|gte:0|max:1000000000',
'current_amount' => ['nullable', new LessThanPiggyTarget(), new IsValidPositiveAmount()],
'target_amount' => ['nullable', new IsValidPositiveAmount()],
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',
'notes' => 'max:65000',

View File

@ -25,6 +25,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRecurrenceData;
@ -92,8 +93,8 @@ class StoreRequest extends FormRequest
'repetitions.*.weekend' => 'numeric|min:1|max:4',
'transactions.*.description' => 'required|between:1,255',
'transactions.*.amount' => 'required|numeric|gt:0|max:1000000000',
'transactions.*.foreign_amount' => 'nullable|numeric|gt:0|max:1000000000',
'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',

View File

@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
use FireflyIII\Models\Recurrence;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRecurrenceData;
@ -99,8 +100,8 @@ class UpdateRequest extends FormRequest
'repetitions.*.weekend' => 'nullable|numeric|min:1|max:4',
'transactions.*.description' => 'between:1,255',
'transactions.*.amount' => 'numeric|gt:0|max:1000000000',
'transactions.*.foreign_amount' => 'nullable|numeric|gt:0|max:1000000000',
'transactions.*.amount' => [new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
@ -164,15 +165,15 @@ class UpdateRequest extends FormRequest
}
if (array_key_exists('moment', $repetition)) {
$current['moment'] = (string)$repetition['moment'];
$current['moment'] = (string) $repetition['moment'];
}
if (array_key_exists('skip', $repetition)) {
$current['skip'] = (int)$repetition['skip'];
$current['skip'] = (int) $repetition['skip'];
}
if (array_key_exists('weekend', $repetition)) {
$current['weekend'] = (int)$repetition['weekend'];
$current['weekend'] = (int) $repetition['weekend'];
}
$return[] = $current;
}

View File

@ -27,6 +27,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Transaction;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\NullArrayObject;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
@ -92,8 +93,8 @@ class StoreRequest extends FormRequest
'transactions.*.foreign_currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
// amount
'transactions.*.amount' => 'required|numeric|gt:0|max:1000000000',
'transactions.*.foreign_amount' => 'numeric|max:1000000000|gt:0|',
'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
// description
'transactions.*.description' => 'nullable|between:1,1000',

View File

@ -29,6 +29,7 @@ use FireflyIII\Models\TransactionGroup;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\GroupValidation;
@ -115,8 +116,8 @@ class UpdateRequest extends FormRequest
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
// amount
'transactions.*.amount' => 'numeric|gt:0|max:100000000000',
'transactions.*.foreign_amount' => 'nullable|numeric|gte:0|max:1000000000',
'transactions.*.amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
// description
'transactions.*.description' => 'nullable|between:1,1000',

View File

@ -28,9 +28,7 @@ use FireflyIII\Support\Http\Controllers\UserNavigation;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\UploadedFile;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Log;
/**
* Class Controller.

View File

@ -26,6 +26,7 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Models\Account;
use FireflyIII\Models\Location;
use FireflyIII\Rules\IsValidAmount;
use FireflyIII\Rules\UniqueIban;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
@ -101,11 +102,11 @@ class AccountFormRequest extends FormRequest
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
$rules = [
'name' => 'required|max:1024|min:1|uniqueAccountForUser',
'opening_balance' => 'numeric|nullable|max:1000000000|min:-1000000000',
'opening_balance' => ['nullable', new IsValidAmount()],
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
'iban' => ['iban', 'nullable', new UniqueIban(null, $this->convertString('objectType'))],
'BIC' => 'bic|nullable',
'virtual_balance' => 'numeric|nullable|max:1000000000|min:-1000000000',
'virtual_balance' => ['nullable', new IsValidAmount()],
'currency_id' => 'exists:transaction_currencies,id',
'account_number' => 'between:1,255|uniqueAccountNumberForUser|nullable',
'account_role' => 'in:'.$accountRoles,

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -64,8 +65,8 @@ class BillStoreRequest extends FormRequest
{
return [
'name' => 'required|between:1,255|uniqueObjectForUser:bills,name',
'amount_min' => 'required|numeric|gt:0|max:1000000000',
'amount_max' => 'required|numeric|gt:0|max:1000000000',
'amount_min' => ['required', new IsValidPositiveAmount()],
'amount_max' => ['required', new IsValidPositiveAmount()],
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
'date' => 'required|date',
'notes' => 'between:1,65536|nullable',

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Models\Bill;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -68,8 +69,8 @@ class BillUpdateRequest extends FormRequest
return [
'name' => sprintf('required|between:1,255|uniqueObjectForUser:bills,name,%d', $bill->id),
'amount_min' => 'required|numeric|gt:0|max:1000000000',
'amount_max' => 'required|numeric|gt:0|max:1000000000',
'amount_min' => ['required', new IsValidPositiveAmount()],
'amount_max' => ['required', new IsValidPositiveAmount()],
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
'date' => 'required|date',
'bill_end_date' => 'nullable|date',

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
@ -64,7 +65,7 @@ class BudgetFormStoreRequest extends FormRequest
'active' => 'numeric|between:0,1',
'auto_budget_type' => 'numeric|integer|gte:0|lte:3',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
'auto_budget_amount' => 'min:0|max:1000000000|required_if:auto_budget_type,1|required_if:auto_budget_type,2',
'auto_budget_amount' => ['required_if:auto_budget_type,1', 'required_if:auto_budget_type,2', new IsValidPositiveAmount()],
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
'notes' => 'between:1,65536|nullable',
];

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Models\Budget;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
@ -73,7 +74,7 @@ class BudgetFormUpdateRequest extends FormRequest
'active' => 'numeric|between:0,1',
'auto_budget_type' => 'numeric|integer|gte:0|lte:31',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
'auto_budget_amount' => 'min:0|max:1000000000|required_if:auto_budget_type,1|required_if:auto_budget_type,2|numeric',
'auto_budget_amount' => ['required_if:auto_budget_type,1', 'required_if:auto_budget_type,2|numeric', new IsValidPositiveAmount()],
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
'notes' => 'between:1,65536|nullable',
];

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use Illuminate\Foundation\Http\FormRequest;
@ -40,7 +41,7 @@ class BudgetIncomeRequest extends FormRequest
{
// fixed
return [
'amount' => 'numeric|required|min:0|max:1000000000',
'amount' => ['required', new IsValidPositiveAmount()],
'start' => 'required|date|before:end',
'end' => 'required|date|after:start',
];

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Rules\IsValidAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -43,9 +44,9 @@ class NewUserFormRequest extends FormRequest
// fixed
return [
'bank_name' => 'required|between:1,200',
'bank_balance' => 'required|numeric|max:1000000000|min:-1000000000',
'savings_balance' => 'numeric|max:1000000000|min:-1000000000',
'credit_card_limit' => 'numeric|max:1000000000|min:-1000000000',
'bank_balance' => ['required', new IsValidAmount()],
'savings_balance' => ['nullable', new IsValidAmount()],
'credit_card_limit' => ['nullable', new IsValidAmount()],
'amount_currency_id_bank_balance' => 'exists:transaction_currencies,id',
'amount_currency_id_savings_balance' => 'exists:transaction_currencies,id',
'amount_currency_id_credit_card_limit' => 'exists:transaction_currencies,id',

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -59,7 +60,7 @@ class PiggyBankStoreRequest extends FormRequest
return [
'name' => 'required|between:1,255|uniquePiggyBankForUser',
'account_id' => 'required|belongsToUser:accounts',
'targetamount' => 'nullable|numeric|max:1000000000|min:-1000000000',
'targetamount' => ['nullable', new IsValidPositiveAmount()],
'startdate' => 'date',
'targetdate' => 'date|nullable',
'order' => 'integer|min:1',

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@ -63,7 +64,7 @@ class PiggyBankUpdateRequest extends FormRequest
return [
'name' => sprintf('required|between:1,255|uniquePiggyBankForUser:%d', $piggy->id),
'account_id' => 'required|belongsToUser:accounts',
'targetamount' => 'nullable|numeric|max:1000000000|min:-1000000000',
'targetamount' => ['nullable', new IsValidPositiveAmount()],
'startdate' => 'date',
'targetdate' => 'date|nullable',
'order' => 'integer|max:65536|min:1',

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Rules\IsValidAmount;
use FireflyIII\Rules\ValidJournals;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
@ -67,9 +68,9 @@ class ReconciliationStoreRequest extends FormRequest
return [
'start' => 'required|date',
'end' => 'required|date',
'startBalance' => 'numeric|max:1000000000|min:-1000000000',
'endBalance' => 'numeric|max:1000000000|min:-1000000000',
'difference' => 'required|numeric|max:1000000000|min:-1000000000',
'startBalance' => ['nullable', new IsValidAmount()],
'endBalance' => ['nullable', new IsValidAmount()],
'difference' => ['required', new IsValidAmount()],
'journals' => [new ValidJournals()],
'reconcile' => 'required|in:create,nothing',
];

View File

@ -27,6 +27,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\CategoryFactory;
use FireflyIII\Models\Recurrence;
use FireflyIII\Models\TransactionType;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\ValidRecurrenceRepetitionType;
use FireflyIII\Rules\ValidRecurrenceRepetitionValue;
use FireflyIII\Support\Request\ChecksLogin;
@ -171,7 +172,7 @@ class RecurrenceFormRequest extends FormRequest
'transaction_description' => 'required|between:1,255',
'transaction_type' => 'required|in:withdrawal,deposit,transfer',
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
'amount' => 'numeric|required|gt:0|max:1000000000',
'amount' => ['required', new IsValidPositiveAmount()],
// mandatory account info:
'source_id' => 'numeric|belongsToUser:accounts,id|nullable',
'source_name' => 'between:1,255|nullable',
@ -179,7 +180,7 @@ class RecurrenceFormRequest extends FormRequest
'destination_name' => 'between:1,255|nullable',
// foreign amount data:
'foreign_amount' => 'nullable|gt:0|max:1000000000',
'foreign_amount' => ['nullable', new IsValidPositiveAmount()],
// optional fields:
'budget_id' => 'mustExist:budgets,id|belongsToUser:budgets,id|nullable',

View File

@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace FireflyIII\Rules;
use FireflyIII\Support\Validation\ValidatesAmountsTrait;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Facades\Log;
class IsValidAmount implements ValidationRule
{
use ValidatesAmountsTrait;
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validate(string $attribute, mixed $value, \Closure $fail): void
{
$value = (string)$value;
// must not be empty:
if($this->emptyString($value)) {
$fail('validation.filled')->translate();
Log::debug(sprintf('IsValidAmount: "%s" cannot be empty.', $value));
return;
}
// must be a number:
if(!$this->isValidNumber($value)) {
$fail('validation.numeric')->translate();
Log::debug(sprintf('IsValidAmount: "%s" is not a number.', $value));
return;
}
// must not be scientific notation:
if($this->scientificNumber($value)) {
$fail('validation.scientific_notation')->translate();
Log::debug(sprintf('IsValidAmount: "%s" cannot be in the scientific notation.', $value));
return;
}
// must be more than minus a lots:
if($this->lessThanLots($value)) {
$amount = bcmul('-1', self::BIG_AMOUNT);
$fail('validation.gte.numeric')->translate(['value' => $amount]);
Log::debug(sprintf('IsValidAmount: "%s" must be more than %s.', $value, $amount));
return;
}
// must be less than 100 million and 1709:
if($this->moreThanLots($value)) {
Log::debug(sprintf('IsValidPositiveAmount: "%s" must be more than %s.', $value, self::BIG_AMOUNT));
$fail('validation.lte.numeric')->translate(['value' => self::BIG_AMOUNT]);
}
Log::debug(sprintf('IsValidAmount: "%s" is a valid positive amount.', $value));
}
}

View File

@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace FireflyIII\Rules;
use FireflyIII\Support\Validation\ValidatesAmountsTrait;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Facades\Log;
class IsValidPositiveAmount implements ValidationRule
{
use ValidatesAmountsTrait;
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validate(string $attribute, mixed $value, \Closure $fail): void
{
$value = (string)$value;
// must not be empty:
if($this->emptyString($value)) {
$fail('validation.filled')->translate();
Log::debug(sprintf('IsValidPositiveAmount: "%s" cannot be empty.', $value));
return;
}
// must be a number:
if(!$this->isValidNumber($value)) {
$fail('validation.numeric')->translate();
Log::debug(sprintf('IsValidPositiveAmount: "%s" is not a number.', $value));
return;
}
// must not be scientific notation:
if($this->scientificNumber($value)) {
$fail('validation.scientific_notation')->translate();
Log::debug(sprintf('IsValidPositiveAmount: "%s" cannot be in the scientific notation.', $value));
return;
}
// must be more than zero:
if($this->lessOrEqualToZero($value)) {
$fail('validation.more_than_zero')->translate();
Log::debug(sprintf('IsValidPositiveAmount: "%s" must be more than zero.', $value));
return;
}
// must be less than 100 million and 1709:
if($this->moreThanLots($value)) {
Log::debug(sprintf('IsValidPositiveAmount: "%s" must be less than %s.', $value, self::BIG_AMOUNT));
$fail('validation.lte.numeric')->translate(['value' => self::BIG_AMOUNT]);
}
Log::debug(sprintf('IsValidPositiveAmount: "%s" is a valid positive amount.', $value));
}
}

View File

@ -0,0 +1,61 @@
<?php
/*
* ValidatesAmountsTrait.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\Support\Validation;
trait ValidatesAmountsTrait
{
protected const string BIG_AMOUNT = '100001709';
final protected function emptyString(string $value): bool
{
return '' === $value;
}
final protected function isValidNumber(string $value): bool
{
return is_numeric($value);
}
final protected function scientificNumber(string $value): bool
{
return str_contains(strtoupper($value), 'E');
}
final protected function lessOrEqualToZero(string $value): bool
{
return -1 === bccomp($value, '0') || 0 === bccomp($value, '0');
}
final protected function moreThanLots(string $value): bool
{
return 1 === bccomp($value, self::BIG_AMOUNT) || 0 === bccomp($value, self::BIG_AMOUNT);
}
final protected function lessThanLots(string $value): bool
{
$amount = bcmul('-1', self::BIG_AMOUNT);
return -1 === bccomp($value, $amount) || 0 === bccomp($value, $amount);
}
}

View File

@ -37,6 +37,8 @@ trait ValidatesAutoBudgetRequest
{
$data = $validator->getData();
$type = $data['auto_budget_type'] ?? '';
/** @var null|float|int|string $amount */
$amount = array_key_exists('auto_budget_amount', $data) ? $data['auto_budget_amount'] : null;
$period = array_key_exists('auto_budget_period', $data) ? $data['auto_budget_period'] : null;
$currencyId = array_key_exists('auto_budget_currency_id', $data) ? (int) $data['auto_budget_currency_id'] : null;
@ -47,12 +49,13 @@ trait ValidatesAutoBudgetRequest
if ('' === $type || 0 === $type) {
return;
}
// TODO lots of duplicates with number validator.
// TODO should be present at more places, stop scientific notification
if (str_contains(strtoupper($amount), 'E')) {
if (str_contains(strtoupper((string)$amount), 'E')) {
$amount = '';
}
// basic float check:
if (!is_numeric($amount) || '' === $amount) {
if (!is_numeric($amount) || '' === (string) $amount) {
$validator->errors()->add('auto_budget_amount', (string) trans('validation.amount_required_for_auto_budget'));
return;
@ -70,8 +73,6 @@ trait ValidatesAutoBudgetRequest
// too big amount
if ((int) $amount > 268435456) {
$validator->errors()->add('auto_budget_amount', (string) trans('validation.amount_required_for_auto_budget'));
return;
}
}
}

View File

@ -34,6 +34,7 @@ return [
'invalid_query_currency' => 'Your query contains accounts that have different currency settings, which is not allowed.',
'iban' => 'This is not a valid IBAN.',
'zero_or_more' => 'The value cannot be negative.',
'more_than_zero' => 'The value must be more than zero.',
'no_asset_account' => 'This is not an asset account.',
'date_or_time' => 'The value must be a valid date or time value (ISO 8601).',
'source_equals_destination' => 'The source account equals the destination account.',
@ -124,6 +125,7 @@ return [
'min.array' => 'The :attribute must have at least :min items.',
'not_in' => 'The selected :attribute is invalid.',
'numeric' => 'The :attribute must be a number.',
'scientific_notation' => 'The :attribute cannot use the scientific notation.',
'numeric_native' => 'The native amount must be a number.',
'numeric_destination' => 'The destination amount must be a number.',
'numeric_source' => 'The source amount must be a number.',