Merge branch 'release/5.6.15'

# Conflicts:
#	yarn.lock
This commit is contained in:
James Cole 2022-02-28 07:10:43 +01:00
commit a8cbbde8fc
No known key found for this signature in database
GPG Key ID: B49A324B7EAD6D80
460 changed files with 30154 additions and 1791 deletions

View File

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

6
.github/mergify.yml vendored
View File

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

11
.gitignore vendored
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

1122
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -98,10 +98,10 @@ return [
'feature_flags' => [
'export' => true,
'telemetry' => false,
'webhooks' => true,
'webhooks' => false,
'handle_debts' => true,
],
'version' => '5.6.14',
'version' => '5.6.15',
'api_version' => '1.5.5',
'db_version' => 18,
@ -222,6 +222,7 @@ return [
TransactionJournal::class,
Recurrence::class,
],
'valid_view_ranges' => ['1D', '1W', '1M', '3M', '6M', '1Y',],
'allowedMimes' => [
/* plain files */
'text/plain',

70
config/sanctum.php Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

9
frontend/.editorconfig Normal file
View File

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

9
frontend/.eslintignore Normal file
View File

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

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

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

33
frontend/.gitignore vendored Normal file
View File

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

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

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

4
frontend/.prettierrc Normal file
View File

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

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

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

53
frontend/package.json Normal file
View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

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

View File

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

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

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

After

Width:  |  Height:  |  Size: 2.3 KiB

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

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

View File

@ -0,0 +1 @@
{}

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

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

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Destroy {
destroy(identifier) {
let url = '/api/v1/accounts/' + identifier;
return api.delete(url);
}
}

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

@ -0,0 +1,35 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Get {
get(identifier, date) {
let url = '/api/v1/accounts/' + identifier;
if(!date) {
return api.get(url);
}
return api.get(url, {params: {date: date}});
}
transactions(identifier, page, cacheKey) {
let url = '/api/v1/accounts/' + identifier + '/transactions';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

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

@ -0,0 +1,28 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class List {
list(type, page, cacheKey) {
let url = '/api/v1/accounts';
return api.get(url, {params: {page: page, cache: cacheKey, type: type}});
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Post {
post(submission) {
let url = '/api/v1/accounts';
return api.post(url, submission);
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Put {
post(identifier, submission) {
let url = '/api/v1/accounts/' + identifier;
return api.put(url, submission);
}
}

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

@ -0,0 +1,27 @@
/*
* basic.js
* Copyright (c) 2021 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Authenticate {
async authenticate() {
return await api.get('/sanctum/csrf-cookie');
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Destroy {
destroy(identifier) {
let url = 'api/v1/budgets/' + identifier;
return api.delete(url);
}
}

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

@ -0,0 +1,38 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Get {
get(identifier) {
let url = '/api/v1/budgets/' + identifier;
return api.get(url);
}
transactions(identifier, page, cacheKey) {
let url = '/api/v1/budgets/' + identifier + '/transactions';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
transactionsWithoutBudget(page, cacheKey) {
let url = '/api/v1/budgets/transactions-without-budget';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

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

@ -0,0 +1,28 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class List {
list(page, cacheKey) {
let url = '/api/v1/budgets';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Post {
post(submission) {
let url = '/api/v1/budgets';
return api.post(url, submission);
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Put {
post(identifier, submission) {
let url = '/api/v1/budgets/' + identifier;
return api.put(url, submission);
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Destroy {
destroy(identifier) {
let url = '/api/v1/categories/' + identifier;
return api.delete(url);
}
}

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

@ -0,0 +1,36 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Get {
get(identifier) {
let url = '/api/v1/categories/' + identifier;
return api.get(url);
}
transactions(identifier, page, cacheKey) {
let url = '/api/v1/categories/' + identifier + '/transactions';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
transactionsWithoutCategory(page, cacheKey) {
let url = '/api/v1/categories/transactions-without-category';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

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

@ -0,0 +1,28 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class List {
list(page, cacheKey) {
let url = '/api/v1/categories';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Post {
post(submission) {
let url = '/api/v1/categories';
return api.post(url, submission);
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Put {
post(identifier, submission) {
let url = '/api/v1/categories/' + identifier;
return api.put(url, submission);
}
}

View File

@ -0,0 +1,30 @@
/*
* overview.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
import {format} from "date-fns";
export default class Overview {
overview(range, cacheKey) {
let startStr = format(range.start, 'y-MM-dd');
let endStr = format(range.end, 'y-MM-dd');
return api.get('/api/v1/chart/account/overview', {params: {start: startStr, end: endStr, cache: cacheKey}});
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Destroy {
destroy(identifier) {
let url = '/api/v1/currencies/' + identifier;
return api.delete(url);
}
}

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

@ -0,0 +1,32 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Get {
get(identifier) {
let url = '/api/v1/currencies/' + identifier;
return api.get(url);
}
transactions(identifier, page, cacheKey) {
let url = '/api/v1/currencies/' + identifier + '/transactions';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

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

@ -0,0 +1,28 @@
/*
* basic.js
* Copyright (c) 2021 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
import Authenticate from '../authenticate/index';
export default class Currencies {
default() {
let auth = new Authenticate();
return auth.authenticate().then(() => {return api.get('/api/v1/currencies/default')});
}
}

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

@ -0,0 +1,28 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class List {
list(page, cacheKey) {
let url = '/api/v1/currencies';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

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

@ -0,0 +1,32 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Post {
post(submission) {
let url = '/api/v1/currencies';
return api.post(url, submission);
}
makeDefault(currency) {
let url = '/api/v1/currencies/' + currency + '/default';
return api.post(url);
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Put {
post(identifier, submission) {
let url = '/api/v1/currencies/' + identifier;
return api.put(url, submission);
}
}

28
frontend/src/api/data/export.js vendored Normal file
View File

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Export {
transactions(start, end) {
let url = '/api/v1/data/export/transactions';
return api.get(url, {params: {start: start, end: end}});
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Destroy {
destroy(identifier) {
let url = '/api/v1/object_groups/' + identifier;
return api.delete(url);
}
}

28
frontend/src/api/groups/get.js vendored Normal file
View File

@ -0,0 +1,28 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Get {
get(identifier) {
let url = '/api/v1/object_groups/' + identifier;
return api.get(url);
}
}

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

@ -0,0 +1,28 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class List {
list(type, page, cacheKey) {
let url = '/api/v1/object_groups';
return api.get(url, {params: {page: page, cache: cacheKey, type: type}});
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Put {
post(identifier, submission) {
let url = '/api/v1/object_groups/' + identifier;
return api.put(url, submission);
}
}

28
frontend/src/api/piggy-banks/destroy.js vendored Normal file
View File

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Destroy {
destroy(identifier) {
let url = '/api/v1/piggy_banks/' + identifier;
return api.delete(url);
}
}

32
frontend/src/api/piggy-banks/get.js vendored Normal file
View File

@ -0,0 +1,32 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Get {
get(identifier) {
let url = '/api/v1/piggy_banks/' + identifier;
return api.get(url);
}
transactions(identifier, page, cacheKey) {
let url = '/api/v1/piggy_banks/' + identifier + '/transactions';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

28
frontend/src/api/piggy-banks/list.js vendored Normal file
View File

@ -0,0 +1,28 @@
/*
* list.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class List {
list(page, cacheKey) {
let url = '/api/v1/piggy_banks';
return api.get(url, {params: {page: page, cache: cacheKey}});
}
}

28
frontend/src/api/piggy-banks/post.js vendored Normal file
View File

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Post {
post(submission) {
let url = '/api/v1/piggy_banks';
return api.post(url, submission);
}
}

28
frontend/src/api/piggy-banks/put.js vendored Normal file
View File

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Put {
post(identifier, submission) {
let url = '/api/v1/piggy_banks/' + identifier;
return api.put(url, submission);
}
}

30
frontend/src/api/preferences/index.js vendored Normal file
View File

@ -0,0 +1,30 @@
/*
* basic.js
* Copyright (c) 2021 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Preferences {
getByName(name) {
return api.get('/api/v1/preferences/' + name);
}
postByName(name, value) {
return api.post('/api/v1/preferences', {name: name, data: value});
}
}

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

@ -0,0 +1,28 @@
/*
* post.js
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {api} from "boot/axios";
export default class Put {
put(name, value) {
let url = '/api/v1/preferences/' + name;
return api.put(url, {data: value});
}
}

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