Compare commits

...

122 Commits

Author SHA1 Message Date
James Cole
e00addc0b0 Merge branch 'release/v6.1.7' 2024-01-20 16:30:16 +01:00
James Cole
da7a2cf0c0 Update meta data for new release. 2024-01-20 16:29:00 +01:00
James Cole
2368788405 Fix issue with "createFromFormat". 2024-01-20 08:07:27 +01:00
James Cole
f603415931 Rebuild edit script. 2024-01-20 07:09:26 +01:00
James Cole
523fa42998 Merge branch 'main' into develop 2024-01-20 07:05:27 +01:00
James Cole
e449395f3f Clean up some code. 2024-01-20 07:04:19 +01:00
James Cole
d8d8002f1e Add some debug to non strict search 2024-01-20 06:53:43 +01:00
James Cole
2570ca9573 Fix account type filter 2024-01-20 06:53:30 +01:00
James Cole
e5fdc2cbfd Merge pull request #8429 from firefly-iii/dependabot/npm_and_yarn/vite-4.5.2
Bump vite from 4.5.1 to 4.5.2
2024-01-20 06:53:12 +01:00
dependabot[bot]
0349cdbc1b Bump vite from 4.5.1 to 4.5.2
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.1 to 4.5.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.5.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.5.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-20 05:39:48 +00:00
James Cole
122f0309a6 Fix #8425 2024-01-19 20:23:04 +01:00
James Cole
09bff5ea4e Fix https://github.com/firefly-iii/firefly-iii/issues/8418 2024-01-18 18:57:29 +01:00
James Cole
7ea112c5e7 Fix https://github.com/firefly-iii/firefly-iii/issues/8349 and 2024-01-18 18:57:23 +01:00
James Cole
44df07a5f5 Update, rebuild, and add a new API endpoint. 2024-01-17 20:23:02 +01:00
James Cole
66b0d9d309 Merge pull request #8394 from firefly-iii/dependabot/npm_and_yarn/develop/date-fns-3.2.0 2024-01-15 05:24:53 +01:00
dependabot[bot]
6ac3d3e62c Bump date-fns from 3.1.0 to 3.2.0
Bumps [date-fns](https://github.com/date-fns/date-fns) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/date-fns/date-fns/releases)
- [Changelog](https://github.com/date-fns/date-fns/blob/main/CHANGELOG.md)
- [Commits](https://github.com/date-fns/date-fns/compare/v3.1.0...v3.2.0)

---
updated-dependencies:
- dependency-name: date-fns
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-15 03:22:07 +00:00
James Cole
925450f84c Fix https://github.com/firefly-iii/firefly-iii/issues/8390 2024-01-14 13:59:09 +01:00
James Cole
62f59c6a19 Update packages 2024-01-14 13:58:16 +01:00
James Cole
7db21612a0 Escape backticks [skip ci] 2024-01-14 11:20:43 +01:00
James Cole
2c0da2cf26 Duh, single quotes [skip ci] 2024-01-14 11:19:47 +01:00
James Cole
79484cc194 Experimental action [skip ci] 2024-01-14 11:18:17 +01:00
James Cole
6f18748c72 Merge branch 'main' into develop 2024-01-14 07:16:21 +01:00
James Cole
577824930f Attempt at newline. 2024-01-14 07:15:08 +01:00
James Cole
d614519ee7 Add necessary params. 2024-01-14 07:12:47 +01:00
James Cole
ae31041f7f Add context 2024-01-14 07:11:39 +01:00
James Cole
62c4d0cf86 new command 2024-01-14 07:07:14 +01:00
James Cole
c2ddabbad2 Expand index. 2024-01-14 07:06:55 +01:00
James Cole
458402aaff Code cleanup. 2024-01-14 05:10:05 +01:00
James Cole
5c81e98218 Add list of transactions. 2024-01-13 20:34:09 +01:00
James Cole
37a46b02f4 Fix https://github.com/firefly-iii/firefly-iii/issues/8374 2024-01-13 08:13:25 +01:00
James Cole
b3e1ecdd02 Merge branch 'main' into develop 2024-01-13 08:13:10 +01:00
James Cole
1780e6dc61 Remove label step, no longer necessary. 2024-01-13 07:55:04 +01:00
James Cole
50f346d092 Add body to secret 2024-01-13 07:54:12 +01:00
James Cole
ccc851090a Manually add comment, lock and redirect user. 2024-01-13 07:50:43 +01:00
James Cole
4605d84cc8 Add more permissions 2024-01-13 07:41:15 +01:00
James Cole
8c7ab50325 Add the action manually. 2024-01-13 07:40:01 +01:00
James Cole
908539836b Use correct string name. 2024-01-13 07:38:21 +01:00
James Cole
9f71cf966c Remove the old step. 2024-01-13 07:36:55 +01:00
James Cole
02ed47c578 Update job. Do it manually. 2024-01-13 07:36:09 +01:00
James Cole
1ddbaf0884 Merge branch 'main' into develop 2024-01-13 07:24:23 +01:00
James Cole
d3ed8c6f0f New action for issues. 2024-01-13 07:24:11 +01:00
James Cole
4f1ac2ac6f Minor code cleanup 2024-01-12 19:03:51 +01:00
James Cole
1e733f4c8b Fix https://github.com/firefly-iii/firefly-iii/issues/8377 2024-01-12 18:57:38 +01:00
James Cole
8e2546da9d Update translations. 2024-01-10 20:29:00 +01:00
James Cole
3a8162d3c5 Add button for https://github.com/firefly-iii/firefly-iii/issues/8369 2024-01-10 05:34:20 +01:00
James Cole
f7ceb75316 Merge pull request #8370 from luzpaz/typos
Fix various typos
2024-01-10 05:31:16 +01:00
luzpaz
744e193faa Fix various typos
Found via `codespell -q 3 -S "./resources/lang,./resources/assets/js/locales" -L hastable`
2024-01-10 01:12:48 +00:00
James Cole
12b0e11592 From error to debug. 2024-01-09 21:05:17 +01:00
James Cole
717f3a9e3d From info to debug 2024-01-09 21:04:12 +01:00
James Cole
b9f0682f04 Add audit entries. 2024-01-09 21:03:26 +01:00
James Cole
8792465fd5 Add validation warnings in audit logs. 2024-01-09 20:58:18 +01:00
James Cole
6fbf9a119d Change priority on audit messages. 2024-01-09 20:48:17 +01:00
James Cole
0dfa21a92e Merge branch 'main' into develop 2024-01-08 20:39:02 +01:00
James Cole
136fe8e8eb Update label-actions.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2024-01-08 20:32:31 +01:00
James Cole
d510c4e31d Rebuild frontend v2 2024-01-08 20:31:35 +01:00
James Cole
c066bcc4ce Update label-actions.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2024-01-08 20:30:47 +01:00
James Cole
c9e7ae1f08 Update label-actions.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2024-01-08 20:25:25 +01:00
James Cole
6a9b4f4d55 Update label-actions.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2024-01-08 20:20:22 +01:00
James Cole
2b5054b905 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2024-01-08 20:11:39 +01:00
James Cole
0a45a2485b Small edit and show updates 2024-01-08 20:11:27 +01:00
James Cole
fcc0294d07 Smaller max size 2024-01-08 12:56:57 +01:00
James Cole
ad981c2bf0 Fix breadcrumb bg color. 2024-01-07 19:55:56 +01:00
James Cole
75a32b2f94 Expand v2 layout with experimental view. 2024-01-07 12:51:42 +01:00
James Cole
70b60f756b Rebuild frontend [skip ci] 2024-01-07 07:02:53 +01:00
James Cole
0d2ae8ae23 Clean up languages [skip ci] 2024-01-07 07:02:28 +01:00
James Cole
8043c86942 Update readme. 2024-01-06 19:22:38 +01:00
James Cole
4c30a7bc55 Expand edit form. 2024-01-06 17:24:54 +01:00
James Cole
f615b9c252 Fix https://github.com/firefly-iii/firefly-iii/issues/8352 2024-01-06 14:44:50 +01:00
James Cole
c19b36a391 Fix https://github.com/firefly-iii/firefly-iii/issues/8352 2024-01-06 14:40:06 +01:00
James Cole
935634e487 Sanity check on number. 2024-01-06 14:23:20 +01:00
James Cole
2c3f032a2b Merge branch 'release/v6.1.6' 2024-01-06 11:13:41 +01:00
James Cole
7e62b75b12 Merge tag 'v6.1.6' into develop
v6.1.6
2024-01-06 11:13:41 +01:00
James Cole
de57ab0874 Update meta files for new release. 2024-01-06 11:11:18 +01:00
James Cole
6fb4aaecd3 Fix a very dumb bug. 2024-01-06 11:09:40 +01:00
James Cole
45fdbf5a11 Merge tag 'v6.1.5' into develop
v6.1.5
2024-01-06 10:59:05 +01:00
James Cole
c6615a7b17 Merge branch 'release/v6.1.5' 2024-01-06 10:59:02 +01:00
James Cole
0efb3d2dcf Fix currency validation. 2024-01-06 08:33:38 +01:00
James Cole
b8a58f83ee New packages. 2024-01-06 07:59:46 +01:00
James Cole
110228e65e Fix phpstan issue. 2024-01-06 07:49:50 +01:00
James Cole
8ad27e0eda Update meta files for new release. 2024-01-06 07:42:00 +01:00
James Cole
2e0d90c685 Expand edit transaction form. 2024-01-06 07:26:03 +01:00
James Cole
bd2ecb13b8 Change time for rule. 2024-01-05 18:09:19 +01:00
James Cole
5725570dbb Add marker. Seems fastest solution. 2024-01-05 14:47:44 +01:00
James Cole
11f77685e4 Experimental code cleanup. 2024-01-05 14:29:59 +01:00
James Cole
0521c46d27 test 2024-01-05 14:15:26 +01:00
James Cole
50d6225590 test 2024-01-05 14:15:02 +01:00
James Cole
df55f7de79 test 2024-01-05 14:13:44 +01:00
James Cole
5152ae9622 test 2024-01-05 14:11:06 +01:00
James Cole
075d0da63d test 2024-01-05 14:10:07 +01:00
James Cole
d804df2a2f test 2024-01-05 14:09:47 +01:00
James Cole
ff0f8beb81 Of course phpstan has an opinion on this lol 2024-01-05 14:07:13 +01:00
James Cole
c00be92f97 Finalize create transaction form. 2024-01-05 14:04:44 +01:00
James Cole
88f6221424 Small code fix. 2024-01-05 11:09:52 +01:00
James Cole
f9463e02a2 Fix null pointer 2024-01-05 10:55:46 +01:00
James Cole
25a23801be Fix error mail 2024-01-05 10:55:07 +01:00
James Cole
fe7bb02dc5 Clean up min/max sizes of requests. 2024-01-05 09:48:59 +01:00
James Cole
68edcfc4e8 Clean up files and add alias 2024-01-05 08:12:17 +01:00
James Cole
5f8a24a684 Add newline. 2024-01-04 15:43:51 +01:00
James Cole
0a5d62605a Code cleanup and new translations. 2024-01-04 15:42:00 +01:00
James Cole
1873be8d95 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2024-01-04 15:41:18 +01:00
James Cole
01892c3828 Merge pull request #8348 from lemuelroberto/develop
Update outdated documentation URLs in .env.example
2024-01-04 15:41:00 +01:00
Lemuel Roberto Bonifácio
b87e60c72f Update outdated documentation URLs in .env.example 2024-01-04 11:32:36 -03:00
James Cole
3a083f88b5 Clean up code. 2024-01-04 14:59:55 +01:00
James Cole
566bb2f097 Expand create transaction form. 2024-01-04 14:59:37 +01:00
James Cole
1ba7847d84 Add more details in message. 2024-01-04 11:46:23 +01:00
James Cole
c32044a8eb Smaller notes 2024-01-04 11:41:03 +01:00
James Cole
72a2d417af Change log levels. 2024-01-04 08:35:58 +01:00
James Cole
09c18d6d44 More audit logs. 2024-01-04 08:34:57 +01:00
James Cole
84ae6a633e Add some audit logs. 2024-01-04 08:32:42 +01:00
James Cole
82749cea07 Sanity check in date. 2024-01-04 07:51:37 +01:00
James Cole
23aa0e3ba3 Add some audit log info. 2024-01-04 07:48:51 +01:00
James Cole
8be27a2201 Small code cleanup 2024-01-04 07:44:52 +01:00
James Cole
ff98f3cc3e Expand create transaction form. 2024-01-04 07:26:45 +01:00
James Cole
01c4d25646 Better currency validation for foreign amount 2024-01-04 07:26:12 +01:00
James Cole
292b9ac9d0 Fix wording for https://github.com/firefly-iii/firefly-iii/issues/8328 2024-01-04 07:25:24 +01:00
James Cole
6bdae03961 Extra fix for https://github.com/firefly-iii/firefly-iii/issues/8328 2024-01-04 06:22:47 +01:00
James Cole
7426c6aac3 Split form in parts, add "edit" page. 2024-01-03 19:34:50 +01:00
James Cole
211526c032 Expand new transaction form. 2024-01-03 17:43:05 +01:00
James Cole
e6fe08dd61 Update translations. 2024-01-03 13:05:54 +01:00
James Cole
7bba67130a Merge pull request #8335 from maureenferreira/patch-2
Update intro.php
2024-01-03 07:28:43 +00:00
maureenferreira
7186d8ddfd Update intro.php
Signed-off-by: maureenferreira <142938968+maureenferreira@users.noreply.github.com>
2024-01-03 00:19:18 -06:00
James Cole
5b11c86113 Merge tag 'v6.1.4' into develop
v6.1.4
2024-01-02 22:29:55 +01:00
503 changed files with 9838 additions and 4517 deletions

View File

@@ -226,21 +226,22 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.45.0",
"version": "v3.48.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "c0daa33cb2533cd73f48dde1c70c2afa3e7953b5"
"reference": "a92472c6fb66349de25211f31c77eceae3df024e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/c0daa33cb2533cd73f48dde1c70c2afa3e7953b5",
"reference": "c0daa33cb2533cd73f48dde1c70c2afa3e7953b5",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a92472c6fb66349de25211f31c77eceae3df024e",
"reference": "a92472c6fb66349de25211f31c77eceae3df024e",
"shasum": ""
},
"require": {
"composer/semver": "^3.4",
"composer/xdebug-handler": "^3.0.3",
"ext-filter": "*",
"ext-json": "*",
"ext-tokenizer": "*",
"php": "^7.4 || ^8.0",
@@ -304,7 +305,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.45.0"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.48.0"
},
"funding": [
{
@@ -312,7 +313,7 @@
"type": "github"
}
],
"time": "2023-12-30T02:07:07+00:00"
"time": "2024-01-19T21:44:39+00:00"
},
{
"name": "psr/container",

View File

@@ -78,7 +78,7 @@ PAPERTRAIL_HOST=
PAPERTRAIL_PORT=
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# For other database types, please see the FAQ: https://docs.firefly-iii.org/firefly-iii/faq/self-hosted/#i-want-to-use-sqlite
# For other database types, please see the FAQ: https://docs.firefly-iii.org/references/faq/install/#i-want-to-use-sqlite
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
# Use "pgsql" for PostgreSQL
# Use "mysql" for MySQL and MariaDB.
@@ -122,7 +122,7 @@ SESSION_DRIVER=file
# If you use Docker or similar, you can set REDIS_HOST_FILE, REDIS_PASSWORD_FILE or
# REDIS_PORT_FILE to set the value from a file instead of from an environment variable
# can be tcp, unix or http
# can be tcp or unix. http is not supported
REDIS_SCHEME=tcp
# use only when using 'unix' for REDIS_SCHEME. Leave empty otherwise.
@@ -150,7 +150,7 @@ COOKIE_SECURE=false
COOKIE_SAMESITE=lax
# If you want Firefly III to email you, update these settings
# For instructions, see: https://docs.firefly-iii.org/firefly-iii/advanced-installation/email/#email
# For instructions, see: https://docs.firefly-iii.org/how-to/firefly-iii/advanced/notifications/#email
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
MAIL_MAILER=log
MAIL_HOST=null
@@ -214,7 +214,7 @@ VALID_URL_PROTOCOLS=
# - 'web' (default, uses built in DB)
# - 'remote_user_guard' for Authelia etc
# Read more about these settings in the documentation.
# https://docs.firefly-iii.org/firefly-iii/advanced-installation/authentication
# https://docs.firefly-iii.org/how-to/firefly-iii/advanced/authentication/
#
# LDAP is no longer supported :(
#
@@ -269,7 +269,7 @@ ALLOW_WEBHOOKS=false
# 1. Set this token to any 32-character value (this is important!).
# 2. Use this token in the cron URL instead of a user's command line token that you can find in /profile
#
# For more info: https://docs.firefly-iii.org/firefly-iii/advanced-installation/cron/
# For more info: https://docs.firefly-iii.org/how-to/firefly-iii/advanced/cron/
#
# You can set this variable from a file by appending it with _FILE
#

View File

@@ -35,3 +35,51 @@ triage:
This issue has been marked as being in triage. The root cause is not known yet, or the issue needs more investigation. You can help by sharing debug information (from `/debug`) if you also have this issue or when you haven't already done so.
Thank you for your contributions.
needs-moar-debug:
issues:
comment: |
Hi there! This is an automatic reply. `Share and enjoy`
To learn more about this issue, please share the output of the `/debug` page of your Firefly III installation.
If this page is no available due to the issue you have, please make sure you share at least:
1. Firefly III version
2. Docker, self-hosted, or hosted by a third party?
3. Operating system and browser
Thank you for your contributions.
unlabel: needs-moar-debug
needs-moar-logs:
issues:
comment: |
Hi there! This is an automatic reply. `Share and enjoy`
To learn more about this issue, please share the relevant log files from your Firefly III or data importer installation.
The relevant instructions can be found in the documentation: [How to debug Firefly III?](https://docs.firefly-iii.org/how-to/general/debug/) Once debug mode is activated per these instructions, you can repeat your action and find the logs, depending on your method of installation. All is explained on the page.
Please share the relevant log lines in your issue, either inline or as an attachment. If you feel the logs contain sensitive information, you may also send them to [james@firefly-iii.org](mailto:james@firefly-iii.org). Without these logs, it may not be possible to properly investigate this issue.
Thank you for your contributions.
unlabel: needs-moar-logs
v2-layout-issue:
issues:
comment: |
Hi there! This is an automatic reply. `Share and enjoy`
It seems your issue is about the new v2-layout that is currently in development for Firefly III.
These issues are collected in [a GitHub discussion](https://github.com/firefly-iii/firefly-iii/issues/8361).
Please note that the v2 layout is still very much in development.
Thank you for your contributions.
close: true
close-reason: completed
lock: false
unlabel: v2-layout-issue

View File

@@ -56,7 +56,9 @@ jobs:
const workflows = [
'cleanup.yml',
'close-duplicates.yml',
'closed-issues.yml',
'debug-info-actions.yml',
'depsreview.yml',
'label-actions.yml',
'lock.yml',

39
.github/workflows/close-duplicates.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: "Issues - Command to close duplicate issues"
# the workflow to execute on is comments that are newly created
on:
issue_comment:
types: [created]
permissions:
issues: write
checks: read
jobs:
close_duplicates:
runs-on: ubuntu-latest
steps:
- uses: github/command@v1.1.0
id: command
with:
allowed_contexts: "issue"
command: ".duplicate"
- name: reply
if: ${{ steps.command.outputs.continue == 'true' }}
run: |
ISSUE_TITLE=$(gh issue view ${{ steps.command.outputs.params }} --json title --jq '.title')
gh issue comment "$NUMBER" --body "Hi there!
This is an automatic reply. \`Share and enjoy\`.
Your issue is probably a duplicate of issue <span>#</span>${{ steps.command.outputs.params }}: [$ISSUE_TITLE](https://github.com/firefly-iii/firefly-iii/issues/${{ steps.command.outputs.params }}). Please refer to issue #${{ steps.command.outputs.params }} for support.
You can close this issue now. If you believe this is not in fact a duplicate, please reply and let us know. Otherwise, this issue will be automatically closed in a few days time.
Thank you for your contributions."
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}

View File

@@ -0,0 +1,32 @@
name: 'Issues - Respond to hidden commands'
# the workflow to execute on is comments that are newly created
on:
issues:
types: [opened, edited]
issue_comment:
types: [created]
# permissions needed for reacting to IssueOps commands on issues and PRs
permissions:
contents: read
pull-requests: write
issues: write
checks: read
jobs:
respond:
runs-on: ubuntu-latest
steps:
- run: |
ISSUE_BODY=$(gh issue view $NUMBER --json body)
if [[ $ISSUE_BODY == *".eOxNZAmyGz6CXMyf"* ]]; then
gh issue comment "$NUMBER" --body "$V2_ISSUE_REPLY_BODY"
gh issue close "$NUMBER" --reason completed
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}
V2_ISSUE_REPLY_BODY: ${{ secrets.V2_ISSUE_REPLY_BODY }}
LABELS: v2-layout-issue

View File

@@ -18,4 +18,4 @@ jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/label-actions@v3
- uses: dessant/label-actions@v4

View File

@@ -15,5 +15,5 @@ jobs:
- uses: JC5/lock-threads@main
with:
github-token: ${{ github.token }}
issue-inactive-days: 90
pr-inactive-days: 90
issue-inactive-days: 7
pr-inactive-days: 7

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
/node_modules
/storage/*.key
/vendor
public/hot
npm-debug.log
yarn-error.log
.env

View File

@@ -45,6 +45,7 @@ use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\AccountDestroyService;
use FireflyIII\Services\Internal\Destroy\JournalDestroyService;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
/**
* Class DestroyController
@@ -175,12 +176,14 @@ class DestroyController extends Controller
$count = $account->transactions()->count();
if (true === $this->unused && 0 === $count) {
app('log')->info(sprintf('Deleted unused account #%d "%s"', $account->id, $account->name));
Log::channel('audit')->info(sprintf('Deleted unused account #%d "%s"', $account->id, $account->name));
$service->destroy($account, null);
continue;
}
if (false === $this->unused) {
app('log')->info(sprintf('Deleting account #%d "%s"', $account->id, $account->name));
Log::channel('audit')->warning(sprintf('Deleted account #%d "%s"', $account->id, $account->name));
$service->destroy($account, null);
}
}

View File

@@ -67,7 +67,7 @@ class DestroyController extends Controller
public function destroy(Attachment $attachment): JsonResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}

View File

@@ -76,7 +76,7 @@ class ShowController extends Controller
public function download(Attachment $attachment): LaravelResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}
@@ -124,7 +124,7 @@ class ShowController extends Controller
public function index(): JsonResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}
@@ -162,7 +162,7 @@ class ShowController extends Controller
public function show(Attachment $attachment): JsonResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}

View File

@@ -75,7 +75,7 @@ class StoreController extends Controller
public function store(StoreRequest $request): JsonResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}
@@ -99,7 +99,7 @@ class StoreController extends Controller
public function upload(Request $request, Attachment $attachment): JsonResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}

View File

@@ -70,7 +70,7 @@ class UpdateController extends Controller
public function update(UpdateRequest $request, Attachment $attachment): JsonResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}

View File

@@ -71,7 +71,7 @@ class AttemptController extends Controller
throw new FireflyException('200040: Webhook and webhook message are no match');
}
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info(sprintf('User lists webhook attempts of webhook #%d and message #%d, but webhooks are DISABLED.', $webhook->id, $message->id));
Log::channel('audit')->warning(sprintf('User lists webhook attempts of webhook #%d and message #%d, but webhooks are DISABLED.', $webhook->id, $message->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
@@ -115,7 +115,7 @@ class AttemptController extends Controller
}
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info(sprintf('User views single webhook attempt #%d of webhook #%d and message #%d, but webhooks are DISABLED', $attempt->id, $webhook->id, $message->id));
Log::channel('audit')->warning(sprintf('User views single webhook attempt #%d of webhook #%d and message #%d, but webhooks are DISABLED', $attempt->id, $webhook->id, $message->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}

View File

@@ -63,7 +63,7 @@ class DestroyController extends Controller
public function destroy(Webhook $webhook): JsonResponse
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info(sprintf('User tries to destroy webhook #%d. but webhooks are DISABLED.', $webhook->id));
Log::channel('audit')->warning(sprintf('User tries to destroy webhook #%d. but webhooks are DISABLED.', $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
@@ -93,7 +93,7 @@ class DestroyController extends Controller
}
if (false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info(sprintf('User tries to destroy webhook #%d, message #%d, attempt #%d, but webhooks are DISABLED.', $webhook->id, $message->id, $attempt->id));
Log::channel('audit')->warning(sprintf('User tries to destroy webhook #%d, message #%d, attempt #%d, but webhooks are DISABLED.', $webhook->id, $message->id, $attempt->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
@@ -121,7 +121,7 @@ class DestroyController extends Controller
}
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info(sprintf('User tries to destroy webhook #%d, message #%d, but webhooks are DISABLED.', $webhook->id, $message->id));
Log::channel('audit')->warning(sprintf('User tries to destroy webhook #%d, message #%d, but webhooks are DISABLED.', $webhook->id, $message->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}

View File

@@ -67,7 +67,7 @@ class MessageController extends Controller
public function index(Webhook $webhook): JsonResponse
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info(sprintf('User tries to view messages of webhook #%d, but webhooks are DISABLED.', $webhook->id));
Log::channel('audit')->warning(sprintf('User tries to view messages of webhook #%d, but webhooks are DISABLED.', $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
@@ -107,7 +107,7 @@ class MessageController extends Controller
throw new FireflyException('200040: Webhook and webhook message are no match');
}
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info(sprintf('User tries to view message #%d of webhook #%d, but webhooks are DISABLED.', $message->id, $webhook->id));
Log::channel('audit')->warning(sprintf('User tries to view message #%d of webhook #%d, but webhooks are DISABLED.', $message->id, $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -59,9 +60,7 @@ class MoveTransactionsRequest extends FormRequest
/**
* Configure the validator instance with special rules for after the basic validation rules.
*
* @param validator $validator
* TODO this is duplicate
* TODO this is duplicate.
*/
public function withValidator(Validator $validator): void
{
@@ -74,6 +73,9 @@ class MoveTransactionsRequest extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
private function validateMove(Validator $validator): void
@@ -81,12 +83,12 @@ class MoveTransactionsRequest extends FormRequest
$data = $validator->getData();
$repository = app(AccountRepositoryInterface::class);
$repository->setUser(auth()->user());
$original = $repository->find((int)$data['original_account']);
$destination = $repository->find((int)$data['destination_account']);
$original = $repository->find((int) $data['original_account']);
$destination = $repository->find((int) $data['destination_account']);
// not the same type:
if ($original->accountType->type !== $destination->accountType->type) {
$validator->errors()->add('title', (string)trans('validation.same_account_type'));
$validator->errors()->add('title', (string) trans('validation.same_account_type'));
return;
}
@@ -96,7 +98,7 @@ class MoveTransactionsRequest extends FormRequest
// check different scenario's.
if (null === $originalCurrency xor null === $destinationCurrency) {
$validator->errors()->add('title', (string)trans('validation.same_account_currency'));
$validator->errors()->add('title', (string) trans('validation.same_account_currency'));
return;
}
@@ -105,7 +107,7 @@ class MoveTransactionsRequest extends FormRequest
return;
}
if ($originalCurrency->code !== $destinationCurrency->code) {
$validator->errors()->add('title', (string)trans('validation.same_account_currency'));
$validator->errors()->add('title', (string) trans('validation.same_account_currency'));
}
}
}

View File

@@ -30,6 +30,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\Api\Data\Bulk\ValidatesBulkTransactionQuery;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -72,5 +73,8 @@ class TransactionRequest extends FormRequest
$this->validateTransactionQuery($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -71,7 +71,7 @@ class ExportRequest extends FormRequest
{
return [
'type' => 'in:csv',
'accounts' => 'min:1|max:65536',
'accounts' => 'min:1|max:32768',
'start' => 'date|before:end',
'end' => 'date|after:start',
];

View File

@@ -101,7 +101,7 @@ class StoreRequest extends FormRequest
'type' => 'required|max:1024|min:1|'.sprintf('in:%s', $types),
'iban' => ['iban', 'nullable', new UniqueIban(null, $type)],
'bic' => 'bic|nullable',
'account_number' => ['between:1,255', 'nullable', new UniqueAccountNumber(null, $type)],
'account_number' => ['min:1', 'max:255', 'nullable', new UniqueAccountNumber(null, $type)],
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
'virtual_balance' => 'numeric|nullable',
@@ -117,9 +117,9 @@ class StoreRequest extends FormRequest
'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',
'interest' => 'min:0|max:100|numeric',
'interest_period' => sprintf('nullable|in:%s', implode(',', config('firefly.interest_periods'))),
'notes' => 'min:0|max:65536',
'notes' => 'min:0|max:32768',
];
return Location::requestRules($rules);

View File

@@ -91,7 +91,7 @@ class UpdateRequest extends FormRequest
'type' => sprintf('in:%s', $types),
'iban' => ['iban', 'nullable', new UniqueIban($account, $this->convertString('type'))],
'bic' => 'bic|nullable',
'account_number' => ['between:1,255', 'nullable', new UniqueAccountNumber($account, $this->convertString('type'))],
'account_number' => ['min:1', 'max:255', 'nullable', new UniqueAccountNumber($account, $this->convertString('type'))],
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
'virtual_balance' => 'numeric|nullable',
@@ -105,9 +105,9 @@ class UpdateRequest extends FormRequest
'monthly_payment_date' => 'date|nullable|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
'liability_type' => 'required_if:type,liability|in:loan,debt,mortgage',
'liability_direction' => 'required_if:type,liability|in:credit,debit',
'interest' => 'required_if:type,liability|between:0,100|numeric',
'interest' => 'required_if:type,liability|min:0|max:100|numeric',
'interest_period' => 'required_if:type,liability|in:daily,monthly,yearly',
'notes' => 'min:0|max:65536',
'notes' => 'min:0|max:32768',
];
return Location::requestRules($rules);

View File

@@ -66,9 +66,9 @@ class StoreRequest extends FormRequest
$model = $this->convertString('attachable_type');
return [
'filename' => 'required|between:1,255',
'title' => 'between:1,255',
'notes' => 'between:1,65000',
'filename' => 'required|min:1|max:255',
'title' => ['min:1', 'max:255'],
'notes' => 'min:1|max:32768',
'attachable_type' => sprintf('required|in:%s', $models),
'attachable_id' => ['required', 'numeric', new IsValidAttachmentModel($model)],
];

View File

@@ -68,9 +68,9 @@ class UpdateRequest extends FormRequest
$model = $this->convertString('attachable_type');
return [
'filename' => 'between:1,255',
'title' => 'between:1,255',
'notes' => 'between:1,65000',
'filename' => ['min:1', 'max:255'],
'title' => ['min:1', 'max:255'],
'notes' => 'min:1|max:32768',
'attachable_type' => sprintf('in:%s', $models),
'attachable_id' => ['numeric', new IsValidAttachmentModel($model)],
];

View File

@@ -28,6 +28,7 @@ use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -87,5 +88,8 @@ class Request extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -29,6 +29,7 @@ use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -72,7 +73,7 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'between:1,255|uniqueObjectForUser:bills,name',
'name' => 'min:1|max:255|uniqueObjectForUser:bills,name',
'amount_min' => ['required', new IsValidPositiveAmount()],
'amount_max' => ['required', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
@@ -81,9 +82,9 @@ class StoreRequest extends FormRequest
'end_date' => 'date|after:date',
'extension_date' => 'date|after:date',
'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly|required',
'skip' => 'between:0,31',
'skip' => 'min:0|max:31|numeric',
'active' => [new IsBoolean()],
'notes' => 'between:1,65536',
'notes' => 'min:1|max:32768',
];
}
@@ -103,5 +104,8 @@ class StoreRequest extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -30,6 +30,7 @@ use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -75,7 +76,7 @@ class UpdateRequest extends FormRequest
$bill = $this->route()->parameter('bill');
return [
'name' => sprintf('between:1,255|uniqueObjectForUser:bills,name,%d', $bill->id),
'name' => sprintf('min:1|max:255|uniqueObjectForUser:bills,name,%d', $bill->id),
'amount_min' => ['nullable', new IsValidPositiveAmount()],
'amount_max' => ['nullable', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
@@ -84,9 +85,9 @@ class UpdateRequest extends FormRequest
'end_date' => 'date|after:date',
'extension_date' => 'date|after:date',
'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly',
'skip' => 'between:0,31',
'skip' => 'min:0|max:31|numeric',
'active' => [new IsBoolean()],
'notes' => 'between:1,65536',
'notes' => 'min:1|max:32768',
];
}
@@ -108,5 +109,8 @@ class UpdateRequest extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -29,6 +29,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -68,11 +69,11 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'required|between:1,100|uniqueObjectForUser:budgets,name',
'name' => 'required|min:1|max:255|uniqueObjectForUser:budgets,name',
'active' => [new IsBoolean()],
'currency_id' => 'exists:transaction_currencies,id',
'currency_code' => 'exists:transaction_currencies,code',
'notes' => 'nullable|between:1,65536',
'notes' => 'nullable|min:1|max:32768',
// auto budget info
'auto_budget_type' => 'in:reset,rollover,adjusted,none',
'auto_budget_amount' => ['required_if:auto_budget_type,reset', 'required_if:auto_budget_type,rollover', 'required_if:auto_budget_type,adjusted', new IsValidPositiveAmount()],
@@ -91,5 +92,8 @@ class StoreRequest extends FormRequest
$this->validateAutoBudgetAmount($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -30,6 +30,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -81,9 +82,9 @@ class UpdateRequest extends FormRequest
$budget = $this->route()->parameter('budget');
return [
'name' => sprintf('between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id),
'name' => sprintf('min:1|max:100|uniqueObjectForUser:budgets,name,%d', $budget->id),
'active' => [new IsBoolean()],
'notes' => 'nullable|between:1,65536',
'notes' => 'nullable|min:1|max:32768',
'auto_budget_type' => 'in:reset,rollover,adjusted,none',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
'auto_budget_currency_code' => 'exists:transaction_currencies,code',
@@ -103,5 +104,8 @@ class UpdateRequest extends FormRequest
$this->validateAutoBudgetAmount($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -70,9 +71,7 @@ class UpdateRequest extends FormRequest
/**
* Configure the validator instance with special rules for after the basic validation rules.
*
* @param Validator $validator
* TODO duplicate code
* TODO duplicate code.
*/
public function withValidator(Validator $validator): void
{
@@ -84,10 +83,13 @@ class UpdateRequest extends FormRequest
$start = new Carbon($data['start']);
$end = new Carbon($data['end']);
if ($end->isBefore($start)) {
$validator->errors()->add('end', (string)trans('validation.date_after'));
$validator->errors()->add('end', (string) trans('validation.date_after'));
}
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -52,7 +52,7 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'required|between:1,100|uniqueObjectForUser:categories,name',
'name' => 'required|min:1|max:100|uniqueObjectForUser:categories,name',
];
}
}

View File

@@ -58,7 +58,7 @@ class UpdateRequest extends FormRequest
$category = $this->route()->parameter('category');
return [
'name' => sprintf('between:1,100|uniqueObjectForUser:categories,name,%d', $category->id),
'name' => sprintf('min:1|max:100|uniqueObjectForUser:categories,name,%d', $category->id),
];
}
}

View File

@@ -64,11 +64,11 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'required|between:1,255|uniquePiggyBankForUser',
'name' => 'required|min:1|max:255|uniquePiggyBankForUser',
'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',
'object_group_title' => ['min:1', 'max:255'],
'target_amount' => ['required', new IsValidPositiveAmount()],
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',

View File

@@ -69,7 +69,7 @@ class UpdateRequest extends FormRequest
$piggyBank = $this->route()->parameter('piggyBank');
return [
'name' => 'between:1,255|uniquePiggyBankForUser:'.$piggyBank->id,
'name' => 'min:1|max:255|uniquePiggyBankForUser:'.$piggyBank->id,
'current_amount' => ['nullable', new LessThanPiggyTarget(), new IsValidPositiveAmount()],
'target_amount' => ['nullable', new IsValidPositiveAmount()],
'start_date' => 'date|nullable',

View File

@@ -33,6 +33,7 @@ use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\RecurrenceValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -79,20 +80,20 @@ class StoreRequest extends FormRequest
{
return [
'type' => 'required|in:withdrawal,transfer,deposit',
'title' => 'required|between:1,255|uniqueObjectForUser:recurrences,title',
'description' => 'between:1,65000',
'title' => 'required|min:1|max:255|uniqueObjectForUser:recurrences,title',
'description' => 'min:1|max:32768',
'first_date' => 'required|date',
'apply_rules' => [new IsBoolean()],
'active' => [new IsBoolean()],
'repeat_until' => 'nullable|date',
'nr_of_repetitions' => 'nullable|numeric|between:1,31',
'nr_of_repetitions' => 'nullable|numeric|min:1|max:31',
'repetitions.*.type' => 'required|in:daily,weekly,ndom,monthly,yearly',
'repetitions.*.moment' => 'between:0,10',
'repetitions.*.skip' => 'nullable|numeric|between:0,31',
'repetitions.*.moment' => 'min:0|max:10',
'repetitions.*.skip' => 'nullable|numeric|min:0|max:31',
'repetitions.*.weekend' => 'numeric|min:1|max:4',
'transactions.*.description' => 'required|between:1,255',
'transactions.*.description' => 'required|min:1|max:255',
'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
@@ -100,18 +101,18 @@ class StoreRequest extends FormRequest
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.source_name' => 'min:1|max:255|nullable',
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.destination_name' => 'min:1|max:255|nullable',
// new and updated fields:
'transactions.*.budget_id' => ['nullable', 'mustExist:budgets,id', new BelongsUser()],
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['nullable', 'mustExist:categories,id', new BelongsUser()],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.piggy_bank_id' => ['nullable', 'numeric', 'mustExist:piggy_banks,id', new BelongsUser()],
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.tags' => 'nullable|between:1,255',
'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.tags' => 'nullable|min:1|max:255',
];
}
@@ -131,6 +132,9 @@ class StoreRequest extends FormRequest
$this->validateAccountInformation($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**

View File

@@ -34,6 +34,7 @@ use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\RecurrenceValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -86,20 +87,20 @@ class UpdateRequest extends FormRequest
$recurrence = $this->route()->parameter('recurrence');
return [
'title' => sprintf('between:1,255|uniqueObjectForUser:recurrences,title,%d', $recurrence->id),
'description' => 'between:1,65000',
'title' => sprintf('min:1|max:255|uniqueObjectForUser:recurrences,title,%d', $recurrence->id),
'description' => 'min:1|max:32768',
'first_date' => 'date',
'apply_rules' => [new IsBoolean()],
'active' => [new IsBoolean()],
'repeat_until' => 'nullable|date',
'nr_of_repetitions' => 'nullable|numeric|between:1,31',
'nr_of_repetitions' => 'nullable|numeric|min:1|max:31',
'repetitions.*.type' => 'in:daily,weekly,ndom,monthly,yearly',
'repetitions.*.moment' => 'between:0,10',
'repetitions.*.skip' => 'nullable|numeric|between:0,31',
'repetitions.*.moment' => 'min:0|max:10|numeric',
'repetitions.*.skip' => 'nullable|numeric|min:0|max:31',
'repetitions.*.weekend' => 'nullable|numeric|min:1|max:4',
'transactions.*.description' => 'between:1,255',
'transactions.*.description' => ['min:1', 'max:255'],
'transactions.*.amount' => [new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
@@ -107,18 +108,18 @@ class UpdateRequest extends FormRequest
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.source_name' => 'min:1|max:255|nullable',
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.destination_name' => 'min:1|max:255|nullable',
// new and updated fields:
'transactions.*.budget_id' => ['nullable', 'mustExist:budgets,id', new BelongsUser()],
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['nullable', 'mustExist:categories,id', new BelongsUser()],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.piggy_bank_id' => ['nullable', 'numeric', 'mustExist:piggy_banks,id', new BelongsUser()],
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.tags' => 'nullable|between:1,255',
'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.tags' => 'nullable|min:1|max:255',
];
}
@@ -141,6 +142,9 @@ class UpdateRequest extends FormRequest
$this->valUpdateAccountInfo($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**

View File

@@ -28,6 +28,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRuleConfiguration;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -76,10 +77,10 @@ class StoreRequest extends FormRequest
$contextActions = implode(',', config('firefly.context-rule-actions'));
return [
'title' => 'required|between:1,100|uniqueObjectForUser:rules,title',
'description' => 'between:1,5000|nullable',
'title' => 'required|min:1|max:100|uniqueObjectForUser:rules,title',
'description' => 'min:1|max:32768|nullable',
'rule_group_id' => 'belongsToUser:rule_groups|required_without:rule_group_title',
'rule_group_title' => 'nullable|between:1,255|required_without:rule_group_id|belongsToUser:rule_groups,title',
'rule_group_title' => 'nullable|min:1|max:255|required_without:rule_group_id|belongsToUser:rule_groups,title',
'trigger' => 'required|in:store-journal,update-journal',
'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
@@ -108,6 +109,9 @@ class StoreRequest extends FormRequest
$this->atLeastOneActiveAction($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**

View File

@@ -29,6 +29,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRuleConfiguration;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -85,10 +86,10 @@ class UpdateRequest extends FormRequest
$contextActions = implode(',', config('firefly.context-rule-actions'));
return [
'title' => sprintf('between:1,100|uniqueObjectForUser:rules,title,%d', $rule->id),
'description' => 'between:1,5000|nullable',
'title' => sprintf('min:1|max:100|uniqueObjectForUser:rules,title,%d', $rule->id),
'description' => 'min:1|max:32768|nullable',
'rule_group_id' => 'belongsToUser:rule_groups',
'rule_group_title' => 'nullable|between:1,255|belongsToUser:rule_groups,title',
'rule_group_title' => 'nullable|min:1|max:255|belongsToUser:rule_groups,title',
'trigger' => 'in:store-journal,update-journal',
'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
@@ -101,7 +102,7 @@ class UpdateRequest extends FormRequest
'strict' => [new IsBoolean()],
'stop_processing' => [new IsBoolean()],
'active' => [new IsBoolean()],
'order' => 'numeric|between:1,1337',
'order' => 'numeric|min:1|max:2048',
];
}
@@ -118,6 +119,9 @@ class UpdateRequest extends FormRequest
$this->atLeastOneValidAction($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**

View File

@@ -64,8 +64,8 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'title' => 'required|between:1,100|uniqueObjectForUser:rule_groups,title',
'description' => 'between:1,5000|nullable',
'title' => 'required|min:1|max:100|uniqueObjectForUser:rule_groups,title',
'description' => 'min:1|max:32768|nullable',
'active' => [new IsBoolean()],
];
}

View File

@@ -62,8 +62,8 @@ class UpdateRequest extends FormRequest
$ruleGroup = $this->route()->parameter('ruleGroup');
return [
'title' => 'between:1,100|uniqueObjectForUser:rule_groups,title,'.$ruleGroup->id,
'description' => 'between:1,5000|nullable',
'title' => 'min:1|max:100|uniqueObjectForUser:rule_groups,title,'.$ruleGroup->id,
'description' => 'min:1|max:32768|nullable',
'active' => [new IsBoolean()],
];
}

View File

@@ -60,7 +60,7 @@ class StoreRequest extends FormRequest
{
$rules = [
'tag' => 'required|min:1|uniqueObjectForUser:tags,tag|max:1024',
'description' => 'min:1|nullable|max:65536',
'description' => 'min:1|nullable|max:32768',
'date' => 'date|nullable',
];

View File

@@ -66,7 +66,7 @@ class UpdateRequest extends FormRequest
// TODO check if uniqueObjectForUser is obsolete
$rules = [
'tag' => 'min:1|max:1024|uniqueObjectForUser:tags,tag,'.$tag->id,
'description' => 'min:1|nullable|max:65536',
'description' => 'min:1|nullable|max:32768',
'date' => 'date|nullable',
];

View File

@@ -28,6 +28,7 @@ use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\IsValidZeroOrMoreAmount;
use FireflyIII\Support\NullArrayObject;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
@@ -36,6 +37,7 @@ use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -77,7 +79,7 @@ class StoreRequest extends FormRequest
return [
// basic fields for group:
'group_title' => 'between:1,1000|nullable',
'group_title' => 'min:1|max:1000|nullable',
'error_if_duplicate_hash' => [new IsBoolean()],
'apply_rules' => [new IsBoolean()],
@@ -94,40 +96,40 @@ class StoreRequest extends FormRequest
// amount
'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
// description
'transactions.*.description' => 'nullable|between:1,1000',
'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.source_iban' => 'between:1,255|nullable|iban',
'transactions.*.source_number' => 'between:1,255|nullable',
'transactions.*.source_bic' => 'between:1,255|nullable|bic',
'transactions.*.source_name' => 'min:1|max:255|nullable',
'transactions.*.source_iban' => 'min:1|max:255|nullable|iban',
'transactions.*.source_number' => 'min:1|max:255|nullable',
'transactions.*.source_bic' => 'min:1|max:255|nullable|bic',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.destination_iban' => 'between:1,255|nullable|iban',
'transactions.*.destination_number' => 'between:1,255|nullable',
'transactions.*.destination_bic' => 'between:1,255|nullable|bic',
'transactions.*.destination_name' => 'min:1|max:255|nullable',
'transactions.*.destination_iban' => 'min:1|max:255|nullable|iban',
'transactions.*.destination_number' => 'min:1|max:255|nullable',
'transactions.*.destination_bic' => 'min:1|max:255|nullable|bic',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser()],
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUser()],
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:50000|nullable',
'transactions.*.tags' => 'between:0,255',
'transactions.*.tags.*' => 'between:0,255',
'transactions.*.notes' => 'min:1|max:32768|nullable',
'transactions.*.tags' => 'min:0|max:255',
'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
@@ -190,6 +192,9 @@ class StoreRequest extends FormRequest
$this->validateGroupDescription($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**

View File

@@ -36,6 +36,7 @@ use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -99,7 +100,7 @@ class UpdateRequest extends FormRequest
return [
// basic fields for group:
'group_title' => 'between:1,1000|nullable',
'group_title' => 'min:1|max:1000|nullable',
'apply_rules' => [new IsBoolean()],
// transaction rules (in array for splits):
@@ -121,29 +122,29 @@ class UpdateRequest extends FormRequest
'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
// description
'transactions.*.description' => 'nullable|between:1,1000',
'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.source_name' => 'min:1|max:255|nullable',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.destination_name' => 'min:1|max:255|nullable',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser(), 'nullable'],
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:50000|nullable',
'transactions.*.tags' => 'between:0,255|nullable',
'transactions.*.tags.*' => 'between:0,255',
'transactions.*.notes' => 'min:1|max:32768|nullable',
'transactions.*.tags' => 'min:0|max:255|nullable',
'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
@@ -205,6 +206,9 @@ class UpdateRequest extends FormRequest
$this->validateAccountInformationUpdate($validator, $transactionGroup);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**

View File

@@ -66,10 +66,10 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'required|between:1,255|unique:transaction_currencies,name',
'code' => 'required|between:3,51|unique:transaction_currencies,code',
'symbol' => 'required|between:1,51|unique:transaction_currencies,symbol',
'decimal_places' => 'between:0,20|numeric|min:0|max:12',
'name' => 'required|min:1|max:255|unique:transaction_currencies,name',
'code' => 'required|min:3|max:32|unique:transaction_currencies,code',
'symbol' => 'required|min:1|max:32|unique:transaction_currencies,symbol',
'decimal_places' => 'numeric|min:0|max:12',
'enabled' => [new IsBoolean()],
'default' => [new IsBoolean()],
];

View File

@@ -42,7 +42,7 @@ class UpdateRequest extends FormRequest
*/
public function getAll(): array
{
// return nothing that isn't explicitely in the array:
// return nothing that isn't explicitly in the array:
$fields = [
'name' => ['name', 'convertString'],
'code' => ['code', 'convertString'],
@@ -64,10 +64,10 @@ class UpdateRequest extends FormRequest
$currency = $this->route()->parameter('currency_code');
return [
'name' => sprintf('between:1,255|unique:transaction_currencies,name,%d', $currency->id),
'code' => sprintf('between:3,51|unique:transaction_currencies,code,%d', $currency->id),
'symbol' => sprintf('between:1,51|unique:transaction_currencies,symbol,%d', $currency->id),
'decimal_places' => 'between:0,20|numeric|min:0|max:12',
'name' => sprintf('min:1|max:255|unique:transaction_currencies,name,%d', $currency->id),
'code' => sprintf('min:3|max:32|unique:transaction_currencies,code,%d', $currency->id),
'symbol' => sprintf('min:1|max:32|unique:transaction_currencies,symbol,%d', $currency->id),
'decimal_places' => 'numeric|min:0|max:12',
'enabled' => [new IsBoolean()],
'default' => [new IsBoolean()],
];

View File

@@ -29,6 +29,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -63,7 +64,7 @@ class StoreRequest extends FormRequest
'link_type_name' => 'exists:link_types,name|required_without:link_type_id',
'inward_id' => 'required|belongsToUser:transaction_journals,id|different:outward_id',
'outward_id' => 'required|belongsToUser:transaction_journals,id|different:inward_id',
'notes' => 'between:0,65000',
'notes' => 'min:1|max:32768|nullable',
];
}
@@ -77,6 +78,9 @@ class StoreRequest extends FormRequest
$this->validateExistingLink($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
private function validateExistingLink(Validator $validator): void

View File

@@ -29,6 +29,7 @@ use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -63,7 +64,7 @@ class UpdateRequest extends FormRequest
'link_type_name' => 'exists:link_types,name',
'inward_id' => 'belongsToUser:transaction_journals,id|different:outward_id',
'outward_id' => 'belongsToUser:transaction_journals,id|different:inward_id',
'notes' => 'between:0,65000',
'notes' => 'min:1|max:32768|nullable',
];
}
@@ -77,6 +78,9 @@ class UpdateRequest extends FormRequest
$this->validateUpdate($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
private function validateUpdate(Validator $validator): void

View File

@@ -72,7 +72,7 @@ class CreateRequest extends FormRequest
$validProtocols = config('firefly.valid_url_protocols');
return [
'title' => 'required|between:1,512|uniqueObjectForUser:webhooks,title',
'title' => 'required|min:1|max:255|uniqueObjectForUser:webhooks,title',
'active' => [new IsBoolean()],
'trigger' => sprintf('required|in:%s', $triggers),
'response' => sprintf('required|in:%s', $responses),

View File

@@ -85,7 +85,7 @@ class UpdateRequest extends FormRequest
$webhook = $this->route()->parameter('webhook');
return [
'title' => sprintf('between:1,512|uniqueObjectForUser:webhooks,title,%d', $webhook->id),
'title' => sprintf('min:1|max:255|uniqueObjectForUser:webhooks,title,%d', $webhook->id),
'active' => [new IsBoolean()],
'trigger' => sprintf('in:%s', $triggers),
'response' => sprintf('in:%s', $responses),

View File

@@ -65,7 +65,7 @@ class UpdateRequest extends FormRequest
return ['value' => ['required', new IsBoolean()]];
}
if ('configuration.permission_update_check' === $name) {
return ['value' => 'required|numeric|between:-1,1'];
return ['value' => 'required|numeric|min:-1|max:1'];
}
if ('configuration.last_update_check' === $name) {
return ['value' => 'required|numeric|min:464272080'];

View File

@@ -29,6 +29,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -97,5 +98,8 @@ class UserUpdateRequest extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -77,11 +77,7 @@ class BudgetController extends Controller
}
/**
* @param DateRequest $request
*
* TODO see autocomplete/accountcontroller
*
* @throws FireflyException
*/
public function dashboard(DateRequest $request): JsonResponse
{

View File

@@ -0,0 +1,43 @@
<?php
/*
* ShowController.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\Api\V2\Controllers\Model\Transaction;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Transformers\V2\TransactionGroupTransformer;
use Illuminate\Http\JsonResponse;
class ShowController extends Controller
{
/**
* TODO this endpoint is not yet reachable.
*/
public function show(TransactionGroup $transactionGroup): JsonResponse
{
$transformer = new TransactionGroupTransformer();
$transformer->setParameters($this->parameters);
return response()->api($this->jsonApiObject('transactions', $transactionGroup, $transformer))->header('Content-Type', self::CONTENT_TYPE);
}
}

View File

@@ -0,0 +1,93 @@
<?php
/*
* UpdateController.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\Api\V2\Controllers\Model\Transaction;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Model\Transaction\UpdateRequest;
use FireflyIII\Events\UpdatedTransactionGroup;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
use FireflyIII\Transformers\V2\TransactionGroupTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
class UpdateController extends Controller
{
private TransactionGroupRepositoryInterface $groupRepository;
/**
* TransactionController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
$this->groupRepository = app(TransactionGroupRepositoryInterface::class);
return $next($request);
}
);
}
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/updateTransaction
*
* Update a transaction.
*
* @throws FireflyException
*/
public function update(UpdateRequest $request, TransactionGroup $transactionGroup): JsonResponse
{
app('log')->debug('Now in update routine for transaction group [v2]!');
$data = $request->getAll();
$transactionGroup = $this->groupRepository->update($transactionGroup, $data);
$applyRules = $data['apply_rules'] ?? true;
$fireWebhooks = $data['fire_webhooks'] ?? true;
event(new UpdatedTransactionGroup($transactionGroup, $applyRules, $fireWebhooks));
app('preferences')->mark();
/** @var User $admin */
$admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($admin)->setTransactionGroup($transactionGroup);
$selectedGroup = $collector->getGroups()->first();
if (null === $selectedGroup) {
throw new FireflyException('200032: Cannot find transaction. Possibly, a rule deleted this transaction after its creation.');
}
$transformer = new TransactionGroupTransformer();
$transformer->setParameters($this->parameters);
return response()->api($this->jsonApiObject('transactions', $selectedGroup, $transformer))->header('Content-Type', self::CONTENT_TYPE);
}
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -79,5 +80,8 @@ class BalanceChartRequest extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -27,6 +27,7 @@ use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -77,5 +78,8 @@ class DashboardChartRequest extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Models\UserGroup;
use FireflyIII\Rules\BelongsUserGroup;
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;
@@ -37,6 +38,7 @@ use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -74,7 +76,6 @@ class StoreRequest extends FormRequest
'fire_webhooks' => $this->boolean('fire_webhooks', true),
'transactions' => $this->getTransactionData(),
];
// TODO include location and ability to process it.
}
/**
@@ -91,81 +92,84 @@ class StoreRequest extends FormRequest
return [
// basic fields for group:
'group_title' => 'between:1,1000|nullable',
'error_if_duplicate_hash' => [new IsBoolean()],
'apply_rules' => [new IsBoolean()],
'group_title' => 'min:1|max:1000|nullable',
'error_if_duplicate_hash' => [new IsBoolean()],
'apply_rules' => [new IsBoolean()],
// transaction rules (in array for splits):
'transactions.*.type' => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation',
'transactions.*.date' => ['required', new IsDateOrTime()],
'transactions.*.order' => 'numeric|min:0',
'transactions.*.type' => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation',
'transactions.*.date' => ['required', new IsDateOrTime()],
'transactions.*.order' => 'numeric|min:0',
// currency info
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.foreign_currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'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|gt:0|max:1000000000',
'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
// description
'transactions.*.description' => 'nullable|between:1,1000',
'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.source_iban' => 'between:1,255|nullable|iban',
'transactions.*.source_number' => 'between:1,255|nullable',
'transactions.*.source_bic' => 'between:1,255|nullable|bic',
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.source_name' => 'min:1|max:255|nullable',
'transactions.*.source_iban' => 'min:1|max:255|nullable|iban',
'transactions.*.source_number' => 'min:1|max:255|nullable',
'transactions.*.source_bic' => 'min:1|max:255|nullable|bic',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.destination_iban' => 'between:1,255|nullable|iban',
'transactions.*.destination_number' => 'between:1,255|nullable',
'transactions.*.destination_bic' => 'between:1,255|nullable|bic',
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.destination_name' => 'min:1|max:255|nullable',
'transactions.*.destination_iban' => 'min:1|max:255|nullable|iban',
'transactions.*.destination_number' => 'min:1|max:255|nullable',
'transactions.*.destination_bic' => 'min:1|max:255|nullable|bic',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUserGroup($userGroup)],
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUserGroup($userGroup), 'nullable'],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUserGroup($userGroup)],
'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUserGroup($userGroup)],
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUserGroup($userGroup)],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUserGroup($userGroup), 'nullable'],
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUserGroup($userGroup)],
'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUserGroup($userGroup)],
'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUserGroup($userGroup)],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:50000|nullable',
'transactions.*.tags' => 'between:0,255',
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:32768|nullable',
'transactions.*.tags' => 'min:0|max:255',
'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
'transactions.*.external_id' => 'min:1|max:255|nullable',
'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
'transactions.*.external_url' => 'min:1|max:255|nullable|url',
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
'transactions.*.external_id' => 'min:1|max:255|nullable',
'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
'transactions.*.external_url' => 'min:1|max:255|nullable|url',
// SEPA fields:
'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable',
'transactions.*.sepa_db' => 'min:1|max:255|nullable',
'transactions.*.sepa_country' => 'min:1|max:255|nullable',
'transactions.*.sepa_ep' => 'min:1|max:255|nullable',
'transactions.*.sepa_ci' => 'min:1|max:255|nullable',
'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable',
'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable',
'transactions.*.sepa_db' => 'min:1|max:255|nullable',
'transactions.*.sepa_country' => 'min:1|max:255|nullable',
'transactions.*.sepa_ep' => 'min:1|max:255|nullable',
'transactions.*.sepa_ci' => 'min:1|max:255|nullable',
'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable',
// dates
'transactions.*.interest_date' => 'date|nullable',
'transactions.*.book_date' => 'date|nullable',
'transactions.*.process_date' => 'date|nullable',
'transactions.*.due_date' => 'date|nullable',
'transactions.*.payment_date' => 'date|nullable',
'transactions.*.invoice_date' => 'date|nullable',
'transactions.*.interest_date' => 'date|nullable',
'transactions.*.book_date' => 'date|nullable',
'transactions.*.process_date' => 'date|nullable',
'transactions.*.due_date' => 'date|nullable',
'transactions.*.payment_date' => 'date|nullable',
'transactions.*.invoice_date' => 'date|nullable',
// TODO include location and ability to process it.
];
}
@@ -208,6 +212,9 @@ class StoreRequest extends FormRequest
$this->validateGroupDescription($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**
@@ -222,7 +229,7 @@ class StoreRequest extends FormRequest
*/
foreach ($this->get('transactions') as $transaction) {
$object = new NullArrayObject($transaction);
$return[] = [
$result = [
'type' => $this->clearString($object['type']),
'date' => $this->dateFromValue($object['date']),
'order' => $this->integerFromValue((string)$object['order']),
@@ -300,6 +307,8 @@ class StoreRequest extends FormRequest
'payment_date' => $this->dateFromValue($object['payment_date']),
'invoice_date' => $this->dateFromValue($object['invoice_date']),
];
$result = $this->addFromromTransactionStore($transaction, $result);
$return[] = $result;
}
return $return;

View File

@@ -0,0 +1,366 @@
<?php
/*
* UpdateRequest.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\Api\V2\Request\Model\Transaction;
use FireflyIII\Api\V1\Requests\Models\AvailableBudget\Request;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\IsValidZeroOrMoreAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
* Class UpdateRequest
*
* TODO it's the same as the v1
*/
class UpdateRequest extends Request
{
use ChecksLogin;
use ConvertsDataTypes;
use GroupValidation;
use TransactionValidation;
private array $arrayFields;
private array $booleanFields;
private array $dateFields;
private array $floatFields;
private array $integerFields;
private array $stringFields;
private array $textareaFields;
/**
* Get all data. Is pretty complex because of all the ??-statements.
*
* @throws FireflyException
*/
public function getAll(): array
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
$this->integerFields = ['order', 'currency_id', 'foreign_currency_id', 'transaction_journal_id', 'source_id', 'destination_id', 'budget_id', 'category_id', 'bill_id', 'recurrence_id'];
$this->dateFields = ['date', 'interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date'];
$this->textareaFields = ['notes'];
// not really floats, for validation.
$this->floatFields = ['amount', 'foreign_amount'];
$this->stringFields = ['type', 'currency_code', 'foreign_currency_code', 'description', 'source_name', 'source_iban', 'source_number', 'source_bic', 'destination_name', 'destination_iban', 'destination_number', 'destination_bic', 'budget_name', 'category_name', 'bill_name', 'internal_reference', 'external_id', 'bunq_payment_id', 'sepa_cc', 'sepa_ct_op', 'sepa_ct_id', 'sepa_db', 'sepa_country', 'sepa_ep', 'sepa_ci', 'sepa_batch_id', 'external_url'];
$this->booleanFields = ['reconciled'];
$this->arrayFields = ['tags'];
$data = [];
if ($this->has('transactions')) {
$data['transactions'] = $this->getTransactionData();
}
if ($this->has('apply_rules')) {
$data['apply_rules'] = $this->boolean('apply_rules', true);
}
if ($this->has('fire_webhooks')) {
$data['fire_webhooks'] = $this->boolean('fire_webhooks', true);
}
if ($this->has('group_title')) {
$data['group_title'] = $this->convertString('group_title');
}
return $data;
}
/**
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
$validProtocols = config('firefly.valid_url_protocols');
return [
// basic fields for group:
'group_title' => 'min:1|max:1000|nullable',
'apply_rules' => [new IsBoolean()],
// transaction rules (in array for splits):
'transactions.*.type' => 'in:withdrawal,deposit,transfer,opening-balance,reconciliation',
'transactions.*.date' => [new IsDateOrTime()],
'transactions.*.order' => 'numeric|min:0',
// group id:
'transactions.*.transaction_journal_id' => ['nullable', 'numeric', new BelongsUser()],
// currency info
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
// amount
'transactions.*.amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
// description
'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'min:1|max:255|nullable',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'min:1|max:255|nullable',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser(), 'nullable'],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:32768|nullable',
'transactions.*.tags' => 'min:0|max:255|nullable',
'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
'transactions.*.external_id' => 'min:1|max:255|nullable',
'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
'transactions.*.external_url' => sprintf('min:1|max:255|nullable|url:%s', $validProtocols),
// SEPA fields:
'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable',
'transactions.*.sepa_db' => 'min:1|max:255|nullable',
'transactions.*.sepa_country' => 'min:1|max:255|nullable',
'transactions.*.sepa_ep' => 'min:1|max:255|nullable',
'transactions.*.sepa_ci' => 'min:1|max:255|nullable',
'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable',
// dates
'transactions.*.interest_date' => 'date|nullable',
'transactions.*.book_date' => 'date|nullable',
'transactions.*.process_date' => 'date|nullable',
'transactions.*.due_date' => 'date|nullable',
'transactions.*.payment_date' => 'date|nullable',
'transactions.*.invoice_date' => 'date|nullable',
];
}
/**
* Configure the validator instance.
*/
public function withValidator(Validator $validator): void
{
app('log')->debug('Now in withValidator');
/** @var TransactionGroup $transactionGroup */
$transactionGroup = $this->route()->parameter('userGroupTransaction');
$validator->after(
function (Validator $validator) use ($transactionGroup): void {
// if more than one, verify that there are journal ID's present.
$this->validateJournalIds($validator, $transactionGroup);
// all transaction types must be equal:
$this->validateTransactionTypesForUpdate($validator);
// user wants to update a reconciled transaction.
// source, destination, amount + foreign_amount cannot be changed
// and must be omitted from the request.
$this->preventUpdateReconciled($validator, $transactionGroup);
// validate source/destination is equal, depending on the transaction journal type.
$this->validateEqualAccountsForUpdate($validator, $transactionGroup);
// see method:
// $this->preventNoAccountInfo($validator, );
// validate that the currency fits the source and/or destination account.
// validate all account info
$this->validateAccountInformationUpdate($validator, $transactionGroup);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**
* Get transaction data.
*
* @throws FireflyException
*/
private function getTransactionData(): array
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
$return = [];
/** @var null|array $transactions */
$transactions = $this->get('transactions');
if (!is_countable($transactions)) {
return $return;
}
/** @var null|array $transaction */
foreach ($transactions as $transaction) {
if (!is_array($transaction)) {
throw new FireflyException('Invalid data submitted: transaction is not array.');
}
// default response is to update nothing in the transaction:
$current = [];
$current = $this->getIntegerData($current, $transaction);
$current = $this->getStringData($current, $transaction);
$current = $this->getNlStringData($current, $transaction);
$current = $this->getDateData($current, $transaction);
$current = $this->getBooleanData($current, $transaction);
$current = $this->getArrayData($current, $transaction);
$current = $this->getFloatData($current, $transaction);
$return[] = $current;
}
return $return;
}
/**
* For each field, add it to the array if a reference is present in the request:
*
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getIntegerData(array $current, array $transaction): array
{
foreach ($this->integerFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->integerFromValue((string) $transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getStringData(array $current, array $transaction): array
{
foreach ($this->stringFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearString((string) $transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getNlStringData(array $current, array $transaction): array
{
foreach ($this->textareaFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearStringKeepNewlines((string) $transaction[$fieldName]); // keep newlines
}
}
return $current;
}
/**
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getDateData(array $current, array $transaction): array
{
foreach ($this->dateFields as $fieldName) {
app('log')->debug(sprintf('Now at date field %s', $fieldName));
if (array_key_exists($fieldName, $transaction)) {
app('log')->debug(sprintf('New value: "%s"', (string) $transaction[$fieldName]));
$current[$fieldName] = $this->dateFromValue((string) $transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getBooleanData(array $current, array $transaction): array
{
foreach ($this->booleanFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->convertBoolean((string) $transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getArrayData(array $current, array $transaction): array
{
foreach ($this->arrayFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->arrayFromValue($transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getFloatData(array $current, array $transaction): array
{
foreach ($this->floatFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$value = $transaction[$fieldName];
if (is_float($value)) {
$current[$fieldName] = sprintf('%.12f', $value);
}
if (!is_float($value)) {
$current[$fieldName] = (string) $value;
}
}
}
return $current;
}
}

View File

@@ -49,7 +49,7 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'title' => 'unique:user_groups,title|required|min:2|max:255',
'title' => 'unique:user_groups,title|required|min:1|max:255',
];
}
}

View File

@@ -53,7 +53,7 @@ class UpdateRequest extends FormRequest
$userGroup = $this->route()->parameter('userGroup');
return [
'title' => sprintf('required|min:2|max:255|unique:user_groups,title,%d', $userGroup->id),
'title' => sprintf('required|min:1|max:255|unique:user_groups,title,%d', $userGroup->id),
];
}
}

View File

@@ -71,7 +71,6 @@ class EnableCurrencies extends Command
$found = [$defaultCurrency->id];
// get all meta entries
/** @var Collection $meta */
$meta = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id')
->where('accounts.user_group_id', $userGroup->id)
->where('account_meta.name', 'currency_id')->groupBy('data')->get(['data'])
@@ -108,6 +107,12 @@ class EnableCurrencies extends Command
$found[] = $entry->transaction_currency_id;
}
// also get all currencies already enabled.
$alreadyEnabled = $userGroup->currencies()->get(['transaction_currencies.id'])->pluck('id')->toArray();
foreach ($alreadyEnabled as $currencyId) {
$found[] = $currencyId;
}
$found = array_values(array_unique($found));
$found = array_values(
array_filter(

View File

@@ -216,6 +216,7 @@ class Handler extends ExceptionHandler
'json' => request()->acceptsJson(),
'method' => request()->method(),
'headers' => $headers,
'post' => 'POST' === request()->method() ? json_encode(request()->all()) : '',
];
// create job that will mail.

View File

@@ -28,6 +28,7 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\DuplicateTransactionException;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\Location;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
@@ -49,6 +50,8 @@ use Illuminate\Support\Collection;
/**
* Class TransactionJournalFactory
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class TransactionJournalFactory
{
@@ -318,10 +321,23 @@ class TransactionJournalFactory
$this->storePiggyEvent($journal, $row);
$this->storeTags($journal, $row['tags']);
$this->storeMetaFields($journal, $row);
$this->storeLocation($journal, $row);
return $journal;
}
private function storeLocation(TransactionJournal $journal, NullArrayObject $data): void
{
if (true === $data['store_location']) {
$location = new Location();
$location->longitude = $data['longitude'];
$location->latitude = $data['latitude'];
$location->zoom_level = $data['zoom_level'];
$location->locatable()->associate($journal);
$location->save();
}
}
private function hashArray(NullArrayObject $row): string
{
$dataRow = $row->getArrayCopy();
@@ -360,16 +376,13 @@ class TransactionJournalFactory
->where('transaction_journals.user_id', $this->user->id)
->where('data', json_encode($hash, JSON_THROW_ON_ERROR))
->with(['transactionJournal', 'transactionJournal.transactionGroup'])
->first()
->first(['journal_meta.*'])
;
if (null !== $result) {
app('log')->warning(sprintf('Found a duplicate in errorIfDuplicate because hash %s is not unique!', $hash));
$journal = $result->transactionJournal()->withTrashed()->first();
$group = $journal?->transactionGroup()->withTrashed()->first();
$groupId = $group?->id;
if (null === $group) {
$groupId = 0;
}
$groupId = (int) $group?->id;
throw new DuplicateTransactionException(sprintf('Duplicate of transaction #%d.', $groupId));
}

View File

@@ -182,7 +182,7 @@ trait MetaCollection
public function excludeInternalReference(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -203,7 +203,7 @@ trait MetaCollection
public function externalIdContains(string $externalId): GroupCollectorInterface
{
$externalId = (string) json_encode($externalId);
$externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -215,7 +215,7 @@ trait MetaCollection
public function externalIdDoesNotContain(string $externalId): GroupCollectorInterface
{
$externalId = (string) json_encode($externalId);
$externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -227,7 +227,7 @@ trait MetaCollection
public function externalIdDoesNotEnd(string $externalId): GroupCollectorInterface
{
$externalId = (string) json_encode($externalId);
$externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -239,7 +239,7 @@ trait MetaCollection
public function externalIdDoesNotStart(string $externalId): GroupCollectorInterface
{
$externalId = (string) json_encode($externalId);
$externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -251,7 +251,7 @@ trait MetaCollection
public function externalIdEnds(string $externalId): GroupCollectorInterface
{
$externalId = (string) json_encode($externalId);
$externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -263,7 +263,7 @@ trait MetaCollection
public function externalIdStarts(string $externalId): GroupCollectorInterface
{
$externalId = (string) json_encode($externalId);
$externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -276,7 +276,7 @@ trait MetaCollection
public function externalUrlContains(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
$url = (string) json_encode($url);
$url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', trim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $url));
@@ -287,7 +287,7 @@ trait MetaCollection
public function externalUrlDoesNotContain(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
$url = (string) json_encode($url);
$url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', trim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s%%', $url));
@@ -298,7 +298,7 @@ trait MetaCollection
public function externalUrlDoesNotEnd(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
$url = (string) json_encode($url);
$url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', ltrim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s', $url));
@@ -309,7 +309,7 @@ trait MetaCollection
public function externalUrlDoesNotStart(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
$url = (string) json_encode($url);
$url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', rtrim($url, '"'));
// var_dump($url);
@@ -322,7 +322,7 @@ trait MetaCollection
public function externalUrlEnds(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
$url = (string) json_encode($url);
$url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', ltrim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s', $url));
@@ -333,7 +333,7 @@ trait MetaCollection
public function externalUrlStarts(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
$url = (string) json_encode($url);
$url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', rtrim($url, '"'));
// var_dump($url);
@@ -371,7 +371,7 @@ trait MetaCollection
public function internalReferenceContains(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
// var_dump($internalReference);
// exit;
@@ -385,7 +385,7 @@ trait MetaCollection
public function internalReferenceDoesNotContain(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -397,7 +397,7 @@ trait MetaCollection
public function internalReferenceDoesNotEnd(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -409,7 +409,7 @@ trait MetaCollection
public function internalReferenceDoesNotStart(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -421,7 +421,7 @@ trait MetaCollection
public function internalReferenceEnds(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -433,7 +433,7 @@ trait MetaCollection
public function internalReferenceStarts(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -629,7 +629,7 @@ trait MetaCollection
public function setInternalReference(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -682,6 +682,7 @@ trait MetaCollection
$list = $tags->pluck('tag')->toArray();
$list = array_map('strtolower', $list);
$filter = static function (array $object) use ($list): bool|array {
$includedJournals = [];
$return = $object;
unset($return['transactions']);
$return['transactions'] = [];
@@ -701,7 +702,12 @@ trait MetaCollection
if (in_array(strtolower($tag['name']), $list, true)) {
app('log')->debug(sprintf('Transaction has tag "%s" so count++.', $tag['name']));
++$foundTagCount;
$return['transactions'][] = $transaction;
$journalId = $transaction['transaction_journal_id'];
// #8377 prevent adding a transaction twice when multiple tag searches find this transaction
if (!in_array($journalId, $includedJournals, true)) {
$includedJournals[] = $journalId;
$return['transactions'][] = $transaction;
}
}
}
}

View File

@@ -462,7 +462,7 @@ trait TimeCollection
*/
public function setBefore(Carbon $date): GroupCollectorInterface
{
$beforeStr = $date->format('Y-m-d 00:00:00');
$beforeStr = $date->format('Y-m-d 23:59:59');
$this->query->where('transaction_journals.date', '<=', $beforeStr);
return $this;

View File

@@ -25,7 +25,6 @@ namespace FireflyIII\Helpers\Collector;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\Extensions\AccountCollection;
use FireflyIII\Helpers\Collector\Extensions\AmountCollection;
@@ -106,6 +105,8 @@ class GroupCollector implements GroupCollectorInterface
'transaction_groups.created_at as created_at',
'transaction_groups.updated_at as updated_at',
'transaction_groups.title as transaction_group_title',
'transaction_groups.created_at as group_created_at',
'transaction_groups.updated_at as group_updated_at',
// journal
'transaction_journals.id as transaction_journal_id',
@@ -702,6 +703,8 @@ class GroupCollector implements GroupCollectorInterface
'user_group_id' => $augumentedJournal->user_group_id,
// Field transaction_group_title was added by the query.
'title' => $augumentedJournal->transaction_group_title, // @phpstan-ignore-line
'created_at' => new Carbon($augumentedJournal->group_created_at, config('app.timezone')),
'updated_at' => new Carbon($augumentedJournal->group_updated_at, config('app.timezone')),
'transaction_type' => $parsedGroup['transaction_type_type'],
'count' => 1,
'sums' => [],
@@ -928,7 +931,6 @@ class GroupCollector implements GroupCollectorInterface
private function postFilterCollection(Collection $collection): Collection
{
$currentCollection = $collection;
app('log')->debug(sprintf('GroupCollector: postFilterCollection has %d filter(s) and %d transaction(s).', count($this->postFilters), count($currentCollection)));
/**
@@ -951,11 +953,11 @@ class GroupCollector implements GroupCollectorInterface
continue;
}
// if the result is a bool, use the unedited results.
if(true === $result) {
if (true === $result) {
$nextCollection->push($item);
}
// if the result is an array, the filter has changed what's being returned.
if(is_array($result)) {
if (is_array($result)) {
$nextCollection->push($result);
}
}

View File

@@ -161,7 +161,7 @@ class CreateController extends Controller
$this->attachments->saveAttachmentsForModel($account, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string) trans('firefly.no_att_demo_user'));
}

View File

@@ -187,7 +187,7 @@ class EditController extends Controller
$this->attachments->saveAttachmentsForModel($account, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string) trans('firefly.no_att_demo_user'));
}

View File

@@ -78,7 +78,7 @@ class LoginController extends Controller
public function login(Request $request): JsonResponse|RedirectResponse
{
Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get($this->username())));
app('log')->info('User is trying to login.');
app('log')->debug('User is trying to login.');
$this->validateLogin($request);
app('log')->debug('Login data is present.');
@@ -88,7 +88,7 @@ class LoginController extends Controller
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if ($this->hasTooManyLoginAttempts($request)) {
Log::channel('audit')->info(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
Log::channel('audit')->warning(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
app('log')->error(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
$this->fireLockoutEvent($request);
@@ -114,7 +114,7 @@ class LoginController extends Controller
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
Log::channel('audit')->info(sprintf('Login failed. Attempt for user "%s" failed.', $request->get($this->username())));
Log::channel('audit')->warning(sprintf('Login failed. Attempt for user "%s" failed.', $request->get($this->username())));
$this->sendFailedLoginResponse($request);

View File

@@ -116,7 +116,7 @@ class CreateController extends Controller
$this->attachments->saveAttachmentsForModel($bill, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}

View File

@@ -128,7 +128,7 @@ class EditController extends Controller
$this->attachments->saveAttachmentsForModel($bill, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string) trans('firefly.no_att_demo_user'));
}

View File

@@ -202,7 +202,9 @@ class BudgetLimitController extends Controller
if ('' === $amount) {
$amount = '0';
}
if ((int)$amount > 268435456) { // 268 million, intentional integer
$amount = '268435456';
}
// sanity check on amount:
if (0 === bccomp($amount, '0')) {
$budgetId = $budgetLimit->budget_id;
@@ -217,9 +219,7 @@ class BudgetLimitController extends Controller
return response()->json($array);
}
if ((int)$amount > 268435456) { // 268 million, intentional integer
$amount = '268435456';
}
if (-1 === bccomp($amount, '0')) {
$amount = bcmul($amount, '-1');
}

View File

@@ -127,7 +127,7 @@ class CreateController extends Controller
$this->attachments->saveAttachmentsForModel($budget, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}

View File

@@ -137,7 +137,7 @@ class EditController extends Controller
$this->attachments->saveAttachmentsForModel($budget, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}

View File

@@ -100,7 +100,7 @@ class CreateController extends Controller
$this->attachments->saveAttachmentsForModel($category, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}

View File

@@ -104,7 +104,7 @@ class EditController extends Controller
$this->attachments->saveAttachmentsForModel($category, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}

View File

@@ -108,7 +108,7 @@ class ReportController extends Controller
continue;
}
$currencyId = $netWorthItem['currency_id'];
$label = $current->isoFormat((string) trans('config.month_and_day_js', [], $locale));
$label = $current->isoFormat((string)trans('config.month_and_day_js', [], $locale));
if (!array_key_exists($currencyId, $chartData)) {
$chartData[$currencyId] = [
'label' => 'Net worth in '.$netWorthItem['currency_name'],
@@ -145,6 +145,7 @@ class ReportController extends Controller
if ($cache->has()) {
return response()->json($cache->get());
}
app('log')->debug('Going to do operations for accounts ', $accounts->pluck('id')->toArray());
$format = app('navigation')->preferredCarbonFormat($start, $end);
$titleFormat = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
@@ -164,13 +165,13 @@ class ReportController extends Controller
/** @var array $journal */
foreach ($journals as $journal) {
$period = $journal['date']->format($format);
$currencyId = (int) $journal['currency_id'];
$currencyId = (int)$journal['currency_id'];
$data[$currencyId] ??= [
'currency_id' => $currencyId,
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
'currency_name' => $journal['currency_name'],
'currency_decimal_places' => (int) $journal['currency_decimal_places'],
'currency_decimal_places' => (int)$journal['currency_decimal_places'],
];
$data[$currencyId][$period] ??= [
'period' => $period,
@@ -193,7 +194,7 @@ class ReportController extends Controller
/** @var array $currency */
foreach ($data as $currency) {
$income = [
'label' => (string) trans('firefly.box_earned_in_currency', ['currency' => $currency['currency_name']]),
'label' => (string)trans('firefly.box_earned_in_currency', ['currency' => $currency['currency_name']]),
'type' => 'bar',
'backgroundColor' => 'rgba(0, 141, 76, 0.5)', // green
'currency_id' => $currency['currency_id'],
@@ -202,7 +203,7 @@ class ReportController extends Controller
'entries' => [],
];
$expense = [
'label' => (string) trans('firefly.box_spent_in_currency', ['currency' => $currency['currency_name']]),
'label' => (string)trans('firefly.box_spent_in_currency', ['currency' => $currency['currency_name']]),
'type' => 'bar',
'backgroundColor' => 'rgba(219, 68, 55, 0.5)', // red
'currency_id' => $currency['currency_id'],
@@ -212,7 +213,13 @@ class ReportController extends Controller
];
// loop all possible periods between $start and $end
$currentStart = clone $start;
while ($currentStart <= $end) {
$currentEnd = clone $end;
// #8374. Sloppy fix for yearly charts. Not really interested in a better fix with v2 layout and all.
if ('1Y' === $preferredRange) {
$currentEnd = app('navigation')->endOfPeriod($currentEnd, $preferredRange);
}
while ($currentStart <= $currentEnd) {
$key = $currentStart->format($format);
$title = $currentStart->isoFormat($titleFormat);
$income['entries'][$title] = app('steam')->bcround($currency[$key]['earned'] ?? '0', $currency['currency_decimal_places']);

View File

@@ -107,7 +107,7 @@ class CreateController extends Controller
$this->attachments->saveAttachmentsForModel($piggyBank, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}

View File

@@ -127,7 +127,7 @@ class EditController extends Controller
$this->attachments->saveAttachmentsForModel($piggyBank, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}

View File

@@ -231,6 +231,7 @@ class CreateController extends Controller
return redirect(route('recurring.create'))->withInput();
}
Log::channel('audit')->info('Stored new recurrence.', $data);
$request->session()->flash('success', (string)trans('firefly.stored_new_recurrence', ['title' => $recurrence->title]));
app('preferences')->mark();
@@ -242,7 +243,7 @@ class CreateController extends Controller
$this->attachments->saveAttachmentsForModel($recurrence, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}

View File

@@ -172,6 +172,7 @@ class EditController extends Controller
$this->recurring->update($recurrence, $data);
$request->session()->flash('success', (string)trans('firefly.updated_recurrence', ['title' => $recurrence->title]));
Log::channel('audit')->info(sprintf('Updated recurrence #%d.', $recurrence->id), $data);
// store new attachment(s):
/** @var null|array $files */
@@ -180,7 +181,7 @@ class EditController extends Controller
$this->attachments->saveAttachmentsForModel($recurrence, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}

View File

@@ -305,7 +305,7 @@ class TagController extends Controller
$this->attachmentsHelper->saveAttachmentsForModel($result, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
@@ -340,7 +340,7 @@ class TagController extends Controller
$this->attachmentsHelper->saveAttachmentsForModel($tag, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->info(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}

View File

@@ -50,7 +50,7 @@ class CreateController extends Controller
$this->middleware(
function ($request, $next) {
app('view')->share('title', (string)trans('firefly.transactions'));
app('view')->share('title', (string) trans('firefly.transactions'));
app('view')->share('mainTitleIcon', 'fa-exchange');
$this->repository = app(TransactionGroupRepositoryInterface::class);
@@ -61,7 +61,7 @@ class CreateController extends Controller
public function cloneGroup(Request $request): JsonResponse
{
$groupId = (int)$request->get('id');
$groupId = (int) $request->get('id');
if (0 !== $groupId) {
$group = $this->repository->find($groupId);
if (null !== $group) {
@@ -101,23 +101,43 @@ class CreateController extends Controller
{
app('preferences')->mark();
$sourceId = (int)request()->get('source');
$destinationId = (int)request()->get('destination');
$sourceId = (int) request()->get('source');
$destinationId = (int) request()->get('destination');
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app(AccountRepositoryInterface::class);
$cash = $accountRepository->getCashAccount();
$preFilled = session()->has('preFilled') ? session('preFilled') : [];
$subTitle = (string)trans(sprintf('breadcrumbs.create_%s', strtolower((string)$objectType)));
$subTitleIcon = 'fa-plus';
$optionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
$allowedOpposingTypes = config('firefly.allowed_opposing_types');
$accountToTypes = config('firefly.account_to_transaction');
$defaultCurrency = app('amount')->getDefaultCurrency();
$previousUrl = $this->rememberPreviousUrl('transactions.create.url');
$parts = parse_url($previousUrl);
$search = sprintf('?%s', $parts['query'] ?? '');
$previousUrl = str_replace($search, '', $previousUrl);
$accountRepository = app(AccountRepositoryInterface::class);
$cash = $accountRepository->getCashAccount();
$preFilled = session()->has('preFilled') ? session('preFilled') : [];
$subTitle = (string) trans(sprintf('breadcrumbs.create_%s', strtolower((string) $objectType)));
$subTitleIcon = 'fa-plus';
$optionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
$allowedOpposingTypes = config('firefly.allowed_opposing_types');
$accountToTypes = config('firefly.account_to_transaction');
$defaultCurrency = app('amount')->getDefaultCurrency();
$previousUrl = $this->rememberPreviousUrl('transactions.create.url');
$parts = parse_url($previousUrl);
$search = sprintf('?%s', $parts['query'] ?? '');
$previousUrl = str_replace($search, '', $previousUrl);
if (!is_array($optionalFields)) {
$optionalFields = [];
}
// not really a fan of this, but meh.
$optionalDateFields = [
'interest_date' => $optionalFields['interest_date'] ?? false,
'book_date' => $optionalFields['book_date'] ?? false,
'process_date' => $optionalFields['process_date'] ?? false,
'due_date' => $optionalFields['due_date'] ?? false,
'payment_date' => $optionalFields['payment_date'] ?? false,
'invoice_date' => $optionalFields['invoice_date'] ?? false,
];
$optionalFields['external_url'] ??= false;
$optionalFields['location'] ??= false;
$optionalFields['location'] = $optionalFields['location'] && true === config('firefly.enable_external_map');
// map info:
$longitude = config('firefly.default_location.longitude');
$latitude = config('firefly.default_location.latitude');
$zoomLevel = config('firefly.default_location.zoom_level');
session()->put('preFilled', $preFilled);
@@ -126,7 +146,11 @@ class CreateController extends Controller
compact(
'subTitleIcon',
'cash',
'longitude',
'latitude',
'zoomLevel',
'objectType',
'optionalDateFields',
'subTitle',
'defaultCurrency',
'previousUrl',

View File

@@ -51,7 +51,7 @@ class EditController extends Controller
// translations:
$this->middleware(
function ($request, $next) {
app('view')->share('title', (string)trans('firefly.transactions'));
app('view')->share('title', (string) trans('firefly.transactions'));
app('view')->share('mainTitleIcon', 'fa-exchange');
$this->repository = app(JournalRepositoryInterface::class);
@@ -73,18 +73,43 @@ class EditController extends Controller
}
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$allowedOpposingTypes = config('firefly.allowed_opposing_types');
$accountToTypes = config('firefly.account_to_transaction');
$expectedSourceTypes = config('firefly.expected_source_types');
$allowedSourceDests = config('firefly.source_dests');
$repository = app(AccountRepositoryInterface::class);
$allowedOpposingTypes = config('firefly.allowed_opposing_types');
$accountToTypes = config('firefly.account_to_transaction');
$expectedSourceTypes = config('firefly.expected_source_types');
$allowedSourceDests = config('firefly.source_dests');
$title = $transactionGroup->transactionJournals()->count() > 1 ? $transactionGroup->title : $transactionGroup->transactionJournals()->first()->description;
$subTitle = (string) trans('firefly.edit_transaction_title', ['description' => $title]);
$subTitleIcon = 'fa-plus';
$defaultCurrency = app('amount')->getDefaultCurrency();
$cash = $repository->getCashAccount();
$previousUrl = $this->rememberPreviousUrl('transactions.edit.url');
$parts = parse_url($previousUrl);
$search = sprintf('?%s', $parts['query'] ?? '');
$previousUrl = str_replace($search, '', $previousUrl);
$defaultCurrency = app('amount')->getDefaultCurrency();
$cash = $repository->getCashAccount();
$previousUrl = $this->rememberPreviousUrl('transactions.edit.url');
$parts = parse_url($previousUrl);
$search = sprintf('?%s', $parts['query'] ?? '');
$previousUrl = str_replace($search, '', $previousUrl);
// settings necessary for v2
$optionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
if (!is_array($optionalFields)) {
$optionalFields = [];
}
// not really a fan of this, but meh.
$optionalDateFields = [
'interest_date' => $optionalFields['interest_date'] ?? false,
'book_date' => $optionalFields['book_date'] ?? false,
'process_date' => $optionalFields['process_date'] ?? false,
'due_date' => $optionalFields['due_date'] ?? false,
'payment_date' => $optionalFields['payment_date'] ?? false,
'invoice_date' => $optionalFields['invoice_date'] ?? false,
];
$optionalFields['external_url'] ??= false;
$optionalFields['location'] ??= false;
$optionalFields['location'] = $optionalFields['location'] && true === config('firefly.enable_external_map');
// map info voor v2:
$longitude = config('firefly.default_location.longitude');
$latitude = config('firefly.default_location.latitude');
$zoomLevel = config('firefly.default_location.zoom_level');
return view(
'transactions.edit',
@@ -92,6 +117,13 @@ class EditController extends Controller
'cash',
'allowedSourceDests',
'expectedSourceTypes',
'optionalDateFields',
'longitude',
'latitude',
'zoomLevel',
'optionalFields',
'subTitle',
'subTitleIcon',
'transactionGroup',
'allowedOpposingTypes',
'accountToTypes',

View File

@@ -75,45 +75,52 @@ class IndexController extends Controller
$objectType = 'transfer';
}
$subTitleIcon = config('firefly.transactionIconsByType.'.$objectType);
$types = config('firefly.transactionTypesByType.'.$objectType);
$page = (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
if (null === $start) {
$start = session('start');
$end = session('end');
// add a split for the (future) v2 release.
$periods = [];
$groups = [];
$subTitle = 'TODO page subtitle in v2';
$subTitleIcon = config('firefly.transactionIconsByType.'.$objectType);
$types = config('firefly.transactionTypesByType.'.$objectType);
$page = (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
if ('v2' !== (string)config('firefly.layout')) {
if (null === $start) {
$start = session('start');
$end = session('end');
}
if (null === $end) {
// get last transaction ever?
$last = $this->repository->getLast();
$end = null !== $last ? $last->date : session('end');
}
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
$startStr = $start->isoFormat($this->monthAndDayFormat);
$endStr = $end->isoFormat($this->monthAndDayFormat);
$subTitle = (string)trans(sprintf('firefly.title_%s_between', $objectType), ['start' => $startStr, 'end' => $endStr]);
$path = route('transactions.index', [$objectType, $start->format('Y-m-d'), $end->format('Y-m-d')]);
$firstJournal = $this->repository->firstNull();
$startPeriod = null === $firstJournal ? new Carbon() : $firstJournal->date;
$endPeriod = clone $end;
$periods = $this->getTransactionPeriodOverview($objectType, $startPeriod, $endPeriod);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)
->setTypes($types)
->setLimit($pageSize)
->setPage($page)
->withBudgetInformation()
->withCategoryInformation()
->withAccountInformation()
->withAttachmentInformation()
;
$groups = $collector->getPaginatedGroups();
$groups->setPath($path);
}
if (null === $end) {
// get last transaction ever?
$last = $this->repository->getLast();
$end = null !== $last ? $last->date : session('end');
}
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
$path = route('transactions.index', [$objectType, $start->format('Y-m-d'), $end->format('Y-m-d')]);
$startStr = $start->isoFormat($this->monthAndDayFormat);
$endStr = $end->isoFormat($this->monthAndDayFormat);
$subTitle = (string)trans(sprintf('firefly.title_%s_between', $objectType), ['start' => $startStr, 'end' => $endStr]);
$firstJournal = $this->repository->firstNull();
$startPeriod = null === $firstJournal ? new Carbon() : $firstJournal->date;
$endPeriod = clone $end;
$periods = $this->getTransactionPeriodOverview($objectType, $startPeriod, $endPeriod);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)
->setTypes($types)
->setLimit($pageSize)
->setPage($page)
->withBudgetInformation()
->withCategoryInformation()
->withAccountInformation()
->withAttachmentInformation()
;
$groups = $collector->getPaginatedGroups();
$groups->setPath($path);
return view('transactions.index', compact('subTitle', 'objectType', 'subTitleIcon', 'groups', 'periods', 'start', 'end'));
}

View File

@@ -105,7 +105,7 @@ class CreateController extends Controller
$data = $request->getCurrencyData();
if (!$this->userRepository->hasRole($user, 'owner')) {
app('log')->error('User '.auth()->user()->id.' is not admin, but tried to store a currency.');
Log::channel('audit')->info('Tried to create (POST) currency without admin rights.', $data);
Log::channel('audit')->warning('Tried to create (POST) currency without admin rights.', $data);
return redirect($this->getPreviousUrl('currencies.create.url'))->withInput();
}
@@ -116,7 +116,7 @@ class CreateController extends Controller
$currency = $this->repository->store($data);
} catch (FireflyException $e) {
app('log')->error($e->getMessage());
Log::channel('audit')->info('Could not store (POST) currency without admin rights.', $data);
Log::channel('audit')->warning('Could not store (POST) currency without admin rights.', $data);
$request->session()->flash('error', (string)trans('firefly.could_not_store_currency'));
$currency = null;
}

View File

@@ -74,7 +74,7 @@ class DeleteController extends Controller
$user = auth()->user();
if (!$this->userRepository->hasRole($user, 'owner')) {
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
Log::channel('audit')->info(sprintf('Tried to visit page to delete currency %s but is not site owner.', $currency->code));
Log::channel('audit')->warning(sprintf('Tried to visit page to delete currency %s but is not site owner.', $currency->code));
return redirect(route('currencies.index'));
}
@@ -83,7 +83,7 @@ class DeleteController extends Controller
$location = $this->repository->currencyInUseAt($currency);
$message = (string)trans(sprintf('firefly.cannot_disable_currency_%s', $location), ['name' => e($currency->name)]);
$request->session()->flash('error', $message);
Log::channel('audit')->info(sprintf('Tried to visit page to delete currency %s but currency is in use.', $currency->code));
Log::channel('audit')->warning(sprintf('Tried to visit page to delete currency %s but currency is in use.', $currency->code));
return redirect(route('currencies.index'));
}
@@ -107,7 +107,7 @@ class DeleteController extends Controller
$user = auth()->user();
if (!$this->userRepository->hasRole($user, 'owner')) {
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
Log::channel('audit')->info(sprintf('Tried to delete currency %s but is not site owner.', $currency->code));
Log::channel('audit')->warning(sprintf('Tried to delete currency %s but is not site owner.', $currency->code));
return redirect(route('currencies.index'));
}

View File

@@ -72,7 +72,7 @@ class EditController extends Controller
$user = auth()->user();
if (!$this->userRepository->hasRole($user, 'owner')) {
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
Log::channel('audit')->info(sprintf('Tried to edit currency %s but is not owner.', $currency->code));
Log::channel('audit')->warning(sprintf('Tried to edit currency %s but is not owner.', $currency->code));
return redirect(route('currencies.index'));
}
@@ -120,7 +120,7 @@ class EditController extends Controller
if (!$this->userRepository->hasRole($user, 'owner')) {
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
Log::channel('audit')->info('Tried to update (POST) currency without admin rights.', $data);
Log::channel('audit')->warning('Tried to update (POST) currency without admin rights.', $data);
return redirect(route('currencies.index'));
}

View File

@@ -60,7 +60,7 @@ class CreateController extends Controller
public function index()
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info('User visits webhook create page, but webhooks are DISABLED.');
Log::channel('audit')->warning('User visits webhook create page, but webhooks are DISABLED.');
throw new NotFoundHttpException('Webhooks are not enabled.');
}

View File

@@ -64,7 +64,7 @@ class DeleteController extends Controller
public function index(Webhook $webhook)
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info('User visits webhook delete page, but webhooks are DISABLED.');
Log::channel('audit')->warning('User visits webhook delete page, but webhooks are DISABLED.');
throw new NotFoundHttpException('Webhooks are not enabled.');
}

View File

@@ -63,7 +63,7 @@ class EditController extends Controller
public function index(Webhook $webhook)
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info('User visits webhook edit page, but webhooks are DISABLED.');
Log::channel('audit')->warning('User visits webhook edit page, but webhooks are DISABLED.');
throw new NotFoundHttpException('Webhooks are not enabled.');
}

View File

@@ -56,7 +56,7 @@ class IndexController extends Controller
public function index()
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info('User visits webhook index page, but webhooks are DISABLED.');
Log::channel('audit')->warning('User visits webhook index page, but webhooks are DISABLED.');
throw new NotFoundHttpException('Webhooks are not enabled.');
}

View File

@@ -63,7 +63,7 @@ class ShowController extends Controller
public function index(Webhook $webhook)
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info(sprintf('User visits webhook #%d page, but webhooks are DISABLED.', $webhook->id));
Log::channel('audit')->warning(sprintf('User visits webhook #%d page, but webhooks are DISABLED.', $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}

View File

@@ -32,6 +32,8 @@ use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
* Class AccountFormRequest.
@@ -108,7 +110,7 @@ class AccountFormRequest extends FormRequest
'BIC' => 'bic|nullable',
'virtual_balance' => ['nullable', new IsValidAmount()],
'currency_id' => 'exists:transaction_currencies,id',
'account_number' => 'between:1,255|uniqueAccountNumberForUser|nullable',
'account_number' => 'min:1|max:255|uniqueAccountNumberForUser|nullable',
'account_role' => 'in:'.$accountRoles,
'active' => 'boolean',
'cc_type' => 'in:'.$ccPaymentTypes,
@@ -116,7 +118,7 @@ class AccountFormRequest extends FormRequest
'amount_currency_id_virtual_balance' => 'exists:transaction_currencies,id',
'what' => 'in:'.$types,
'interest_period' => 'in:daily,monthly,yearly',
'notes' => 'between:1,65536|nullable',
'notes' => 'min:1|max:32768|nullable',
];
$rules = Location::requestRules($rules);
@@ -131,4 +133,11 @@ class AccountFormRequest extends FormRequest
return $rules;
}
public function withValidator(Validator $validator): void
{
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -26,6 +26,8 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
* Class AttachmentFormRequest.
@@ -53,8 +55,15 @@ class AttachmentFormRequest extends FormRequest
{
// fixed
return [
'title' => 'between:1,255|nullable',
'notes' => 'between:1,65536|nullable',
'title' => 'min:1|max:255|nullable',
'notes' => 'min:1|max:32768|nullable',
];
}
public function withValidator(Validator $validator): void
{
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -27,6 +27,8 @@ use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
* Class BillStoreRequest.
@@ -64,12 +66,12 @@ class BillStoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'required|between:1,255|uniqueObjectForUser:bills,name',
'name' => 'required|min:1|max:255|uniqueObjectForUser:bills,name',
'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',
'notes' => 'min:1|max:32768|nullable',
'bill_end_date' => 'nullable|date',
'extension_date' => 'nullable|date',
'repeat_freq' => sprintf('required|in:%s', implode(',', config('firefly.bill_periods'))),
@@ -77,4 +79,11 @@ class BillStoreRequest extends FormRequest
'active' => 'boolean',
];
}
public function withValidator(Validator $validator): void
{
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -28,6 +28,8 @@ use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
* Class BillUpdateRequest.
@@ -68,7 +70,7 @@ class BillUpdateRequest extends FormRequest
$bill = $this->route()->parameter('bill');
return [
'name' => sprintf('required|between:1,255|uniqueObjectForUser:bills,name,%d', $bill->id),
'name' => sprintf('required|min:1|max:255|uniqueObjectForUser:bills,name,%d', $bill->id),
'amount_min' => ['required', new IsValidPositiveAmount()],
'amount_max' => ['required', new IsValidPositiveAmount()],
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
@@ -78,7 +80,14 @@ class BillUpdateRequest extends FormRequest
'repeat_freq' => sprintf('required|in:%s', implode(',', config('firefly.bill_periods'))),
'skip' => 'required|integer|gte:0|lte:31',
'active' => 'boolean',
'notes' => 'between:1,65536|nullable',
'notes' => 'min:1|max:32768|nullable',
];
}
public function withValidator(Validator $validator): void
{
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -61,13 +61,13 @@ class BudgetFormStoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'required|between:1,100|uniqueObjectForUser:budgets,name',
'active' => 'numeric|between:0,1',
'name' => 'required|min:1|max:255|uniqueObjectForUser:budgets,name',
'active' => 'numeric|min:0|max:1',
'auto_budget_type' => 'numeric|integer|gte:0|lte:3',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
'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',
'notes' => 'min:1|max:32768|nullable',
];
}
@@ -76,15 +76,15 @@ class BudgetFormStoreRequest extends FormRequest
*/
public function withValidator(Validator $validator): void
{
if($validator->fails()) {
Log::channel('audit')->error('Validation errors for budget', $validator->errors()->toArray());
}
$validator->after(
function (Validator $validator): void {
// validate all account info
$this->validateAutoBudgetAmount($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -29,6 +29,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -60,23 +61,23 @@ class BudgetFormUpdateRequest extends FormRequest
*/
public function rules(): array
{
$nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name';
$nameRule = 'required|min:1|max:255|uniqueObjectForUser:budgets,name';
/** @var null|Budget $budget */
$budget = $this->route()->parameter('budget');
if (null !== $budget) {
$nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name,'.$budget->id;
$nameRule = 'required|min:1|max:255|uniqueObjectForUser:budgets,name,'.$budget->id;
}
return [
'name' => $nameRule,
'active' => 'numeric|between:0,1',
'active' => 'numeric|min:0|max:1',
'auto_budget_type' => 'numeric|integer|gte:0|lte:31',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
'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',
'notes' => 'min:1|max:32768|nullable',
];
}
@@ -91,5 +92,8 @@ class BudgetFormUpdateRequest extends FormRequest
$this->validateAutoBudgetAmount($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

Some files were not shown because too many files have changed in this diff Show More