mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-12-12 01:42:32 +00:00
🤖 Auto commit for release 'develop' on 2025-08-22
This commit is contained in:
@@ -97,7 +97,7 @@ class ShowController extends Controller
|
||||
$admin = auth()->user();
|
||||
$enrichment = new WebhookEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
$webhooks = $enrichment->enrich($webhooks);
|
||||
$webhooks = $enrichment->enrich($webhooks);
|
||||
|
||||
/** @var WebhookTransformer $transformer */
|
||||
$transformer = app(WebhookTransformer::class);
|
||||
|
||||
@@ -24,17 +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\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;
|
||||
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
|
||||
|
||||
@@ -30,9 +30,7 @@ use FireflyIII\Rules\IsBoolean;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use FireflyIII\Support\Request\ValidatesWebhooks;
|
||||
use Illuminate\Contracts\Validation\Validator;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class CreateRequest
|
||||
@@ -45,14 +43,14 @@ class CreateRequest extends FormRequest
|
||||
|
||||
public function getData(): array
|
||||
{
|
||||
$fields = [
|
||||
$fields = [
|
||||
'title' => ['title', 'convertString'],
|
||||
'active' => ['active', 'boolean'],
|
||||
'url' => ['url', 'convertString'],
|
||||
];
|
||||
$triggers = $this->get('triggers', []);
|
||||
$responses = $this->get('responses', []);
|
||||
$deliveries = $this->get('deliveries', []);
|
||||
$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.');
|
||||
|
||||
@@ -24,17 +24,13 @@ 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;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use FireflyIII\Support\Request\ValidatesWebhooks;
|
||||
use Illuminate\Contracts\Validation\Validator;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class UpdateRequest
|
||||
@@ -47,15 +43,15 @@ class UpdateRequest extends FormRequest
|
||||
|
||||
public function getData(): array
|
||||
{
|
||||
$fields = [
|
||||
$fields = [
|
||||
'title' => ['title', 'convertString'],
|
||||
'active' => ['active', 'boolean'],
|
||||
'url' => ['url', 'convertString'],
|
||||
];
|
||||
|
||||
$triggers = $this->get('triggers', []);
|
||||
$responses = $this->get('responses', []);
|
||||
$deliveries = $this->get('deliveries', []);
|
||||
$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.');
|
||||
@@ -83,8 +79,8 @@ class UpdateRequest extends FormRequest
|
||||
$webhook = $this->route()->parameter('webhook');
|
||||
|
||||
return [
|
||||
'title' => sprintf('min:1|max:255|uniqueObjectForUser:webhooks,title,%d', $webhook->id),
|
||||
'active' => [new IsBoolean()],
|
||||
'title' => sprintf('min:1|max:255|uniqueObjectForUser:webhooks,title,%d', $webhook->id),
|
||||
'active' => [new IsBoolean()],
|
||||
|
||||
'trigger' => 'prohibited',
|
||||
'triggers' => 'required|array|min:1|max:10',
|
||||
@@ -96,7 +92,7 @@ class UpdateRequest extends FormRequest
|
||||
'deliveries' => 'required|array|min:1|max:1',
|
||||
'deliveries.*' => sprintf('required|in:%s', $deliveries),
|
||||
|
||||
'url' => [sprintf('url:%s', $validProtocols), sprintf('uniqueExistingWebhook:%d', $webhook->id)],
|
||||
'url' => [sprintf('url:%s', $validProtocols), sprintf('uniqueExistingWebhook:%d', $webhook->id)],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,9 +51,8 @@ class SeparateTimezoneCaster implements CastsAttributes
|
||||
}
|
||||
$timeZone = $attributes[sprintf('%s_tz', $key)] ?? config('app.timezone');
|
||||
|
||||
$result = Carbon::parse($value, $timeZone)->setTimezone(config('app.timezone'));
|
||||
return Carbon::parse($value, $timeZone)->setTimezone(config('app.timezone'));
|
||||
// Log::debug(sprintf('SeparateTimezoneCaster: %s.%s = %s', str_replace('FireflyIII\\Models\\','',get_class($model)), $key, $result->toAtomString()));
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
@@ -17,8 +19,8 @@ class UpgradesWebhooks extends Command
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
public const string CONFIG_NAME = '640_upgrade_webhooks';
|
||||
protected $description = 'Upgrade webhooks so they can handle multiple triggers.';
|
||||
protected $signature = 'upgrade:640-upgrade-webhooks {--F|force : Force the execution of this command.}';
|
||||
protected $description = 'Upgrade webhooks so they can handle multiple triggers.';
|
||||
protected $signature = 'upgrade:640-upgrade-webhooks {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -32,7 +34,7 @@ class UpgradesWebhooks extends Command
|
||||
}
|
||||
|
||||
$this->upgradeWebhooks();
|
||||
$this->markAsExecuted();
|
||||
$this->markAsExecuted();
|
||||
$this->friendlyPositive('Upgraded webhooks.');
|
||||
|
||||
return 0;
|
||||
@@ -48,10 +50,10 @@ class UpgradesWebhooks extends Command
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private function upgradeWebhooks(): void
|
||||
{
|
||||
$set = Webhook::where('delivery', '>', 1)->orWhere('trigger', '>', 1)->orWhere('response', '>', 1)->get();
|
||||
|
||||
/** @var Webhook $webhook */
|
||||
foreach ($set as $webhook) {
|
||||
$this->upgradeWebhook($webhook);
|
||||
@@ -60,18 +62,20 @@ class UpgradesWebhooks extends Command
|
||||
|
||||
private function upgradeWebhook(Webhook $webhook): void
|
||||
{
|
||||
$delivery = WebhookDelivery::tryFrom((int)$webhook->delivery);
|
||||
$response = WebhookResponse::tryFrom((int)$webhook->response);
|
||||
$trigger = WebhookTrigger::tryFrom((int)$webhook->trigger);
|
||||
$delivery = WebhookDelivery::tryFrom((int)$webhook->delivery);
|
||||
$response = WebhookResponse::tryFrom((int)$webhook->response);
|
||||
$trigger = WebhookTrigger::tryFrom((int)$webhook->trigger);
|
||||
if (null === $delivery || null === $response || null === $trigger) {
|
||||
$this->friendlyError(sprintf('[a] Webhook #%d has an invalid delivery, response or trigger value. Will not upgrade.', $webhook->id));
|
||||
|
||||
return;
|
||||
}
|
||||
$deliveryModel = WebhookDeliveryModel::where('key', $delivery->value)->first();
|
||||
$responseModel = WebhookResponseModel::where('key', $response->value)->first();
|
||||
$triggerModel = WebhookTriggerModel::where('key', $trigger->value)->first();
|
||||
$deliveryModel = WebhookDeliveryModel::where('key', $delivery->value)->first();
|
||||
$responseModel = WebhookResponseModel::where('key', $response->value)->first();
|
||||
$triggerModel = WebhookTriggerModel::where('key', $trigger->value)->first();
|
||||
if (null === $deliveryModel || null === $responseModel || null === $triggerModel) {
|
||||
$this->friendlyError(sprintf('[b] Webhook #%d has an invalid delivery, response or trigger model. Will not upgrade.', $webhook->id));
|
||||
|
||||
return;
|
||||
}
|
||||
$webhook->webhookDeliveries()->attach([$deliveryModel->id]);
|
||||
@@ -83,6 +87,7 @@ class UpgradesWebhooks extends Command
|
||||
$webhook->save();
|
||||
$this->friendlyPositive(sprintf('Webhook #%d upgraded.', $webhook->id));
|
||||
}
|
||||
|
||||
private function markAsExecuted(): void
|
||||
{
|
||||
app('fireflyconfig')->set(self::CONFIG_NAME, true);
|
||||
|
||||
@@ -32,6 +32,6 @@ enum WebhookResponse: int
|
||||
case TRANSACTIONS = 200;
|
||||
case ACCOUNTS = 210;
|
||||
case BUDGET = 230;
|
||||
case RELEVANT = 240;
|
||||
case RELEVANT = 240;
|
||||
case NONE = 220;
|
||||
}
|
||||
|
||||
@@ -102,18 +102,18 @@ class RecurrenceFactory
|
||||
|
||||
$recurrence = new Recurrence(
|
||||
[
|
||||
'user_id' => $this->user->id,
|
||||
'user_group_id' => $this->user->user_group_id,
|
||||
'transaction_type_id' => $type->id,
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'first_date' => $firstDate?->format('Y-m-d'),
|
||||
'user_id' => $this->user->id,
|
||||
'user_group_id' => $this->user->user_group_id,
|
||||
'transaction_type_id' => $type->id,
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'first_date' => $firstDate?->format('Y-m-d'),
|
||||
'first_date_tz' => $firstDate?->format('e'),
|
||||
'repeat_until' => $repetitions > 0 ? null : $repeatUntilString,
|
||||
'latest_date' => null,
|
||||
'repetitions' => $repetitions,
|
||||
'apply_rules' => $applyRules,
|
||||
'active' => $active,
|
||||
'repeat_until' => $repetitions > 0 ? null : $repeatUntilString,
|
||||
'latest_date' => null,
|
||||
'repetitions' => $repetitions,
|
||||
'apply_rules' => $applyRules,
|
||||
'active' => $active,
|
||||
]
|
||||
);
|
||||
$recurrence->save();
|
||||
|
||||
@@ -83,11 +83,12 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
private function getWebhooks(): Collection
|
||||
{
|
||||
return $this->user->webhooks()
|
||||
->leftJoin('webhook_webhook_trigger', 'webhook_webhook_trigger.webhook_id', 'webhooks.id')
|
||||
->leftJoin('webhook_triggers', 'webhook_webhook_trigger.webhook_trigger_id', 'webhook_triggers.id')
|
||||
->where('active', true)
|
||||
->whereIn('webhook_triggers.title', [$this->trigger->name, WebhookTrigger::ANY->name])
|
||||
->get(['webhooks.*']);
|
||||
->leftJoin('webhook_webhook_trigger', 'webhook_webhook_trigger.webhook_id', 'webhooks.id')
|
||||
->leftJoin('webhook_triggers', 'webhook_webhook_trigger.webhook_trigger_id', 'webhook_triggers.id')
|
||||
->where('active', true)
|
||||
->whereIn('webhook_triggers.title', [$this->trigger->name, WebhookTrigger::ANY->name])
|
||||
->get(['webhooks.*'])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,14 +123,15 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
*/
|
||||
private function generateMessage(Webhook $webhook, Model $model): void
|
||||
{
|
||||
$class = $model::class;
|
||||
$class = $model::class;
|
||||
// Line is ignored because all of Firefly III's Models have an id property.
|
||||
Log::debug(sprintf('Now in generateMessage(#%d, %s#%d)', $webhook->id, $class, $model->id));
|
||||
$uuid = Uuid::uuid4();
|
||||
$uuid = Uuid::uuid4();
|
||||
|
||||
/** @var WebhookResponseModel $response */
|
||||
$response = $webhook->webhookResponses()->first();
|
||||
$triggers = $this->getTriggerTitles($webhook->webhookTriggers()->get());
|
||||
$basicMessage = [
|
||||
$response = $webhook->webhookResponses()->first();
|
||||
$triggers = $this->getTriggerTitles($webhook->webhookTriggers()->get());
|
||||
$basicMessage = [
|
||||
'uuid' => $uuid->toString(),
|
||||
'user_id' => 0,
|
||||
'user_group_id' => 0,
|
||||
@@ -180,23 +182,23 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
case WebhookResponse::BUDGET->name:
|
||||
$basicMessage['content'] = [];
|
||||
if ($model instanceof Budget) {
|
||||
$enrichment = new BudgetEnrichment();
|
||||
$enrichment = new BudgetEnrichment();
|
||||
$enrichment->setUser($model->user);
|
||||
$model = $enrichment->enrichSingle($model);
|
||||
$transformer = new BudgetTransformer();
|
||||
$basicMessage['content'] = $transformer->transform($model);
|
||||
}
|
||||
if ($model instanceof BudgetLimit) {
|
||||
$user = $model->budget->user;
|
||||
$enrichment = new BudgetLimitEnrichment();
|
||||
$user = $model->budget->user;
|
||||
$enrichment = new BudgetLimitEnrichment();
|
||||
$enrichment->setUser($user);
|
||||
|
||||
$parameters = new ParameterBag();
|
||||
$parameters = new ParameterBag();
|
||||
$parameters->set('start', $model->start_date);
|
||||
$parameters->set('end', $model->end_date);
|
||||
|
||||
$model = $enrichment->enrichSingle($model);
|
||||
$transformer = new BudgetLimitTransformer();
|
||||
$model = $enrichment->enrichSingle($model);
|
||||
$transformer = new BudgetLimitTransformer();
|
||||
$transformer->setParameters($parameters);
|
||||
$basicMessage['content'] = $transformer->transform($model);
|
||||
}
|
||||
@@ -210,7 +212,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
|
||||
case WebhookResponse::TRANSACTIONS->name:
|
||||
/** @var TransactionGroup $model */
|
||||
$transformer = new TransactionGroupTransformer();
|
||||
$transformer = new TransactionGroupTransformer();
|
||||
|
||||
try {
|
||||
$basicMessage['content'] = $transformer->transformObject($model);
|
||||
@@ -227,13 +229,13 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
|
||||
case WebhookResponse::ACCOUNTS->name:
|
||||
/** @var TransactionGroup $model */
|
||||
$accounts = $this->collectAccounts($model);
|
||||
$enrichment = new AccountEnrichment();
|
||||
$accounts = $this->collectAccounts($model);
|
||||
$enrichment = new AccountEnrichment();
|
||||
$enrichment->setDate(null);
|
||||
$enrichment->setUser($model->user);
|
||||
$accounts = $enrichment->enrich($accounts);
|
||||
$accounts = $enrichment->enrich($accounts);
|
||||
foreach ($accounts as $account) {
|
||||
$transformer = new AccountTransformer();
|
||||
$transformer = new AccountTransformer();
|
||||
$transformer->setParameters(new ParameterBag());
|
||||
$basicMessage['content'][] = $transformer->transform($account);
|
||||
}
|
||||
@@ -263,7 +265,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
|
||||
private function storeMessage(Webhook $webhook, array $message): void
|
||||
{
|
||||
$webhookMessage = new WebhookMessage();
|
||||
$webhookMessage = new WebhookMessage();
|
||||
$webhookMessage->webhook()->associate($webhook);
|
||||
$webhookMessage->sent = false;
|
||||
$webhookMessage->errored = false;
|
||||
@@ -298,35 +300,44 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
// return none if none.
|
||||
if (WebhookResponse::NONE->name === $response->title) {
|
||||
Log::debug(sprintf('Return "%s" because requested nothing.', WebhookResponse::NONE->name));
|
||||
|
||||
return WebhookResponse::NONE->name;
|
||||
}
|
||||
|
||||
if (WebhookResponse::RELEVANT->name === $response->title) {
|
||||
Log::debug('Expected response is any relevant data.');
|
||||
|
||||
// depends on the $class
|
||||
switch ($class) {
|
||||
case TransactionGroup::class:
|
||||
Log::debug(sprintf('Return "%s" because class is %s', WebhookResponse::TRANSACTIONS->name, $class));
|
||||
|
||||
return WebhookResponse::TRANSACTIONS->name;
|
||||
|
||||
case Budget::class:
|
||||
case BudgetLimit::class:
|
||||
Log::debug(sprintf('Return "%s" because class is %s', WebhookResponse::BUDGET->name, $class));
|
||||
|
||||
return WebhookResponse::BUDGET->name;
|
||||
|
||||
default:
|
||||
throw new FireflyException(sprintf('Cannot deal with "relevant" if the given object is a "%s"', $class));
|
||||
}
|
||||
}
|
||||
Log::debug(sprintf('Return response again: %s', $response->title));
|
||||
|
||||
return $response->title;
|
||||
}
|
||||
|
||||
private function getTriggerTitles(Collection $collection): array
|
||||
{
|
||||
$return = [];
|
||||
|
||||
/** @var WebhookTriggerModel $item */
|
||||
foreach ($collection as $item) {
|
||||
$return[] = $item->title;
|
||||
}
|
||||
|
||||
return array_unique($return);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ namespace FireflyIII\Handlers\Observer;
|
||||
|
||||
use FireflyIII\Enums\WebhookTrigger;
|
||||
use FireflyIII\Events\RequestedSendWebhookMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Generator\Webhook\MessageGeneratorInterface;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\Budget;
|
||||
|
||||
@@ -31,10 +31,6 @@ use FireflyIII\Events\RequestedVersionCheckStatus;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Http\Middleware\Installer;
|
||||
use FireflyIII\Models\Webhook;
|
||||
use FireflyIII\Models\WebhookDelivery;
|
||||
use FireflyIII\Models\WebhookResponse;
|
||||
use FireflyIII\Models\WebhookTrigger;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
|
||||
@@ -134,10 +134,10 @@ class Webhook extends Model
|
||||
$webhookId = (int)$value;
|
||||
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var null|Webhook $webhook */
|
||||
$webhook = $user->webhooks()->find($webhookId);
|
||||
$webhook = $user->webhooks()->find($webhookId);
|
||||
if (null !== $webhook) {
|
||||
return $webhook;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
|
||||
@@ -10,8 +12,6 @@ class WebhookDelivery extends Model
|
||||
{
|
||||
use ReturnsIntegerIdTrait;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the ID
|
||||
*
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
|
||||
@@ -10,8 +12,6 @@ class WebhookResponse extends Model
|
||||
{
|
||||
use ReturnsIntegerIdTrait;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the ID
|
||||
*
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
|
||||
@@ -10,8 +12,6 @@ class WebhookTrigger extends Model
|
||||
{
|
||||
use ReturnsIntegerIdTrait;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the ID
|
||||
*
|
||||
|
||||
@@ -47,10 +47,11 @@ class WebhookRepository implements WebhookRepositoryInterface, UserGroupInterfac
|
||||
{
|
||||
return $this->user->webhooks()
|
||||
// only get upgraded webhooks
|
||||
->where('delivery', 1)
|
||||
->where('response', 1)
|
||||
->where('trigger', 1)
|
||||
->get();
|
||||
->where('delivery', 1)
|
||||
->where('response', 1)
|
||||
->where('trigger', 1)
|
||||
->get()
|
||||
;
|
||||
}
|
||||
|
||||
public function destroy(Webhook $webhook): void
|
||||
@@ -79,26 +80,28 @@ class WebhookRepository implements WebhookRepositoryInterface, UserGroupInterfac
|
||||
public function getMessages(Webhook $webhook): Collection
|
||||
{
|
||||
return $webhook->webhookMessages()
|
||||
->orderBy('created_at', 'DESC')
|
||||
->get(['webhook_messages.*']);
|
||||
->orderBy('created_at', 'DESC')
|
||||
->get(['webhook_messages.*'])
|
||||
;
|
||||
}
|
||||
|
||||
public function getReadyMessages(Webhook $webhook): Collection
|
||||
{
|
||||
return $webhook->webhookMessages()
|
||||
->where('webhook_messages.sent', 0)
|
||||
->where('webhook_messages.errored', 0)
|
||||
->get(['webhook_messages.*'])
|
||||
->filter(
|
||||
static fn(WebhookMessage $message) // @phpstan-ignore-line
|
||||
=> $message->webhookAttempts()->count() <= 2
|
||||
)->splice(0, 3);
|
||||
->where('webhook_messages.sent', 0)
|
||||
->where('webhook_messages.errored', 0)
|
||||
->get(['webhook_messages.*'])
|
||||
->filter(
|
||||
static fn (WebhookMessage $message) // @phpstan-ignore-line
|
||||
=> $message->webhookAttempts()->count() <= 2
|
||||
)->splice(0, 3)
|
||||
;
|
||||
}
|
||||
|
||||
public function store(array $data): Webhook
|
||||
{
|
||||
$secret = Str::random(24);
|
||||
$fullData = [
|
||||
$secret = Str::random(24);
|
||||
$fullData = [
|
||||
'user_id' => $this->user->id,
|
||||
'user_group_id' => $this->user->user_group_id,
|
||||
'active' => $data['active'] ?? false,
|
||||
@@ -112,6 +115,7 @@ class WebhookRepository implements WebhookRepositoryInterface, UserGroupInterfac
|
||||
'secret' => $secret,
|
||||
'url' => $data['url'],
|
||||
];
|
||||
|
||||
/** @var Webhook $webhook */
|
||||
$webhook = Webhook::create($fullData);
|
||||
$triggers = new Collection();
|
||||
@@ -154,8 +158,8 @@ class WebhookRepository implements WebhookRepositoryInterface, UserGroupInterfac
|
||||
public function update(Webhook $webhook, array $data): Webhook
|
||||
{
|
||||
$webhook->active = $data['active'] ?? $webhook->active;
|
||||
$webhook->title = $data['title'] ?? $webhook->title;
|
||||
$webhook->url = $data['url'] ?? $webhook->url;
|
||||
$webhook->title = $data['title'] ?? $webhook->title;
|
||||
$webhook->url = $data['url'] ?? $webhook->url;
|
||||
|
||||
if (array_key_exists('secret', $data) && true === $data['secret']) {
|
||||
$secret = Str::random(24);
|
||||
@@ -164,9 +168,9 @@ class WebhookRepository implements WebhookRepositoryInterface, UserGroupInterfac
|
||||
|
||||
$webhook->save();
|
||||
|
||||
$triggers = new Collection();
|
||||
$responses = new Collection();
|
||||
$deliveries = new Collection();
|
||||
$triggers = new Collection();
|
||||
$responses = new Collection();
|
||||
$deliveries = new Collection();
|
||||
|
||||
foreach ($data['triggers'] as $trigger) {
|
||||
// get the relevant ID:
|
||||
|
||||
@@ -137,7 +137,8 @@ class RecurringEnrichment implements EnrichmentInterface
|
||||
// get the (future) occurrences for this specific type of repetition:
|
||||
$amount = 'daily' === $repetition->repetition_type ? 9 : 5;
|
||||
$set = $repository->getXOccurrencesSince($repetition, $fromDate, now(config('app.timezone')), $amount);
|
||||
$occurrences = [];
|
||||
$occurrences = [];
|
||||
|
||||
/** @var Carbon $carbon */
|
||||
foreach ($set as $carbon) {
|
||||
$occurrences[] = $carbon->toAtomString();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\JsonApi\Enrichments;
|
||||
|
||||
use FireflyIII\Enums\WebhookDelivery as WebhookDeliveryEnum;
|
||||
@@ -15,22 +17,22 @@ use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use stdClass;
|
||||
|
||||
class WebhookEnrichment implements EnrichmentInterface
|
||||
{
|
||||
private Collection $collection;
|
||||
private User $user;
|
||||
private UserGroup $userGroup;
|
||||
private array $ids = [];
|
||||
private array $deliveries = [];
|
||||
private array $responses = [];
|
||||
private array $triggers = [];
|
||||
private array $ids = [];
|
||||
private array $deliveries = [];
|
||||
private array $responses = [];
|
||||
private array $triggers = [];
|
||||
|
||||
private array $webhookDeliveries = [];
|
||||
private array $webhookResponses = [];
|
||||
private array $webhookTriggers = [];
|
||||
|
||||
|
||||
public function enrich(Collection $collection): Collection
|
||||
{
|
||||
$this->collection = $collection;
|
||||
@@ -40,10 +42,11 @@ class WebhookEnrichment implements EnrichmentInterface
|
||||
$this->collectWebhookInfo();
|
||||
$this->appendCollectedInfo();
|
||||
}
|
||||
|
||||
return $this->collection;
|
||||
}
|
||||
|
||||
public function enrichSingle(Model|array $model): array|Model
|
||||
public function enrichSingle(array|Model $model): array|Model
|
||||
{
|
||||
Log::debug(__METHOD__);
|
||||
$collection = new Collection([$model]);
|
||||
@@ -74,16 +77,19 @@ class WebhookEnrichment implements EnrichmentInterface
|
||||
private function collectInfo(): void
|
||||
{
|
||||
$all = WebhookDelivery::get();
|
||||
|
||||
/** @var WebhookDelivery $item */
|
||||
foreach ($all as $item) {
|
||||
$this->deliveries[$item->id] = $item->key;
|
||||
}
|
||||
$all = WebhookResponse::get();
|
||||
|
||||
/** @var WebhookResponse $item */
|
||||
foreach ($all as $item) {
|
||||
$this->responses[$item->id] = $item->key;
|
||||
}
|
||||
$all = WebhookTrigger::get();
|
||||
|
||||
/** @var WebhookTrigger $item */
|
||||
foreach ($all as $item) {
|
||||
$this->triggers[$item->id] = $item->key;
|
||||
@@ -94,7 +100,8 @@ class WebhookEnrichment implements EnrichmentInterface
|
||||
private function collectWebhookInfo(): void
|
||||
{
|
||||
$set = DB::table('webhook_webhook_delivery')->whereIn('webhook_id', $this->ids)->get(['webhook_id', 'webhook_delivery_id']);
|
||||
/** @var \stdClass $item */
|
||||
|
||||
/** @var stdClass $item */
|
||||
foreach ($set as $item) {
|
||||
$id = $item->webhook_id;
|
||||
$deliveryId = $item->webhook_delivery_id;
|
||||
@@ -102,7 +109,8 @@ class WebhookEnrichment implements EnrichmentInterface
|
||||
}
|
||||
|
||||
$set = DB::table('webhook_webhook_response')->whereIn('webhook_id', $this->ids)->get(['webhook_id', 'webhook_response_id']);
|
||||
/** @var \stdClass $item */
|
||||
|
||||
/** @var stdClass $item */
|
||||
foreach ($set as $item) {
|
||||
$id = $item->webhook_id;
|
||||
$responseId = $item->webhook_response_id;
|
||||
@@ -110,7 +118,8 @@ class WebhookEnrichment implements EnrichmentInterface
|
||||
}
|
||||
|
||||
$set = DB::table('webhook_webhook_trigger')->whereIn('webhook_id', $this->ids)->get(['webhook_id', 'webhook_trigger_id']);
|
||||
/** @var \stdClass $item */
|
||||
|
||||
/** @var stdClass $item */
|
||||
foreach ($set as $item) {
|
||||
$id = $item->webhook_id;
|
||||
$triggerId = $item->webhook_trigger_id;
|
||||
@@ -127,8 +136,8 @@ class WebhookEnrichment implements EnrichmentInterface
|
||||
'triggers' => $this->webhookTriggers[$item->id] ?? [],
|
||||
];
|
||||
$item->meta = $meta;
|
||||
|
||||
return $item;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ trait ConvertsDataTypes
|
||||
if (10 === strlen((string) $value)) {
|
||||
// probably a date format.
|
||||
try {
|
||||
$carbon = Carbon::createFromFormat('Y-m-d', $value,config('app.timezone'));
|
||||
$carbon = Carbon::createFromFormat('Y-m-d', $value, config('app.timezone'));
|
||||
} catch (InvalidDateException $e) { // @phpstan-ignore-line
|
||||
Log::error(sprintf('[1] "%s" is not a valid date: %s', $value, $e->getMessage()));
|
||||
|
||||
@@ -276,7 +276,7 @@ trait ConvertsDataTypes
|
||||
|
||||
// is an atom string, I hope?
|
||||
try {
|
||||
$carbon = Carbon::parse($value, $value,config('app.timezone'));
|
||||
$carbon = Carbon::parse($value, $value, config('app.timezone'));
|
||||
} catch (InvalidDateException $e) { // @phpstan-ignore-line
|
||||
Log::error(sprintf('[3] "%s" is not a valid date or time: %s', $value, $e->getMessage()));
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Request;
|
||||
|
||||
use FireflyIII\Enums\WebhookTrigger;
|
||||
@@ -17,9 +19,9 @@ trait ValidatesWebhooks
|
||||
if ($validator->failed()) {
|
||||
return;
|
||||
}
|
||||
$data = $validator->getData();
|
||||
$triggers = $data['triggers'] ?? [];
|
||||
$responses = $data['responses'] ?? [];
|
||||
$data = $validator->getData();
|
||||
$triggers = $data['triggers'] ?? [];
|
||||
$responses = $data['responses'] ?? [];
|
||||
|
||||
if (0 === count($triggers) || 0 === count($responses)) {
|
||||
Log::debug('No trigger or response, return.');
|
||||
@@ -28,19 +30,20 @@ trait ValidatesWebhooks
|
||||
}
|
||||
$validTriggers = array_values(Webhook::getTriggers());
|
||||
$validResponses = array_values(Webhook::getResponses());
|
||||
$containsAny = false;
|
||||
$count = 0;
|
||||
$containsAny = false;
|
||||
$count = 0;
|
||||
foreach ($triggers as $trigger) {
|
||||
if (!in_array($trigger, $validTriggers, true)) {
|
||||
return;
|
||||
}
|
||||
$count++;
|
||||
if($trigger === WebhookTrigger::ANY->name) {
|
||||
++$count;
|
||||
if ($trigger === WebhookTrigger::ANY->name) {
|
||||
$containsAny = true;
|
||||
}
|
||||
}
|
||||
if($containsAny && $count > 1) {
|
||||
if ($containsAny && $count > 1) {
|
||||
$validator->errors()->add('triggers.0', trans('validation.only_any_trigger'));
|
||||
|
||||
return;
|
||||
}
|
||||
foreach ($responses as $response) {
|
||||
@@ -52,13 +55,15 @@ trait ValidatesWebhooks
|
||||
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,]));
|
||||
$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,]));
|
||||
$validator->errors()->add(sprintf('responses.%d', $ii), trans('validation.bad_webhook_combination', ['trigger' => $trigger, 'response' => $response]));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,12 +51,12 @@ class WebhookTransformer extends AbstractTransformer
|
||||
'active' => $webhook->active,
|
||||
'title' => $webhook->title,
|
||||
'secret' => $webhook->secret,
|
||||
'triggers' => $webhook->meta['triggers'],
|
||||
'triggers' => $webhook->meta['triggers'],
|
||||
'deliveries' => $webhook->meta['deliveries'],
|
||||
'responses' => $webhook->meta['responses'],
|
||||
// 'trigger' => $this->getEnum('trigger', $webhook->trigger),
|
||||
// 'response' => $this->getEnum('response', $webhook->response),
|
||||
// 'delivery' => $this->getEnum('delivery', $webhook->delivery),
|
||||
'responses' => $webhook->meta['responses'],
|
||||
// 'trigger' => $this->getEnum('trigger', $webhook->trigger),
|
||||
// 'response' => $this->getEnum('response', $webhook->response),
|
||||
// 'delivery' => $this->getEnum('delivery', $webhook->delivery),
|
||||
'url' => $webhook->url,
|
||||
'links' => [
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user