mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'develop' into develop
This commit is contained in:
commit
4846d102f2
@ -188,7 +188,7 @@ AUTHENTICATION_GUARD=web
|
|||||||
# Enter a custom URL here that will force a logout (your authentication provider can tell you).
|
# Enter a custom URL here that will force a logout (your authentication provider can tell you).
|
||||||
# Setting this variable only works when AUTHENTICATION_GUARD != web
|
# Setting this variable only works when AUTHENTICATION_GUARD != web
|
||||||
#
|
#
|
||||||
CUSTOM_LOGOUT_URI=
|
CUSTOM_LOGOUT_URL=
|
||||||
|
|
||||||
# LDAP connection configuration
|
# LDAP connection configuration
|
||||||
# OpenLDAP, FreeIPA or ActiveDirectory
|
# OpenLDAP, FreeIPA or ActiveDirectory
|
||||||
|
@ -189,7 +189,7 @@ AUTHENTICATION_GUARD=web
|
|||||||
# Enter a custom URL here that will force a logout (your authentication provider can tell you).
|
# Enter a custom URL here that will force a logout (your authentication provider can tell you).
|
||||||
# Setting this variable only works when AUTHENTICATION_GUARD != web
|
# Setting this variable only works when AUTHENTICATION_GUARD != web
|
||||||
#
|
#
|
||||||
CUSTOM_LOGOUT_URI=
|
CUSTOM_LOGOUT_URL=
|
||||||
|
|
||||||
# LDAP connection configuration
|
# LDAP connection configuration
|
||||||
# OpenLDAP, FreeIPA or ActiveDirectory
|
# OpenLDAP, FreeIPA or ActiveDirectory
|
||||||
|
129
.env.example
129
.env.example
@ -53,8 +53,7 @@ LOG_CHANNEL=stack
|
|||||||
APP_LOG_LEVEL=notice
|
APP_LOG_LEVEL=notice
|
||||||
|
|
||||||
# Audit log level.
|
# Audit log level.
|
||||||
# set to "emergency" if you dont want to store audit logs.
|
# Set this to "emergency" if you dont want to store audit logs, leave on info otherwise.
|
||||||
# leave on info otherwise.
|
|
||||||
AUDIT_LOG_LEVEL=info
|
AUDIT_LOG_LEVEL=info
|
||||||
|
|
||||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||||
@ -89,11 +88,11 @@ PGSQL_SSL_CERT=null
|
|||||||
PGSQL_SSL_KEY=null
|
PGSQL_SSL_KEY=null
|
||||||
PGSQL_SSL_CRL_FILE=null
|
PGSQL_SSL_CRL_FILE=null
|
||||||
|
|
||||||
# If you're looking for performance improvements, you could install memcached.
|
# If you're looking for performance improvements, you could install memcached or redis
|
||||||
CACHE_DRIVER=file
|
CACHE_DRIVER=file
|
||||||
SESSION_DRIVER=file
|
SESSION_DRIVER=file
|
||||||
|
|
||||||
# If you set either of these to 'redis', you might want to update these settings too
|
# If you set either of the options above to 'redis', you might want to update these settings too
|
||||||
# If you use Docker or similar, you can set REDIS_HOST_FILE, REDIS_PASSWORD_FILE or
|
# If you use Docker or similar, you can set REDIS_HOST_FILE, REDIS_PASSWORD_FILE or
|
||||||
# REDIS_PORT_FILE to set the value from a file instead of from an environment variable
|
# REDIS_PORT_FILE to set the value from a file instead of from an environment variable
|
||||||
|
|
||||||
@ -106,8 +105,8 @@ REDIS_PATH=
|
|||||||
# use only when using 'tcp' or 'http' for REDIS_SCHEME. Leave empty otherwise.
|
# use only when using 'tcp' or 'http' for REDIS_SCHEME. Leave empty otherwise.
|
||||||
REDIS_HOST=127.0.0.1
|
REDIS_HOST=127.0.0.1
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
|
|
||||||
REDIS_PASSWORD=null
|
REDIS_PASSWORD=null
|
||||||
|
|
||||||
# always use quotes and make sure redis db "0" and "1" exists. Otherwise change accordingly.
|
# always use quotes and make sure redis db "0" and "1" exists. Otherwise change accordingly.
|
||||||
REDIS_DB="0"
|
REDIS_DB="0"
|
||||||
REDIS_CACHE_DB="1"
|
REDIS_CACHE_DB="1"
|
||||||
@ -115,12 +114,13 @@ REDIS_CACHE_DB="1"
|
|||||||
# Cookie settings. Should not be necessary to change these.
|
# Cookie settings. Should not be necessary to change these.
|
||||||
# If you use Docker or similar, you can set COOKIE_DOMAIN_FILE to set
|
# If you use Docker or similar, you can set COOKIE_DOMAIN_FILE to set
|
||||||
# the value from a file instead of from an environment variable
|
# the value from a file instead of from an environment variable
|
||||||
|
# Setting samesite to "strict" may give you trouble logging in.
|
||||||
COOKIE_PATH="/"
|
COOKIE_PATH="/"
|
||||||
COOKIE_DOMAIN=
|
COOKIE_DOMAIN=
|
||||||
COOKIE_SECURE=false
|
COOKIE_SECURE=false
|
||||||
COOKIE_SAMESITE=lax
|
COOKIE_SAMESITE=lax
|
||||||
|
|
||||||
# If you want Firefly III to mail you, update these settings
|
# If you want Firefly III to email you, update these settings
|
||||||
# For instructions, see: https://docs.firefly-iii.org/advanced-installation/email
|
# For instructions, see: https://docs.firefly-iii.org/advanced-installation/email
|
||||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||||
MAIL_MAILER=log
|
MAIL_MAILER=log
|
||||||
@ -145,7 +145,7 @@ MAILGUN_ENDPOINT=api.mailgun.net
|
|||||||
MANDRILL_SECRET=
|
MANDRILL_SECRET=
|
||||||
SPARKPOST_SECRET=
|
SPARKPOST_SECRET=
|
||||||
|
|
||||||
# Firefly III can send you the following messages
|
# Firefly III can send you the following messages.
|
||||||
SEND_REGISTRATION_MAIL=true
|
SEND_REGISTRATION_MAIL=true
|
||||||
SEND_ERROR_MESSAGE=true
|
SEND_ERROR_MESSAGE=true
|
||||||
SEND_LOGIN_NEW_IP_WARNING=true
|
SEND_LOGIN_NEW_IP_WARNING=true
|
||||||
@ -153,16 +153,9 @@ SEND_LOGIN_NEW_IP_WARNING=true
|
|||||||
# These messages contain (sensitive) transaction information:
|
# These messages contain (sensitive) transaction information:
|
||||||
SEND_REPORT_JOURNALS=true
|
SEND_REPORT_JOURNALS=true
|
||||||
|
|
||||||
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
|
# Set this value to true if you want to set the location
|
||||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
|
||||||
# Take note: it is no longer necessary to set this value, and it will be removed in future versions.
|
|
||||||
MAPBOX_API_KEY=
|
|
||||||
|
|
||||||
#
|
|
||||||
# Instead of the mapbox API key, just set this value to true if you want to set the location
|
|
||||||
# of certain things, like transactions. Since this involves an external service, it's optional
|
# of certain things, like transactions. Since this involves an external service, it's optional
|
||||||
# and disabled by default.
|
# and disabled by default.
|
||||||
#
|
|
||||||
ENABLE_EXTERNAL_MAP=false
|
ENABLE_EXTERNAL_MAP=false
|
||||||
|
|
||||||
# The map will default to this location:
|
# The map will default to this location:
|
||||||
@ -170,100 +163,47 @@ MAP_DEFAULT_LAT=51.983333
|
|||||||
MAP_DEFAULT_LONG=5.916667
|
MAP_DEFAULT_LONG=5.916667
|
||||||
MAP_DEFAULT_ZOOM=6
|
MAP_DEFAULT_ZOOM=6
|
||||||
|
|
||||||
# Firefly III has two options for user authentication. "eloquent" is the default,
|
|
||||||
# and "ldap" for LDAP servers.
|
|
||||||
# For full instructions on these settings please visit:
|
|
||||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
|
||||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
|
||||||
#
|
#
|
||||||
# If you enable 'ldap' AND you run Docker, the Docker image will contact packagist.org
|
# Firefly III authentication settings
|
||||||
# This is necessary to download the required packages.
|
|
||||||
#
|
#
|
||||||
LOGIN_PROVIDER=eloquent
|
|
||||||
|
|
||||||
# It's also possible to change the way users are authenticated. You could use Authelia for example.
|
|
||||||
# Authentication via the REMOTE_USER header is supported. Change the value below to "remote_user_guard".
|
|
||||||
#
|
#
|
||||||
# This will also allow Windows SSO.
|
# Firefly III supports a few authentication methods:
|
||||||
#
|
# - 'web' (default, uses built in DB)
|
||||||
# If you do this please read the documentation for instructions and warnings:
|
# - 'ldap'
|
||||||
|
# - 'remote_user_guard' for Authelia etc
|
||||||
|
# Read more about these settings in the documentation.
|
||||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
# https://docs.firefly-iii.org/advanced-installation/authentication
|
||||||
|
|
||||||
|
#
|
||||||
|
# Set to 'ldap' to enable LDAP
|
||||||
#
|
#
|
||||||
# This function is available in Firefly III v5.3.0 and higher.
|
|
||||||
AUTHENTICATION_GUARD=web
|
AUTHENTICATION_GUARD=web
|
||||||
|
|
||||||
# If the guard is changed, Firefly III uses the 'REMOTE_USER' header as per RFC 3875.
|
|
||||||
# You can also use another header, like AUTH_USER when using Windows SSO.
|
|
||||||
# Some systems use X-Auth headers. In that case, use HTTP_X_AUTH_USERNAME or HTTP_X_AUTH_EMAIL
|
|
||||||
# Depending on your system, REMOTE_USER may need to be changed to HTTP_REMOTE_USER
|
|
||||||
#
|
#
|
||||||
# If this header is 'unexpectedly empty', check out the documentation.
|
# LDAP connection settings:
|
||||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
|
||||||
#
|
#
|
||||||
AUTHENTICATION_GUARD_HEADER=REMOTE_USER
|
LDAP_HOST=ldap.yourserver.com
|
||||||
|
LDAP_USERNAME="uid=X,ou=,o=,dc=something,dc=com"
|
||||||
|
LDAP_PASSWORD=super_secret
|
||||||
|
LDAP_PORT=389
|
||||||
|
LDAP_BASE_DN="o=something,dc=site,dc=com"
|
||||||
|
LDAP_TIMEOUT=5
|
||||||
|
LDAP_SSL=false
|
||||||
|
LDAP_TLS=false
|
||||||
|
LDAP_AUTH_FIELD=uid
|
||||||
|
|
||||||
#
|
#
|
||||||
# Firefly III uses email addresses as user identifiers. When you're using an external authentication guard
|
# Remote user guard settings
|
||||||
# that doesn't do this, Firefly III is incapable of emailing you. Messages sent to "Bill Gates" always fail.
|
|
||||||
#
|
|
||||||
# However, if you set this value, Firefly III will store the value from this header as the user's backup
|
|
||||||
# email address and use it to communicate. So user "Bill Gates" could still have
|
|
||||||
# the email address "bill@microsoft.com".
|
|
||||||
#
|
|
||||||
# Example value: AUTHENTICATION_GUARD_EMAIL=HTTP_X_AUTH_EMAIL
|
|
||||||
#
|
#
|
||||||
|
AUTHENTICATION_GUARD_HEADER=REMOTE_USER
|
||||||
AUTHENTICATION_GUARD_EMAIL=
|
AUTHENTICATION_GUARD_EMAIL=
|
||||||
|
|
||||||
|
|
||||||
# It's impossible to log out users who's authentication is handled by an external system.
|
|
||||||
# Enter a custom URL here that will force a logout (your authentication provider can tell you).
|
|
||||||
# Setting this variable only works when AUTHENTICATION_GUARD != web
|
|
||||||
#
|
#
|
||||||
CUSTOM_LOGOUT_URI=
|
# Extra authentication settings
|
||||||
|
#
|
||||||
# LDAP connection configuration
|
CUSTOM_LOGOUT_URL=
|
||||||
# OpenLDAP, FreeIPA or ActiveDirectory
|
|
||||||
# # If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
|
||||||
ADLDAP_CONNECTION_SCHEME=OpenLDAP
|
|
||||||
ADLDAP_AUTO_CONNECT=true
|
|
||||||
|
|
||||||
# LDAP connection settings
|
|
||||||
# You can set the following variables from a file by appending them with _FILE:
|
|
||||||
# ADLDAP_CONTROLLERS, ADLDAP_PORT, ADLDAP_BASEDN
|
|
||||||
ADLDAP_CONTROLLERS=
|
|
||||||
ADLDAP_PORT=389
|
|
||||||
ADLDAP_TIMEOUT=5
|
|
||||||
ADLDAP_BASEDN=""
|
|
||||||
ADLDAP_FOLLOW_REFFERALS=false
|
|
||||||
|
|
||||||
# SSL/TLS settings
|
|
||||||
ADLDAP_USE_SSL=false
|
|
||||||
ADLDAP_USE_TLS=false
|
|
||||||
ADLDAP_SSL_CACERTDIR=
|
|
||||||
ADLDAP_SSL_CACERTFILE=
|
|
||||||
ADLDAP_SSL_CERTFILE=
|
|
||||||
ADLDAP_SSL_KEYFILE=
|
|
||||||
ADLDAP_SSL_CIPHER_SUITE=
|
|
||||||
ADLDAP_SSL_REQUIRE_CERT=
|
|
||||||
|
|
||||||
# You can set the following variables from a file by appending them with _FILE:
|
|
||||||
ADLDAP_ADMIN_USERNAME=
|
|
||||||
ADLDAP_ADMIN_PASSWORD=
|
|
||||||
|
|
||||||
# You can set the following variables from a file by appending them with _FILE:
|
|
||||||
ADLDAP_ACCOUNT_PREFIX=
|
|
||||||
ADLDAP_ACCOUNT_SUFFIX=
|
|
||||||
|
|
||||||
# LDAP authentication settings.
|
|
||||||
ADLDAP_PASSWORD_SYNC=false
|
|
||||||
ADLDAP_LOGIN_FALLBACK=false
|
|
||||||
|
|
||||||
ADLDAP_DISCOVER_FIELD=distinguishedname
|
|
||||||
ADLDAP_AUTH_FIELD=distinguishedname
|
|
||||||
|
|
||||||
# field to sync as local username.
|
|
||||||
# You can set the following variable from a file by appending it with _FILE:
|
|
||||||
ADLDAP_SYNC_FIELD=userprincipalname
|
|
||||||
|
|
||||||
# You can disable the X-Frame-Options header if it interferes with tools like
|
# You can disable the X-Frame-Options header if it interferes with tools like
|
||||||
# Organizr. This is at your own risk. Applications running in frames run the risk
|
# Organizr. This is at your own risk. Applications running in frames run the risk
|
||||||
@ -284,11 +224,6 @@ DISABLE_CSP_HEADER=false
|
|||||||
TRACKER_SITE_ID=
|
TRACKER_SITE_ID=
|
||||||
TRACKER_URL=
|
TRACKER_URL=
|
||||||
|
|
||||||
# Firefly III can collect telemetry on how you use Firefly III. This is opt-in.
|
|
||||||
# In order to allow this, change the following variable to true.
|
|
||||||
# To read more about this feature, go to this page: https://docs.firefly-iii.org/support/telemetry
|
|
||||||
SEND_TELEMETRY=false
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Firefly III supports webhooks. These are security sensitive and must be enabled manually first.
|
# Firefly III supports webhooks. These are security sensitive and must be enabled manually first.
|
||||||
#
|
#
|
||||||
|
4
.github/workflows/lock.yml
vendored
4
.github/workflows/lock.yml
vendored
@ -13,7 +13,3 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
github-token: ${{ github.token }}
|
github-token: ${{ github.token }}
|
||||||
issue-lock-inactive-days: '90'
|
issue-lock-inactive-days: '90'
|
||||||
issue-lock-comment: >
|
|
||||||
This issue has been automatically locked since there
|
|
||||||
has not been any recent activity after it was closed.
|
|
||||||
Please open a new issue for related bugs.
|
|
||||||
|
@ -87,7 +87,7 @@ class AccountController extends Controller
|
|||||||
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
|
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
|
||||||
$default = app('amount')->getDefaultCurrency();
|
$default = app('amount')->getDefaultCurrency();
|
||||||
|
|
||||||
if (0 === count($frontPage->data)) {
|
if (empty($frontPage->data)) {
|
||||||
$frontPage->data = $defaultSet;
|
$frontPage->data = $defaultSet;
|
||||||
$frontPage->save();
|
$frontPage->save();
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ use Illuminate\Http\JsonResponse;
|
|||||||
*
|
*
|
||||||
* Shows income information grouped or limited by date.
|
* Shows income information grouped or limited by date.
|
||||||
* Ie. all income grouped by account + currency.
|
* Ie. all income grouped by account + currency.
|
||||||
* TODO same code as Expense/AccountController.
|
* See reference nr. 75
|
||||||
*/
|
*/
|
||||||
class AccountController extends Controller
|
class AccountController extends Controller
|
||||||
{
|
{
|
||||||
@ -74,8 +74,8 @@ class AccountController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO same code as Expense/AccountController.
|
* See reference nr. 76
|
||||||
* TODO does not actually include the name of the expense account.
|
* See reference nr. 77
|
||||||
* @param GenericRequest $request
|
* @param GenericRequest $request
|
||||||
*
|
*
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
@ -103,7 +103,7 @@ class AccountController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO does not actually include the name of the expense account.
|
* See reference nr. 78
|
||||||
*
|
*
|
||||||
* @param GenericRequest $request
|
* @param GenericRequest $request
|
||||||
*
|
*
|
||||||
|
@ -35,7 +35,7 @@ use Illuminate\Support\Collection;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CategoryController
|
* Class CategoryController
|
||||||
* TODO same as opposing category controller
|
* See reference nr. 79
|
||||||
*/
|
*/
|
||||||
class CategoryController extends Controller
|
class CategoryController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -58,8 +58,8 @@ class AccountController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO same code as Expense/AccountController.
|
* See reference nr. 80
|
||||||
* TODO does not actually include the name of the expense account.
|
* See reference nr. 81
|
||||||
*
|
*
|
||||||
* @param GenericRequest $request
|
* @param GenericRequest $request
|
||||||
*
|
*
|
||||||
|
@ -39,7 +39,7 @@ class TagController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* TagController constructor.
|
* TagController constructor.
|
||||||
* TODO lots of copying and pasting here.
|
* See reference nr. 82
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
@ -103,7 +103,9 @@ class StoreController extends Controller
|
|||||||
throw new ValidationException($validator,0, $e);
|
throw new ValidationException($validator,0, $e);
|
||||||
}
|
}
|
||||||
app('preferences')->mark();
|
app('preferences')->mark();
|
||||||
event(new StoredTransactionGroup($transactionGroup, $data['apply_rules'] ?? true));
|
$applyRules = $data['apply_rules'] ?? true;
|
||||||
|
$fireWebhooks = $data['fire_webhooks'] ?? true;
|
||||||
|
event(new StoredTransactionGroup($transactionGroup, $applyRules, $fireWebhooks));
|
||||||
|
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
|
@ -80,7 +80,9 @@ class UpdateController extends Controller
|
|||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
app('preferences')->mark();
|
app('preferences')->mark();
|
||||||
event(new UpdatedTransactionGroup($transactionGroup, $data['apply_rules'] ?? true));
|
$applyRules = $data['apply_rules'] ?? true;
|
||||||
|
$fireWebhooks = $data['fire_webhooks'] ?? true;
|
||||||
|
event(new UpdatedTransactionGroup($transactionGroup, $applyRules, $fireWebhooks));
|
||||||
|
|
||||||
/** @var User $admin */
|
/** @var User $admin */
|
||||||
$admin = auth()->user();
|
$admin = auth()->user();
|
||||||
|
@ -72,7 +72,7 @@ class UpdateController extends Controller
|
|||||||
*
|
*
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
*
|
*
|
||||||
* TODO generates query exception when link exists.
|
* See reference nr. 84
|
||||||
*/
|
*/
|
||||||
public function update(UpdateRequest $request, TransactionJournalLink $journalLink): JsonResponse
|
public function update(UpdateRequest $request, TransactionJournalLink $journalLink): JsonResponse
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ class PreferencesController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(): JsonResponse
|
public function index(): JsonResponse
|
||||||
{
|
{
|
||||||
// TODO via repository.
|
// See reference nr. 83
|
||||||
$collection = auth()->user()->preferences()->get();
|
$collection = auth()->user()->preferences()->get();
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
|
@ -42,7 +42,7 @@ class MoveTransactionsRequest extends FormRequest
|
|||||||
* Configure the validator instance with special rules for after the basic validation rules.
|
* Configure the validator instance with special rules for after the basic validation rules.
|
||||||
*
|
*
|
||||||
* @param Validator $validator
|
* @param Validator $validator
|
||||||
* TODO duplicate code.
|
* See reference nr. 74
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
@ -76,7 +76,7 @@ class UpdateRequest extends FormRequest
|
|||||||
* Configure the validator instance with special rules for after the basic validation rules.
|
* Configure the validator instance with special rules for after the basic validation rules.
|
||||||
*
|
*
|
||||||
* @param Validator $validator
|
* @param Validator $validator
|
||||||
* TODO duplicate code.
|
* See reference nr. 72
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
@ -109,7 +109,7 @@ class UpdateRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
$return[] = $current;
|
$return[] = $current;
|
||||||
}
|
}
|
||||||
if (0 === count($return)) {
|
if (empty($return)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ class StoreRequest extends FormRequest
|
|||||||
$data = $validator->getData();
|
$data = $validator->getData();
|
||||||
$triggers = $data['triggers'] ?? [];
|
$triggers = $data['triggers'] ?? [];
|
||||||
// need at least one trigger
|
// need at least one trigger
|
||||||
if (!is_countable($triggers) || 0 === count($triggers)) {
|
if (!is_countable($triggers) || empty($triggers)) {
|
||||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger'));
|
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ class StoreRequest extends FormRequest
|
|||||||
$data = $validator->getData();
|
$data = $validator->getData();
|
||||||
$actions = $data['actions'] ?? [];
|
$actions = $data['actions'] ?? [];
|
||||||
// need at least one trigger
|
// need at least one trigger
|
||||||
if (!is_countable($actions) || 0 === count($actions)) {
|
if (!is_countable($actions) || empty($actions)) {
|
||||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
|
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ class UpdateRequest extends FormRequest
|
|||||||
$data = $validator->getData();
|
$data = $validator->getData();
|
||||||
$triggers = $data['triggers'] ?? null;
|
$triggers = $data['triggers'] ?? null;
|
||||||
// need at least one trigger
|
// need at least one trigger
|
||||||
if (is_array($triggers) && 0 === count($triggers)) {
|
if (is_array($triggers) && empty($triggers)) {
|
||||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger'));
|
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ class UpdateRequest extends FormRequest
|
|||||||
$data = $validator->getData();
|
$data = $validator->getData();
|
||||||
$actions = $data['actions'] ?? null;
|
$actions = $data['actions'] ?? null;
|
||||||
// need at least one action
|
// need at least one action
|
||||||
if (is_array($actions) && 0 === count($actions)) {
|
if (is_array($actions) && empty($actions)) {
|
||||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
|
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ class UpdateRequest extends FormRequest
|
|||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
$tag = $this->route()->parameter('tagOrId');
|
$tag = $this->route()->parameter('tagOrId');
|
||||||
// TODO is uniqueObjectForUser not obsolete?
|
// See reference nr. 73
|
||||||
$rules = [
|
$rules = [
|
||||||
'tag' => 'min:1|uniqueObjectForUser:tags,tag,' . $tag->id,
|
'tag' => 'min:1|uniqueObjectForUser:tags,tag,' . $tag->id,
|
||||||
'description' => 'min:1|nullable',
|
'description' => 'min:1|nullable',
|
||||||
|
@ -57,9 +57,10 @@ class StoreRequest extends FormRequest
|
|||||||
'group_title' => $this->string('group_title'),
|
'group_title' => $this->string('group_title'),
|
||||||
'error_if_duplicate_hash' => $this->boolean('error_if_duplicate_hash'),
|
'error_if_duplicate_hash' => $this->boolean('error_if_duplicate_hash'),
|
||||||
'apply_rules' => $this->boolean('apply_rules', true),
|
'apply_rules' => $this->boolean('apply_rules', true),
|
||||||
|
'fire_webhooks' => $this->boolean('fire_webhooks', true),
|
||||||
'transactions' => $this->getTransactionData(),
|
'transactions' => $this->getTransactionData(),
|
||||||
];
|
];
|
||||||
// TODO location
|
// See reference nr. 71
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,6 +129,9 @@ class UpdateRequest extends FormRequest
|
|||||||
if ($this->has('apply_rules')) {
|
if ($this->has('apply_rules')) {
|
||||||
$data['apply_rules'] = $this->boolean('apply_rules', true);
|
$data['apply_rules'] = $this->boolean('apply_rules', true);
|
||||||
}
|
}
|
||||||
|
if ($this->has('fire_webhooks')) {
|
||||||
|
$data['fire_webhooks'] = $this->boolean('fire_webhooks', true);
|
||||||
|
}
|
||||||
if ($this->has('group_title')) {
|
if ($this->has('group_title')) {
|
||||||
$data['group_title'] = $this->string('group_title');
|
$data['group_title'] = $this->string('group_title');
|
||||||
}
|
}
|
||||||
|
@ -125,18 +125,16 @@ class ExportData extends Command
|
|||||||
$exporter->setExportBills($options['export']['bills']);
|
$exporter->setExportBills($options['export']['bills']);
|
||||||
$exporter->setExportPiggies($options['export']['piggies']);
|
$exporter->setExportPiggies($options['export']['piggies']);
|
||||||
$data = $exporter->export();
|
$data = $exporter->export();
|
||||||
if (0 === count($data)) {
|
if (empty($data)) {
|
||||||
$this->error('You must export *something*. Use --export-transactions or another option. See docs.firefly-iii.org');
|
$this->error('You must export *something*. Use --export-transactions or another option. See docs.firefly-iii.org');
|
||||||
}
|
}
|
||||||
$returnCode = 0;
|
$returnCode = 0;
|
||||||
if (0 !== count($data)) {
|
if (!empty($data)) {
|
||||||
try {
|
try {
|
||||||
$this->exportData($options, $data);
|
$this->exportData($options, $data);
|
||||||
app('telemetry')->feature('system.command.executed', 'firefly-iii:export-data');
|
|
||||||
} catch (FireflyException $e) {
|
} catch (FireflyException $e) {
|
||||||
$this->error(sprintf('Could not store data: %s', $e->getMessage()));
|
$this->error(sprintf('Could not store data: %s', $e->getMessage()));
|
||||||
|
|
||||||
app('telemetry')->feature('system.command.errored', 'firefly-iii:export-data');
|
|
||||||
$returnCode = 1;
|
$returnCode = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,8 +84,6 @@ class ScanAttachments extends Command
|
|||||||
$this->line(sprintf('Fixed attachment #%d', $attachment->id));
|
$this->line(sprintf('Fixed attachment #%d', $attachment->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
app('telemetry')->feature('system.command.executed', $this->signature);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,6 @@ class SetLatestVersion extends Command
|
|||||||
app('fireflyconfig')->set('ff3_version', config('firefly.version'));
|
app('fireflyconfig')->set('ff3_version', config('firefly.version'));
|
||||||
$this->line('Updated version.');
|
$this->line('Updated version.');
|
||||||
|
|
||||||
app('telemetry')->feature('system.command.executed', 'firefly-iii:set-latest-version');
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,8 +99,6 @@ class ApplyRules extends Command
|
|||||||
|
|
||||||
$result = $this->verifyInput();
|
$result = $this->verifyInput();
|
||||||
if (false === $result) {
|
if (false === $result) {
|
||||||
app('telemetry')->feature('system.command.errored', 'firefly-iii:apply-rules');
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,8 +117,6 @@ class ApplyRules extends Command
|
|||||||
$this->warn(' --rule_groups=1,2,...');
|
$this->warn(' --rule_groups=1,2,...');
|
||||||
$this->warn(' --all_rules');
|
$this->warn(' --all_rules');
|
||||||
|
|
||||||
app('telemetry')->feature('system.command.errored', 'firefly-iii:apply-rules');
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,8 +144,6 @@ class ApplyRules extends Command
|
|||||||
// file the rule(s)
|
// file the rule(s)
|
||||||
$ruleEngine->fire();
|
$ruleEngine->fire();
|
||||||
|
|
||||||
app('telemetry')->feature('system.command.executed', 'firefly-iii:apply-rules');
|
|
||||||
|
|
||||||
$this->line('');
|
$this->line('');
|
||||||
$end = round(microtime(true) - $start, 2);
|
$end = round(microtime(true) - $start, 2);
|
||||||
$this->line(sprintf('Done in %s seconds!', $end));
|
$this->line(sprintf('Done in %s seconds!', $end));
|
||||||
|
@ -92,8 +92,6 @@ class Cron extends Command
|
|||||||
|
|
||||||
$this->info('More feedback on the cron jobs can be found in the log files.');
|
$this->info('More feedback on the cron jobs can be found in the log files.');
|
||||||
|
|
||||||
app('telemetry')->feature('system.command.executed', 'firefly-iii:cron');
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ class UpgradeDatabase extends Command
|
|||||||
|
|
||||||
// instructions
|
// instructions
|
||||||
'firefly:instructions update',
|
'firefly:instructions update',
|
||||||
|
'firefly-iii:verify-security-alerts'
|
||||||
];
|
];
|
||||||
$args = [];
|
$args = [];
|
||||||
if ($this->option('force')) {
|
if ($this->option('force')) {
|
||||||
|
@ -63,18 +63,6 @@ class UpgradeFireflyInstructions extends Command
|
|||||||
$this->installInstructions();
|
$this->installInstructions();
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect system telemetry
|
|
||||||
$isDocker = true === env('IS_DOCKER', false) ? 'true' : 'false';
|
|
||||||
app('telemetry')->feature('system.php.version', PHP_VERSION);
|
|
||||||
app('telemetry')->feature('system.os.version', PHP_OS);
|
|
||||||
app('telemetry')->feature('system.database.driver', env('DB_CONNECTION', '(unknown)'));
|
|
||||||
app('telemetry')->feature('system.os.is_docker', $isDocker);
|
|
||||||
try {
|
|
||||||
app('telemetry')->feature('system.users.count', (string)User::count());
|
|
||||||
} catch (QueryException $e) {
|
|
||||||
// @ignoreException
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
85
app/Console/Commands/VerifySecurityAlerts.php
Normal file
85
app/Console/Commands/VerifySecurityAlerts.php
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Storage;
|
||||||
|
use Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class VerifySecurityAlerts
|
||||||
|
*/
|
||||||
|
class VerifySecurityAlerts extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'firefly-iii:verify-security-alerts';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Verify security alerts';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
// remove old advisory
|
||||||
|
app('fireflyconfig')->delete('upgrade_security_message');
|
||||||
|
app('fireflyconfig')->delete('upgrade_security_level');
|
||||||
|
|
||||||
|
// check for security advisories.
|
||||||
|
$version = config('firefly.version');
|
||||||
|
$disk = Storage::disk('resources');
|
||||||
|
if (!$disk->has('alerts.json')) {
|
||||||
|
Log::debug('No alerts.json file present.');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
$content = $disk->get('alerts.json');
|
||||||
|
$json = json_decode($content, true, 10);
|
||||||
|
|
||||||
|
/** @var array $array */
|
||||||
|
foreach ($json as $array) {
|
||||||
|
if ($version === $array['version'] && true === $array['advisory']) {
|
||||||
|
Log::debug(sprintf('Version %s has an alert!', $array['version']));
|
||||||
|
// add advisory to configuration.
|
||||||
|
app('fireflyconfig')->set('upgrade_security_message', $array['message']);
|
||||||
|
app('fireflyconfig')->set('upgrade_security_level', $array['level']);
|
||||||
|
|
||||||
|
// depends on level
|
||||||
|
if ('info' === $array['level']) {
|
||||||
|
Log::debug('INFO level alert');
|
||||||
|
$this->info($array['message']);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ('warning' === $array['level']) {
|
||||||
|
Log::debug('WARNING level alert');
|
||||||
|
$this->warn('------------------------ :o');
|
||||||
|
$this->warn($array['message']);
|
||||||
|
$this->warn('------------------------ :o');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ('danger' === $array['level']) {
|
||||||
|
Log::debug('DANGER level alert');
|
||||||
|
$this->error('------------------------ :-(');
|
||||||
|
$this->error($array['message']);
|
||||||
|
$this->error('------------------------ :-(');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log::debug('This version is not mentioned.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -37,16 +37,19 @@ class StoredTransactionGroup extends Event
|
|||||||
use SerializesModels;
|
use SerializesModels;
|
||||||
|
|
||||||
public bool $applyRules;
|
public bool $applyRules;
|
||||||
|
public bool $fireWebhooks;
|
||||||
public TransactionGroup $transactionGroup;
|
public TransactionGroup $transactionGroup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new event instance.
|
* Create a new event instance.
|
||||||
*
|
*
|
||||||
* @param TransactionGroup $transactionGroup
|
* @param TransactionGroup $transactionGroup
|
||||||
* @param bool $applyRules
|
* @param bool $applyRules
|
||||||
*/
|
*/
|
||||||
public function __construct(TransactionGroup $transactionGroup, bool $applyRules = true)
|
public function __construct(TransactionGroup $transactionGroup, bool $applyRules = true, bool $fireWebhooks = true)
|
||||||
{
|
{
|
||||||
$this->transactionGroup = $transactionGroup;
|
$this->transactionGroup = $transactionGroup;
|
||||||
|
$this->fireWebhooks = $fireWebhooks;
|
||||||
$this->applyRules = $applyRules;
|
$this->applyRules = $applyRules;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ use Illuminate\Queue\SerializesModels;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class StoredTransactionLink
|
* Class StoredTransactionLink
|
||||||
* TODO not used.
|
* See reference nr. 85
|
||||||
*/
|
*/
|
||||||
class StoredTransactionLink extends Event
|
class StoredTransactionLink extends Event
|
||||||
{
|
{
|
||||||
|
@ -36,10 +36,9 @@ class UpdatedTransactionGroup extends Event
|
|||||||
{
|
{
|
||||||
use SerializesModels;
|
use SerializesModels;
|
||||||
|
|
||||||
/** @var bool */
|
public bool $applyRules;
|
||||||
public $applyRules;
|
public bool $fireWebhooks;
|
||||||
/** @var TransactionGroup The group that was stored. */
|
public TransactionGroup $transactionGroup;
|
||||||
public $transactionGroup;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new event instance.
|
* Create a new event instance.
|
||||||
@ -47,9 +46,10 @@ class UpdatedTransactionGroup extends Event
|
|||||||
* @param TransactionGroup $transactionGroup
|
* @param TransactionGroup $transactionGroup
|
||||||
* @param bool $applyRules
|
* @param bool $applyRules
|
||||||
*/
|
*/
|
||||||
public function __construct(TransactionGroup $transactionGroup, bool $applyRules = true)
|
public function __construct(TransactionGroup $transactionGroup, bool $applyRules = true, bool $fireWebhooks = true)
|
||||||
{
|
{
|
||||||
$this->transactionGroup = $transactionGroup;
|
$this->transactionGroup = $transactionGroup;
|
||||||
|
$this->fireWebhooks = $fireWebhooks;
|
||||||
$this->applyRules = $applyRules;
|
$this->applyRules = $applyRules;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ use Illuminate\Queue\SerializesModels;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class UpdatedTransactionLink
|
* Class UpdatedTransactionLink
|
||||||
* TODO unused
|
* See reference nr. 86
|
||||||
*/
|
*/
|
||||||
class UpdatedTransactionLink extends Event
|
class UpdatedTransactionLink extends Event
|
||||||
{
|
{
|
||||||
|
@ -149,7 +149,7 @@ class AccountFactory
|
|||||||
// try with type:
|
// try with type:
|
||||||
if (null === $result) {
|
if (null === $result) {
|
||||||
$types = config(sprintf('firefly.accountTypeByIdentifier.%s', $accountTypeName)) ?? [];
|
$types = config(sprintf('firefly.accountTypeByIdentifier.%s', $accountTypeName)) ?? [];
|
||||||
if (count($types) > 0) {
|
if (!empty($types)) {
|
||||||
$result = AccountType::whereIn('type', $types)->first();
|
$result = AccountType::whereIn('type', $types)->first();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ class TransactionJournalFactory
|
|||||||
Log::debug('Start of TransactionJournalFactory::create()');
|
Log::debug('Start of TransactionJournalFactory::create()');
|
||||||
$collection = new Collection;
|
$collection = new Collection;
|
||||||
$transactions = $dataObject['transactions'] ?? [];
|
$transactions = $dataObject['transactions'] ?? [];
|
||||||
if (0 === count($transactions)) {
|
if (empty($transactions)) {
|
||||||
Log::error('There are no transactions in the array, the TransactionJournalFactory cannot continue.');
|
Log::error('There are no transactions in the array, the TransactionJournalFactory cannot continue.');
|
||||||
|
|
||||||
return new Collection;
|
return new Collection;
|
||||||
|
@ -253,7 +253,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
return [
|
return [
|
||||||
'journals' => $journals,
|
'journals' => $journals,
|
||||||
'currency' => $currency,
|
'currency' => $currency,
|
||||||
'exists' => 0!==count($journals),
|
'exists' => !empty($journals),
|
||||||
'end' => $this->end->formatLocalized((string)trans('config.month_and_day', [], $locale)),
|
'end' => $this->end->formatLocalized((string)trans('config.month_and_day', [], $locale)),
|
||||||
'endBalance' => app('steam')->balance($account, $this->end),
|
'endBalance' => app('steam')->balance($account, $this->end),
|
||||||
'dayBefore' => $date->formatLocalized((string)trans('config.month_and_day', [], $locale)),
|
'dayBefore' => $date->formatLocalized((string)trans('config.month_and_day', [], $locale)),
|
||||||
|
@ -34,7 +34,7 @@ use Throwable;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class MonthReportGenerator.
|
* Class MonthReportGenerator.
|
||||||
* TODO include info about tags.
|
* See reference nr. 19
|
||||||
*
|
*
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
@ -179,7 +179,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
*/
|
*/
|
||||||
protected function getExpenses(): array
|
protected function getExpenses(): array
|
||||||
{
|
{
|
||||||
if (count($this->expenses) > 0) {
|
if (!empty($this->expenses)) {
|
||||||
Log::debug('Return previous set of expenses.');
|
Log::debug('Return previous set of expenses.');
|
||||||
|
|
||||||
return $this->expenses;
|
return $this->expenses;
|
||||||
|
@ -35,7 +35,7 @@ use Throwable;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class MonthReportGenerator.
|
* Class MonthReportGenerator.
|
||||||
* TODO include info about tags.
|
* See reference nr. 18
|
||||||
*
|
*
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
@ -188,7 +188,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
*/
|
*/
|
||||||
protected function getExpenses(): array
|
protected function getExpenses(): array
|
||||||
{
|
{
|
||||||
if (count($this->expenses) > 0) {
|
if (!empty($this->expenses)) {
|
||||||
Log::debug('Return previous set of expenses.');
|
Log::debug('Return previous set of expenses.');
|
||||||
|
|
||||||
return $this->expenses;
|
return $this->expenses;
|
||||||
@ -213,7 +213,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
*/
|
*/
|
||||||
protected function getIncome(): array
|
protected function getIncome(): array
|
||||||
{
|
{
|
||||||
if (count($this->income) > 0) {
|
if (!empty($this->income)) {
|
||||||
return $this->income;
|
return $this->income;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,13 @@ class StoredGroupEventHandler
|
|||||||
{
|
{
|
||||||
Log::debug(__METHOD__);
|
Log::debug(__METHOD__);
|
||||||
$group = $storedGroupEvent->transactionGroup;
|
$group = $storedGroupEvent->transactionGroup;
|
||||||
$user = $group->user;
|
if (false === $storedGroupEvent->fireWebhooks) {
|
||||||
|
Log::info(sprintf('Will not fire webhooks for transaction group #%d', $group->id));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $group->user;
|
||||||
/** @var MessageGeneratorInterface $engine */
|
/** @var MessageGeneratorInterface $engine */
|
||||||
$engine = app(MessageGeneratorInterface::class);
|
$engine = app(MessageGeneratorInterface::class);
|
||||||
$engine->setUser($user);
|
$engine->setUser($user);
|
||||||
|
@ -82,9 +82,14 @@ class UpdatedGroupEventHandler
|
|||||||
*/
|
*/
|
||||||
public function triggerWebhooks(UpdatedTransactionGroup $updatedGroupEvent): void
|
public function triggerWebhooks(UpdatedTransactionGroup $updatedGroupEvent): void
|
||||||
{
|
{
|
||||||
Log::debug('UpdatedGroupEventHandler:triggerWebhooks');
|
Log::debug(__METHOD__);
|
||||||
$group = $updatedGroupEvent->transactionGroup;
|
$group = $updatedGroupEvent->transactionGroup;
|
||||||
$user = $group->user;
|
if (false === $updatedGroupEvent->fireWebhooks) {
|
||||||
|
Log::info(sprintf('Will not fire webhooks for transaction group #%d', $group->id));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$user = $group->user;
|
||||||
/** @var MessageGeneratorInterface $engine */
|
/** @var MessageGeneratorInterface $engine */
|
||||||
$engine = app(MessageGeneratorInterface::class);
|
$engine = app(MessageGeneratorInterface::class);
|
||||||
$engine->setUser($user);
|
$engine->setUser($user);
|
||||||
|
@ -207,7 +207,7 @@ trait MetaCollection
|
|||||||
$this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id');
|
$this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id');
|
||||||
}
|
}
|
||||||
$this->query->where('journal_meta.name', '=', 'external_id');
|
$this->query->where('journal_meta.name', '=', 'external_id');
|
||||||
$this->query->where('journal_meta.data', '=', sprintf('%s', $externalId));
|
$this->query->where('journal_meta.data', '=', sprintf('%s', json_encode($externalId)));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -325,7 +325,7 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
*/
|
*/
|
||||||
public function setJournalIds(array $journalIds): GroupCollectorInterface
|
public function setJournalIds(array $journalIds): GroupCollectorInterface
|
||||||
{
|
{
|
||||||
if (0 !== count($journalIds)) {
|
if (!empty($journalIds)) {
|
||||||
// make all integers.
|
// make all integers.
|
||||||
$integerIDs = array_map('intval', $journalIds);
|
$integerIDs = array_map('intval', $journalIds);
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class Sha3SignatureGenerator implements SignatureGeneratorInterface
|
|||||||
try {
|
try {
|
||||||
$json = json_encode($message->message, JSON_THROW_ON_ERROR);
|
$json = json_encode($message->message, JSON_THROW_ON_ERROR);
|
||||||
} catch (JsonException $e) {
|
} catch (JsonException $e) {
|
||||||
// TODO needs FireflyException.
|
// See reference nr. 87
|
||||||
return sprintf('t=1,v%d=err-invalid-signature', $this->getVersion());
|
return sprintf('t=1,v%d=err-invalid-signature', $this->getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ class IndexController extends Controller
|
|||||||
|
|
||||||
$accounts->each(
|
$accounts->each(
|
||||||
function (Account $account) use ($activities, $startBalances, $endBalances) {
|
function (Account $account) use ($activities, $startBalances, $endBalances) {
|
||||||
// TODO lots of queries executed in this block.
|
// See reference nr. 68
|
||||||
$account->lastActivityDate = $this->isInArray($activities, $account->id);
|
$account->lastActivityDate = $this->isInArray($activities, $account->id);
|
||||||
$account->startBalance = $this->isInArray($startBalances, $account->id);
|
$account->startBalance = $this->isInArray($startBalances, $account->id);
|
||||||
$account->endBalance = $this->isInArray($endBalances, $account->id);
|
$account->endBalance = $this->isInArray($endBalances, $account->id);
|
||||||
|
@ -100,10 +100,6 @@ class UpdateController extends Controller
|
|||||||
$channel = $request->get('update_channel');
|
$channel = $request->get('update_channel');
|
||||||
$channel = in_array($channel, ['stable', 'beta', 'alpha'], true) ? $channel : 'stable';
|
$channel = in_array($channel, ['stable', 'beta', 'alpha'], true) ? $channel : 'stable';
|
||||||
|
|
||||||
// store as telemetry
|
|
||||||
app('telemetry')->feature('admin.update.channel', $channel);
|
|
||||||
app('telemetry')->feature('admin.update.permission', (string)$checkForUpdates);
|
|
||||||
|
|
||||||
app('fireflyconfig')->set('permission_update_check', $checkForUpdates);
|
app('fireflyconfig')->set('permission_update_check', $checkForUpdates);
|
||||||
app('fireflyconfig')->set('last_update_check', time());
|
app('fireflyconfig')->set('last_update_check', time());
|
||||||
app('fireflyconfig')->set('update_channel', $channel);
|
app('fireflyconfig')->set('update_channel', $channel);
|
||||||
|
@ -35,7 +35,6 @@ use Illuminate\Http\Request;
|
|||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
use Log;
|
use Log;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class LoginController
|
* Class LoginController
|
||||||
@ -55,7 +54,9 @@ class LoginController extends Controller
|
|||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $redirectTo = RouteServiceProvider::HOME;
|
protected string $redirectTo = RouteServiceProvider::HOME;
|
||||||
|
|
||||||
|
private string $username;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new controller instance.
|
* Create a new controller instance.
|
||||||
@ -65,6 +66,7 @@ class LoginController extends Controller
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
$this->username = 'email';
|
||||||
$this->middleware('guest')->except('logout');
|
$this->middleware('guest')->except('logout');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,25 +82,31 @@ class LoginController extends Controller
|
|||||||
public function login(Request $request)
|
public function login(Request $request)
|
||||||
{
|
{
|
||||||
Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get('email')));
|
Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get('email')));
|
||||||
Log::info('User is trying to login.');
|
Log::info(sprintf('User is trying to login.'));
|
||||||
if ('ldap' === config('auth.providers.users.driver')) {
|
|
||||||
/** @var Adldap\Connections\Provider $provider */
|
$guard = config('auth.defaults.guard');
|
||||||
Adldap::getProvider('default'); // @phpstan-ignore-line
|
|
||||||
|
// if the user logs in using LDAP the field is also changed (per LDAP config)
|
||||||
|
if ('ldap' === $guard) {
|
||||||
|
Log::debug('User wishes to login using LDAP.');
|
||||||
|
$this->username = config('firefly.ldap_auth_field');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$this->validateLogin($request);
|
$this->validateLogin($request);
|
||||||
|
Log::debug('Login data is valid.');
|
||||||
|
|
||||||
/** Copied directly from AuthenticatesUsers, but with logging added: */
|
/** Copied directly from AuthenticatesUsers, but with logging added: */
|
||||||
// If the class is using the ThrottlesLogins trait, we can automatically throttle
|
// If the class is using the ThrottlesLogins trait, we can automatically throttle
|
||||||
// the login attempts for this application. We'll key this by the username and
|
// the login attempts for this application. We'll key this by the username and
|
||||||
// the IP address of the client making these requests into this application.
|
// the IP address of the client making these requests into this application.
|
||||||
if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) {
|
if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) {
|
||||||
Log::channel('audit')->info(sprintf('Login for user "%s" was locked out.', $request->get('email')));
|
Log::channel('audit')->info(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
|
||||||
|
Log::error(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
|
||||||
$this->fireLockoutEvent($request);
|
$this->fireLockoutEvent($request);
|
||||||
|
|
||||||
$this->sendLockoutResponse($request);
|
$this->sendLockoutResponse($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Copied directly from AuthenticatesUsers, but with logging added: */
|
/** Copied directly from AuthenticatesUsers, but with logging added: */
|
||||||
if ($this->attemptLogin($request)) {
|
if ($this->attemptLogin($request)) {
|
||||||
Log::channel('audit')->info(sprintf('User "%s" has been logged in.', $request->get('email')));
|
Log::channel('audit')->info(sprintf('User "%s" has been logged in.', $request->get('email')));
|
||||||
@ -108,6 +116,7 @@ class LoginController extends Controller
|
|||||||
|
|
||||||
return $this->sendLoginResponse($request);
|
return $this->sendLoginResponse($request);
|
||||||
}
|
}
|
||||||
|
Log::warning('Login attempt failed.');
|
||||||
|
|
||||||
/** Copied directly from AuthenticatesUsers, but with logging added: */
|
/** Copied directly from AuthenticatesUsers, but with logging added: */
|
||||||
// If the login attempt was unsuccessful we will increment the number of attempts
|
// If the login attempt was unsuccessful we will increment the number of attempts
|
||||||
@ -129,7 +138,7 @@ class LoginController extends Controller
|
|||||||
public function logout(Request $request)
|
public function logout(Request $request)
|
||||||
{
|
{
|
||||||
$authGuard = config('firefly.authentication_guard');
|
$authGuard = config('firefly.authentication_guard');
|
||||||
$logoutUri = config('firefly.custom_logout_uri');
|
$logoutUri = config('firefly.custom_logout_url');
|
||||||
if ('remote_user_guard' === $authGuard && '' !== $logoutUri) {
|
if ('remote_user_guard' === $authGuard && '' !== $logoutUri) {
|
||||||
return redirect($logoutUri);
|
return redirect($logoutUri);
|
||||||
}
|
}
|
||||||
@ -189,14 +198,26 @@ class LoginController extends Controller
|
|||||||
{
|
{
|
||||||
Log::channel('audit')->info('Show login form (1.1).');
|
Log::channel('audit')->info('Show login form (1.1).');
|
||||||
|
|
||||||
$count = DB::table('users')->count();
|
$count = DB::table('users')->count();
|
||||||
$loginProvider = config('firefly.login_provider');
|
$guard = config('auth.defaults.guard');
|
||||||
$title = (string)trans('firefly.login_page_title');
|
$title = (string)trans('firefly.login_page_title');
|
||||||
if (0 === $count && 'eloquent' === $loginProvider) {
|
|
||||||
return redirect(route('register'));
|
if (0 === $count && 'web' === $guard) {
|
||||||
|
return redirect(route('register'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// is allowed to?
|
// switch to LDAP settings:
|
||||||
|
if ('ldap' === $guard) {
|
||||||
|
Log::debug('User wishes to login using LDAP.');
|
||||||
|
$this->username = config('firefly.ldap_auth_field');
|
||||||
|
}
|
||||||
|
|
||||||
|
// throw warning if still using login_provider
|
||||||
|
$ldapWarning = false;
|
||||||
|
if ('ldap' === config('firefly.login_provider')) {
|
||||||
|
$ldapWarning = true;
|
||||||
|
}
|
||||||
|
// is allowed to register, etc.
|
||||||
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
|
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
|
||||||
$allowRegistration = true;
|
$allowRegistration = true;
|
||||||
$allowReset = true;
|
$allowReset = true;
|
||||||
@ -205,7 +226,7 @@ class LoginController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// single user mode is ignored when the user is not using eloquent:
|
// single user mode is ignored when the user is not using eloquent:
|
||||||
if ('eloquent' !== $loginProvider) {
|
if ('web' !== $guard) {
|
||||||
$allowRegistration = false;
|
$allowRegistration = false;
|
||||||
$allowReset = false;
|
$allowReset = false;
|
||||||
}
|
}
|
||||||
@ -218,8 +239,18 @@ class LoginController extends Controller
|
|||||||
$cookieName = config('google2fa.cookie_name', 'google2fa_token');
|
$cookieName = config('google2fa.cookie_name', 'google2fa_token');
|
||||||
request()->cookies->set($cookieName, 'invalid');
|
request()->cookies->set($cookieName, 'invalid');
|
||||||
}
|
}
|
||||||
|
$usernameField = $this->username();
|
||||||
|
|
||||||
return prefixView('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'title'));
|
return prefixView('auth.login', compact('allowRegistration', 'email', 'remember', 'ldapWarning', 'allowReset', 'title', 'usernameField'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the login username to be used by the controller.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function username()
|
||||||
|
{
|
||||||
|
return $this->username;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,9 +112,6 @@ class RegisterController extends Controller
|
|||||||
|
|
||||||
$this->registered($request, $user);
|
$this->registered($request, $user);
|
||||||
|
|
||||||
// telemetry
|
|
||||||
app('telemetry')->feature('system.users.count', (string)User::count());
|
|
||||||
|
|
||||||
return redirect($this->redirectPath());
|
return redirect($this->redirectPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ class IndexController extends Controller
|
|||||||
$sums = $this->getSums($budgets);
|
$sums = $this->getSums($budgets);
|
||||||
|
|
||||||
// get budgeted for default currency:
|
// get budgeted for default currency:
|
||||||
if (0 === count($availableBudgets)) {
|
if (empty($availableBudgets)) {
|
||||||
$budgeted = $this->blRepository->budgeted($start, $end, $defaultCurrency,);
|
$budgeted = $this->blRepository->budgeted($start, $end, $defaultCurrency,);
|
||||||
$spentArr = $this->opsRepository->sumExpenses($start, $end, null, null, $defaultCurrency);
|
$spentArr = $this->opsRepository->sumExpenses($start, $end, null, null, $defaultCurrency);
|
||||||
$spent = $spentArr[$defaultCurrency->id]['sum'] ?? '0';
|
$spent = $spentArr[$defaultCurrency->id]['sum'] ?? '0';
|
||||||
|
@ -331,7 +331,7 @@ class AccountController extends Controller
|
|||||||
Log::debug('Default set is ', $defaultSet);
|
Log::debug('Default set is ', $defaultSet);
|
||||||
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
|
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
|
||||||
Log::debug('Frontpage preference set is ', $frontPage->data);
|
Log::debug('Frontpage preference set is ', $frontPage->data);
|
||||||
if (0 === count($frontPage->data)) {
|
if (empty($frontPage->data)) {
|
||||||
app('preferences')->set('frontPageAccounts', $defaultSet);
|
app('preferences')->set('frontPageAccounts', $defaultSet);
|
||||||
Log::debug('frontpage set is empty!');
|
Log::debug('frontpage set is empty!');
|
||||||
}
|
}
|
||||||
@ -509,7 +509,7 @@ class AccountController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Shows the balances for a given set of dates and accounts.
|
* Shows the balances for a given set of dates and accounts.
|
||||||
*
|
*
|
||||||
* TODO this chart is not multi-currency aware.
|
* See reference nr. 55
|
||||||
*
|
*
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
|
@ -63,7 +63,7 @@ class CategoryController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Show an overview for a category for all time, per month/week/year.
|
* Show an overview for a category for all time, per month/week/year.
|
||||||
* TODO test method, for category refactor.
|
* See reference nr. 59
|
||||||
*
|
*
|
||||||
* @param Category $category
|
* @param Category $category
|
||||||
*
|
*
|
||||||
@ -111,7 +111,7 @@ class CategoryController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the category chart on the front page.
|
* Shows the category chart on the front page.
|
||||||
* TODO test method, for category refactor.
|
* See reference nr. 60
|
||||||
*
|
*
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
@ -138,7 +138,7 @@ class CategoryController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Chart report.
|
* Chart report.
|
||||||
* TODO test method, for category refactor.
|
* See reference nr. 61
|
||||||
*
|
*
|
||||||
* @param Category $category
|
* @param Category $category
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
@ -254,7 +254,7 @@ class CategoryController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Chart for period for transactions without a category.
|
* Chart for period for transactions without a category.
|
||||||
* TODO test me.
|
* See reference nr. 62
|
||||||
*
|
*
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
@ -281,7 +281,7 @@ class CategoryController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Chart for a specific period.
|
* Chart for a specific period.
|
||||||
* TODO test method, for category refactor.
|
* See reference nr. 63
|
||||||
*
|
*
|
||||||
* @param Category $category
|
* @param Category $category
|
||||||
* @param Carbon $date
|
* @param Carbon $date
|
||||||
|
@ -318,7 +318,7 @@ class CategoryReportController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO duplicate function
|
* See reference nr. 57
|
||||||
*
|
*
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
|
@ -249,7 +249,7 @@ class DoubleReportController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO this method is double.
|
* See reference nr. 51
|
||||||
*
|
*
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
* @param int $id
|
* @param int $id
|
||||||
@ -274,7 +274,7 @@ class DoubleReportController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO duplicate function
|
* See reference nr. 52
|
||||||
*
|
*
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
@ -319,7 +319,7 @@ class DoubleReportController extends Controller
|
|||||||
$journalId = $journal['transaction_journal_id'];
|
$journalId = $journal['transaction_journal_id'];
|
||||||
|
|
||||||
// no tags? also deserves a sport
|
// no tags? also deserves a sport
|
||||||
if (0 === count($journal['tags'])) {
|
if (empty($journal['tags'])) {
|
||||||
$includedJournals[] = $journalId;
|
$includedJournals[] = $journalId;
|
||||||
// do something
|
// do something
|
||||||
$tagName = trans('firefly.no_tags');
|
$tagName = trans('firefly.no_tags');
|
||||||
@ -379,7 +379,7 @@ class DoubleReportController extends Controller
|
|||||||
$journalId = $journal['transaction_journal_id'];
|
$journalId = $journal['transaction_journal_id'];
|
||||||
|
|
||||||
// no tags? also deserves a sport
|
// no tags? also deserves a sport
|
||||||
if (0 === count($journal['tags'])) {
|
if (empty($journal['tags'])) {
|
||||||
$includedJournals[] = $journalId;
|
$includedJournals[] = $journalId;
|
||||||
// do something
|
// do something
|
||||||
$tagName = trans('firefly.no_tags');
|
$tagName = trans('firefly.no_tags');
|
||||||
|
@ -69,7 +69,7 @@ class ExpenseReportController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Main chart that shows income and expense for a combination of expense/revenue accounts.
|
* Main chart that shows income and expense for a combination of expense/revenue accounts.
|
||||||
*
|
*
|
||||||
* TODO this chart is not multi-currency aware.
|
* See reference nr. 58
|
||||||
*
|
*
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
* @param Collection $expense
|
* @param Collection $expense
|
||||||
@ -187,7 +187,7 @@ class ExpenseReportController extends Controller
|
|||||||
$newSet[$key] = $entry;
|
$newSet[$key] = $entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0===count($newSet)) {
|
if (empty($newSet)) {
|
||||||
$newSet = $chartData;
|
$newSet = $chartData;
|
||||||
}
|
}
|
||||||
$data = $this->generator->multiSet($newSet);
|
$data = $this->generator->multiSet($newSet);
|
||||||
|
@ -58,7 +58,7 @@ class PiggyBankController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Shows the piggy bank history.
|
* Shows the piggy bank history.
|
||||||
*
|
*
|
||||||
* TODO this chart is not multi-currency aware.
|
* See reference nr. 53
|
||||||
*
|
*
|
||||||
* @param PiggyBankRepositoryInterface $repository
|
* @param PiggyBankRepositoryInterface $repository
|
||||||
* @param PiggyBank $piggyBank
|
* @param PiggyBank $piggyBank
|
||||||
|
@ -102,7 +102,7 @@ class ReportController extends Controller
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO get liabilities and include those as well?
|
// See reference nr. 56
|
||||||
|
|
||||||
while ($current < $end) {
|
while ($current < $end) {
|
||||||
// get balances by date, grouped by currency.
|
// get balances by date, grouped by currency.
|
||||||
|
@ -323,7 +323,7 @@ class TagReportController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO duplicate function
|
* See reference nr. 54
|
||||||
*
|
*
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
|
@ -63,7 +63,7 @@ abstract class Controller extends BaseController
|
|||||||
|
|
||||||
// share custom auth guard info.
|
// share custom auth guard info.
|
||||||
$authGuard = config('firefly.authentication_guard');
|
$authGuard = config('firefly.authentication_guard');
|
||||||
$logoutUri = config('firefly.custom_logout_uri');
|
$logoutUri = config('firefly.custom_logout_url');
|
||||||
|
|
||||||
app('view')->share('authGuard', $authGuard);
|
app('view')->share('authGuard', $authGuard);
|
||||||
app('view')->share('logoutUri', $logoutUri);
|
app('view')->share('logoutUri', $logoutUri);
|
||||||
|
@ -189,7 +189,7 @@ class BoxController extends Controller
|
|||||||
$incomes[$currencyId] = app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false);
|
$incomes[$currencyId] = app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false);
|
||||||
$expenses[$currencyId] = app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false);
|
$expenses[$currencyId] = app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false);
|
||||||
}
|
}
|
||||||
if (0===count($sums)) {
|
if (empty($sums)) {
|
||||||
$currency = app('amount')->getDefaultCurrency();
|
$currency = app('amount')->getDefaultCurrency();
|
||||||
$sums[$currency->id] = app('amount')->formatAnything($currency, '0', false);
|
$sums[$currency->id] = app('amount')->formatAnything($currency, '0', false);
|
||||||
$incomes[$currency->id] = app('amount')->formatAnything($currency, '0', false);
|
$incomes[$currency->id] = app('amount')->formatAnything($currency, '0', false);
|
||||||
|
@ -64,7 +64,7 @@ class FrontpageController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$html = '';
|
$html = '';
|
||||||
if (0!==count($info)) {
|
if (!empty($info)) {
|
||||||
try {
|
try {
|
||||||
$html = prefixView('json.piggy-banks', compact('info'))->render();
|
$html = prefixView('json.piggy-banks', compact('info'))->render();
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ class IntroController extends Controller
|
|||||||
$specificPage = $specificPage ?? '';
|
$specificPage = $specificPage ?? '';
|
||||||
$steps = $this->getBasicSteps($route);
|
$steps = $this->getBasicSteps($route);
|
||||||
$specificSteps = $this->getSpecificSteps($route, $specificPage);
|
$specificSteps = $this->getSpecificSteps($route, $specificPage);
|
||||||
if (0 === count($specificSteps)) {
|
if (empty($specificSteps)) {
|
||||||
Log::debug(sprintf('No specific steps for route "%s" and page "%s"', $route, $specificPage));
|
Log::debug(sprintf('No specific steps for route "%s" and page "%s"', $route, $specificPage));
|
||||||
|
|
||||||
return response()->json($steps);
|
return response()->json($steps);
|
||||||
|
@ -125,11 +125,6 @@ class NewUserController extends Controller
|
|||||||
'invoice_date' => false, 'internal_reference' => false, 'notes' => true, 'attachments' => true,];
|
'invoice_date' => false, 'internal_reference' => false, 'notes' => true, 'attachments' => true,];
|
||||||
app('preferences')->set('transaction_journal_optional_fields', $visibleFields);
|
app('preferences')->set('transaction_journal_optional_fields', $visibleFields);
|
||||||
|
|
||||||
// telemetry: user language preference + default language.
|
|
||||||
app('telemetry')->feature('config.firefly.default_language', config('firefly.default_language', 'en_US'));
|
|
||||||
app('telemetry')->feature('user.preferences.language', app('steam')->getLanguage());
|
|
||||||
app('telemetry')->feature('user.preferences.locale', app('steam')->getLocale());
|
|
||||||
|
|
||||||
session()->flash('success', (string) trans('firefly.stored_new_accounts_new_user'));
|
session()->flash('success', (string) trans('firefly.stored_new_accounts_new_user'));
|
||||||
app('preferences')->mark();
|
app('preferences')->mark();
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ class IndexController extends Controller
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Show overview of all piggy banks.
|
* Show overview of all piggy banks.
|
||||||
* TODO complicated
|
* See reference nr. 66
|
||||||
*
|
*
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
*
|
*
|
||||||
|
@ -115,7 +115,7 @@ class PreferencesController extends Controller
|
|||||||
$locales = ['equal' => (string)trans('firefly.equal_to_language')] + $locales;
|
$locales = ['equal' => (string)trans('firefly.equal_to_language')] + $locales;
|
||||||
// an important fallback is that the frontPageAccount array gets refilled automatically
|
// an important fallback is that the frontPageAccount array gets refilled automatically
|
||||||
// when it turns up empty.
|
// when it turns up empty.
|
||||||
if (0 === count($frontPageAccounts->data)) {
|
if (empty($frontPageAccounts->data)) {
|
||||||
$frontPageAccounts = $accountIds;
|
$frontPageAccounts = $accountIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,11 +217,6 @@ class PreferencesController extends Controller
|
|||||||
session()->flash('success', (string)trans('firefly.saved_preferences'));
|
session()->flash('success', (string)trans('firefly.saved_preferences'));
|
||||||
app('preferences')->mark();
|
app('preferences')->mark();
|
||||||
|
|
||||||
// telemetry: user language preference + default language.
|
|
||||||
app('telemetry')->feature('config.firefly.default_language', config('firefly.default_language', 'en_US'));
|
|
||||||
app('telemetry')->feature('user.preferences.language', app('steam')->getLanguage());
|
|
||||||
app('telemetry')->feature('user.preferences.locale', app('steam')->getLocale());
|
|
||||||
|
|
||||||
return redirect(route('preferences.index'));
|
return redirect(route('preferences.index'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -653,7 +653,7 @@ class ProfileController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO duplicate code.
|
* See reference nr. 64
|
||||||
*
|
*
|
||||||
* @param string $mfaCode
|
* @param string $mfaCode
|
||||||
*/
|
*/
|
||||||
|
@ -86,7 +86,7 @@ class EditController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function edit(Request $request, Recurrence $recurrence)
|
public function edit(Request $request, Recurrence $recurrence)
|
||||||
{
|
{
|
||||||
// TODO should be in repos
|
// See reference nr. 69
|
||||||
$count = $recurrence->recurrenceTransactions()->count();
|
$count = $recurrence->recurrenceTransactions()->count();
|
||||||
if (0 === $count) {
|
if (0 === $count) {
|
||||||
throw new FireflyException('This recurring transaction has no meta-data. You will have to delete it and recreate it. Sorry!');
|
throw new FireflyException('This recurring transaction has no meta-data. You will have to delete it and recreate it. Sorry!');
|
||||||
|
@ -68,7 +68,7 @@ class IndexController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO the notes of a recurrence are pretty pointless at this moment.
|
* See reference nr. 70
|
||||||
* Show all recurring transactions.
|
* Show all recurring transactions.
|
||||||
*
|
*
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
|
@ -292,7 +292,7 @@ class DoubleController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO this method is double.
|
* See reference nr. 67
|
||||||
*
|
*
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
* @param int $id
|
* @param int $id
|
||||||
|
@ -143,7 +143,7 @@ class EditController extends Controller
|
|||||||
*/
|
*/
|
||||||
private function parseFromOperators(array $submittedOperators): array
|
private function parseFromOperators(array $submittedOperators): array
|
||||||
{
|
{
|
||||||
// TODO duplicated code.
|
// See reference nr. 65
|
||||||
$operators = config('firefly.search.operators');
|
$operators = config('firefly.search.operators');
|
||||||
$renderedEntries = [];
|
$renderedEntries = [];
|
||||||
$triggers = [];
|
$triggers = [];
|
||||||
|
@ -144,7 +144,7 @@ class SelectController extends Controller
|
|||||||
$textTriggers = $this->getValidTriggerList($request);
|
$textTriggers = $this->getValidTriggerList($request);
|
||||||
|
|
||||||
// warn if nothing.
|
// warn if nothing.
|
||||||
if (0 === count($textTriggers)) {
|
if (empty($textTriggers)) {
|
||||||
return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]);
|
return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +168,7 @@ class SelectController extends Controller
|
|||||||
|
|
||||||
// Warn the user if only a subset of transactions is returned
|
// Warn the user if only a subset of transactions is returned
|
||||||
$warning = '';
|
$warning = '';
|
||||||
if (0 === count($collection)) {
|
if (empty($collection)) {
|
||||||
$warning = (string)trans('firefly.warning_no_matching_transactions');
|
$warning = (string)trans('firefly.warning_no_matching_transactions');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ class SelectController extends Controller
|
|||||||
{
|
{
|
||||||
$triggers = $rule->ruleTriggers;
|
$triggers = $rule->ruleTriggers;
|
||||||
|
|
||||||
if (0 === count($triggers)) {
|
if (empty($triggers)) {
|
||||||
return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]);
|
return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]);
|
||||||
}
|
}
|
||||||
// create new rule engine:
|
// create new rule engine:
|
||||||
@ -210,7 +210,7 @@ class SelectController extends Controller
|
|||||||
$collection = $collection->slice(0, 20);
|
$collection = $collection->slice(0, 20);
|
||||||
|
|
||||||
$warning = '';
|
$warning = '';
|
||||||
if (0 === count($collection)) {
|
if (empty($collection)) {
|
||||||
$warning = (string)trans('firefly.warning_no_matching_transactions');
|
$warning = (string)trans('firefly.warning_no_matching_transactions');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ class SearchController extends Controller
|
|||||||
public function index(Request $request, SearchInterface $searcher)
|
public function index(Request $request, SearchInterface $searcher)
|
||||||
{
|
{
|
||||||
// search params:
|
// search params:
|
||||||
|
$fullQuery = $request->get('search');
|
||||||
if(is_array($request->get('search'))) {
|
if(is_array($request->get('search'))) {
|
||||||
$fullQuery = '';
|
$fullQuery = '';
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,7 @@ class InstallController extends Controller
|
|||||||
|
|
||||||
// final command to set latest version in DB
|
// final command to set latest version in DB
|
||||||
'firefly-iii:set-latest-version' => ['--james-is-cool' => true],
|
'firefly-iii:set-latest-version' => ['--james-is-cool' => true],
|
||||||
|
'firefly-iii:verify-security-alerts' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->lastError = '';
|
$this->lastError = '';
|
||||||
|
@ -63,7 +63,7 @@ class BulkController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Edit a set of journals in bulk.
|
* Edit a set of journals in bulk.
|
||||||
*
|
*
|
||||||
* TODO user wont be able to tell if journal is part of split.
|
* See reference nr. 47
|
||||||
*
|
*
|
||||||
* @param array $journals
|
* @param array $journals
|
||||||
*
|
*
|
||||||
|
@ -47,7 +47,7 @@ use Log;
|
|||||||
/**
|
/**
|
||||||
* Class ConvertController.
|
* Class ConvertController.
|
||||||
*
|
*
|
||||||
* TODO when converting to a split transfer, all sources and destinations must be the same.
|
* See reference nr. 49
|
||||||
*/
|
*/
|
||||||
class ConvertController extends Controller
|
class ConvertController extends Controller
|
||||||
{
|
{
|
||||||
@ -346,7 +346,7 @@ class ConvertController extends Controller
|
|||||||
throw new FireflyException(sprintf(trans('firefly.convert_invalid_destination'), $journal->id));
|
throw new FireflyException(sprintf(trans('firefly.convert_invalid_destination'), $journal->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
|
// See reference nr. 50
|
||||||
|
|
||||||
$update = [
|
$update = [
|
||||||
'source_id' => $sourceId,
|
'source_id' => $sourceId,
|
||||||
|
@ -70,7 +70,7 @@ class CreateController extends Controller
|
|||||||
$newGroup = $service->cloneGroup($group);
|
$newGroup = $service->cloneGroup($group);
|
||||||
|
|
||||||
// event!
|
// event!
|
||||||
event(new StoredTransactionGroup($newGroup, true));
|
event(new StoredTransactionGroup($newGroup));
|
||||||
|
|
||||||
app('preferences')->mark();
|
app('preferences')->mark();
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ class MassController extends Controller
|
|||||||
{
|
{
|
||||||
$journalIds = $request->get('journals');
|
$journalIds = $request->get('journals');
|
||||||
if (!is_array($journalIds)) {
|
if (!is_array($journalIds)) {
|
||||||
// TODO something error.
|
// See reference nr. 48
|
||||||
throw new FireflyException('This is not an array.');
|
throw new FireflyException('This is not an array.');
|
||||||
}
|
}
|
||||||
$count = 0;
|
$count = 0;
|
||||||
|
@ -88,7 +88,7 @@ class Authenticate
|
|||||||
protected function authenticate($request, array $guards)
|
protected function authenticate($request, array $guards)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (0 === count($guards)) {
|
if (empty($guards)) {
|
||||||
try {
|
try {
|
||||||
// go for default guard:
|
// go for default guard:
|
||||||
/** @noinspection PhpUndefinedMethodInspection */
|
/** @noinspection PhpUndefinedMethodInspection */
|
||||||
|
@ -87,7 +87,7 @@ class Installer
|
|||||||
*/
|
*/
|
||||||
private function hasNoTables(): bool
|
private function hasNoTables(): bool
|
||||||
{
|
{
|
||||||
Log::debug('Now in routine hasNoTables()');
|
//Log::debug('Now in routine hasNoTables()');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DB::table('users')->count();
|
DB::table('users')->count();
|
||||||
@ -107,7 +107,7 @@ class Installer
|
|||||||
}
|
}
|
||||||
throw new FireflyException(sprintf('Could not access the database: %s', $message), 0, $e);
|
throw new FireflyException(sprintf('Could not access the database: %s', $message), 0, $e);
|
||||||
}
|
}
|
||||||
Log::debug('Everything seems OK with the tables.');
|
//Log::debug('Everything seems OK with the tables.');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ class Range
|
|||||||
// send error to view if could not set money format
|
// send error to view if could not set money format
|
||||||
if (false === $moneyResult) {
|
if (false === $moneyResult) {
|
||||||
Log::error('Could not set locale. The following array doesnt work: ', $localeArray);
|
Log::error('Could not set locale. The following array doesnt work: ', $localeArray);
|
||||||
app('view')->share('invalidMonetaryLocale', true);
|
app('view')->share('invalidMonetaryLocale', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// save some formats:
|
// save some formats:
|
||||||
@ -133,5 +133,14 @@ class Range
|
|||||||
{
|
{
|
||||||
$pref = app('preferences')->get('list-length', config('firefly.list_length', 10))->data;
|
$pref = app('preferences')->get('list-length', config('firefly.list_length', 10))->data;
|
||||||
app('view')->share('listLength', $pref);
|
app('view')->share('listLength', $pref);
|
||||||
|
|
||||||
|
// share security message:
|
||||||
|
if (
|
||||||
|
app('fireflyconfig')->has('upgrade_security_message')
|
||||||
|
&& app('fireflyconfig')->has('upgrade_security_level')
|
||||||
|
) {
|
||||||
|
app('view')->share('upgrade_security_message', app('fireflyconfig')->get('upgrade_security_message')->data);
|
||||||
|
app('view')->share('upgrade_security_level', app('fireflyconfig')->get('upgrade_security_level')->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,9 @@ class AccountFormRequest extends FormRequest
|
|||||||
if (false === $this->boolean('include_net_worth')) {
|
if (false === $this->boolean('include_net_worth')) {
|
||||||
$data['include_net_worth'] = '0';
|
$data['include_net_worth'] = '0';
|
||||||
}
|
}
|
||||||
|
if('0' === $data['opening_balance']) {
|
||||||
|
$data['opening_balance'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
// if the account type is "liabilities" there are actually four types of liability
|
// if the account type is "liabilities" there are actually four types of liability
|
||||||
// that could have been selected.
|
// that could have been selected.
|
||||||
@ -95,7 +98,7 @@ class AccountFormRequest extends FormRequest
|
|||||||
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
|
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
|
||||||
$rules = [
|
$rules = [
|
||||||
'name' => 'required|min:1|uniqueAccountForUser',
|
'name' => 'required|min:1|uniqueAccountForUser',
|
||||||
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable|max:1000000000',
|
'opening_balance' => 'numeric|nullable|max:1000000000',
|
||||||
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
|
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
|
||||||
'iban' => ['iban', 'nullable', new UniqueIban(null, $this->string('objectType'))],
|
'iban' => ['iban', 'nullable', new UniqueIban(null, $this->string('objectType'))],
|
||||||
'BIC' => 'bic|nullable',
|
'BIC' => 'bic|nullable',
|
||||||
|
@ -304,7 +304,7 @@ class RecurrenceFormRequest extends FormRequest
|
|||||||
$sourceId = null;
|
$sourceId = null;
|
||||||
$destinationId = null;
|
$destinationId = null;
|
||||||
|
|
||||||
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
|
// See reference nr. 45
|
||||||
|
|
||||||
switch ($this->string('transaction_type')) {
|
switch ($this->string('transaction_type')) {
|
||||||
default:
|
default:
|
||||||
|
@ -37,7 +37,7 @@ class TestRuleFormRequest extends FormRequest
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Rules for this request.
|
* Rules for this request.
|
||||||
* TODO these rules are not valid anymore.
|
* See reference nr. 46
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LdapFilterScope.php
|
* AttributeHandler.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2021 james@firefly-iii.org
|
||||||
*
|
*
|
||||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
@ -20,28 +19,23 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
namespace FireflyIII\Ldap;
|
||||||
|
|
||||||
namespace FireflyIII\Scopes;
|
use FireflyIII\User as DatabaseUser;
|
||||||
|
use LdapRecord\Models\OpenLDAP\User as LdapUser;
|
||||||
|
|
||||||
use Adldap\Laravel\Scopes\ScopeInterface;
|
/**
|
||||||
use Adldap\Query\Builder;
|
* Class AttributeHandler
|
||||||
|
*/
|
||||||
// @phpstan-ignore-next-line
|
class AttributeHandler
|
||||||
class LdapFilterScope implements ScopeInterface // @phpstan-ignore-line
|
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* If the ADLDAP_AUTH_FILTER is provided, apply the filter to the LDAP query.
|
* @param LdapUser $ldap
|
||||||
*
|
* @param DatabaseUser $database
|
||||||
* @param Builder $query
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function apply(Builder $query)
|
public function handle(LdapUser $ldap, DatabaseUser $database)
|
||||||
{
|
{
|
||||||
$filter = (string)config('ldap_auth.custom_filter');
|
$database->email = $ldap->getFirstAttribute('mail');
|
||||||
if ('' !== $filter) {
|
$database->save();
|
||||||
$query->rawFilter($filter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -70,7 +70,7 @@ class Configuration extends Model
|
|||||||
protected $table = 'configuration';
|
protected $table = 'configuration';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO can be replaced by native laravel code
|
* See reference nr. 17
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*
|
*
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
|
@ -319,7 +319,7 @@ class TransactionJournal extends Model
|
|||||||
if (!self::isJoined($query, 'transaction_types')) {
|
if (!self::isJoined($query, 'transaction_types')) {
|
||||||
$query->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
|
$query->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
|
||||||
}
|
}
|
||||||
if (0 !== count($types)) {
|
if (!empty($types)) {
|
||||||
$query->whereIn('transaction_types.type', $types);
|
$query->whereIn('transaction_types.type', $types);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,12 +125,12 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
{
|
{
|
||||||
$query = $this->user->accounts()->where('iban', '!=', '')->whereNotNull('iban');
|
$query = $this->user->accounts()->where('iban', '!=', '')->whereNotNull('iban');
|
||||||
|
|
||||||
if (0 !== count($types)) {
|
if (!empty($types)) {
|
||||||
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
||||||
$query->whereIn('account_types.type', $types);
|
$query->whereIn('account_types.type', $types);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO a loop like this is no longer necessary
|
// See reference nr. 9
|
||||||
|
|
||||||
$accounts = $query->get(['accounts.*']);
|
$accounts = $query->get(['accounts.*']);
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
@ -153,7 +153,7 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
{
|
{
|
||||||
$query = $this->user->accounts();
|
$query = $this->user->accounts();
|
||||||
|
|
||||||
if (0 !== count($types)) {
|
if (!empty($types)) {
|
||||||
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
||||||
$query->whereIn('account_types.type', $types);
|
$query->whereIn('account_types.type', $types);
|
||||||
}
|
}
|
||||||
@ -161,7 +161,7 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
|
|
||||||
$accounts = $query->get(['accounts.*']);
|
$accounts = $query->get(['accounts.*']);
|
||||||
|
|
||||||
// TODO no longer need to loop like this
|
// See reference nr. 10
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
@ -222,7 +222,7 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
{
|
{
|
||||||
$query = $this->user->accounts();
|
$query = $this->user->accounts();
|
||||||
|
|
||||||
if (0 !== count($accountIds)) {
|
if (!empty($accountIds)) {
|
||||||
$query->whereIn('accounts.id', $accountIds);
|
$query->whereIn('accounts.id', $accountIds);
|
||||||
}
|
}
|
||||||
$query->orderBy('accounts.order', 'ASC');
|
$query->orderBy('accounts.order', 'ASC');
|
||||||
@ -242,19 +242,19 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
{
|
{
|
||||||
$res = array_intersect([AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], $types);
|
$res = array_intersect([AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], $types);
|
||||||
$query = $this->user->accounts();
|
$query = $this->user->accounts();
|
||||||
if (0 !== count($types)) {
|
if (!empty($types)) {
|
||||||
$query->accountTypeIn($types);
|
$query->accountTypeIn($types);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add sort parameters. At this point they're filtered to allowed fields to sort by:
|
// add sort parameters. At this point they're filtered to allowed fields to sort by:
|
||||||
if (count($sort) > 0) {
|
if (!empty($sort)) {
|
||||||
foreach ($sort as $param) {
|
foreach ($sort as $param) {
|
||||||
$query->orderBy($param[0], $param[1]);
|
$query->orderBy($param[0], $param[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 === count($sort)) {
|
if (empty($sort)) {
|
||||||
if (0 !== count($res)) {
|
if (!empty($res)) {
|
||||||
$query->orderBy('accounts.order', 'ASC');
|
$query->orderBy('accounts.order', 'ASC');
|
||||||
}
|
}
|
||||||
$query->orderBy('accounts.active', 'DESC');
|
$query->orderBy('accounts.active', 'DESC');
|
||||||
@ -276,7 +276,7 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
$query->where('name', 'account_role');
|
$query->where('name', 'account_role');
|
||||||
}, 'attachments']
|
}, 'attachments']
|
||||||
);
|
);
|
||||||
if (0 !== count($types)) {
|
if (!empty($types)) {
|
||||||
$query->accountTypeIn($types);
|
$query->accountTypeIn($types);
|
||||||
}
|
}
|
||||||
$query->where('active', true);
|
$query->where('active', true);
|
||||||
@ -336,7 +336,7 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
$query->where('name', 'account_role');
|
$query->where('name', 'account_role');
|
||||||
}]
|
}]
|
||||||
);
|
);
|
||||||
if (0 !== count($types)) {
|
if (!empty($types)) {
|
||||||
$query->accountTypeIn($types);
|
$query->accountTypeIn($types);
|
||||||
}
|
}
|
||||||
$query->where('active', 0);
|
$query->where('active', 0);
|
||||||
@ -674,7 +674,7 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (0 !== count($types)) {
|
if (!empty($types)) {
|
||||||
$dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
$dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
||||||
$dbQuery->whereIn('account_types.type', $types);
|
$dbQuery->whereIn('account_types.type', $types);
|
||||||
}
|
}
|
||||||
@ -712,7 +712,7 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0 !== count($types)) {
|
if (!empty($types)) {
|
||||||
$dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
$dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
||||||
$dbQuery->whereIn('account_types.type', $types);
|
$dbQuery->whereIn('account_types.type', $types);
|
||||||
}
|
}
|
||||||
@ -791,7 +791,7 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (0 !== count($types)) {
|
if (!empty($types)) {
|
||||||
$dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
$dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
||||||
$dbQuery->whereIn('account_types.type', $types);
|
$dbQuery->whereIn('account_types.type', $types);
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
{
|
{
|
||||||
$bills = $this->user->bills()->get(['bills.*']);
|
$bills = $this->user->bills()->get(['bills.*']);
|
||||||
|
|
||||||
// TODO no longer need to loop like this
|
// See reference nr. 6
|
||||||
|
|
||||||
/** @var Bill $bill */
|
/** @var Bill $bill */
|
||||||
foreach ($bills as $bill) {
|
foreach ($bills as $bill) {
|
||||||
|
@ -72,7 +72,7 @@ interface BudgetLimitRepositoryInterface
|
|||||||
public function find(Budget $budget, TransactionCurrency $currency, Carbon $start, Carbon $end): ?BudgetLimit;
|
public function find(Budget $budget, TransactionCurrency $currency, Carbon $start, Carbon $end): ?BudgetLimit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO this method is not multi-currency aware.
|
* See reference nr. 11
|
||||||
*
|
*
|
||||||
* @param Carbon|null $start
|
* @param Carbon|null $start
|
||||||
* @param Carbon|null $end
|
* @param Carbon|null $end
|
||||||
|
@ -74,7 +74,7 @@ interface BudgetRepositoryInterface
|
|||||||
public function findByName(?string $name): ?Budget;
|
public function findByName(?string $name): ?Budget;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO refactor to "find"
|
* See reference nr. 12
|
||||||
*
|
*
|
||||||
* @param int|null $budgetId
|
* @param int|null $budgetId
|
||||||
*
|
*
|
||||||
|
@ -146,8 +146,8 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
|
|||||||
|
|
||||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||||
/**
|
/**
|
||||||
* TODO this method does not include foreign amount transactions. It only sums up "amount".
|
* See reference nr. 15
|
||||||
* TODO this probably also applies to the other "sumExpenses" methods.
|
* See reference nr. 16
|
||||||
*
|
*
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
|
@ -227,7 +227,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
|||||||
if ($accounts->count() > 0) {
|
if ($accounts->count() > 0) {
|
||||||
$collector->setAccounts($accounts);
|
$collector->setAccounts($accounts);
|
||||||
}
|
}
|
||||||
// TODO possible candidate for getExtractedGroups
|
// See reference nr. 13
|
||||||
$set = $collector->getGroups();
|
$set = $collector->getGroups();
|
||||||
$return = [];
|
$return = [];
|
||||||
$total = [];
|
$total = [];
|
||||||
@ -359,7 +359,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* For now, simply refer to whichever repository holds this function.
|
* For now, simply refer to whichever repository holds this function.
|
||||||
* TODO might be done better in the future.
|
* See reference nr. 14
|
||||||
*
|
*
|
||||||
* @param Budget $budget
|
* @param Budget $budget
|
||||||
* @param Carbon|null $start
|
* @param Carbon|null $start
|
||||||
|
@ -89,7 +89,7 @@ class CategoryRepository implements CategoryRepositoryInterface
|
|||||||
{
|
{
|
||||||
$categories = $this->user->categories()->get(['categories.*']);
|
$categories = $this->user->categories()->get(['categories.*']);
|
||||||
|
|
||||||
// TODO no longer need to loop like this
|
// See reference nr. 7
|
||||||
|
|
||||||
foreach ($categories as $category) {
|
foreach ($categories as $category) {
|
||||||
if ($category->name === $name) {
|
if ($category->name === $name) {
|
||||||
|
@ -58,7 +58,7 @@ interface JournalRepositoryInterface
|
|||||||
public function findByType(array $types): Collection;
|
public function findByType(array $types): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO Refactor to "find".
|
* See reference nr. 1
|
||||||
* Find a specific journal.
|
* Find a specific journal.
|
||||||
*
|
*
|
||||||
* @param int $journalId
|
* @param int $journalId
|
||||||
@ -85,7 +85,7 @@ interface JournalRepositoryInterface
|
|||||||
public function getDestinationAccount(TransactionJournal $journal): Account;
|
public function getDestinationAccount(TransactionJournal $journal): Account;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO this method is no longer well-fitted in 4.8,0. Should be refactored and/or removed.
|
* See reference nr. 2
|
||||||
* Return a list of all destination accounts related to journal.
|
* Return a list of all destination accounts related to journal.
|
||||||
*
|
*
|
||||||
* @param TransactionJournal $journal
|
* @param TransactionJournal $journal
|
||||||
@ -96,7 +96,7 @@ interface JournalRepositoryInterface
|
|||||||
public function getJournalDestinationAccounts(TransactionJournal $journal): Collection;
|
public function getJournalDestinationAccounts(TransactionJournal $journal): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO this method is no longer well-fitted in 4.8,0. Should be refactored and/or removed.
|
* See reference nr. 3
|
||||||
* Return a list of all source accounts related to journal.
|
* Return a list of all source accounts related to journal.
|
||||||
*
|
*
|
||||||
* @param TransactionJournal $journal
|
* @param TransactionJournal $journal
|
||||||
@ -121,7 +121,7 @@ interface JournalRepositoryInterface
|
|||||||
public function getLast(): ?TransactionJournal;
|
public function getLast(): ?TransactionJournal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO used only in transformer, so only for API use.
|
* See reference nr. 4
|
||||||
*
|
*
|
||||||
* @param TransactionJournalLink $link
|
* @param TransactionJournalLink $link
|
||||||
*
|
*
|
||||||
@ -150,7 +150,7 @@ interface JournalRepositoryInterface
|
|||||||
public function getSourceAccount(TransactionJournal $journal): Account;
|
public function getSourceAccount(TransactionJournal $journal): Account;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO maybe move to account repository?
|
* See reference nr. 5
|
||||||
*
|
*
|
||||||
* @param int $journalId
|
* @param int $journalId
|
||||||
*/
|
*/
|
||||||
|
@ -355,7 +355,7 @@ class RecurringRepository implements RecurringRepositoryInterface
|
|||||||
foreach ($journalMeta as $journalId) {
|
foreach ($journalMeta as $journalId) {
|
||||||
$search[] = (int)$journalId;
|
$search[] = (int)$journalId;
|
||||||
}
|
}
|
||||||
if (0 === count($search)) {
|
if (empty($search)) {
|
||||||
|
|
||||||
return new Collection;
|
return new Collection;
|
||||||
}
|
}
|
||||||
|
@ -542,8 +542,6 @@ class RuleRepository implements RuleRepositoryInterface
|
|||||||
'order' => $order,
|
'order' => $order,
|
||||||
'active' => $active,
|
'active' => $active,
|
||||||
];
|
];
|
||||||
app('telemetry')->feature('rules.triggers.uses_trigger', $trigger['type']);
|
|
||||||
|
|
||||||
$this->storeTrigger($rule, $triggerValues);
|
$this->storeTrigger($rule, $triggerValues);
|
||||||
++$order;
|
++$order;
|
||||||
}
|
}
|
||||||
@ -571,8 +569,6 @@ class RuleRepository implements RuleRepositoryInterface
|
|||||||
'order' => $order,
|
'order' => $order,
|
||||||
'active' => $active,
|
'active' => $active,
|
||||||
];
|
];
|
||||||
app('telemetry')->feature('rules.actions.uses_action', $action['type']);
|
|
||||||
|
|
||||||
$this->storeAction($rule, $actionValues);
|
$this->storeAction($rule, $actionValues);
|
||||||
++$order;
|
++$order;
|
||||||
}
|
}
|
||||||
|
@ -380,7 +380,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
|
|||||||
{
|
{
|
||||||
/** @var GroupUpdateService $service */
|
/** @var GroupUpdateService $service */
|
||||||
$service = app(GroupUpdateService::class);
|
$service = app(GroupUpdateService::class);
|
||||||
|
|
||||||
return $service->update($transactionGroup, $data);
|
return $service->update($transactionGroup, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,9 +397,9 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
|
|||||||
$array['categories'] = $journal->categories->toArray();
|
$array['categories'] = $journal->categories->toArray();
|
||||||
$array['budgets'] = $journal->budgets->toArray();
|
$array['budgets'] = $journal->budgets->toArray();
|
||||||
$array['notes'] = $journal->notes->toArray();
|
$array['notes'] = $journal->notes->toArray();
|
||||||
$array['locations'] = []; // todo
|
$array['locations'] = [];
|
||||||
$array['attachments'] = $journal->attachments->toArray();
|
$array['attachments'] = $journal->attachments->toArray();
|
||||||
$array['links'] = []; // todo
|
$array['links'] = [];
|
||||||
$array['piggy_bank_events'] = $journal->piggyBankEvents->toArray();
|
$array['piggy_bank_events'] = $journal->piggyBankEvents->toArray();
|
||||||
|
|
||||||
/** @var Transaction $transaction */
|
/** @var Transaction $transaction */
|
||||||
|
@ -269,7 +269,7 @@ class UserRepository implements UserRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function hasRole(User $user, string $role): bool
|
public function hasRole(User $user, string $role): bool
|
||||||
{
|
{
|
||||||
// TODO no longer need to loop like this
|
// See reference nr. 8
|
||||||
|
|
||||||
/** @var Role $userRole */
|
/** @var Role $userRole */
|
||||||
foreach ($user->roles as $userRole) {
|
foreach ($user->roles as $userRole) {
|
||||||
|
@ -102,7 +102,7 @@ trait AccountServiceTrait
|
|||||||
/**
|
/**
|
||||||
* Update meta data for account. Depends on type which fields are valid.
|
* Update meta data for account. Depends on type which fields are valid.
|
||||||
*
|
*
|
||||||
* TODO this method treats expense accounts and liabilities the same way (tries to save interest)
|
* See reference nr. 97
|
||||||
*
|
*
|
||||||
* @param Account $account
|
* @param Account $account
|
||||||
* @param array $data
|
* @param array $data
|
||||||
@ -410,7 +410,7 @@ trait AccountServiceTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO rename to "getOpposingTransaction"
|
* See reference nr. 98
|
||||||
*
|
*
|
||||||
* @param TransactionJournal $journal
|
* @param TransactionJournal $journal
|
||||||
* @param Account $account
|
* @param Account $account
|
||||||
@ -705,7 +705,7 @@ trait AccountServiceTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO Refactor to "getFirstJournal"
|
* See reference nr. 99
|
||||||
*
|
*
|
||||||
* @param TransactionGroup $group
|
* @param TransactionGroup $group
|
||||||
*
|
*
|
||||||
|
@ -67,7 +67,7 @@ class CreditRecalculateService
|
|||||||
// work based on account.
|
// work based on account.
|
||||||
$this->processAccount();
|
$this->processAccount();
|
||||||
}
|
}
|
||||||
if (0 === count($this->work)) {
|
if (empty($this->work)) {
|
||||||
Log::debug('No work accounts, do not do CreditRecalculationService');
|
Log::debug('No work accounts, do not do CreditRecalculationService');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -127,7 +127,7 @@ class CreditRecalculateService
|
|||||||
{
|
{
|
||||||
/** @var TransactionJournal $journal */
|
/** @var TransactionJournal $journal */
|
||||||
foreach ($this->group->transactionJournals as $journal) {
|
foreach ($this->group->transactionJournals as $journal) {
|
||||||
if (0 === count($this->work)) {
|
if (empty($this->work)) {
|
||||||
try {
|
try {
|
||||||
$this->findByJournal($journal);
|
$this->findByJournal($journal);
|
||||||
} catch (FireflyException $e) {
|
} catch (FireflyException $e) {
|
||||||
|
@ -145,7 +145,7 @@ trait RecurringTransactionTrait
|
|||||||
if (array_key_exists('foreign_amount', $array) && '' === (string)$array['foreign_amount']) {
|
if (array_key_exists('foreign_amount', $array) && '' === (string)$array['foreign_amount']) {
|
||||||
unset($array['foreign_amount']);
|
unset($array['foreign_amount']);
|
||||||
}
|
}
|
||||||
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
|
// See reference nr. 100
|
||||||
$transaction = new RecurrenceTransaction(
|
$transaction = new RecurrenceTransaction(
|
||||||
[
|
[
|
||||||
'recurrence_id' => $recurrence->id,
|
'recurrence_id' => $recurrence->id,
|
||||||
@ -313,7 +313,7 @@ trait RecurringTransactionTrait
|
|||||||
*/
|
*/
|
||||||
protected function updateTags(RecurrenceTransaction $transaction, array $tags): void
|
protected function updateTags(RecurrenceTransaction $transaction, array $tags): void
|
||||||
{
|
{
|
||||||
if (count($tags) > 0) {
|
if (!empty($tags)) {
|
||||||
/** @var RecurrenceMeta|null $entry */
|
/** @var RecurrenceMeta|null $entry */
|
||||||
$entry = $transaction->recurrenceTransactionMeta()->where('name', 'tags')->first();
|
$entry = $transaction->recurrenceTransactionMeta()->where('name', 'tags')->first();
|
||||||
if (null === $entry) {
|
if (null === $entry) {
|
||||||
@ -322,7 +322,7 @@ trait RecurringTransactionTrait
|
|||||||
$entry->value = json_encode($tags);
|
$entry->value = json_encode($tags);
|
||||||
$entry->save();
|
$entry->save();
|
||||||
}
|
}
|
||||||
if (0 === count($tags)) {
|
if (empty($tags)) {
|
||||||
// delete if present
|
// delete if present
|
||||||
$transaction->recurrenceTransactionMeta()->where('name', 'tags')->delete();
|
$transaction->recurrenceTransactionMeta()->where('name', 'tags')->delete();
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ use Log;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AccountUpdateService
|
* Class AccountUpdateService
|
||||||
* TODO this is a mess.
|
* See reference nr. 90
|
||||||
*/
|
*/
|
||||||
class AccountUpdateService
|
class AccountUpdateService
|
||||||
{
|
{
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user