From 01cce49070f110414ae86e2ca875e3f0fcc84727 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 20 Aug 2025 06:22:55 +0200 Subject: [PATCH] Expand webhook API, edit and create screen. --- .../V1/Controllers/Webhook/ShowController.php | 7 ++ .../Controllers/Webhook/StoreController.php | 11 ++ .../Controllers/Webhook/UpdateController.php | 27 +++-- .../Requests/Models/Webhook/CreateRequest.php | 114 ++++++++++-------- .../Requests/Models/Webhook/UpdateRequest.php | 110 +++++++++-------- app/Enums/WebhookResponse.php | 1 + .../Webhook/WebhookRepository.php | 80 +++++++++++- config/webhooks.php | 79 ++++++++++++ public/v1/js/.gitkeep | 0 .../src/components/form/WebhookDelivery.vue | 4 +- .../src/components/form/WebhookResponse.vue | 4 +- .../v1/src/components/form/WebhookTrigger.vue | 9 +- .../v1/src/components/webhooks/Create.vue | 42 +++---- .../v1/src/components/webhooks/Edit.vue | 88 ++++---------- .../v1/src/components/webhooks/Index.vue | 28 +++-- .../v1/src/components/webhooks/Show.vue | 42 +++++-- resources/lang/en_US/firefly.php | 4 +- resources/lang/en_US/validation.php | 3 + 18 files changed, 421 insertions(+), 232 deletions(-) create mode 100644 config/webhooks.php mode change 100644 => 100755 public/v1/js/.gitkeep diff --git a/app/Api/V1/Controllers/Webhook/ShowController.php b/app/Api/V1/Controllers/Webhook/ShowController.php index cfc2b1ab39..69be75a49a 100644 --- a/app/Api/V1/Controllers/Webhook/ShowController.php +++ b/app/Api/V1/Controllers/Webhook/ShowController.php @@ -126,6 +126,13 @@ class ShowController extends Controller Log::channel('audit')->info(sprintf('User views webhook #%d.', $webhook->id)); $manager = $this->getManager(); + // enrich + /** @var User $admin */ + $admin = auth()->user(); + $enrichment = new WebhookEnrichment(); + $enrichment->setUser($admin); + $webhook = $enrichment->enrichSingle($webhook); + /** @var WebhookTransformer $transformer */ $transformer = app(WebhookTransformer::class); $transformer->setParameters($this->parameters); diff --git a/app/Api/V1/Controllers/Webhook/StoreController.php b/app/Api/V1/Controllers/Webhook/StoreController.php index 77ea1de82a..12c7b1bf75 100644 --- a/app/Api/V1/Controllers/Webhook/StoreController.php +++ b/app/Api/V1/Controllers/Webhook/StoreController.php @@ -27,7 +27,9 @@ namespace FireflyIII\Api\V1\Controllers\Webhook; use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Requests\Models\Webhook\CreateRequest; use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface; +use FireflyIII\Support\JsonApi\Enrichments\WebhookEnrichment; use FireflyIII\Transformers\WebhookTransformer; +use FireflyIII\User; use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Log; use League\Fractal\Resource\Item; @@ -68,6 +70,15 @@ class StoreController extends Controller } $webhook = $this->repository->store($data); + + // enrich + /** @var User $admin */ + $admin = auth()->user(); + $enrichment = new WebhookEnrichment(); + $enrichment->setUser($admin); + $webhook = $enrichment->enrichSingle($webhook); + + $manager = $this->getManager(); Log::channel('audit')->info('User stores new webhook', $data); diff --git a/app/Api/V1/Controllers/Webhook/UpdateController.php b/app/Api/V1/Controllers/Webhook/UpdateController.php index 7e2e0e2353..96411d5ca1 100644 --- a/app/Api/V1/Controllers/Webhook/UpdateController.php +++ b/app/Api/V1/Controllers/Webhook/UpdateController.php @@ -24,15 +24,17 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Controllers\Webhook; -use FireflyIII\Api\V1\Controllers\Controller; -use FireflyIII\Api\V1\Requests\Models\Webhook\UpdateRequest; -use FireflyIII\Models\Webhook; -use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface; -use FireflyIII\Transformers\WebhookTransformer; -use Illuminate\Http\JsonResponse; -use Illuminate\Support\Facades\Log; -use League\Fractal\Resource\Item; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; + use FireflyIII\Api\V1\Controllers\Controller; + use FireflyIII\Api\V1\Requests\Models\Webhook\UpdateRequest; + use FireflyIII\Models\Webhook; + use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface; + use FireflyIII\Support\JsonApi\Enrichments\WebhookEnrichment; + use FireflyIII\Transformers\WebhookTransformer; + use FireflyIII\User; + use Illuminate\Http\JsonResponse; + use Illuminate\Support\Facades\Log; + use League\Fractal\Resource\Item; + use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Class UpdateController @@ -70,6 +72,13 @@ class UpdateController extends Controller $webhook = $this->repository->update($webhook, $data); $manager = $this->getManager(); + // enrich + /** @var User $admin */ + $admin = auth()->user(); + $enrichment = new WebhookEnrichment(); + $enrichment->setUser($admin); + $webhook = $enrichment->enrichSingle($webhook); + Log::channel('audit')->info(sprintf('User updates webhook #%d', $webhook->id), $data); /** @var WebhookTransformer $transformer */ diff --git a/app/Api/V1/Requests/Models/Webhook/CreateRequest.php b/app/Api/V1/Requests/Models/Webhook/CreateRequest.php index 66064a0e19..51bef14ad3 100644 --- a/app/Api/V1/Requests/Models/Webhook/CreateRequest.php +++ b/app/Api/V1/Requests/Models/Webhook/CreateRequest.php @@ -24,8 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Requests\Models\Webhook; -use FireflyIII\Enums\WebhookResponse; -use FireflyIII\Enums\WebhookTrigger; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Webhook; use FireflyIII\Rules\IsBoolean; use FireflyIII\Support\Request\ChecksLogin; @@ -44,24 +43,24 @@ class CreateRequest extends FormRequest public function getData(): array { - $triggers = Webhook::getTriggersForValidation(); - $responses = Webhook::getResponsesForValidation(); - $deliveries = Webhook::getDeliveriesForValidation(); - - $fields = [ - 'title' => ['title', 'convertString'], - 'active' => ['active', 'boolean'], - 'trigger' => ['trigger', 'convertString'], - 'response' => ['response', 'convertString'], - 'delivery' => ['delivery', 'convertString'], - 'url' => ['url', 'convertString'], + $fields = [ + 'title' => ['title', 'convertString'], + 'active' => ['active', 'boolean'], + 'url' => ['url', 'convertString'], ]; + $triggers = $this->get('triggers', []); + $responses = $this->get('responses', []); + $deliveries = $this->get('deliveries', []); - // this is the way. - $return = $this->getAllData($fields); - $return['trigger'] = $triggers[$return['trigger']] ?? (int)$return['trigger']; - $return['response'] = $responses[$return['response']] ?? (int)$return['response']; - $return['delivery'] = $deliveries[$return['delivery']] ?? (int)$return['delivery']; + if (0 === count($triggers) || 0 === count($responses) || 0 === count($deliveries)) { + throw new FireflyException('Unexpectedly got no responses, triggers or deliveries.'); + } + + + $return = $this->getAllData($fields); + $return['triggers'] = $triggers; + $return['responses'] = $responses; + $return['deliveries'] = $deliveries; return $return; } @@ -71,18 +70,24 @@ class CreateRequest extends FormRequest */ public function rules(): array { - $triggers = implode(',', array_keys(Webhook::getTriggersForValidation())); - $responses = implode(',', array_keys(Webhook::getResponsesForValidation())); - $deliveries = implode(',', array_keys(Webhook::getDeliveriesForValidation())); + $triggers = implode(',', array_values(Webhook::getTriggers())); + $responses = implode(',', array_values(Webhook::getResponses())); + $deliveries = implode(',', array_values(Webhook::getDeliveries())); $validProtocols = config('firefly.valid_url_protocols'); return [ - 'title' => 'required|min:1|max:255|uniqueObjectForUser:webhooks,title', - 'active' => [new IsBoolean()], - 'trigger' => sprintf('required|in:%s', $triggers), - 'response' => sprintf('required|in:%s', $responses), - 'delivery' => sprintf('required|in:%s', $deliveries), - 'url' => ['required', sprintf('url:%s', $validProtocols), 'uniqueWebhook'], + 'title' => 'required|min:1|max:255|uniqueObjectForUser:webhooks,title', + 'active' => [new IsBoolean()], + 'trigger' => 'prohibited', + 'triggers' => 'required|array|min:1|max:10', + 'triggers.*' => sprintf('required|in:%s', $triggers), + 'response' => 'prohibited', + 'responses' => 'required|array|min:1|max:1', + 'responses.*' => sprintf('required|in:%s', $responses), + 'delivery' => 'prohibited', + 'deliveries' => 'required|array|min:1|max:1', + 'deliveries.*' => sprintf('required|in:%s', $deliveries), + 'url' => ['required', sprintf('url:%s', $validProtocols)], ]; } @@ -91,37 +96,44 @@ class CreateRequest extends FormRequest $validator->after( function (Validator $validator): void { Log::debug('Validating webhook'); + if ($validator->failed()) { + return; + } $data = $validator->getData(); - $trigger = $data['trigger'] ?? null; - $response = $data['response'] ?? null; - if (null === $trigger || null === $response) { + $triggers = $data['triggers'] ?? []; + $responses = $data['responses'] ?? []; + + if (0 === count($triggers) || 0 === count($responses)) { Log::debug('No trigger or response, return.'); return; } - $triggers = array_keys(Webhook::getTriggersForValidation()); - $responses = array_keys(Webhook::getResponsesForValidation()); - if (!in_array($trigger, $triggers, true) || !in_array($response, $responses, true)) { - return; + $validTriggers = array_values(Webhook::getTriggers()); + $validResponses = array_values(Webhook::getResponses()); + foreach ($triggers as $trigger) { + if (!in_array($trigger, $validTriggers, true)) { + return; + } } - // cannot deliver budget info. - if (is_int($trigger)) { - Log::debug(sprintf('Trigger was integer (%d).', $trigger)); - $trigger = WebhookTrigger::from($trigger)->name; + foreach ($responses as $response) { + if (!in_array($response, $validResponses, true)) { + return; + } } - if (is_int($response)) { - Log::debug(sprintf('Response was integer (%d).', $response)); - $response = WebhookResponse::from($response)->name; - } - Log::debug(sprintf('Trigger is %s, response is %s', $trigger, $response)); - if (str_contains($trigger, 'TRANSACTION') && str_contains($response, 'BUDGET')) { - $validator->errors()->add('response', trans('validation.webhook_budget_info')); - } - if (str_contains($trigger, 'BUDGET') && str_contains($response, 'ACCOUNT')) { - $validator->errors()->add('response', trans('validation.webhook_account_info')); - } - if (str_contains($trigger, 'BUDGET') && str_contains($response, 'TRANSACTION')) { - $validator->errors()->add('response', trans('validation.webhook_transaction_info')); + // some combinations are illegal. + foreach ($triggers as $i => $trigger) { + $forbidden = config(sprintf('webhooks.forbidden_responses.%s', $trigger)); + if (null === $forbidden) { + $validator->errors()->add(sprintf('triggers.%d', $i), trans('validation.unknown_webhook_trigger', ['trigger' => $trigger,])); + continue; + } + foreach ($responses as $ii => $response) { + if (in_array($response, $forbidden, true)) { + Log::debug(sprintf('Trigger %s and response %s are forbidden.', $trigger, $response)); + $validator->errors()->add(sprintf('responses.%d', $ii), trans('validation.bad_webhook_combination', ['trigger' => $trigger, 'response' => $response,])); + return; + } + } } } ); diff --git a/app/Api/V1/Requests/Models/Webhook/UpdateRequest.php b/app/Api/V1/Requests/Models/Webhook/UpdateRequest.php index d235ca048c..a3c2eed05a 100644 --- a/app/Api/V1/Requests/Models/Webhook/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/Webhook/UpdateRequest.php @@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Webhook; use FireflyIII\Enums\WebhookResponse; use FireflyIII\Enums\WebhookTrigger; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Webhook; use FireflyIII\Rules\IsBoolean; use FireflyIII\Support\Request\ChecksLogin; @@ -44,35 +45,25 @@ class UpdateRequest extends FormRequest public function getData(): array { - $triggers = Webhook::getTriggersForValidation(); - $responses = Webhook::getResponsesForValidation(); - $deliveries = Webhook::getDeliveriesForValidation(); - $fields = [ 'title' => ['title', 'convertString'], 'active' => ['active', 'boolean'], - 'trigger' => ['trigger', 'convertString'], - 'response' => ['response', 'convertString'], - 'delivery' => ['delivery', 'convertString'], 'url' => ['url', 'convertString'], ]; - // this is the way. - $return = $this->getAllData($fields); - if (array_key_exists('trigger', $return)) { - $return['trigger'] = $triggers[$return['trigger']] ?? 0; - } - if (array_key_exists('response', $return)) { - $return['response'] = $responses[$return['response']] ?? 0; - } - if (array_key_exists('delivery', $return)) { - $return['delivery'] = $deliveries[$return['delivery']] ?? 0; - } - $return['secret'] = null !== $this->get('secret'); - if (null !== $this->get('title')) { - $return['title'] = $this->convertString('title'); + $triggers = $this->get('triggers', []); + $responses = $this->get('responses', []); + $deliveries = $this->get('deliveries', []); + + if (0 === count($triggers) || 0 === count($responses) || 0 === count($deliveries)) { + throw new FireflyException('Unexpectedly got no responses, triggers or deliveries.'); } + $return = $this->getAllData($fields); + $return['triggers'] = $triggers; + $return['responses'] = $responses; + $return['deliveries'] = $deliveries; + return $return; } @@ -81,9 +72,9 @@ class UpdateRequest extends FormRequest */ public function rules(): array { - $triggers = implode(',', array_keys(Webhook::getTriggersForValidation())); - $responses = implode(',', array_keys(Webhook::getResponsesForValidation())); - $deliveries = implode(',', array_keys(Webhook::getDeliveriesForValidation())); + $triggers = implode(',', array_values(Webhook::getTriggers())); + $responses = implode(',', array_values(Webhook::getResponses())); + $deliveries = implode(',', array_values(Webhook::getDeliveries())); $validProtocols = config('firefly.valid_url_protocols'); /** @var Webhook $webhook */ @@ -92,9 +83,17 @@ class UpdateRequest extends FormRequest return [ 'title' => sprintf('min:1|max:255|uniqueObjectForUser:webhooks,title,%d', $webhook->id), 'active' => [new IsBoolean()], - 'trigger' => sprintf('in:%s', $triggers), - 'response' => sprintf('in:%s', $responses), - 'delivery' => sprintf('in:%s', $deliveries), + + 'trigger' => 'prohibited', + 'triggers' => 'required|array|min:1|max:10', + 'triggers.*' => sprintf('required|in:%s', $triggers), + 'response' => 'prohibited', + 'responses' => 'required|array|min:1|max:1', + 'responses.*' => sprintf('required|in:%s', $responses), + 'delivery' => 'prohibited', + 'deliveries' => 'required|array|min:1|max:1', + 'deliveries.*' => sprintf('required|in:%s', $deliveries), + 'url' => [sprintf('url:%s', $validProtocols), sprintf('uniqueExistingWebhook:%d', $webhook->id)], ]; } @@ -104,38 +103,47 @@ class UpdateRequest extends FormRequest $validator->after( function (Validator $validator): void { Log::debug('Validating webhook'); + + if ($validator->failed()) { + return; + } $data = $validator->getData(); - $trigger = $data['trigger'] ?? null; - $response = $data['response'] ?? null; - if (null === $trigger || null === $response) { + $triggers = $data['triggers'] ?? []; + $responses = $data['responses'] ?? []; + + if (0 === count($triggers) || 0 === count($responses)) { Log::debug('No trigger or response, return.'); return; } - $triggers = array_keys(Webhook::getTriggersForValidation()); - $responses = array_keys(Webhook::getResponsesForValidation()); - if (!in_array($trigger, $triggers, true) || !in_array($response, $responses, true)) { - return; + $validTriggers = array_values(Webhook::getTriggers()); + $validResponses = array_values(Webhook::getResponses()); + foreach ($triggers as $trigger) { + if (!in_array($trigger, $validTriggers, true)) { + return; + } } - // cannot deliver budget info. - if (is_int($trigger)) { - Log::debug(sprintf('Trigger was integer (%d).', $trigger)); - $trigger = WebhookTrigger::from($trigger)->name; + foreach ($responses as $response) { + if (!in_array($response, $validResponses, true)) { + return; + } } - if (is_int($response)) { - Log::debug(sprintf('Response was integer (%d).', $response)); - $response = WebhookResponse::from($response)->name; - } - Log::debug(sprintf('Trigger is %s, response is %s', $trigger, $response)); - if (str_contains($trigger, 'TRANSACTION') && str_contains($response, 'BUDGET')) { - $validator->errors()->add('response', trans('validation.webhook_budget_info')); - } - if (str_contains($trigger, 'BUDGET') && str_contains($response, 'ACCOUNT')) { - $validator->errors()->add('response', trans('validation.webhook_account_info')); - } - if (str_contains($trigger, 'BUDGET') && str_contains($response, 'TRANSACTION')) { - $validator->errors()->add('response', trans('validation.webhook_transaction_info')); + // some combinations are illegal. + foreach ($triggers as $i => $trigger) { + $forbidden = config(sprintf('webhooks.forbidden_responses.%s', $trigger)); + if (null === $forbidden) { + $validator->errors()->add(sprintf('triggers.%d', $i), trans('validation.unknown_webhook_trigger', ['trigger' => $trigger,])); + continue; + } + foreach ($responses as $ii => $response) { + if (in_array($response, $forbidden, true)) { + Log::debug(sprintf('Trigger %s and response %s are forbidden.', $trigger, $response)); + $validator->errors()->add(sprintf('responses.%d', $ii), trans('validation.bad_webhook_combination', ['trigger' => $trigger, 'response' => $response,])); + return; + } + } } + } ); } diff --git a/app/Enums/WebhookResponse.php b/app/Enums/WebhookResponse.php index ead11117a0..f1dfa213e6 100644 --- a/app/Enums/WebhookResponse.php +++ b/app/Enums/WebhookResponse.php @@ -32,5 +32,6 @@ enum WebhookResponse: int case TRANSACTIONS = 200; case ACCOUNTS = 210; case BUDGET = 230; + case RELEVANT = 240; case NONE = 220; } diff --git a/app/Repositories/Webhook/WebhookRepository.php b/app/Repositories/Webhook/WebhookRepository.php index 64f6230ac3..7a54e0fd7c 100644 --- a/app/Repositories/Webhook/WebhookRepository.php +++ b/app/Repositories/Webhook/WebhookRepository.php @@ -24,9 +24,13 @@ declare(strict_types=1); namespace FireflyIII\Repositories\Webhook; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Webhook; use FireflyIII\Models\WebhookAttempt; +use FireflyIII\Models\WebhookDelivery; use FireflyIII\Models\WebhookMessage; +use FireflyIII\Models\WebhookResponse; +use FireflyIII\Models\WebhookTrigger; use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface; use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait; use Illuminate\Support\Collection; @@ -105,26 +109,92 @@ class WebhookRepository implements WebhookRepositoryInterface, UserGroupInterfac 'secret' => $secret, 'url' => $data['url'], ]; + /** @var Webhook $webhook */ + $webhook = Webhook::create($fullData); + $triggers = new Collection(); + $responses = new Collection(); + $deliveries = new Collection(); - return Webhook::create($fullData); + foreach ($data['triggers'] as $trigger) { + // get the relevant ID: + $object = WebhookTrigger::where('title', $trigger)->first(); + if (null === $object) { + throw new FireflyException(sprintf('Could not find webhook trigger with title "%s".', $trigger)); + } + $triggers->push($object); + } + $webhook->webhookTriggers()->saveMany($triggers); + + foreach ($data['responses'] as $response) { + // get the relevant ID: + $object = WebhookResponse::where('title', $response)->first(); + if (null === $object) { + throw new FireflyException(sprintf('Could not find webhook response with title "%s".', $response)); + } + $responses->push($object); + } + $webhook->webhookResponses()->saveMany($responses); + + foreach ($data['deliveries'] as $delivery) { + // get the relevant ID: + $object = WebhookDelivery::where('title', $delivery)->first(); + if (null === $object) { + throw new FireflyException(sprintf('Could not find webhook delivery with title "%s".', $delivery)); + } + $deliveries->push($object); + } + $webhook->webhookDeliveries()->saveMany($deliveries); + + return $webhook; } public function update(Webhook $webhook, array $data): Webhook { $webhook->active = $data['active'] ?? $webhook->active; -// $webhook->trigger = $data['trigger'] ?? $webhook->trigger; -// $webhook->response = $data['response'] ?? $webhook->response; -// $webhook->delivery = $data['delivery'] ?? $webhook->delivery; $webhook->title = $data['title'] ?? $webhook->title; $webhook->url = $data['url'] ?? $webhook->url; - if (true === $data['secret']) { + if (array_key_exists('secret', $data) && true === $data['secret']) { $secret = Str::random(24); $webhook->secret = $secret; } $webhook->save(); + $triggers = new Collection(); + $responses = new Collection(); + $deliveries = new Collection(); + + foreach ($data['triggers'] as $trigger) { + // get the relevant ID: + $object = WebhookTrigger::where('title', $trigger)->first(); + if (null === $object) { + throw new FireflyException(sprintf('Could not find webhook trigger with title "%s".', $trigger)); + } + $triggers->push($object); + } + $webhook->webhookTriggers()->sync($triggers); + + foreach ($data['responses'] as $response) { + // get the relevant ID: + $object = WebhookResponse::where('title', $response)->first(); + if (null === $object) { + throw new FireflyException(sprintf('Could not find webhook response with title "%s".', $response)); + } + $responses->push($object); + } + $webhook->webhookResponses()->sync($responses); + + foreach ($data['deliveries'] as $delivery) { + // get the relevant ID: + $object = WebhookDelivery::where('title', $delivery)->first(); + if (null === $object) { + throw new FireflyException(sprintf('Could not find webhook delivery with title "%s".', $delivery)); + } + $deliveries->push($object); + } + $webhook->webhookDeliveries()->sync($deliveries); + return $webhook; } } diff --git a/config/webhooks.php b/config/webhooks.php new file mode 100644 index 0000000000..49eaff18cd --- /dev/null +++ b/config/webhooks.php @@ -0,0 +1,79 @@ + [ + WebhookTrigger::STORE_TRANSACTION->name => [ + WebhookTrigger::STORE_BUDGET->name, + WebhookTrigger::UPDATE_BUDGET->name, + WebhookTrigger::DESTROY_BUDGET->name, + WebhookTrigger::STORE_UPDATE_BUDGET_LIMIT->name, + + ], + WebhookTrigger::UPDATE_TRANSACTION->name => [ + WebhookTrigger::STORE_BUDGET->name, + WebhookTrigger::UPDATE_BUDGET->name, + WebhookTrigger::DESTROY_BUDGET->name, + WebhookTrigger::STORE_UPDATE_BUDGET_LIMIT->name, + ], + WebhookTrigger::DESTROY_TRANSACTION->name => [ + WebhookTrigger::STORE_BUDGET->name, + WebhookTrigger::UPDATE_BUDGET->name, + WebhookTrigger::DESTROY_BUDGET->name, + WebhookTrigger::STORE_UPDATE_BUDGET_LIMIT->name, + ], + WebhookTrigger::STORE_BUDGET->name => [ + WebhookTrigger::STORE_TRANSACTION->name, + WebhookTrigger::UPDATE_TRANSACTION->name, + WebhookTrigger::DESTROY_TRANSACTION->name, + + ], + WebhookTrigger::UPDATE_BUDGET->name => [ + WebhookTrigger::STORE_TRANSACTION->name, + WebhookTrigger::UPDATE_TRANSACTION->name, + WebhookTrigger::DESTROY_TRANSACTION->name, + ], + WebhookTrigger::DESTROY_BUDGET->name => [ + WebhookTrigger::STORE_TRANSACTION->name, + WebhookTrigger::UPDATE_TRANSACTION->name, + WebhookTrigger::DESTROY_TRANSACTION->name, + ], + WebhookTrigger::STORE_UPDATE_BUDGET_LIMIT->name => [ + WebhookTrigger::STORE_TRANSACTION->name, + WebhookTrigger::UPDATE_TRANSACTION->name, + WebhookTrigger::DESTROY_TRANSACTION->name, + ], + ], + 'forbidden_responses' => [ + WebhookTrigger::STORE_TRANSACTION->name => [ + WebhookResponse::BUDGET->name, + ], + WebhookTrigger::UPDATE_TRANSACTION->name => [ + WebhookResponse::BUDGET->name, + ], + WebhookTrigger::DESTROY_TRANSACTION->name => [ + WebhookResponse::BUDGET->name, + ], + WebhookTrigger::STORE_BUDGET->name => [ + WebhookResponse::TRANSACTIONS->name, + WebhookResponse::ACCOUNTS->name, + + ], + WebhookTrigger::UPDATE_BUDGET->name => [ + WebhookResponse::TRANSACTIONS->name, + WebhookResponse::ACCOUNTS->name, + ], + WebhookTrigger::DESTROY_BUDGET->name => [ + WebhookResponse::TRANSACTIONS->name, + WebhookResponse::ACCOUNTS->name, + ], + WebhookTrigger::STORE_UPDATE_BUDGET_LIMIT->name => [ + WebhookResponse::TRANSACTIONS->name, + WebhookResponse::ACCOUNTS->name, + ], + ] +]; diff --git a/public/v1/js/.gitkeep b/public/v1/js/.gitkeep old mode 100644 new mode 100755 diff --git a/resources/assets/v1/src/components/form/WebhookDelivery.vue b/resources/assets/v1/src/components/form/WebhookDelivery.vue index ef844cdb1d..ff184466ac 100644 --- a/resources/assets/v1/src/components/form/WebhookDelivery.vue +++ b/resources/assets/v1/src/components/form/WebhookDelivery.vue @@ -68,7 +68,7 @@ export default { } }, value: { - type: Number, + type: String, required: true, } }, @@ -84,7 +84,7 @@ export default { } this.deliveries.push( { - id: response.data.data.value[key], + id: key, name: this.$t('firefly.webhook_delivery_' + key), } ); diff --git a/resources/assets/v1/src/components/form/WebhookResponse.vue b/resources/assets/v1/src/components/form/WebhookResponse.vue index 754c29e609..1ce8eb32b9 100644 --- a/resources/assets/v1/src/components/form/WebhookResponse.vue +++ b/resources/assets/v1/src/components/form/WebhookResponse.vue @@ -66,7 +66,7 @@ export default { } }, value: { - type: Number, + type: String, required: true, } }, @@ -88,7 +88,7 @@ export default { } this.responses.push( { - id: response.data.data.value[key], + id: key, name: this.$t('firefly.webhook_response_' + key), } ); diff --git a/resources/assets/v1/src/components/form/WebhookTrigger.vue b/resources/assets/v1/src/components/form/WebhookTrigger.vue index c62d75a44f..0a13381b03 100644 --- a/resources/assets/v1/src/components/form/WebhookTrigger.vue +++ b/resources/assets/v1/src/components/form/WebhookTrigger.vue @@ -29,6 +29,7 @@ - + {{ $t('list.secret') }} + 'After budgeted amount change', 'webhook_response_TRANSACTIONS' => 'Transaction details', 'webhook_response_ACCOUNTS' => 'Account details', - 'webhook_response_none_BUDGET' => 'Budget details', - 'webhook_response_none_NONE' => 'No details', + 'webhook_response_BUDGET' => 'Budget details', + 'webhook_response_RELEVANT' => 'Relevant details', 'webhook_response_NONE' => 'No details', 'webhook_delivery_JSON' => 'JSON', 'inspect' => 'Inspect', diff --git a/resources/lang/en_US/validation.php b/resources/lang/en_US/validation.php index 91d04df320..33ec3b34e8 100644 --- a/resources/lang/en_US/validation.php +++ b/resources/lang/en_US/validation.php @@ -34,6 +34,9 @@ return [ 'filter_not_string' => 'Filter ":filter" is expected to be a string of text', 'bad_api_filter' => 'This API endpoint does not support ":filter" as a filter.', 'nog_logged_in' => 'You are not logged in.', + 'prohibited' => 'You must not submit anything in field.', + 'bad_webhook_combination' => 'Webhook trigger ":trigger" cannot be combined with webhook response ":response".', + 'unknown_webhook_trigger' => 'Unknown webhook trigger ":trigger".', 'bad_type_source' => 'Firefly III can\'t determine the transaction type based on this source account.', 'bad_type_destination' => 'Firefly III can\'t determine the transaction type based on this destination account.', 'missing_where' => 'Array is missing "where"-clause',