Compare commits

...

119 Commits

Author SHA1 Message Date
James Cole
ef8f9672af Merge branch 'release/5.6.16' 2022-02-28 09:00:56 +01:00
James Cole
b696b09f92 New meta files for release. 2022-02-28 09:00:33 +01:00
James Cole
9892e70028 Rename file. 2022-02-28 08:53:12 +01:00
James Cole
52f885df20 Rename migration so it doesn't clash. 2022-02-28 08:47:58 +01:00
James Cole
a58c6b0cec Do not search for empty number. 2022-02-28 08:31:58 +01:00
James Cole
a8cbbde8fc Merge branch 'release/5.6.15'
# Conflicts:
#	yarn.lock
2022-02-28 07:10:43 +01:00
James Cole
efb7d4275d Update meta files for new release. 2022-02-28 06:40:34 +01:00
mergify[bot]
d4f275e566 Merge pull request #5829 from firefly-iii/dependabot/npm_and_yarn/develop/postcss-8.4.7
Bump postcss from 8.4.6 to 8.4.7
2022-02-28 03:02:15 +00:00
mergify[bot]
45db911011 Merge pull request #5828 from firefly-iii/dependabot/npm_and_yarn/develop/bootstrap-sass-3.4.2
Bump bootstrap-sass from 3.4.1 to 3.4.2
2022-02-28 03:02:11 +00:00
dependabot[bot]
50fccec438 Bump postcss from 8.4.6 to 8.4.7
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.6 to 8.4.7.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.6...8.4.7)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 03:02:02 +00:00
dependabot[bot]
67e72e864c Bump bootstrap-sass from 3.4.1 to 3.4.2
Bumps [bootstrap-sass](https://github.com/twbs/bootstrap-sass) from 3.4.1 to 3.4.2.
- [Release notes](https://github.com/twbs/bootstrap-sass/releases)
- [Changelog](https://github.com/twbs/bootstrap-sass/blob/master/CHANGELOG.md)
- [Commits](https://github.com/twbs/bootstrap-sass/compare/v3.4.1...v3.4.2)

---
updated-dependencies:
- dependency-name: bootstrap-sass
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 03:01:53 +00:00
mergify[bot]
dff4946b48 Merge pull request #5827 from firefly-iii/dependabot/composer/develop/phpunit/phpunit-9.5.16
Bump phpunit/phpunit from 9.5.14 to 9.5.16
2022-02-28 03:01:31 +00:00
mergify[bot]
a38700f3fa Merge pull request #5826 from firefly-iii/dependabot/composer/develop/laravel/framework-8.83.2
Bump laravel/framework from 8.83.1 to 8.83.2
2022-02-28 03:01:26 +00:00
mergify[bot]
42c4441755 Merge pull request #5825 from firefly-iii/dependabot/composer/develop/league/commonmark-2.2.3
Bump league/commonmark from 2.2.2 to 2.2.3
2022-02-28 03:01:23 +00:00
mergify[bot]
1a4b646acd Merge pull request #5824 from firefly-iii/dependabot/composer/develop/laravel/sanctum-2.14.2
Bump laravel/sanctum from 2.14.1 to 2.14.2
2022-02-28 03:01:19 +00:00
mergify[bot]
5888dd38a2 Merge pull request #5823 from firefly-iii/dependabot/composer/develop/laravel/ui-3.4.5
Bump laravel/ui from 3.4.4 to 3.4.5
2022-02-28 03:01:15 +00:00
dependabot[bot]
f56d63c754 Bump phpunit/phpunit from 9.5.14 to 9.5.16
Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 9.5.14 to 9.5.16.
- [Release notes](https://github.com/sebastianbergmann/phpunit/releases)
- [Changelog](https://github.com/sebastianbergmann/phpunit/blob/master/ChangeLog-9.5.md)
- [Commits](https://github.com/sebastianbergmann/phpunit/compare/9.5.14...9.5.16)

---
updated-dependencies:
- dependency-name: phpunit/phpunit
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 03:01:06 +00:00
dependabot[bot]
93db50383a Bump laravel/framework from 8.83.1 to 8.83.2
Bumps [laravel/framework](https://github.com/laravel/framework) from 8.83.1 to 8.83.2.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/9.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v8.83.1...v8.83.2)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 03:01:02 +00:00
dependabot[bot]
4e9b5a71db Bump league/commonmark from 2.2.2 to 2.2.3
Bumps [league/commonmark](https://github.com/thephpleague/commonmark) from 2.2.2 to 2.2.3.
- [Release notes](https://github.com/thephpleague/commonmark/releases)
- [Changelog](https://github.com/thephpleague/commonmark/blob/2.2/CHANGELOG.md)
- [Commits](https://github.com/thephpleague/commonmark/compare/2.2.2...2.2.3)

---
updated-dependencies:
- dependency-name: league/commonmark
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 03:00:53 +00:00
dependabot[bot]
c85be915e6 Bump laravel/sanctum from 2.14.1 to 2.14.2
Bumps [laravel/sanctum](https://github.com/laravel/sanctum) from 2.14.1 to 2.14.2.
- [Release notes](https://github.com/laravel/sanctum/releases)
- [Changelog](https://github.com/laravel/sanctum/blob/2.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/sanctum/compare/v2.14.1...v2.14.2)

---
updated-dependencies:
- dependency-name: laravel/sanctum
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 03:00:47 +00:00
dependabot[bot]
1df4cdda42 Bump laravel/ui from 3.4.4 to 3.4.5
Bumps [laravel/ui](https://github.com/laravel/ui) from 3.4.4 to 3.4.5.
- [Release notes](https://github.com/laravel/ui/releases)
- [Changelog](https://github.com/laravel/ui/blob/3.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/ui/compare/v3.4.4...v3.4.5)

---
updated-dependencies:
- dependency-name: laravel/ui
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-28 03:00:41 +00:00
James Cole
cad03b04ae Initial build. 2022-02-27 10:16:34 +01:00
James Cole
cddfa3a8d2 Router and store 2022-02-27 10:14:26 +01:00
James Cole
3a49af94d0 Initial set of pages. 2022-02-27 10:14:08 +01:00
James Cole
e60320a9be Main layout 2022-02-27 10:13:55 +01:00
James Cole
0ffb3508c6 Support for languages 2022-02-27 10:13:43 +01:00
James Cole
d618f6d355 CSS 2022-02-27 10:13:31 +01:00
James Cole
e542a65bf3 Various components 2022-02-27 10:13:25 +01:00
James Cole
d1e1314dcf boot code 2022-02-27 10:13:16 +01:00
James Cole
9ebdb00579 API code 2022-02-27 10:13:07 +01:00
James Cole
95a7a0c90d Root source 2022-02-27 10:12:54 +01:00
James Cole
cabd3d60f0 Icons and other meta files. 2022-02-27 10:12:38 +01:00
James Cole
ab8ee8b72a Config files related to new layout. 2022-02-27 10:04:43 +01:00
James Cole
01f06a7e5b Meta files related to new layout. 2022-02-27 10:04:30 +01:00
James Cole
aa7d4a610b Add files and updates necessary to manage new layout. 2022-02-27 10:04:08 +01:00
James Cole
3f61b6d707 Clean up git ignore. 2022-02-27 09:52:08 +01:00
James Cole
9ae0cc5700 Clean up git ignore. 2022-02-27 09:51:54 +01:00
James Cole
6f65a73dd9 Add migration, update languages. 2022-02-26 11:24:16 +01:00
James Cole
fb676a9ad7 Update languages, config. 2022-02-26 07:55:36 +01:00
James Cole
dd66a1adf0 Fix https://github.com/firefly-iii/firefly-iii/issues/5810 2022-02-23 10:52:24 +01:00
James Cole
8c9bb3addb Tiny fixes in API 2022-02-23 06:33:27 +01:00
James Cole
472c1a0c37 Fix string conversion error. 2022-02-21 19:53:49 +01:00
James Cole
6fe8bf6c41 Update recurrence API 2022-02-21 16:48:26 +01:00
James Cole
342e6f2fef Fix https://github.com/firefly-iii/firefly-iii/issues/5806 2022-02-21 16:48:16 +01:00
mergify[bot]
23a8e3ef41 Merge pull request #5805 from firefly-iii/dependabot/npm_and_yarn/develop/vue-i18n-9.1.9
Bump vue-i18n from 8.27.0 to 9.1.9
2022-02-21 03:04:32 +00:00
dependabot[bot]
7c11b99469 Bump vue-i18n from 8.27.0 to 9.1.9
Bumps [vue-i18n](https://github.com/intlify/vue-i18n-next/tree/HEAD/packages/vue-i18n) from 8.27.0 to 9.1.9.
- [Release notes](https://github.com/intlify/vue-i18n-next/releases)
- [Changelog](https://github.com/intlify/vue-i18n-next/blob/v9.1.9/CHANGELOG.md)
- [Commits](https://github.com/intlify/vue-i18n-next/commits/v9.1.9/packages/vue-i18n)

---
updated-dependencies:
- dependency-name: vue-i18n
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-21 03:04:01 +00:00
mergify[bot]
e715162ed6 Merge pull request #5804 from firefly-iii/dependabot/npm_and_yarn/develop/laravel-mix-6.0.43
Bump laravel-mix from 6.0.42 to 6.0.43
2022-02-21 03:02:53 +00:00
mergify[bot]
368cc550cb Merge pull request #5803 from firefly-iii/dependabot/npm_and_yarn/develop/uiv-2.0.0
Bump uiv from 1.4.1 to 2.0.0
2022-02-21 03:02:49 +00:00
dependabot[bot]
60311341e0 Bump laravel-mix from 6.0.42 to 6.0.43
Bumps [laravel-mix](https://github.com/JeffreyWay/laravel-mix) from 6.0.42 to 6.0.43.
- [Release notes](https://github.com/JeffreyWay/laravel-mix/releases)
- [Changelog](https://github.com/laravel-mix/laravel-mix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/JeffreyWay/laravel-mix/commits)

---
updated-dependencies:
- dependency-name: laravel-mix
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-21 03:02:27 +00:00
dependabot[bot]
749ebd9cc4 Bump uiv from 1.4.1 to 2.0.0
Bumps [uiv](https://github.com/uiv-lib/uiv) from 1.4.1 to 2.0.0.
- [Release notes](https://github.com/uiv-lib/uiv/releases)
- [Commits](https://github.com/uiv-lib/uiv/compare/v1.4.1...v2.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-21 03:02:16 +00:00
mergify[bot]
c699a14a35 Merge pull request #5802 from firefly-iii/dependabot/composer/develop/laravel/ui-3.4.4
Bump laravel/ui from 3.4.3 to 3.4.4
2022-02-21 03:01:30 +00:00
mergify[bot]
b05a2d385c Merge pull request #5801 from firefly-iii/dependabot/composer/develop/laravel/sanctum-2.14.1
Bump laravel/sanctum from 2.14.0 to 2.14.1
2022-02-21 03:01:27 +00:00
mergify[bot]
7c78d19e3a Merge pull request #5800 from firefly-iii/dependabot/composer/develop/laravel/framework-8.83.1
Bump laravel/framework from 8.83.0 to 8.83.1
2022-02-21 03:01:22 +00:00
mergify[bot]
8632307cb1 Merge pull request #5799 from firefly-iii/dependabot/composer/develop/phpunit/phpunit-9.5.14
Bump phpunit/phpunit from 9.5.13 to 9.5.14
2022-02-21 03:01:19 +00:00
dependabot[bot]
5a18f3ce4a Bump laravel/ui from 3.4.3 to 3.4.4
Bumps [laravel/ui](https://github.com/laravel/ui) from 3.4.3 to 3.4.4.
- [Release notes](https://github.com/laravel/ui/releases)
- [Changelog](https://github.com/laravel/ui/blob/3.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/ui/compare/v3.4.3...v3.4.4)

---
updated-dependencies:
- dependency-name: laravel/ui
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-21 03:01:07 +00:00
dependabot[bot]
1258aff0b4 Bump laravel/sanctum from 2.14.0 to 2.14.1
Bumps [laravel/sanctum](https://github.com/laravel/sanctum) from 2.14.0 to 2.14.1.
- [Release notes](https://github.com/laravel/sanctum/releases)
- [Changelog](https://github.com/laravel/sanctum/blob/2.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/sanctum/compare/v2.14.0...v2.14.1)

---
updated-dependencies:
- dependency-name: laravel/sanctum
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-21 03:01:01 +00:00
dependabot[bot]
b0904c11a0 Bump laravel/framework from 8.83.0 to 8.83.1
Bumps [laravel/framework](https://github.com/laravel/framework) from 8.83.0 to 8.83.1.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/9.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v8.83.0...v8.83.1)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-21 03:00:53 +00:00
dependabot[bot]
ca517eb4d9 Bump phpunit/phpunit from 9.5.13 to 9.5.14
Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 9.5.13 to 9.5.14.
- [Release notes](https://github.com/sebastianbergmann/phpunit/releases)
- [Changelog](https://github.com/sebastianbergmann/phpunit/blob/master/ChangeLog-9.5.md)
- [Commits](https://github.com/sebastianbergmann/phpunit/compare/9.5.13...9.5.14)

---
updated-dependencies:
- dependency-name: phpunit/phpunit
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-21 03:00:45 +00:00
James Cole
c522dd2931 Update security.txt and associated key. 2022-02-19 07:28:13 +01:00
James Cole
7399edee2e Use dropIfExists 2022-02-19 05:20:42 +01:00
James Cole
ec93b7b5a0 Fix https://github.com/firefly-iii/firefly-iii/issues/5694 2022-02-17 19:22:58 +01:00
James Cole
280762fff3 Make sure fields are named properly 2022-02-17 19:03:54 +01:00
James Cole
b733fa2961 Update mandatory fields. 2022-02-17 19:03:41 +01:00
James Cole
5176f8bdc2 Add instructions. 2022-02-17 19:03:31 +01:00
mergify[bot]
91d96b2f0e Merge pull request #5784 from firefly-iii/dependabot/npm_and_yarn/develop/vue-3.2.31
Bump vue from 2.6.14 to 3.2.31
2022-02-14 03:03:30 +00:00
mergify[bot]
c3229e597c Merge pull request #5785 from firefly-iii/dependabot/npm_and_yarn/develop/axios-0.26.0
Bump axios from 0.25.0 to 0.26.0
2022-02-14 03:03:25 +00:00
dependabot[bot]
0f371bc5a9 Bump vue from 2.6.14 to 3.2.31
Bumps [vue](https://github.com/vuejs/core) from 2.6.14 to 3.2.31.
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/commits/v3.2.31)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 03:03:16 +00:00
dependabot[bot]
297d5940ce Bump axios from 0.25.0 to 0.26.0
Bumps [axios](https://github.com/axios/axios) from 0.25.0 to 0.26.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.25.0...v0.26.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 03:02:52 +00:00
mergify[bot]
3b27ceaf53 Merge pull request #5783 from firefly-iii/dependabot/npm_and_yarn/develop/laravel-mix-6.0.42
Bump laravel-mix from 6.0.41 to 6.0.42
2022-02-14 03:02:44 +00:00
dependabot[bot]
d9142c1197 Bump laravel-mix from 6.0.41 to 6.0.42
Bumps [laravel-mix](https://github.com/JeffreyWay/laravel-mix) from 6.0.41 to 6.0.42.
- [Release notes](https://github.com/JeffreyWay/laravel-mix/releases)
- [Changelog](https://github.com/laravel-mix/laravel-mix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/JeffreyWay/laravel-mix/commits)

---
updated-dependencies:
- dependency-name: laravel-mix
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 03:02:36 +00:00
mergify[bot]
9b3d1160d6 Merge pull request #5781 from firefly-iii/dependabot/npm_and_yarn/develop/vue-loader-17.0.0
Bump vue-loader from 15.9.8 to 17.0.0
2022-02-14 03:02:05 +00:00
dependabot[bot]
05d144c279 Bump vue-loader from 15.9.8 to 17.0.0
Bumps [vue-loader](https://github.com/vuejs/vue-loader) from 15.9.8 to 17.0.0.
- [Release notes](https://github.com/vuejs/vue-loader/releases)
- [Changelog](https://github.com/vuejs/vue-loader/blob/next/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-loader/commits)

---
updated-dependencies:
- dependency-name: vue-loader
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 03:02:01 +00:00
mergify[bot]
a318b66854 Merge pull request #5780 from firefly-iii/dependabot/composer/develop/laravel/ui-3.4.3
Bump laravel/ui from 3.4.2 to 3.4.3
2022-02-14 03:02:00 +00:00
mergify[bot]
431eef5e80 Merge pull request #5779 from firefly-iii/dependabot/composer/develop/barryvdh/laravel-debugbar-3.6.7
Bump barryvdh/laravel-debugbar from 3.6.6 to 3.6.7
2022-02-14 03:01:54 +00:00
dependabot[bot]
a8d20c5a01 Bump laravel/ui from 3.4.2 to 3.4.3
Bumps [laravel/ui](https://github.com/laravel/ui) from 3.4.2 to 3.4.3.
- [Release notes](https://github.com/laravel/ui/releases)
- [Changelog](https://github.com/laravel/ui/blob/3.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/ui/compare/v3.4.2...v3.4.3)

---
updated-dependencies:
- dependency-name: laravel/ui
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 03:01:49 +00:00
mergify[bot]
676d75646e Merge pull request #5778 from firefly-iii/dependabot/composer/develop/barryvdh/laravel-ide-helper-2.12.2
Bump barryvdh/laravel-ide-helper from 2.12.1 to 2.12.2
2022-02-14 03:01:48 +00:00
mergify[bot]
6cbc438aa0 Merge pull request #5777 from firefly-iii/dependabot/composer/develop/laravel/framework-8.83.0
Bump laravel/framework from 8.82.0 to 8.83.0
2022-02-14 03:01:43 +00:00
dependabot[bot]
4a8913c98c Bump barryvdh/laravel-debugbar from 3.6.6 to 3.6.7
Bumps [barryvdh/laravel-debugbar](https://github.com/barryvdh/laravel-debugbar) from 3.6.6 to 3.6.7.
- [Release notes](https://github.com/barryvdh/laravel-debugbar/releases)
- [Changelog](https://github.com/barryvdh/laravel-debugbar/blob/master/changelog.md)
- [Commits](https://github.com/barryvdh/laravel-debugbar/compare/v3.6.6...v3.6.7)

---
updated-dependencies:
- dependency-name: barryvdh/laravel-debugbar
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 03:01:40 +00:00
mergify[bot]
9d1ecd845a Merge pull request #5776 from firefly-iii/dependabot/composer/develop/league/commonmark-2.2.2
Bump league/commonmark from 2.2.1 to 2.2.2
2022-02-14 03:01:39 +00:00
mergify[bot]
16987aca71 Merge pull request #5775 from firefly-iii/dependabot/composer/develop/rcrowe/twigbridge-0.13.1
Bump rcrowe/twigbridge from 0.13.0 to 0.13.1
2022-02-14 03:01:34 +00:00
mergify[bot]
445e8d7838 Merge pull request #5774 from firefly-iii/dependabot/composer/develop/laravelcollective/html-6.3.0
Bump laravelcollective/html from 6.2.1 to 6.3.0
2022-02-14 03:01:30 +00:00
dependabot[bot]
e521d5dcd0 Bump barryvdh/laravel-ide-helper from 2.12.1 to 2.12.2
Bumps [barryvdh/laravel-ide-helper](https://github.com/barryvdh/laravel-ide-helper) from 2.12.1 to 2.12.2.
- [Release notes](https://github.com/barryvdh/laravel-ide-helper/releases)
- [Changelog](https://github.com/barryvdh/laravel-ide-helper/blob/master/CHANGELOG.md)
- [Commits](https://github.com/barryvdh/laravel-ide-helper/compare/v2.12.1...v2.12.2)

---
updated-dependencies:
- dependency-name: barryvdh/laravel-ide-helper
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 03:01:29 +00:00
dependabot[bot]
a4ed85d33b Bump laravel/framework from 8.82.0 to 8.83.0
Bumps [laravel/framework](https://github.com/laravel/framework) from 8.82.0 to 8.83.0.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/9.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v8.82.0...v8.83.0)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 03:01:23 +00:00
dependabot[bot]
65e8a7fed6 Bump league/commonmark from 2.2.1 to 2.2.2
Bumps [league/commonmark](https://github.com/thephpleague/commonmark) from 2.2.1 to 2.2.2.
- [Release notes](https://github.com/thephpleague/commonmark/releases)
- [Changelog](https://github.com/thephpleague/commonmark/blob/2.2/CHANGELOG.md)
- [Commits](https://github.com/thephpleague/commonmark/compare/2.2.1...2.2.2)

---
updated-dependencies:
- dependency-name: league/commonmark
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 03:01:09 +00:00
dependabot[bot]
1052a19262 Bump rcrowe/twigbridge from 0.13.0 to 0.13.1
Bumps [rcrowe/twigbridge](https://github.com/rcrowe/TwigBridge) from 0.13.0 to 0.13.1.
- [Release notes](https://github.com/rcrowe/TwigBridge/releases)
- [Changelog](https://github.com/rcrowe/TwigBridge/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rcrowe/TwigBridge/compare/v0.13.0...v0.13.1)

---
updated-dependencies:
- dependency-name: rcrowe/twigbridge
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 03:01:04 +00:00
dependabot[bot]
a2b7a5f1f0 Bump laravelcollective/html from 6.2.1 to 6.3.0
Bumps [laravelcollective/html](https://github.com/LaravelCollective/html) from 6.2.1 to 6.3.0.
- [Release notes](https://github.com/LaravelCollective/html/releases)
- [Commits](https://github.com/LaravelCollective/html/compare/v6.2.1...v6.3.0)

---
updated-dependencies:
- dependency-name: laravelcollective/html
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 03:00:54 +00:00
James Cole
9f09872e0f Merge pull request #5765 from firefly-iii/dependabot/npm_and_yarn/follow-redirects-1.14.8
Bump follow-redirects from 1.14.7 to 1.14.8
2022-02-12 10:25:25 +00:00
dependabot[bot]
60ea033064 Bump follow-redirects from 1.14.7 to 1.14.8
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.7 to 1.14.8.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.7...v1.14.8)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-12 10:05:59 +00:00
James Cole
1f3badb731 Update various routes 2022-02-09 17:31:30 +01:00
James Cole
eb0281e47f Fix code for #5493 as suggested by @tjmv 2022-02-09 11:14:00 +01:00
James Cole
7fc94415fb Update request must also have valid triggers and actions. 2022-02-09 07:50:36 +01:00
James Cole
8dd7d9ba26 Add validation for at least one active action. 2022-02-07 09:42:23 +01:00
James Cole
b9ac43e86d Fix https://github.com/firefly-iii/firefly-iii/issues/5724 2022-02-07 06:20:50 +01:00
James Cole
99a5f827ae Disable webhooks again 2022-02-07 06:19:35 +01:00
James Cole
fbdb7e099c Add new config key 2022-02-07 06:19:27 +01:00
James Cole
6080dabb56 Catch invalid setting 2022-02-07 06:19:19 +01:00
mergify[bot]
cf1540060a Merge pull request #5727 from firefly-iii/dependabot/composer/develop/doctrine/dbal-3.3.2
Bump doctrine/dbal from 3.3.1 to 3.3.2
2022-02-07 03:01:06 +00:00
dependabot[bot]
f96a9f652d Bump doctrine/dbal from 3.3.1 to 3.3.2
Bumps [doctrine/dbal](https://github.com/doctrine/dbal) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/doctrine/dbal/releases)
- [Commits](https://github.com/doctrine/dbal/compare/3.3.1...3.3.2)

---
updated-dependencies:
- dependency-name: doctrine/dbal
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-07 03:00:32 +00:00
James Cole
d969109e05 Clean up changelog. 2022-02-05 12:53:05 +01:00
James Cole
9a08cf6266 Merge branch 'release/5.6.14' 2022-02-05 09:10:45 +01:00
James Cole
10ea575cd8 Merge tag '5.6.14' into develop
5.6.14
2022-02-05 09:10:45 +01:00
James Cole
356876b2b2 Update meta files for new release. 2022-02-05 09:02:30 +01:00
James Cole
f5197ec2e0 Update meta files for new release. 2022-02-05 08:59:41 +01:00
James Cole
71af5db38e Update meta files for new release. 2022-02-05 08:59:24 +01:00
James Cole
45195e6496 Update version and language strings. 2022-02-05 08:53:58 +01:00
James Cole
a56a6df557 Final changes to bills 2022-02-05 08:53:45 +01:00
James Cole
d7e6a7b125 Fix https://github.com/firefly-iii/firefly-iii/issues/5670 2022-02-03 13:16:20 +01:00
James Cole
ddabfbc1ad Remove references to help 2022-02-03 10:32:20 +01:00
James Cole
944864ed25 Add daily bill period 2022-02-03 06:45:45 +01:00
James Cole
1c795e71d5 Fix https://github.com/firefly-iii/firefly-iii/issues/5695 2022-02-02 20:15:28 +01:00
James Cole
7d7e1366a6 Catch empty string. 2022-02-01 07:14:51 +01:00
mergify[bot]
158a7b1517 Merge pull request #5672 from firefly-iii/dependabot/composer/develop/doctrine/dbal-3.3.1
Bump doctrine/dbal from 3.3.0 to 3.3.1
2022-01-31 03:01:13 +00:00
mergify[bot]
03f19ec235 Merge pull request #5671 from firefly-iii/dependabot/composer/develop/bacon/bacon-qr-code-2.0.5
Bump bacon/bacon-qr-code from 2.0.4 to 2.0.5
2022-01-31 03:01:09 +00:00
dependabot[bot]
a82ec20833 Bump doctrine/dbal from 3.3.0 to 3.3.1
Bumps [doctrine/dbal](https://github.com/doctrine/dbal) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/doctrine/dbal/releases)
- [Commits](https://github.com/doctrine/dbal/compare/3.3.0...3.3.1)

---
updated-dependencies:
- dependency-name: doctrine/dbal
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-31 03:00:40 +00:00
dependabot[bot]
fb8e238319 Bump bacon/bacon-qr-code from 2.0.4 to 2.0.5
Bumps [bacon/bacon-qr-code](https://github.com/Bacon/BaconQrCode) from 2.0.4 to 2.0.5.
- [Release notes](https://github.com/Bacon/BaconQrCode/releases)
- [Changelog](https://github.com/Bacon/BaconQrCode/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Bacon/BaconQrCode/compare/2.0.4...2.0.5)

---
updated-dependencies:
- dependency-name: bacon/bacon-qr-code
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-31 03:00:35 +00:00
James Cole
ab943bf006 Fix https://github.com/firefly-iii/firefly-iii/issues/5666 2022-01-30 19:41:24 +01:00
James Cole
b15b58f099 Fix https://github.com/firefly-iii/firefly-iii/issues/5664 2022-01-30 17:37:44 +01:00
James Cole
fee8d962e3 Fix issues with accounts API https://github.com/firefly-iii/firefly-iii/discussions/5661 2022-01-30 17:17:01 +01:00
James Cole
c0aca0e021 Merge tag '5.6.13' into develop
5.6.13
2022-01-30 17:01:28 +01:00
486 changed files with 30658 additions and 2342 deletions

View File

@@ -254,6 +254,8 @@ ALLOW_WEBHOOKS=false
#
# For more info: https://docs.firefly-iii.org/firefly-iii/advanced-installation/cron/
#
# You can set this variable from a file by appending it with _FILE
#
STATIC_CRON_TOKEN=
# You can fine tune the start-up of a Docker container by editing these environment variables.

6
.github/mergify.yml vendored
View File

@@ -1,10 +1,4 @@
pull_request_rules:
- name: Security update by dependabot
conditions:
- author~=^dependabot(|-preview)\[bot\]$
actions:
merge:
method: merge
- name: Close all on main
conditions:
- base=main

11
.gitignore vendored
View File

@@ -1,19 +1,8 @@
/node_modules
/frontend/node_modules
/frontend/fonts
/frontend/images
/public/hot
/public/storage
/storage/*.key
/vendor
/.vagrant
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
.env
public/google*.html
report.html
composer.phar
app.js.map
frontend-v3

View File

@@ -94,7 +94,7 @@ abstract class Controller extends BaseController
$obj = Carbon::parse($date);
} catch (InvalidDateException | InvalidFormatException $e) {
// don't care
Log::error(sprintf('Invalid date exception in API controller: %s', $e->getMessage()));
Log::warn(sprintf('Ignored invalid date "%s" in API controller parameter check: %s', (string) $date, $e->getMessage()));
}
}
$bag->set($field, $obj);

View File

@@ -77,7 +77,7 @@ class ShowController extends Controller
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getAll();
$collection = $this->repository->get();
$count = $collection->count();
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);

View File

@@ -145,11 +145,11 @@ class TriggerController extends Controller
// add a range:
$ruleEngine->addOperator(['type' => 'date_before', 'value' => $parameters['end']->format('Y-m-d')]);
}
if (array_key_exists('accounts', $parameters) && '' !== $parameters['accounts']) {
if (array_key_exists('accounts', $parameters) && is_array($parameters['accounts']) && count($parameters['accounts']) > 0) {
$ruleEngine->addOperator(['type' => 'account_id', 'value' => implode(',', $parameters['accounts'])]);
}
// file the rule(s)
// fire the rule(s)
$ruleEngine->fire();
return response()->json([], 204);

View File

@@ -70,8 +70,8 @@ class AccountController extends Controller
{
Log::debug('Now in account search()');
$manager = $this->getManager();
$query = $request->get('query');
$field = $request->get('field');
$query = trim((string)$request->get('query'));
$field = trim((string)$request->get('field'));
$type = $request->get('type') ?? 'all';
if ('' === $query || !in_array($field, $this->validFields, true)) {
return response(null, 422);

View File

@@ -116,15 +116,15 @@ class StoreRequest extends FormRequest
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'active' => [new IsBoolean],
'include_net_worth' => [new IsBoolean],
'account_role' => sprintf('in:%s|required_if:type,asset', $accountRoles),
'credit_card_type' => sprintf('in:%s|required_if:account_role,ccAsset', $ccPaymentTypes),
'monthly_payment_date' => 'date' . '|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
'liability_type' => 'required_if:type,liability|required_if:type,liabilities|in:loan,debt,mortgage',
'account_role' => sprintf('nullable|in:%s|required_if:type,asset', $accountRoles),
'credit_card_type' => sprintf('nullable|in:%s|required_if:account_role,ccAsset', $ccPaymentTypes),
'monthly_payment_date' => 'nullable|date|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
'liability_type' => 'nullable|required_if:type,liability|required_if:type,liabilities|in:loan,debt,mortgage',
'liability_amount' => 'required_with:liability_start_date|min:0|numeric',
'liability_start_date' => 'required_with:liability_amount|date',
'liability_direction' => 'required_if:type,liability|required_if:type,liabilities|in:credit,debit',
'liability_direction' => 'nullable|required_if:type,liability|required_if:type,liabilities|in:credit,debit',
'interest' => 'between:0,100|numeric',
'interest_period' => sprintf('in:%s', join(',', config('firefly.interest_periods'))),
'interest_period' => sprintf('nullable|in:%s', join(',', config('firefly.interest_periods'))),
'notes' => 'min:0|max:65536',
];

View File

@@ -141,32 +141,34 @@ class StoreRequest extends FormRequest
'first_date' => 'required|date',
'apply_rules' => [new IsBoolean],
'active' => [new IsBoolean],
'repeat_until' => 'date',
'nr_of_repetitions' => 'numeric|between:1,31',
'repeat_until' => 'nullable|date',
'nr_of_repetitions' => 'nullable|numeric|between:1,31',
'repetitions.*.type' => 'required|in:daily,weekly,ndom,monthly,yearly',
'repetitions.*.moment' => 'between:0,10',
'repetitions.*.skip' => 'numeric|between:0,31',
'repetitions.*.skip' => 'nullable|numeric|between:0,31',
'repetitions.*.weekend' => 'numeric|min:1|max:4',
'transactions.*.description' => 'required|between:1,255',
'transactions.*.amount' => 'required|numeric|gt:0',
'transactions.*.foreign_amount' => 'numeric|gt:0',
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'transactions.*.foreign_amount' => 'nullable|numeric|gt:0',
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser],
'transactions.*.destination_name' => 'between:1,255|nullable',
// new and updated fields:
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser],
'transactions.*.budget_id' => ['nullable','mustExist:budgets,id', new BelongsUser],
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser],
'transactions.*.category_id' => ['nullable','mustExist:categories,id', new BelongsUser],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.piggy_bank_id' => ['numeric', 'mustExist:piggy_banks,id', new BelongsUser],
'transactions.*.piggy_bank_id' => ['nullable','numeric', 'mustExist:piggy_banks,id', new BelongsUser],
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser],
'transactions.*.tags' => 'between:1,64000',
'transactions.*.tags' => 'nullable|between:1,64000',
];
}

View File

@@ -155,33 +155,34 @@ class UpdateRequest extends FormRequest
'first_date' => 'date',
'apply_rules' => [new IsBoolean],
'active' => [new IsBoolean],
'repeat_until' => 'date',
'nr_of_repetitions' => 'numeric|between:1,31',
'repeat_until' => 'nullable|date',
'nr_of_repetitions' => 'nullable|numeric|between:1,31',
'repetitions.*.type' => 'in:daily,weekly,ndom,monthly,yearly',
'repetitions.*.moment' => 'between:0,10',
'repetitions.*.skip' => 'numeric|between:0,31',
'repetitions.*.weekend' => 'numeric|min:1|max:4',
'repetitions.*.skip' => 'nullable|numeric|between:0,31',
'repetitions.*.weekend' => 'nullable|numeric|min:1|max:4',
'transactions.*.description' => 'between:1,255',
'transactions.*.amount' => 'numeric|gt:0',
'transactions.*.foreign_amount' => 'numeric|gt:0',
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'transactions.*.foreign_amount' => 'nullable|numeric|gt:0',
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser],
'transactions.*.destination_name' => 'between:1,255|nullable',
// new and updated fields:
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser],
'transactions.*.budget_id' => ['nullable','mustExist:budgets,id', new BelongsUser],
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser],
'transactions.*.category_id' => ['nullable','mustExist:categories,id', new BelongsUser],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.piggy_bank_id' => ['numeric', 'mustExist:piggy_banks,id', new BelongsUser],
'transactions.*.piggy_bank_id' => ['nullable','numeric', 'mustExist:piggy_banks,id', new BelongsUser],
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser],
'transactions.*.tags' => 'between:1,64000',
'transactions.*.tags' => 'nullable|between:1,64000',
];
}

View File

@@ -153,12 +153,14 @@ class StoreRequest extends FormRequest
function (Validator $validator) {
$this->atLeastOneTrigger($validator);
$this->atLeastOneAction($validator);
$this->atLeastOneActiveTrigger($validator);
$this->atLeastOneActiveAction($validator);
}
);
}
/**
* Adds an error to the validator when there are no repetitions in the array of data.
* Adds an error to the validator when there are no triggers in the array of data.
*
* @param Validator $validator
*/
@@ -172,6 +174,64 @@ class StoreRequest extends FormRequest
}
}
/**
* Adds an error to the validator when there are no ACTIVE triggers in the array of data.
*
* @param Validator $validator
*/
protected function atLeastOneActiveTrigger(Validator $validator): void
{
$data = $validator->getData();
$triggers = $data['triggers'] ?? [];
// need at least one trigger
if (!is_countable($triggers) || empty($triggers)) {
return;
}
$allInactive = true;
$inactiveIndex = 0;
foreach ($triggers as $index => $trigger) {
$active = array_key_exists('active', $trigger) ? $trigger['active'] : true; // assume true
if (true === $active) {
$allInactive = false;
}
if (false === $active) {
$inactiveIndex = $index;
}
}
if (true === $allInactive) {
$validator->errors()->add(sprintf('triggers.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_trigger'));
}
}
/**
* Adds an error to the validator when there are no ACTIVE actions in the array of data.
*
* @param Validator $validator
*/
protected function atLeastOneActiveAction(Validator $validator): void
{
$data = $validator->getData();
$actions = $data['actions'] ?? [];
// need at least one trigger
if (!is_countable($actions) || empty($actions)) {
return;
}
$allInactive = true;
$inactiveIndex = 0;
foreach ($actions as $index => $action) {
$active = array_key_exists('active', $action) ? $action['active'] : true; // assume true
if (true === $active) {
$allInactive = false;
}
if (false === $active) {
$inactiveIndex = $index;
}
}
if (true === $allInactive) {
$validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action'));
}
}
/**
* Adds an error to the validator when there are no repetitions in the array of data.
*

View File

@@ -55,7 +55,7 @@ class TriggerRequest extends FormRequest
*/
private function getDate(string $field): ?Carbon
{
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field));
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($this->query($field),0,10));
}
/**
@@ -63,7 +63,7 @@ class TriggerRequest extends FormRequest
*/
private function getAccounts(): array
{
return $this->get('accounts');
return $this->get('accounts') ?? [];
}
/**

View File

@@ -167,7 +167,9 @@ class UpdateRequest extends FormRequest
$validator->after(
function (Validator $validator) {
$this->atLeastOneTrigger($validator);
$this->atLeastOneValidTrigger($validator);
$this->atLeastOneAction($validator);
$this->atLeastOneValidAction($validator);
}
);
}
@@ -187,6 +189,35 @@ class UpdateRequest extends FormRequest
}
}
/**
* Adds an error to the validator when there are no repetitions in the array of data.
*
* @param Validator $validator
*/
protected function atLeastOneValidTrigger(Validator $validator): void
{
$data = $validator->getData();
$triggers = $data['triggers'] ?? [];
$allInactive = true;
$inactiveIndex = 0;
// need at least one trigger
if (is_array($triggers) && empty($triggers)) {
return;
}
foreach ($triggers as $index => $trigger) {
$active = array_key_exists('active', $trigger) ? $trigger['active'] : true; // assume true
if (true === $active) {
$allInactive = false;
}
if (false === $active) {
$inactiveIndex = $index;
}
}
if (true === $allInactive) {
$validator->errors()->add(sprintf('triggers.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_trigger'));
}
}
/**
* Adds an error to the validator when there are no repetitions in the array of data.
*
@@ -201,4 +232,34 @@ class UpdateRequest extends FormRequest
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
}
}
/**
* Adds an error to the validator when there are no repetitions in the array of data.
*
* @param Validator $validator
*/
protected function atLeastOneValidAction(Validator $validator): void
{
$data = $validator->getData();
$actions = $data['actions'] ?? [];
$allInactive = true;
$inactiveIndex = 0;
// need at least one action
if (is_array($actions) && empty($actions)) {
return;
}
foreach ($actions as $index => $action) {
$active = array_key_exists('active', $action) ? $action['active'] : true; // assume true
if (true === $active) {
$allInactive = false;
}
if (false === $active) {
$inactiveIndex = $index;
}
}
if (true === $allInactive) {
$validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action'));
}
}
}

View File

@@ -98,17 +98,17 @@ class StoreRequest extends FormRequest
// source of transaction. If everything is null, assume cash account.
'source_id' => $this->integerFromValue((string)$object['source_id']),
'source_name' => $this->clearString($object['source_name'], false),
'source_iban' => $this->clearString($object['source_iban'], false),
'source_number' => $this->clearString($object['source_number'], false),
'source_bic' => $this->clearString($object['source_bic'], false),
'source_name' => $this->clearString((string)$object['source_name'], false),
'source_iban' => $this->clearString((string)$object['source_iban'], false),
'source_number' => $this->clearString((string)$object['source_number'], false),
'source_bic' => $this->clearString((string)$object['source_bic'], false),
// destination of transaction. If everything is null, assume cash account.
'destination_id' => $this->integerFromValue((string)$object['destination_id']),
'destination_name' => $this->clearString($object['destination_name'], false),
'destination_iban' => $this->clearString($object['destination_iban'], false),
'destination_number' => $this->clearString($object['destination_number'], false),
'destination_bic' => $this->clearString($object['destination_bic'], false),
'destination_name' => $this->clearString((string)$object['destination_name'], false),
'destination_iban' => $this->clearString((string)$object['destination_iban'], false),
'destination_number' => $this->clearString((string)$object['destination_number'], false),
'destination_bic' => $this->clearString((string)$object['destination_bic'], false),
// budget info
'budget_id' => $this->integerFromValue((string)$object['budget_id']),

View File

@@ -181,7 +181,7 @@ class UpdateRequest extends FormRequest
{
foreach ($this->integerFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->integerFromValue((string)$transaction[$fieldName]);
$current[$fieldName] = $this->integerFromValue((string) $transaction[$fieldName]);
}
}
@@ -198,7 +198,7 @@ class UpdateRequest extends FormRequest
{
foreach ($this->stringFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearString((string)$transaction[$fieldName], false);
$current[$fieldName] = $this->clearString((string) $transaction[$fieldName], false);
}
}
@@ -215,7 +215,7 @@ class UpdateRequest extends FormRequest
{
foreach ($this->textareaFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearString((string)$transaction[$fieldName]);
$current[$fieldName] = $this->clearString((string) $transaction[$fieldName]);
}
}
@@ -233,8 +233,8 @@ class UpdateRequest extends FormRequest
foreach ($this->dateFields as $fieldName) {
Log::debug(sprintf('Now at date field %s', $fieldName));
if (array_key_exists($fieldName, $transaction)) {
Log::debug(sprintf('New value: "%s"', (string)$transaction[$fieldName]));
$current[$fieldName] = $this->dateFromValue((string)$transaction[$fieldName]);
Log::debug(sprintf('New value: "%s"', (string) $transaction[$fieldName]));
$current[$fieldName] = $this->dateFromValue((string) $transaction[$fieldName]);
}
}
@@ -251,7 +251,7 @@ class UpdateRequest extends FormRequest
{
foreach ($this->booleanFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->convertBoolean((string)$transaction[$fieldName]);
$current[$fieldName] = $this->convertBoolean((string) $transaction[$fieldName]);
}
}
@@ -293,7 +293,7 @@ class UpdateRequest extends FormRequest
'transactions.*.order' => 'numeric|min:0',
// group id:
'transactions.*.transaction_journal_id' => ['numeric', 'exists:transaction_journals,id', new BelongsUser],
'transactions.*.transaction_journal_id' => ['nullable', 'numeric', new BelongsUser],
// currency info

View File

@@ -28,6 +28,7 @@ use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;
/**
* Class UserUpdateRequest
@@ -43,7 +44,7 @@ class UserUpdateRequest extends FormRequest
*/
public function authorize(): bool
{
return auth()->check() && auth()->user()->hasRole('owner');
return auth()->check();
}
/**
@@ -83,4 +84,25 @@ class UserUpdateRequest extends FormRequest
];
}
/**
* Configure the validator instance.
*
* @param Validator $validator
*
* @return void
*/
public function withValidator(Validator $validator): void
{
$current = $this->route()->parameter('user');
$validator->after(
static function (Validator $validator) use($current) {
$isAdmin = auth()->user()->hasRole('owner');
// not admin, and not own user?
if (auth()->check() && false === $isAdmin && $current?->id !== auth()->user()->id) {
$validator->errors()->add('email', (string) trans('validation.invalid_selection'));
}
}
);
}
}

View File

@@ -68,6 +68,7 @@ class RenameMetaFields extends Command
'sepa-ep' => 'sepa_ep',
'sepa-ci' => 'sepa_ci',
'sepa-batch-id' => 'sepa_batch_id',
'external_uri' => 'external_url',
];
foreach ($changes as $original => $update) {
$this->rename($original, $update);

View File

@@ -29,6 +29,7 @@ use FireflyIII\Models\Bill;
use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\Tag;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
@@ -221,8 +222,8 @@ trait MetaCollection
$this->hasJoinedMetaTables = true;
$this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id');
}
$this->query->where(function(Builder $q1) {
$q1->where(function(Builder $q2) {
$this->query->where(function (Builder $q1) {
$q1->where(function (Builder $q2) {
$q2->where('journal_meta.name', '=', 'external_url');
$q2->whereNull('journal_meta.data');
})->orWhereNull('journal_meta.name');
@@ -487,7 +488,10 @@ trait MetaCollection
public function withoutNotes(): GroupCollectorInterface
{
$this->withNotes();
$this->query->whereNull('notes.text');
$this->query->where(function (Builder $q) {
$q->whereNull('notes.text');
$q->orWhere('notes.text', '');
});
return $this;
}

View File

@@ -481,6 +481,7 @@ class GroupCollector implements GroupCollectorInterface
public function withAttachmentInformation(): GroupCollectorInterface
{
$this->fields[] = 'attachments.id as attachment_id';
$this->fields[] = 'attachments.uploaded as attachment_uploaded';
$this->joinAttachmentTables();
return $this;
@@ -498,7 +499,7 @@ class GroupCollector implements GroupCollectorInterface
->where(
static function (EloquentBuilder $q1) {
$q1->where('attachments.attachable_type', TransactionJournal::class);
$q1->where('attachments.uploaded', true);
//$q1->where('attachments.uploaded', true);
$q1->orWhereNull('attachments.attachable_type');
}
);
@@ -564,8 +565,8 @@ class GroupCollector implements GroupCollectorInterface
*/
public function dumpQueryInLogs(): void
{
Log::debug($this->query->select($this->fields)->toSql()) ;
Log::debug('Bindings',$this->query->getBindings());
Log::debug($this->query->select($this->fields)->toSql());
Log::debug('Bindings', $this->query->getBindings());
}
/**
@@ -578,7 +579,7 @@ class GroupCollector implements GroupCollectorInterface
private function convertToInteger(array $array): array
{
foreach ($this->integerFields as $field) {
$array[$field] = array_key_exists($field, $array) ? (int)$array[$field] : null;
$array[$field] = array_key_exists($field, $array) ? (int) $array[$field] : null;
}
return $array;
@@ -594,7 +595,8 @@ class GroupCollector implements GroupCollectorInterface
{
$newArray = $newJournal->toArray();
if (array_key_exists('attachment_id', $newArray)) {
$attachmentId = (int)$newJournal['tag_id'];
$attachmentId = (int) $newJournal['attachment_id'];
$existingJournal['attachments'][$attachmentId] = [
'id' => $attachmentId,
];
@@ -613,7 +615,7 @@ class GroupCollector implements GroupCollectorInterface
{
$newArray = $newJournal->toArray();
if (array_key_exists('tag_id', $newArray)) { // assume the other fields are present as well.
$tagId = (int)$newJournal['tag_id'];
$tagId = (int) $newJournal['tag_id'];
$tagDate = null;
try {
@@ -623,7 +625,7 @@ class GroupCollector implements GroupCollectorInterface
}
$existingJournal['tags'][$tagId] = [
'id' => (int)$newArray['tag_id'],
'id' => (int) $newArray['tag_id'],
'name' => $newArray['tag_name'],
'date' => $tagDate,
'description' => $newArray['tag_description'],
@@ -649,21 +651,21 @@ class GroupCollector implements GroupCollectorInterface
// make new array
$parsedGroup = $this->parseAugmentedJournal($augumentedJournal);
$groupArray = [
'id' => (int)$augumentedJournal->transaction_group_id,
'user_id' => (int)$augumentedJournal->user_id,
'id' => (int) $augumentedJournal->transaction_group_id,
'user_id' => (int) $augumentedJournal->user_id,
'title' => $augumentedJournal->transaction_group_title,
'transaction_type' => $parsedGroup['transaction_type_type'],
'count' => 1,
'sums' => [],
'transactions' => [],
];
$journalId = (int)$augumentedJournal->transaction_journal_id;
$journalId = (int) $augumentedJournal->transaction_journal_id;
$groupArray['transactions'][$journalId] = $parsedGroup;
$groups[$groupId] = $groupArray;
continue;
}
// or parse the rest.
$journalId = (int)$augumentedJournal->transaction_journal_id;
$journalId = (int) $augumentedJournal->transaction_journal_id;
if (array_key_exists($journalId, $groups[$groupId]['transactions'])) {
// append data to existing group + journal (for multiple tags or multiple attachments)
$groups[$groupId]['transactions'][$journalId] = $this->mergeTags($groups[$groupId]['transactions'][$journalId], $augumentedJournal);
@@ -708,9 +710,9 @@ class GroupCollector implements GroupCollectorInterface
// convert values to integers:
$result = $this->convertToInteger($result);
$result['reconciled'] = 1 === (int)$result['reconciled'];
$result['reconciled'] = 1 === (int) $result['reconciled'];
if (array_key_exists('tag_id', $result) && null !== $result['tag_id']) { // assume the other fields are present as well.
$tagId = (int)$augumentedJournal['tag_id'];
$tagId = (int) $augumentedJournal['tag_id'];
$tagDate = null;
try {
$tagDate = Carbon::parse($augumentedJournal['tag_date']);
@@ -719,7 +721,7 @@ class GroupCollector implements GroupCollectorInterface
}
$result['tags'][$tagId] = [
'id' => (int)$result['tag_id'],
'id' => (int) $result['tag_id'],
'name' => $result['tag_name'],
'date' => $tagDate,
'description' => $result['tag_description'],
@@ -728,8 +730,9 @@ class GroupCollector implements GroupCollectorInterface
// also merge attachments:
if (array_key_exists('attachment_id', $result)) {
$attachmentId = (int)$augumentedJournal['attachment_id'];
if (0 !== $attachmentId) {
$uploaded = 1 === (int)$result['attachment_uploaded'];
$attachmentId = (int) $augumentedJournal['attachment_id'];
if (0 !== $attachmentId && $uploaded) {
$result['attachments'][$attachmentId] = [
'id' => $attachmentId,
];
@@ -753,7 +756,7 @@ class GroupCollector implements GroupCollectorInterface
foreach ($groups as $groudId => $group) {
/** @var array $transaction */
foreach ($group['transactions'] as $transaction) {
$currencyId = (int)$transaction['currency_id'];
$currencyId = (int) $transaction['currency_id'];
// set default:
if (!array_key_exists($currencyId, $groups[$groudId]['sums'])) {
@@ -766,7 +769,7 @@ class GroupCollector implements GroupCollectorInterface
$groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $transaction['amount'] ?? '0');
if (null !== $transaction['foreign_amount'] && null !== $transaction['foreign_currency_id']) {
$currencyId = (int)$transaction['foreign_currency_id'];
$currencyId = (int) $transaction['foreign_currency_id'];
// set default:
if (!array_key_exists($currencyId, $groups[$groudId]['sums'])) {

View File

@@ -1,163 +0,0 @@
<?php
/**
* Help.php
* Copyright (c) 2019 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\Helpers\Help;
use Cache;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use League\CommonMark\CommonMarkConverter;
use Log;
use Route;
/**
* Class Help.
*/
class Help implements HelpInterface
{
/** @var string The cache key */
public const CACHEKEY = 'help_%s_%s';
/** @var string The user agent. */
protected $userAgent = 'Firefly III v%s';
/**
* Constructor.
*/
public function __construct()
{
$this->userAgent = sprintf($this->userAgent, config('firefly.version'));
}
/**
* Get from cache.
*
* @codeCoverageIgnore
*
* @param string $route
* @param string $language
*
* @return string
*/
public function getFromCache(string $route, string $language): string
{
$line = sprintf(self::CACHEKEY, $route, $language);
return Cache::get($line);
}
/**
* Get text from GitHub.
*
* @param string $route
* @param string $language
*
* @return string
* @throws GuzzleException
*/
public function getFromGitHub(string $route, string $language): string
{
$uri = sprintf('https://raw.githubusercontent.com/firefly-iii/help/main/%s/%s.md', $language, $route);
Log::debug(sprintf('Trying to get %s...', $uri));
$opt = ['headers' => ['User-Agent' => $this->userAgent]];
$content = '';
$statusCode = 500;
$client = app(Client::class);
try {
$res = $client->request('GET', $uri, $opt);
$statusCode = $res->getStatusCode();
$content = trim($res->getBody()->getContents());
} catch (Exception $e) { // @phpstan-ignore-line
Log::info($e->getMessage());
//Log::info($e->getTraceAsString());
}
Log::debug(sprintf('Status code is %d', $statusCode));
if ('' !== $content) {
Log::debug('Content is longer than zero. Expect something.');
$converter = new CommonMarkConverter();
$content = (string)$converter->convertToHtml($content);
}
return $content;
}
/**
* Do we have the route?
*
* @codeCoverageIgnore
*
* @param string $route
*
* @return bool
*/
public function hasRoute(string $route): bool
{
return Route::has($route);
}
/**
* Is in cache?
*
* @codeCoverageIgnore
*
* @param string $route
* @param string $language
*
* @return bool
*/
public function inCache(string $route, string $language): bool
{
$line = sprintf(self::CACHEKEY, $route, $language);
$result = Cache::has($line);
if ($result) {
Log::debug(sprintf('Cache has this entry: %s', 'help.' . $route . '.' . $language));
}
if (!$result) {
Log::debug(sprintf('Cache does not have this entry: %s', 'help.' . $route . '.' . $language));
}
return $result;
}
/**
* Put help text in cache.
*
* @codeCoverageIgnore
*
* @param string $route
* @param string $language
* @param string $content
*/
public function putInCache(string $route, string $language, string $content): void
{
$key = sprintf(self::CACHEKEY, $route, $language);
if ('' !== $content) {
Log::debug(sprintf('Will store entry in cache: %s', $key));
Cache::put($key, $content, 10080); // a week.
return;
}
Log::info(sprintf('Will not cache %s because content is empty.', $key));
}
}

View File

@@ -1,77 +0,0 @@
<?php
/**
* HelpInterface.php
* Copyright (c) 2019 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\Helpers\Help;
/**
* Interface HelpInterface.
*/
interface HelpInterface
{
/**
* Get the help text from cache.
*
* @param string $route
* @param string $language
*
* @return string
*/
public function getFromCache(string $route, string $language): string;
/**
* Get the help text from GitHub.
*
* @param string $route
* @param string $language
*
* @return string
*/
public function getFromGitHub(string $route, string $language): string;
/**
* Is the route a known route?
*
* @param string $route
*
* @return bool
*/
public function hasRoute(string $route): bool;
/**
* Is the help text in cache?
*
* @param string $route
* @param string $language
*
* @return bool
*/
public function inCache(string $route, string $language): bool;
/**
* Put the result in cache.
*
* @param string $route
* @param string $language
* @param string $content
*/
public function putInCache(string $route, string $language, string $content);
}

View File

@@ -203,6 +203,7 @@ class IndexController extends Controller
'quarterly' => '4',
'monthly' => '12',
'weekly' => '52.17',
'daily' => '365.24',
];
$yearAmount = bcmul($avg, bcdiv($multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1)));
Log::debug(sprintf('Amount per year is %s (%s * %s / %s)', $yearAmount, $avg, $multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1)));

View File

@@ -131,7 +131,7 @@ class ShowController extends Controller
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setLimit($pageSize)->setPage($page)
->withoutBudget()->withAccountInformation()->withCategoryInformation();
$groups = $collector->getPaginatedGroups();
$groups->setPath(route('budgets.no-budget'));
$groups->setPath(route('budgets.no-budget-all'));
return view('budgets.no-budget', compact('groups', 'subTitle', 'start', 'end'));
}

View File

@@ -1,50 +0,0 @@
<?php
/**
* HelpController.php
* Copyright (c) 2019 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\Http\Controllers;
use FireflyIII\Exceptions\FireflyException;
use Illuminate\Http\JsonResponse;
/**
* Class HelpController.
*/
class HelpController extends Controller
{
/**
* Show help for a route.
*
* @param string $route
*
* @return JsonResponse
* @throws FireflyException
*/
public function show(string $route): JsonResponse
{
/** @var string $language */
$language = app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data;
$html = $this->getHelpText($route, $language);
return response()->json(['html' => $html]);
}
}

View File

@@ -103,7 +103,7 @@ class HomeController extends Controller
public function index(AccountRepositoryInterface $repository): mixed
{
if ('v3' === config('firefly.layout')) {
die('Please set your layout to "v1".');
return view('pwa');
}
$types = config('firefly.accountTypesByIdentifier.asset');
$count = $repository->count($types);

View File

@@ -47,6 +47,7 @@ use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Session\Middleware\AuthenticateSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
use Laravel\Passport\Http\Middleware\CreateFreshApiToken;
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
use PragmaRX\Google2FALaravel\Middleware as MFAMiddleware;
/**
@@ -177,9 +178,9 @@ class Kernel extends HttpKernel
CreateFreshApiToken::class,
],
'apiX' => [
'auth:api',
//'throttle:60,1',
'api' => [
EnsureFrontendRequestsAreStateful::class,
'auth:api,sanctum',
'bindings',
],
'apiY' => [

View File

@@ -62,9 +62,16 @@ class SecureHeaders
"manifest-src 'self'",
];
$route = $request->route();
$route = $request->route();
$customUrl = '';
$authGuard = (string)config('firefly.authentication_guard');
$logoutUrl = (string)config('firefly.custom_logout_url');
if ('remote_user_guard' === $authGuard && '' !== $logoutUrl) {
$customUrl = $logoutUrl;
}
if (null !== $route && 'oauth/authorize' !== $route->uri) {
$csp[] = "form-action 'self'";
$csp[] = sprintf("form-action 'self' %s", $customUrl);
}
$featurePolicies = [

View File

@@ -68,7 +68,7 @@ class BillStoreRequest extends FormRequest
'amount_max' => 'required|numeric|gt:0|max:1000000000',
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
'date' => 'required|date',
'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly',
'repeat_freq' => sprintf('required|in:%s', join(',', config('firefly.bill_periods'))),
'skip' => 'required|integer|gte:0|lte:31',
'active' => 'boolean',
];

View File

@@ -72,7 +72,7 @@ class BillUpdateRequest extends FormRequest
'amount_max' => 'required|numeric|gt:0|max:1000000000',
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
'date' => 'required|date',
'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly',
'repeat_freq' => sprintf('required|in:%s', join(',', config('firefly.bill_periods'))),
'skip' => 'required|integer|gte:0|lte:31',
'active' => 'boolean',
];

View File

@@ -187,7 +187,7 @@ class ReportFormRequest extends FormRequest
$pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][\d]|3[01])$/';
if (preg_match($pattern, $string)) {
try {
$date = new Carbon($parts[1]);
$date = new Carbon($parts[0]);
} catch (Exception $e) {
$error = sprintf('"%s" is not a valid date range: %s', $range, $e->getMessage());
Log::error($error);

View File

@@ -26,6 +26,7 @@ use Adldap\Laravel\Middleware\WindowsAuthenticate;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
use Laravel\Passport\Passport;
use Laravel\Sanctum\Sanctum;
use URL;
/**
@@ -48,6 +49,7 @@ class AppServiceProvider extends ServiceProvider
if (config('ldap_auth.identifiers.windows.enabled', false)) {
$this->app['router']->pushMiddlewareToGroup('web', WindowsAuthenticate::class);
}
Sanctum::ignoreMigrations();
}
/**

View File

@@ -49,48 +49,25 @@ class RouteServiceProvider extends ServiceProvider
/**
* Define the routes for the application.
*/
public function map(): void
public function boot(): void
{
$this->mapApiRoutes();
$this->mapCronApiRoutes();
$this->mapWebRoutes();
$this->routes(function () {
Route::prefix('api/v1')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::prefix('api/v1/cron')
->middleware('apiY')
->namespace($this->namespace)
->group(base_path('routes/api-noauth.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
});
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*/
protected function mapApiRoutes(): void
{
Route::prefix('api/v1')
->middleware('apiX')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*/
protected function mapCronApiRoutes(): void
{
Route::prefix('api/v1/cron')
->middleware('apiY')
->namespace($this->namespace)
->group(base_path('routes/api-noauth.php'));
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*/
protected function mapWebRoutes(): void
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
}

View File

@@ -172,7 +172,7 @@ trait JournalServiceTrait
private function findAccountByNumber(?Account $account, array $data, array $types): ?Account
{
// third attempt, find by account number
if (null === $account && null !== $data['number']) {
if (null === $account && null !== $data['number'] && '' !== (string) $data['number']) {
Log::debug(sprintf('Searching for account number "%s".', $data['number']));
// find by preferred type.
$source = $this->accountRepository->findByAccountNumber((string)$data['number'], [$types[0]]);

View File

@@ -177,7 +177,7 @@ trait RecurringTransactionTrait
$this->updatePiggyBank($transaction, (int)$array['piggy_bank_id']);
}
if (array_key_exists('tags', $array)) {
if (array_key_exists('tags', $array) && is_array($array['tags'])) {
$this->updateTags($transaction, $array['tags']);
}

View File

@@ -303,7 +303,7 @@ class RecurrenceUpdateService
$this->setCategory($match, (int)$current['category_id']);
}
if (array_key_exists('tags', $current)) {
if (array_key_exists('tags', $current) && is_array($current['tags'])) {
$this->updateTags($match, $current['tags']);
}
if (array_key_exists('piggy_bank_id', $current)) {

View File

@@ -48,6 +48,12 @@ class EitherConfigKey
'firefly.credit_card_types',
'firefly.languages',
'app.timezone',
'firefly.valid_view_ranges',
// triggers and actions:
'firefly.rule-actions',
'firefly.context-rule-actions',
'firefly.search.operators'
];
/**

View File

@@ -57,66 +57,6 @@ trait RequestInformation
return $parts['host'];
}
/**
* Gets the help text.
*
* @param string $route
* @param string $language
*
* @return string
*
*/
final protected function getHelpText(string $route, string $language): string // get from internet.
{
$help = app(HelpInterface::class);
// get language and default variables.
$content = '<p>' . trans('firefly.route_has_no_help') . '</p>';
// if no such route, log error and return default text.
if (!$help->hasRoute($route)) {
Log::error('No such route: ' . $route);
return $content;
}
// help content may be cached:
if ($help->inCache($route, $language)) {
$content = $help->getFromCache($route, $language);
Log::debug(sprintf('Help text %s was in cache.', $language));
return $content;
}
// get help content from Github:
$content = $help->getFromGitHub($route, $language);
$originalLanguage = $language;
// content will have 0 length when Github failed. Try en_US when it does:
if ('' === $content) {
$language = 'en_US';
// also check cache first:
if ($help->inCache($route, $language)) {
Log::debug(sprintf('Help text %s was in cache.', $language));
return $help->getFromCache($route, $language);
}
$baseHref = route('index');
$helpString = sprintf(
'<p><em><img alt="" src="%s/v1/images/flags/%s.png" /> %s</em></p>', $baseHref, $originalLanguage, (string)trans('firefly.help_translating')
);
$content = $helpString . $help->getFromGitHub($route, $language);
}
// help still empty?
if ('' !== $content) {
$help->putInCache($route, $language, $content);
return $content;
}
return '<p>' . trans('firefly.route_has_no_help') . '</p>';
}
/**
* Get a list of triggers.
*

View File

@@ -481,7 +481,7 @@ class OperatorQuerySearch implements SearchInterface
$this->collector->withCategory();
break;
case 'category_is':
$result = $this->categoryRepository->searchCategory($value, 25);
$result = $this->categoryRepository->searchCategory($value, 1337);
if ($result->count() > 0) {
$this->collector->setCategories($result);
}
@@ -499,7 +499,7 @@ class OperatorQuerySearch implements SearchInterface
$this->collector->withBudget();
break;
case 'budget_is':
$result = $this->budgetRepository->searchBudget($value, 25);
$result = $this->budgetRepository->searchBudget($value, 1337);
if ($result->count() > 0) {
$this->collector->setBudgets($result);
}
@@ -517,7 +517,7 @@ class OperatorQuerySearch implements SearchInterface
$this->collector->withBill();
break;
case 'bill_is':
$result = $this->billRepository->searchBill($value, 25);
$result = $this->billRepository->searchBill($value, 1337);
if ($result->count() > 0) {
$this->collector->setBills($result);
}
@@ -708,7 +708,7 @@ class OperatorQuerySearch implements SearchInterface
}
// get accounts:
$accounts = $this->accountRepository->searchAccount($value, $searchTypes, 25);
$accounts = $this->accountRepository->searchAccount($value, $searchTypes, 1337);
if (0 === $accounts->count()) {
Log::debug('Found zero accounts, search for non existing account, NO results will be returned.');
$this->collector->findNothing();
@@ -769,7 +769,7 @@ class OperatorQuerySearch implements SearchInterface
}
// search for accounts:
$accounts = $this->accountRepository->searchAccountNr($value, $searchTypes, 25);
$accounts = $this->accountRepository->searchAccountNr($value, $searchTypes, 1337);
if (0 === $accounts->count()) {
Log::debug('Found zero accounts, search for invalid account.');
$this->collector->findNothing();

View File

@@ -111,7 +111,7 @@ class Steam
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($account->user);
$currencyId = (int)$repository->getMetaValue($account, 'currency_id');
$currencyId = (int) $repository->getMetaValue($account, 'currency_id');
$transactions = $account->transactions()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
@@ -191,7 +191,7 @@ class Steam
$repository->setUser($account->user);
$currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user);
}
$currencyId = (int)$currency->id;
$currencyId = (int) $currency->id;
$start->addDay();
@@ -219,14 +219,14 @@ class Steam
/** @var Transaction $entry */
foreach ($set as $entry) {
// normal amount and foreign amount
$modified = null === $entry->modified ? '0' : (string)$entry->modified;
$foreignModified = null === $entry->modified_foreign ? '0' : (string)$entry->modified_foreign;
$modified = null === $entry->modified ? '0' : (string) $entry->modified;
$foreignModified = null === $entry->modified_foreign ? '0' : (string) $entry->modified_foreign;
$amount = '0';
if ($currencyId === (int)$entry->transaction_currency_id || 0 === $currencyId) {
if ($currencyId === (int) $entry->transaction_currency_id || 0 === $currencyId) {
// use normal amount:
$amount = $modified;
}
if ($currencyId === (int)$entry->foreign_currency_id) {
if ($currencyId === (int) $entry->foreign_currency_id) {
// use foreign amount:
$amount = $foreignModified;
}
@@ -284,7 +284,7 @@ class Steam
->get(['transactions.foreign_amount'])->toArray();
$foreignBalance = $this->sumTransactions($transactions, 'foreign_amount');
$balance = bcadd($nativeBalance, $foreignBalance);
$virtual = null === $account->virtual_balance ? '0' : (string)$account->virtual_balance;
$virtual = null === $account->virtual_balance ? '0' : (string) $account->virtual_balance;
$balance = bcadd($balance, $virtual);
$cache->store($balance);
@@ -384,7 +384,7 @@ class Steam
$return = [];
/** @var stdClass $entry */
foreach ($balances as $entry) {
$return[(int)$entry->transaction_currency_id] = $entry->sum_for_currency;
$return[(int) $entry->transaction_currency_id] = $entry->sum_for_currency;
}
$cache->store($return);
@@ -408,7 +408,7 @@ class Steam
foreach ($set as $entry) {
$date = new Carbon($entry->max_date, config('app.timezone'));
$date->setTimezone(config('app.timezone'));
$list[(int)$entry->account_id] = $date;
$list[(int) $entry->account_id] = $date;
}
return $list;
@@ -443,7 +443,11 @@ class Steam
*/
public function getLanguage(): string // get preference
{
return app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data;
$preference = app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data;
if (!is_string($preference)) {
throw new FireflyException(sprintf('Preference "language" must be a string, but is unexpectedly a "%s".', gettype($preference)));
}
return $preference;
}
/**
@@ -503,24 +507,24 @@ class Steam
// has a K in it, remove the K and multiply by 1024.
$bytes = bcmul(rtrim($string, 'k'), '1024');
return (int)$bytes;
return (int) $bytes;
}
if (false !== stripos($string, 'm')) {
// has a M in it, remove the M and multiply by 1048576.
$bytes = bcmul(rtrim($string, 'm'), '1048576');
return (int)$bytes;
return (int) $bytes;
}
if (false !== stripos($string, 'g')) {
// has a G in it, remove the G and multiply by (1024)^3.
$bytes = bcmul(rtrim($string, 'g'), '1073741824');
return (int)$bytes;
return (int) $bytes;
}
return (int)$string;
return (int) $string;
}
/**

View File

@@ -267,6 +267,9 @@ class BillTransformer extends AbstractTransformer
$nextExpectedMatch->addDay();
$currentStart = clone $nextExpectedMatch;
$loop++;
if($loop > 4) {
break;
}
}
$simple = $set->map(
static function (Carbon $date) {

View File

@@ -162,7 +162,7 @@ class User extends Authenticatable
use Notifiable, HasApiTokens;
/**
* The attributes that should be casted to native types.
* The attributes that should be cast to native types.
*
* @var array
*/

View File

@@ -93,7 +93,7 @@ trait RecurrenceValidation
// validate source account.
$sourceId = array_key_exists('source_id', $transaction) ? (int)$transaction['source_id'] : null;
$sourceName = $transaction['source_name'] ?? null;
$validSource = $accountValidator->validateSource($sourceId, $sourceName, null);
$validSource = $accountValidator->validateSource(['id' => $sourceId, 'name' => $sourceName]);
// do something with result:
if (false === $validSource) {

View File

@@ -2,6 +2,48 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## 5.6.16 - 2022-03-01
### Fixed
- Broken migration would clash during startup.
## 5.6.15 - 2022-03-01
### Changed
- Meta field `external_uri` will be renamed properly.
- Migrations are more robust.
### Fixed
- [Issue 5493](https://github.com/firefly-iii/firefly-iii/issues/5493) CSP is too strict in some cases
- [Issue 5694](https://github.com/firefly-iii/firefly-iii/issues/5694) Adding attachment on some expenses causes them to disappear from transactions list
- [Issue 5724](https://github.com/firefly-iii/firefly-iii/issues/5724) Filter `no_external_url` fixed.
- [Issue 5806](https://github.com/firefly-iii/firefly-iii/issues/5806) Pagination on "all transactions without budget" was broken
- [Issue 5810](https://github.com/firefly-iii/firefly-iii/issues/5810) Search query with `no_notes:true` breaks after editing transaction
### API
- Expanded the number of config fields you can pick up.
- Rules also validate the number of active triggers or actions.
## 5.6.14 - 2022-02-06
### Added
- Can now add daily bills
### Removed
- Code related to the dynamic help text on GitHub
### Fixed
- [Issue 5664](https://github.com/firefly-iii/firefly-iii/issues/5664) Bad report dates
- [Issue 5666](https://github.com/firefly-iii/firefly-iii/issues/5666) Unexpected parse issue.
- [Issue 5695](https://github.com/firefly-iii/firefly-iii/issues/5695) Search would miss the 26th account in a wildcard search.
- Install template was not working, thanks Softaculous!
- Empty string in reports URL could lead to parse issues.
### API
- [Issue 5661](https://github.com/firefly-iii/firefly-iii/issues/5661) Various fields could not be set to NULL
- [Issue 5670](https://github.com/firefly-iii/firefly-iii/issues/5670) Better date validation for rules
- Various YAML updates to better reflect the API.
## 5.6.13 - 2022-01-29
### Fixed

View File

@@ -94,7 +94,7 @@
"guzzlehttp/guzzle": "^7.4",
"jc5/google2fa-laravel": "2.0.6",
"jc5/recovery": "^2",
"laravel/framework": "^8.80",
"laravel/framework": "^8.83",
"laravel/passport": "10.*",
"laravel/sanctum": "^2.14",
"laravel/ui": "^3.4",

1185
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -98,10 +98,10 @@ return [
'feature_flags' => [
'export' => true,
'telemetry' => false,
'webhooks' => true,
'webhooks' => false,
'handle_debts' => true,
],
'version' => '5.6.13',
'version' => '5.6.16',
'api_version' => '1.5.5',
'db_version' => 18,
@@ -222,6 +222,7 @@ return [
TransactionJournal::class,
Recurrence::class,
],
'valid_view_ranges' => ['1D', '1W', '1M', '3M', '6M', '1Y',],
'allowedMimes' => [
/* plain files */
'text/plain',
@@ -289,7 +290,7 @@ return [
'credit_card_types' => ['monthlyFull'],
// "period must be in this list" values
'bill_periods' => ['weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
'bill_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
'interest_periods' => ['weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
// settings to translate X to Y

70
config/sanctum.php Normal file
View File

@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
return [
/*
|--------------------------------------------------------------------------
| Stateful Domains
|--------------------------------------------------------------------------
|
| Requests from the following domains / hosts will receive stateful API
| authentication cookies. Typically, these should include your local
| and production domains which access your API via a frontend SPA.
|
*/
'stateful' => explode(
',', env(
'SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
env('APP_URL') ? ',' . parse_url(env('APP_URL'), PHP_URL_HOST) : ''
)
)
),
/*
|--------------------------------------------------------------------------
| Sanctum Guards
|--------------------------------------------------------------------------
|
| This array contains the authentication guards that will be checked when
| Sanctum is trying to authenticate a request. If none of these guards
| are able to authenticate the request, Sanctum will use the bearer
| token that's present on an incoming request for authentication.
|
*/
'guard' => ['web'],
/*
|--------------------------------------------------------------------------
| Expiration Minutes
|--------------------------------------------------------------------------
|
| This value controls the number of minutes until an issued token will be
| considered expired. If this value is null, personal access tokens do
| not expire. This won't tweak the lifetime of first-party sessions.
|
*/
'expiration' => null,
/*
|--------------------------------------------------------------------------
| Sanctum Middleware
|--------------------------------------------------------------------------
|
| When authenticating your first-party SPA with Sanctum you may need to
| customize some of the middleware Sanctum uses while processing the
| request. You may change the middleware listed below as required.
|
*/
'middleware' => [
'verify_csrf_token' => \FireflyIII\Http\Middleware\VerifyCsrfToken::class,
'encrypt_cookies' => \FireflyIII\Http\Middleware\EncryptCookies::class,
],
];

View File

@@ -35,16 +35,16 @@ class CreateSupportTables extends Migration
*/
public function down(): void
{
Schema::drop('account_types');
Schema::drop('transaction_currencies');
Schema::drop('transaction_types');
Schema::drop('jobs');
Schema::drop('password_resets');
Schema::drop('permission_role');
Schema::drop('permissions');
Schema::drop('roles');
Schema::drop('sessions');
Schema::drop('configuration');
Schema::dropIfExists('account_types');
Schema::dropIfExists('transaction_currencies');
Schema::dropIfExists('transaction_types');
Schema::dropIfExists('jobs');
Schema::dropIfExists('password_resets');
Schema::dropIfExists('permission_role');
Schema::dropIfExists('permissions');
Schema::dropIfExists('roles');
Schema::dropIfExists('sessions');
Schema::dropIfExists('configuration');
}
/**

View File

@@ -35,7 +35,7 @@ class CreateUsersTable extends Migration
*/
public function down(): void
{
Schema::drop('users');
Schema::dropIfExists('users');
}
/**

View File

@@ -35,34 +35,34 @@ class CreateMainTables extends Migration
*/
public function down(): void
{
Schema::drop('account_meta');
Schema::drop('piggy_bank_repetitions');
Schema::drop('attachments');
Schema::drop('limit_repetitions');
Schema::drop('budget_limits');
Schema::drop('export_jobs');
Schema::drop('import_jobs');
Schema::drop('preferences');
Schema::drop('role_user');
Schema::drop('rule_actions');
Schema::drop('rule_triggers');
Schema::drop('rules');
Schema::drop('rule_groups');
Schema::drop('category_transaction');
Schema::drop('budget_transaction');
Schema::drop('transactions');
Schema::drop('piggy_bank_events');
Schema::drop('piggy_banks');
Schema::drop('accounts');
Schema::drop('category_transaction_journal');
Schema::drop('budget_transaction_journal');
Schema::drop('categories');
Schema::drop('budgets');
Schema::drop('tag_transaction_journal');
Schema::drop('tags');
Schema::drop('journal_meta');
Schema::drop('transaction_journals');
Schema::drop('bills');
Schema::dropIfExists('account_meta');
Schema::dropIfExists('piggy_bank_repetitions');
Schema::dropIfExists('attachments');
Schema::dropIfExists('limit_repetitions');
Schema::dropIfExists('budget_limits');
Schema::dropIfExists('export_jobs');
Schema::dropIfExists('import_jobs');
Schema::dropIfExists('preferences');
Schema::dropIfExists('role_user');
Schema::dropIfExists('rule_actions');
Schema::dropIfExists('rule_triggers');
Schema::dropIfExists('rules');
Schema::dropIfExists('rule_groups');
Schema::dropIfExists('category_transaction');
Schema::dropIfExists('budget_transaction');
Schema::dropIfExists('transactions');
Schema::dropIfExists('piggy_bank_events');
Schema::dropIfExists('piggy_banks');
Schema::dropIfExists('accounts');
Schema::dropIfExists('category_transaction_journal');
Schema::dropIfExists('budget_transaction_journal');
Schema::dropIfExists('categories');
Schema::dropIfExists('budgets');
Schema::dropIfExists('tag_transaction_journal');
Schema::dropIfExists('tags');
Schema::dropIfExists('journal_meta');
Schema::dropIfExists('transaction_journals');
Schema::dropIfExists('bills');
}
/**

View File

@@ -36,7 +36,7 @@ class ChangesForV440 extends Migration
public function down(): void
{
if (Schema::hasTable('currency_exchange_rates')) {
Schema::drop('currency_exchange_rates');
Schema::dropIfExists('currency_exchange_rates');
}
Schema::table(

View File

@@ -38,7 +38,7 @@ class CreateOauthAuthCodesTable extends Migration
*/
public function down(): void
{
Schema::drop('oauth_auth_codes');
Schema::dropIfExists('oauth_auth_codes');
}
/**

View File

@@ -38,7 +38,7 @@ class CreateOauthAccessTokensTable extends Migration
*/
public function down(): void
{
Schema::drop('oauth_access_tokens');
Schema::dropIfExists('oauth_access_tokens');
}
/**

View File

@@ -38,7 +38,7 @@ class CreateOauthRefreshTokensTable extends Migration
*/
public function down(): void
{
Schema::drop('oauth_refresh_tokens');
Schema::dropIfExists('oauth_refresh_tokens');
}
/**

View File

@@ -38,7 +38,7 @@ class CreateOauthClientsTable extends Migration
*/
public function down(): void
{
Schema::drop('oauth_clients');
Schema::dropIfExists('oauth_clients');
}
/**

View File

@@ -38,7 +38,7 @@ class CreateOauthPersonalAccessClientsTable extends Migration
*/
public function down(): void
{
Schema::drop('oauth_personal_access_clients');
Schema::dropIfExists('oauth_personal_access_clients');
}
/**

View File

@@ -39,7 +39,7 @@ class ChangesForV550 extends Migration
public function down()
{
// recreate jobs table.
Schema::drop('jobs');
Schema::dropIfExists('jobs');
Schema::create(
'jobs',
static function (Blueprint $table) {
@@ -88,7 +88,7 @@ class ChangesForV550 extends Migration
public function up()
{
// drop and recreate jobs table.
Schema::drop('jobs');
Schema::dropIfExists('jobs');
// this is the NEW table
Schema::create(
'jobs', function (Blueprint $table) {

View File

@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Class CreateLocalPersonalAccessTokensTable
*/
class CreateLocalPersonalAccessTokensTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (!Schema::hasTable('personal_access_tokens')) {
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->bigIncrements('id');
$table->morphs('tokenable');
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamps();
});
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('personal_access_tokens');
}
}

9
frontend/.editorconfig Normal file
View File

@@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

9
frontend/.eslintignore Normal file
View File

@@ -0,0 +1,9 @@
/dist
/src-bex/www
/src-capacitor
/src-cordova
/.quasar
/node_modules
.eslintrc.js
babel.config.js
/src-ssr

88
frontend/.eslintrc.js vendored Normal file
View File

@@ -0,0 +1,88 @@
const { resolve } = require('path');
module.exports = {
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
// https://eslint.vuejs.org/user-guide/#how-to-use-custom-parser
// Must use parserOptions instead of "parser" to allow vue-eslint-parser to keep working
// `parser: 'vue-eslint-parser'` is already included with any 'plugin:vue/**' config and should be omitted
parserOptions: {
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser#configuration
// https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#eslint
// Needed to make the parser take into account 'vue' files
extraFileExtensions: ['.vue'],
parser: '@typescript-eslint/parser',
project: resolve(__dirname, './tsconfig.json'),
tsconfigRootDir: __dirname,
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module' // Allows for the use of imports
},
env: {
browser: true
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
// 'eslint:recommended',
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// consider disabling this class of rules if linting takes too long
'plugin:@typescript-eslint/recommended-requiring-type-checking',
// Uncomment any of the lines below to choose desired strictness,
// but leave only one uncommented!
// See https://eslint.vuejs.org/rules/#available-rules
'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'prettier'
],
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-file
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
globals: {
ga: 'readonly', // Google Analytics
cordova: 'readonly',
__statics: 'readonly',
__QUASAR_SSR__: 'readonly',
__QUASAR_SSR_SERVER__: 'readonly',
__QUASAR_SSR_CLIENT__: 'readonly',
__QUASAR_SSR_PWA__: 'readonly',
process: 'readonly',
Capacitor: 'readonly',
chrome: 'readonly'
},
// add your custom rules here
rules: {
'prefer-promise-reject-errors': 'off',
// TypeScript
quotes: ['warn', 'single', { avoidEscape: true }],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
// allow debugger during development only
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
}
}

33
frontend/.gitignore vendored Normal file
View File

@@ -0,0 +1,33 @@
.DS_Store
.thumbs.db
node_modules
# Quasar core related directories
.quasar
/dist
# Cordova related directories and files
/src-cordova/node_modules
/src-cordova/platforms
/src-cordova/plugins
/src-cordova/www
# Capacitor related directories and files
/src-capacitor/www
/src-capacitor/node_modules
# BEX related directories and files
/src-bex/www
/src-bex/js/core
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
*.suo
*.ntvs*
*.njsproj
*.sln

8
frontend/.postcssrc.js vendored Normal file
View File

@@ -0,0 +1,8 @@
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
plugins: [
// to edit target browsers: use "browserslist" field in package.json
require('autoprefixer')
]
}

4
frontend/.prettierrc Normal file
View File

@@ -0,0 +1,4 @@
{
"singleQuote": true,
"semi": true
}

15
frontend/babel.config.js vendored Normal file
View File

@@ -0,0 +1,15 @@
/* eslint-env node */
module.exports = api => {
return {
presets: [
[
'@quasar/babel-preset-app',
api.caller(caller => caller && caller.target === 'node')
? { targets: { node: 'current' } }
: {}
]
]
}
}

53
frontend/package.json Normal file
View File

@@ -0,0 +1,53 @@
{
"name": "firefly-iii",
"version": "0.0.1",
"description": "Personal finances manager",
"productName": "Firefly III",
"author": "James Cole <james@firefly-iii.org>",
"private": true,
"scripts": {
"lint": "eslint --ext .js,.ts,.vue ./",
"test": "echo \"No test specified\" && exit 0"
},
"dependencies": {
"@popperjs/core": "^2.11.2",
"@quasar/extras": "^1.12.5",
"apexcharts": "^3.32.1",
"axios": "^0.21.1",
"axios-cache-adapter": "^2.7.3",
"core-js": "^3.6.5",
"date-fns": "^2.28.0",
"quasar": "^2.5.5",
"vue": "3",
"vue-i18n": "^9.0.0",
"vue-router": "^4.0.0",
"vue3-apexcharts": "^1.4.1",
"vuex": "^4.0.1"
},
"devDependencies": {
"@babel/eslint-parser": "^7.13.14",
"@quasar/app": "^3.3.3",
"@types/node": "^12.20.21",
"@typescript-eslint/eslint-plugin": "^4.16.1",
"@typescript-eslint/parser": "^4.16.1",
"eslint": "^7.14.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-vue": "^7.0.0"
},
"browserslist": [
"last 10 Chrome versions",
"last 10 Firefox versions",
"last 4 Edge versions",
"last 7 Safari versions",
"last 8 Android versions",
"last 8 ChromeAndroid versions",
"last 8 FirefoxAndroid versions",
"last 10 iOS versions",
"last 5 Opera versions"
],
"engines": {
"node": ">= 12.22.1",
"npm": ">= 6.13.4",
"yarn": ">= 1.21.1"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,88 @@
{
"name": "Firefly III",
"short_name": "Firefly III",
"start_url": "/",
"icons": [
{
"src": "/maskable72.png",
"sizes": "72x72",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable76.png",
"sizes": "76x76",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable96.png",
"sizes": "96x96",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable120.png",
"sizes": "120x120",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable128.png",
"sizes": "128x128",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable144.png",
"sizes": "144x144",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable152.png",
"sizes": "152x152",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable180.png",
"sizes": "180x180",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png",
"scope": "any"
},
{
"src": "/maskable192.png",
"sizes": "192x192",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable384.png",
"sizes": "384x384",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png",
"scope": "any"
},
{
"src": "/maskable512.png",
"sizes": "512x512",
"type": "image/png",
"scope": "maskable"
}
],
"theme_color": "#1e6581",
"background_color": "#1e6581",
"display": "standalone"
}

View File

@@ -0,0 +1,16 @@
<svg height="377.95276" width="377.95276" xmlns="http://www.w3.org/2000/svg">
<path d="m0 0h377.95276v377.95276h-377.95276z" fill="#cd5029" stroke-width="1.96129"/>
<g transform="matrix(.77452773 0 0 .77452773 21.636074 21.374655)">
<path
d="m140.49013 78.646381 2.249 53.017999s-40.103 29.566-45.538 68l-16.001 1.231s-11.539 2.564-11.539 14.103v37.18s3.846 11.538 12.82 11.538l16.487-.319s8 30.5 36.5 50.5v25.5s-2 8.5 15.5 11 40.75 2.25 44.5-1.5 3.75-4.5 3.75-9c0 0 21.25 5 60.25 0v5s3.5 7 29 7 33-3 37.5-12v-25s37.009-36.264 35.75-91.75c-1.083-47.75-15.901-64.299-35.806-82.96-22.67-21.254-69.944-31.165-117.944-25.353.001-.001-24.341-43.937999-67.478-36.187999z"
fill="#fff"/>
<circle cx="135.46912" cy="214.39638" fill="#cd5029" r="9.5"/>
<path
d="m360.08113 190.51238s-18.218-8.742-40.662 3.996c0 0-26.711-8.987-40.99 2.593-14.828 12.025-16.299 26.115-15.525 42.785 0 0 12.837-43.915 45.252-32.571 0 0-22.947 40.43 12.761 47.508 0 0 8.436-.05 15.401-4.256 6.644-4.011 11.842-11.433 9.711-24.814 0 0-4.348-13.336-15.569-21.42 0 0 11.042-7.806 31.988-2.209z"
fill="#cd5029"/>
<path d="m320.19013 213.01938s-16.689 31.461 5.607 29.767c0 0 11.838-5.656 4.887-17.127-7.147-11.796-10.494-12.64-10.494-12.64z" fill="#fff"/>
</g>
<path
d="m188.97638 175.70052s4.01698 13.60604-3.69586 21.52748c-7.713 7.92145-6.8792 16.6767-3.75227 20.84588 3.12692 4.16917 2.91831 7.29593.41674 9.58905-2.50141 2.29312-4.58608 3.96073-6.04523.20846-1.45916-3.75228-3.12676-3.75228-3.75228-5.62834-.62552-1.87605-1.87622-5.21142-1.87622-5.21142s-3.96072 6.25384-6.46229 10.00611c-2.50157 3.75228-2.50141 9.58922-.83381 12.71598 1.66761 3.12676 1.04226 6.87903-.20845 12.09046-1.2507 5.21143.4169 13.13288 6.25369 16.2598 5.83678 3.12692 12.92459 5.62833 16.05135 8.5468s10.42301 5.62833 19.80362 3.54382c9.3806-2.0845 21.26294-11.67355 23.34744-18.13585 0 0 5.41988-6.04523 4.37763-13.96668s-4.79469-7.71316-6.4623-13.75839c-1.6676-6.04523 3.60854-4.55469-.8338-14.93382 0 0-1.98012-4.94005-9.50352-8.49899-4.83404-2.28661-1.54469-12.63061-10.09149-23.05347s-16.73295-12.14688-16.73295-12.14688z"
fill="#ffa284" stroke-width=".162598"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.14, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1782 3997 c-8 -9 -7 -92 0 -280 l11 -268 -54 -46 c-200 -171 -361
-405 -407 -594 l-18 -74 -95 -10 c-101 -12 -121 -19 -159 -60 -25 -26 -25 -27
-28 -252 -3 -250 -1 -264 55 -313 33 -29 36 -30 139 -30 l105 0 11 -32 c53
-152 188 -347 308 -445 l70 -57 0 -152 0 -152 30 -26 c17 -14 49 -30 72 -36
101 -28 350 -39 449 -20 64 12 109 50 109 92 0 15 5 28 11 28 5 0 7 -5 3 -12
-4 -6 -3 -8 3 -5 5 4 66 2 134 -2 115 -8 430 2 472 15 13 4 17 -1 17 -24 0
-49 47 -75 165 -92 146 -20 363 -5 440 31 73 35 85 64 85 214 l0 128 54 66
c153 189 262 423 302 651 19 114 17 451 -3 471 -17 17 -188 17 -235 1 -22 -8
-38 -20 -38 -29 0 -8 18 -36 41 -61 64 -73 99 -150 99 -219 0 -139 -102 -239
-250 -246 -65 -3 -156 44 -195 101 -26 37 -30 55 -33 121 -3 66 1 91 28 171
30 90 30 95 13 108 -30 23 -152 11 -206 -21 -61 -36 -143 -128 -180 -204 -36
-73 -57 -71 -57 6 0 108 53 225 137 301 89 82 188 103 356 75 l105 -17 64 25
c82 33 166 46 251 40 64 -6 67 -5 67 16 0 33 -56 162 -99 228 -91 140 -256
296 -389 366 -225 118 -538 177 -872 163 -85 -3 -164 -9 -175 -11 -15 -5 -26
4 -48 38 -98 157 -294 302 -455 336 -73 15 -197 14 -210 -2z m869 -1298 c104
-66 196 -190 219 -296 26 -116 29 -121 75 -149 99 -57 149 -154 125 -238 -15
-53 -7 -83 40 -151 60 -87 56 -173 -12 -293 -54 -94 -127 -160 -236 -214 -76
-38 -89 -42 -165 -42 -91 -1 -125 9 -202 62 -27 19 -91 53 -142 77 -140 65
-169 123 -144 289 11 70 11 87 -3 125 -30 83 -22 123 52 239 l47 74 20 -43
c31 -67 74 -129 90 -129 7 0 26 10 40 23 35 30 35 77 1 137 -19 33 -26 59 -26
98 0 65 15 101 72 175 57 71 72 124 66 222 -5 73 -4 75 16 69 12 -3 42 -19 67
-35z m-869 -48 c27 -24 33 -36 33 -71 0 -35 -6 -47 -33 -71 -42 -37 -89 -39
-130 -4 -35 29 -47 70 -33 107 27 72 105 91 163 39z m1279 -318 c-12 -20 -14
-14 -5 12 4 9 9 14 11 11 3 -2 0 -13 -6 -23z"/>
<path d="M3629 2536 c-25 -57 -41 -143 -33 -179 23 -106 184 -80 184 30 0 55
-86 193 -121 193 -6 0 -19 -20 -30 -44z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

301
frontend/quasar.conf.js vendored Normal file
View File

@@ -0,0 +1,301 @@
/*
* This file runs in a Node context (it's NOT transpiled by Babel), so use only
* the ES6 features that are supported by your Node version. https://node.green/
*/
// Configuration for your app
// https://quasar.dev/quasar-cli/quasar-conf-js
/* eslint-env node */
/* eslint-disable @typescript-eslint/no-var-requires */
const { configure } = require('quasar/wrappers');
module.exports = configure(function (ctx) {
return {
// https://quasar.dev/quasar-cli/supporting-ts
supportTS: false,
// https://quasar.dev/quasar-cli/prefetch-feature
preFetch: true,
// app boot file (/src/boot)
// --> boot files are part of "main.js"
// https://quasar.dev/quasar-cli/boot-files
boot: [
'i18n',
'axios',
],
// https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css
css: [
'app.scss'
],
// https://github.com/quasarframework/quasar/tree/dev/extras
extras: [
// 'ionicons-v4',
// 'mdi-v5',
'fontawesome-v5',
// 'eva-icons',
// 'themify',
// 'line-awesome',
// 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
// 'roboto-font', // optional, you are not bound to it
// 'material-icons', // optional, you are not bound to it
],
// Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build
build: {
vueRouterMode: 'hash', // available values: 'hash', 'history'
// transpile: false,
publicPath: '/v3/',
distDir: '../public/v3',
// Add dependencies for transpiling with Babel (Array of string/regex)
// (from node_modules, which are by default not transpiled).
// Applies only if "transpile" is set to true.
// transpileDependencies: [],
// rtl: true, // https://quasar.dev/options/rtl-support
// preloadChunks: true,
// showProgress: false,
// gzip: true,
// analyze: true,
// Options below are automatically set depending on the env, set them if you want to override
// extractCSS: false,
// https://quasar.dev/quasar-cli/handling-webpack
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
chainWebpack (/* chain */) {
//
},
},
// Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-devServer
devServer: {
server: {
type: 'https'
},
port: 8080,
host: 'firefly-dev.sd.home',
open: false, // opens browser window automatically
proxy: [
{
context: ['/sanctum', '/api'],
target: 'https://firefly.sd.home', // Laravel Homestead end-point
// avoid problems with session and XSRF cookies
// When using capacitor, use the IP of the dev server streaming the app
// For SPA and PWA use localhost, given that the app is streamed on that host
// xxx address is your machine current IP address
cookieDomainRewrite:
ctx.modeName === 'capacitor' ? '10.0.0.1' : '.sd.home',
changeOrigin: true,
}
]
},
// https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-framework
framework: {
config: {
dark: 'auto'
},
lang: 'en-US', // Quasar language pack
iconSet: 'fontawesome-v5',
// For special cases outside of where the auto-import strategy can have an impact
// (like functional components as one of the examples),
// you can manually specify Quasar components/directives to be available everywhere:
//
// components: [],
// directives: [],
// Quasar plugins
plugins: [
'Dialog',
'LocalStorage',
]
},
// animations: 'all', // --- includes all animations
// https://quasar.dev/options/animations
animations: [],
// https://quasar.dev/quasar-cli/developing-ssr/configuring-ssr
ssr: {
pwa: false,
// manualStoreHydration: true,
// manualPostHydrationTrigger: true,
prodPort: 3000, // The default port that the production server should use
// (gets superseded if process.env.PORT is specified at runtime)
maxAge: 1000 * 60 * 60 * 24 * 30,
// Tell browser when a file from the server should expire from cache (in ms)
chainWebpackWebserver (/* chain */) {
//
},
middlewares: [
ctx.prod ? 'compression' : '',
'render' // keep this as last one
]
},
// https://quasar.dev/quasar-cli/developing-pwa/configuring-pwa
pwa: {
workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest'
workboxOptions: {}, // only for GenerateSW
// for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts])
// if using workbox in InjectManifest mode
chainWebpackCustomSW (/* chain */) {
//
},
manifest: {
name: 'Firefly III',
short_name: 'Firefly III',
description: 'Personal Finances Manager',
start_url: '/',
display: 'standalone',
orientation: 'portrait',
theme_color: "#1e6581",
background_color: "#1e6581",
icons: [
{
"src": "/maskable72.png",
"sizes": "72x72",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable76.png",
"sizes": "76x76",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable96.png",
"sizes": "96x96",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable120.png",
"sizes": "120x120",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable128.png",
"sizes": "128x128",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable144.png",
"sizes": "144x144",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable152.png",
"sizes": "152x152",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable180.png",
"sizes": "180x180",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png",
"scope": "any"
},
{
"src": "/maskable192.png",
"sizes": "192x192",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/maskable384.png",
"sizes": "384x384",
"type": "image/png",
"scope": "maskable"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png",
"scope": "any"
},
{
"src": "/maskable512.png",
"sizes": "512x512",
"type": "image/png",
"scope": "maskable"
}
]
}
},
// Full list of options: https://quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova
cordova: {
// noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
},
// Full list of options: https://quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor
capacitor: {
hideSplashscreen: true
},
// Full list of options: https://quasar.dev/quasar-cli/developing-electron-apps/configuring-electron
electron: {
bundler: 'packager', // 'packager' or 'builder'
packager: {
// https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
// OS X / Mac App Store
// appBundleId: '',
// appCategoryType: '',
// osxSign: '',
// protocol: 'myapp://path',
// Windows only
// win32metadata: { ... }
},
builder: {
// https://www.electron.build/configuration/configuration
appId: 'firefly-iii'
},
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
chainWebpack (/* chain */) {
// do something with the Electron main process Webpack cfg
// extendWebpackMain also available besides this chainWebpackMain
},
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
chainWebpackPreload (/* chain */) {
// do something with the Electron main process Webpack cfg
// extendWebpackPreload also available besides this chainWebpackPreload
},
}
}
});

View File

@@ -0,0 +1 @@
{}

62
frontend/src/App.vue Normal file
View File

@@ -0,0 +1,62 @@
<template>
<router-view/>
</template>
<script>
import {defineComponent} from 'vue';
import Preferences from "./api/preferences";
import Currencies from "./api/currencies";
import {setDatesFromViewRange} from "./store/fireflyiii/actions";
export default defineComponent(
{
name: 'App',
preFetch({store}) {
store.dispatch('fireflyiii/refreshCacheKey');
const getViewRange = function() {
let pref = new Preferences();
return pref.getByName('viewRange').then(data => {
const viewRange = data.data.data.attributes.data;
store.commit('fireflyiii/updateViewRange', viewRange);
store.dispatch('fireflyiii/setDatesFromViewRange');
}).catch((err) => {
console.error('Could not load view range.')
console.log(err);
});
};
const getListPageSize = function() {
let pref = new Preferences();
return pref.getByName('listPageSize').then(data => {
const listPageSize = data.data.data.attributes.data;
store.commit('fireflyiii/updateListPageSize', listPageSize);
}).catch((err) => {
console.error('Could not load listPageSize.')
console.log(err);
});
};
const getDefaultCurrency = function() {
let curr = new Currencies();
return curr.default().then(data => {
let currencyId = parseInt(data.data.data.id);
let currencyCode = data.data.data.attributes.code;
store.commit('fireflyiii/setCurrencyId', currencyId);
store.commit('fireflyiii/setCurrencyCode', currencyCode);
}).catch((err) => {
console.error('Could not load preferences.');
console.log(err);
});
};
getDefaultCurrency().then(() => {
getViewRange();
getListPageSize();
});
}
})
</script>

28
frontend/src/api/accounts/destroy.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Destroy {
destroy(identifier) {
let url = '/api/v1/accounts/' + identifier;
return api.delete(url);
}
}

35
frontend/src/api/accounts/get.js vendored Normal file
View File

@@ -0,0 +1,35 @@
/*
* list.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Get {
get(identifier, date) {
let url = '/api/v1/accounts/' + identifier;
if(!date) {
return api.get(url);
}
return api.get(url, {params: {date: date}});
}
transactions(identifier, page, cacheKey) {
let url = '/api/v1/accounts/' + identifier + '/transactions';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

28
frontend/src/api/accounts/list.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* list.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class List {
list(type, page, cacheKey) {
let url = '/api/v1/accounts';
return api.get(url, {params: {page: page, cache: cacheKey, type: type}});
}
}

28
frontend/src/api/accounts/post.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Post {
post(submission) {
let url = '/api/v1/accounts';
return api.post(url, submission);
}
}

28
frontend/src/api/accounts/put.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Put {
post(identifier, submission) {
let url = '/api/v1/accounts/' + identifier;
return api.put(url, submission);
}
}

27
frontend/src/api/authenticate/index.js vendored Normal file
View File

@@ -0,0 +1,27 @@
/*
* basic.js
* Copyright (c) 2021 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/>.
*/
import {api} from "boot/axios";
export default class Authenticate {
async authenticate() {
return await api.get('/sanctum/csrf-cookie');
}
}

28
frontend/src/api/budgets/destroy.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Destroy {
destroy(identifier) {
let url = 'api/v1/budgets/' + identifier;
return api.delete(url);
}
}

38
frontend/src/api/budgets/get.js vendored Normal file
View File

@@ -0,0 +1,38 @@
/*
* list.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Get {
get(identifier) {
let url = '/api/v1/budgets/' + identifier;
return api.get(url);
}
transactions(identifier, page, cacheKey) {
let url = '/api/v1/budgets/' + identifier + '/transactions';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
transactionsWithoutBudget(page, cacheKey) {
let url = '/api/v1/budgets/transactions-without-budget';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

28
frontend/src/api/budgets/list.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* list.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class List {
list(page, cacheKey) {
let url = '/api/v1/budgets';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

28
frontend/src/api/budgets/post.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Post {
post(submission) {
let url = '/api/v1/budgets';
return api.post(url, submission);
}
}

28
frontend/src/api/budgets/put.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Put {
post(identifier, submission) {
let url = '/api/v1/budgets/' + identifier;
return api.put(url, submission);
}
}

28
frontend/src/api/categories/destroy.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Destroy {
destroy(identifier) {
let url = '/api/v1/categories/' + identifier;
return api.delete(url);
}
}

36
frontend/src/api/categories/get.js vendored Normal file
View File

@@ -0,0 +1,36 @@
/*
* list.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Get {
get(identifier) {
let url = '/api/v1/categories/' + identifier;
return api.get(url);
}
transactions(identifier, page, cacheKey) {
let url = '/api/v1/categories/' + identifier + '/transactions';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
transactionsWithoutCategory(page, cacheKey) {
let url = '/api/v1/categories/transactions-without-category';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

28
frontend/src/api/categories/list.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* list.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class List {
list(page, cacheKey) {
let url = '/api/v1/categories';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

28
frontend/src/api/categories/post.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Post {
post(submission) {
let url = '/api/v1/categories';
return api.post(url, submission);
}
}

28
frontend/src/api/categories/put.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Put {
post(identifier, submission) {
let url = '/api/v1/categories/' + identifier;
return api.put(url, submission);
}
}

View File

@@ -0,0 +1,30 @@
/*
* overview.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
import {format} from "date-fns";
export default class Overview {
overview(range, cacheKey) {
let startStr = format(range.start, 'y-MM-dd');
let endStr = format(range.end, 'y-MM-dd');
return api.get('/api/v1/chart/account/overview', {params: {start: startStr, end: endStr, cache: cacheKey}});
}
}

28
frontend/src/api/currencies/destroy.js vendored Normal file
View File

@@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Destroy {
destroy(identifier) {
let url = '/api/v1/currencies/' + identifier;
return api.delete(url);
}
}

32
frontend/src/api/currencies/get.js vendored Normal file
View File

@@ -0,0 +1,32 @@
/*
* list.js
* Copyright (c) 2022 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/>.
*/
import {api} from "boot/axios";
export default class Get {
get(identifier) {
let url = '/api/v1/currencies/' + identifier;
return api.get(url);
}
transactions(identifier, page, cacheKey) {
let url = '/api/v1/currencies/' + identifier + '/transactions';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

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