diff --git a/app/Console/Commands/Tax/GenerateTaxExport.php b/app/Console/Commands/Tax/GenerateTaxExport.php new file mode 100644 index 0000000..555b66d --- /dev/null +++ b/app/Console/Commands/Tax/GenerateTaxExport.php @@ -0,0 +1,252 @@ + 20, + "BE" => 21, + "BG" => 20, + "HR" => 25, + "CY" => 19, + "CZ" => 21, + "DK" => 25, + "EE" => 20, + "FI" => 24, + "FR" => 20, + "DE" => 19, + "GR" => 24, + "HU" => 27, + "IE" => 23, + "IT" => 22, + "LV" => 21, + "LT" => 21, + "LU" => 17, + "MT" => 18, + "NL" => 21, + "PL" => 23, + "PT" => 23, + "RO" => 19, + "SK" => 20, + "SI" => 22, + "ES" => 21, + "SE" => 25 + ]; + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + // iterate through all Stripe invoices + $startDate = $this->option('start-date'); + $endDate = $this->option('end-date'); + + // Validate the date format + if ($startDate && !Carbon::createFromFormat('Y-m-d', $startDate)) { + $this->error('Invalid start date format. Use YYYY-MM-DD.'); + return Command::FAILURE; + } + + if ($endDate && !Carbon::createFromFormat('Y-m-d', $endDate)) { + $this->error('Invalid end date format. Use YYYY-MM-DD.'); + return Command::FAILURE; + } else if (!$endDate && $this->option('full-month')) { + $endDate = Carbon::parse($startDate)->endOfMonth()->endOfDay()->format('Y-m-d'); + } + + $this->info('Start date: ' . $startDate); + $this->info('End date: ' . $endDate); + + $processedInvoices = []; + + // Create a progress bar + $queryOptions = [ + 'limit' => 100, + 'expand' => ['data.customer', 'data.customer.address', 'data.customer.tax_ids', 'data.payment_intent', + 'data.payment_intent.payment_method', 'data.charge.balance_transaction'], + 'status' => 'paid', + ]; + if ($startDate) { + $queryOptions['created']['gte'] = Carbon::parse($startDate)->startOfDay()->timestamp; + } + if ($endDate) { + $queryOptions['created']['lte'] = Carbon::parse($endDate)->endOfDay()->timestamp; + } + + $invoices = Cashier::stripe()->invoices->all($queryOptions); + $bar = $this->output->createProgressBar(); + $bar->start(); + $paymentNotSuccessfulCount = 0; + $totalInvoice = 0; + + do { + foreach ($invoices as $invoice) { + // Ignore if payment was refunded + if (($invoice->payment_intent->status ?? null) !== 'succeeded') { + $paymentNotSuccessfulCount++; + continue; + } + + $processedInvoices[] = $this->formatInvoice($invoice); + $totalInvoice++; + + // Advance the progress bar + $bar->advance(); + } + + $queryOptions['starting_after'] = end($invoices->data)->id; + + sleep(5); + $invoices = $invoices->all($queryOptions); + } while ($invoices->has_more); + + $bar->finish(); + $this->line(''); + + $aggregatedReport = $this->aggregateReport($processedInvoices); + + $filePath = 'tax-export-per-invoice_' . $startDate . '_' . $endDate . '.xlsx'; + $this->exportAsXlsx($processedInvoices, $filePath); + + $aggregatedReportFilePath = 'tax-export-aggregated_' . $startDate . '_' . $endDate . '.xlsx'; + $this->exportAsXlsx($aggregatedReport, $aggregatedReportFilePath); + + // Display the results + $this->info('Total invoices: ' . $totalInvoice . ' (with ' . $paymentNotSuccessfulCount . ' payment not successful or trial free invoice)'); + + return Command::SUCCESS; + } + + private function aggregateReport($invoices): array + { + // Sum invoices per country + $aggregatedReport = []; + foreach ($invoices as $invoice) { + $country = $invoice['cust_country']; + $customerType = is_null($invoice['cust_vat_id']) && $this->isEuropeanCountry($country) ? 'individual' : 'business'; + if (!isset($aggregatedReport[$country])) { + $defaultVal = [ + 'count' => 0, + 'total_usd' => 0, + 'tax_total_usd' => 0, + 'total_after_tax_usd' => 0, + 'total_eur' => 0, + 'tax_total_eur' => 0, + 'total_after_tax_eur' => 0, + ]; + $aggregatedReport[$country] = [ + 'individual' => $defaultVal, + 'business' => $defaultVal + ]; + } + $aggregatedReport[$country][$customerType]['count']++; + $aggregatedReport[$country][$customerType]['total_usd'] = ($aggregatedReport[$country][$customerType]['total_usd'] ?? 0) + $invoice['total_usd']; + $aggregatedReport[$country][$customerType]['tax_total_usd'] = ($aggregatedReport[$country][$customerType]['tax_total_usd'] ?? 0) + $invoice['tax_total_usd']; + $aggregatedReport[$country][$customerType]['total_after_tax_usd'] = ($aggregatedReport[$country][$customerType]['total_after_tax_usd'] ?? 0) + $invoice['total_after_tax_usd']; + $aggregatedReport[$country][$customerType]['total_eur'] = ($aggregatedReport[$country][$customerType]['total_eur'] ?? 0) + $invoice['total_eur']; + $aggregatedReport[$country][$customerType]['tax_total_eur'] = ($aggregatedReport[$country][$customerType]['tax_total_eur'] ?? 0) + $invoice['tax_total_eur']; + $aggregatedReport[$country][$customerType]['total_after_tax_eur'] = ($aggregatedReport[$country][$customerType]['total_after_tax_eur'] ?? 0) + $invoice['total_after_tax_eur']; + } + + $finalReport = []; + foreach ($aggregatedReport as $country => $data) { + foreach ($data as $customerType => $aggData) { + $finalReport[] = [ + 'country' => $country, + 'customer_type' => $customerType, + ...$aggData + ]; + } + } + return $finalReport; + } + + private function formatInvoice(Invoice $invoice): array + { + $country = $invoice->customer->address->country ?? $invoice->payment_intent->payment_method->card->country ?? null; + + $vatId = $invoice->customer->tax_ids->data[0]->value ?? null; + $taxRate = $this->computeTaxRate($country, $vatId); + + $taxAmountCollectedUsd = $taxRate > 0 ? $invoice->total * $taxRate / ($taxRate + 100) : 0; + $totalEur = $invoice->charge->balance_transaction->amount; + $taxAmountCollectedEur = $taxRate > 0 ? $totalEur * $taxRate / ($taxRate + 100) : 0; + + return [ + 'invoice_id' => $invoice->id, + 'created_at' => Carbon::createFromTimestamp($invoice->created)->format('Y-m-d H:i:s'), + 'cust_id' => $invoice->customer->id, + 'cust_vat_id' => $vatId, + 'cust_country' => $country, + 'tax_rate' => $taxRate, + 'total_usd' => $invoice->total / 100, + 'tax_total_usd' => $taxAmountCollectedUsd / 100, + 'total_after_tax_usd' => ($invoice->total - $taxAmountCollectedUsd) / 100, + 'total_eur' => $totalEur / 100, + 'tax_total_eur' => $taxAmountCollectedEur / 100, + 'total_after_tax_eur' => ($totalEur - $taxAmountCollectedEur) / 100, + ]; + } + + private function computeTaxRate($countryCode, $vatId) + { + // Since we're a French company, for France, always apply 20% VAT + if ($countryCode == 'FR' || + is_null($countryCode) || + empty($countryCode)) { + return self::EU_TAX_RATES['FR']; + } + + if ($taxRate = (self::EU_TAX_RATES[$countryCode] ?? null)) { + // If VAT ID is provided, then TAX is 0% + if (!$vatId) return $taxRate; + } + + return 0; + } + + private function isEuropeanCountry($countryCode) + { + return isset(self::EU_TAX_RATES[$countryCode]); + } + + private function exportAsXlsx($data, $filename) + { + if (count($data) == 0) { + $this->info('Empty data. No file generated.'); + return; + } + + (new ArrayExport($data))->store($filename, 'local', \Maatwebsite\Excel\Excel::XLSX); + $this->line('File generated: ' . storage_path('app/' . $filename)); + } + + +} diff --git a/app/Exports/Tax/ArrayExport.php b/app/Exports/Tax/ArrayExport.php new file mode 100644 index 0000000..733f5d8 --- /dev/null +++ b/app/Exports/Tax/ArrayExport.php @@ -0,0 +1,27 @@ +data; + } + + public function headings(): array + { + return array_keys($this->data[0]); + } +} + diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index bf4b76b..10678e3 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -2,6 +2,7 @@ namespace App\Http; +use App\Http\Middleware\AuthenticateJWT; use App\Http\Middleware\CustomDomainRestriction; use App\Http\Middleware\EmbeddableForms; use App\Http\Middleware\IsAdmin; @@ -27,6 +28,7 @@ class Kernel extends HttpKernel \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, \App\Http\Middleware\SetLocale::class, + AuthenticateJWT::class, CustomDomainRestriction::class, ]; diff --git a/app/Http/Middleware/AuthenticateJWT.php b/app/Http/Middleware/AuthenticateJWT.php new file mode 100644 index 0000000..7fc10ef --- /dev/null +++ b/app/Http/Middleware/AuthenticateJWT.php @@ -0,0 +1,46 @@ +getPayload(); + } catch (JWTException $e) { + return $next($request); + } + + // Validate IP and User Agent + if ($payload) { + $error = null; + if (!\Hash::check($request->ip(), $payload->get('ip'))) { + $error = 'Origin IP is invalid'; + } + + if (!\Hash::check($request->userAgent(), $payload->get('ua'))) { + $error = 'Origin User Agent is invalid'; + } + + if ($error) { + auth()->invalidate(); + return response()->json([ + 'message' => $error + ], 403); + } + } + + return $next($request); + } +} diff --git a/app/Http/Resources/FormResource.php b/app/Http/Resources/FormResource.php index 85f11c2..f75942a 100644 --- a/app/Http/Resources/FormResource.php +++ b/app/Http/Resources/FormResource.php @@ -51,12 +51,9 @@ class FormResource extends JsonResource 'removed_properties' => $this->removed_properties, 'last_edited_human' => $this->updated_at?->diffForHumans(), 'seo_meta' => $this->seo_meta, - 'max_file_size' => $this->max_file_size / 1000000, ] : []; - $baseData = $this->getFilteredFormData(parent::toArray($request), $this->userIsFormOwner()); - - return array_merge($baseData, $ownerData, [ + return array_merge(parent::toArray($request), $ownerData, [ 'is_pro' => $this->workspaceIsPro(), 'workspace_id' => $this->workspace_id, 'workspace' => new WorkspaceResource($this->getWorkspace()), @@ -64,32 +61,11 @@ class FormResource extends JsonResource 'is_password_protected' => false, 'has_password' => $this->has_password, 'max_number_of_submissions_reached' => $this->max_number_of_submissions_reached, - 'form_pending_submission_key' => $this->form_pending_submission_key + 'form_pending_submission_key' => $this->form_pending_submission_key, + 'max_file_size' => $this->max_file_size / 1000000, ]); } - /** - * Filter form data to hide properties from users. - * - For relation fields, hides the relation information - */ - private function getFilteredFormData(array $data, bool $userIsFormOwner) - { - if ($userIsFormOwner) return $data; - - $properties = collect($data['properties'])->map(function($property){ - // Remove database details from relation - if ($property['type'] === 'relation') { - if (isset($property['relation'])) { - unset($property['relation']); - } - } - return $property; - }); - - $data['properties'] = $properties->toArray(); - return $data; - } - public function setCleanings(array $cleanings) { $this->cleanings = $cleanings; diff --git a/app/Models/User.php b/app/Models/User.php index 0ec9698..0d826f5 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -194,7 +194,10 @@ class User extends Authenticatable implements JWTSubject */ public function getJWTCustomClaims() { - return []; + return [ + 'ip' => \Hash::make(request()->ip()), + 'ua' => \Hash::make(request()->userAgent()), + ]; } public function getIsRiskyAttribute() diff --git a/composer.json b/composer.json index f3f87b9..a72810e 100644 --- a/composer.json +++ b/composer.json @@ -1,12 +1,12 @@ { - "name": "humanj/notionforms", - "description": "A beautiful form builder for Notion", + "name": "jhumanj/opnform", + "description": "A beautiful open-source form builder ", "keywords": [ - "notion", "form", "api", "laravel", "vue", + "nuxt", "Tailwind" ], "license": "MIT", diff --git a/composer.lock b/composer.lock index e28300b..d8d30b4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0be6db490e46ccb2f60614cbb563ff52", + "content-hash": "eeab5fbed4656bcec44ad7e412c0ef36", "packages": [ { "name": "aws/aws-crt-php", @@ -62,16 +62,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.294.4", + "version": "3.295.8", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "4f59bf50aa445fc3ec0b10648b205dd2465e9bec" + "reference": "dc23d1d1e2e0413a3707d5dd90d8c43cb6c7521b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/4f59bf50aa445fc3ec0b10648b205dd2465e9bec", - "reference": "4f59bf50aa445fc3ec0b10648b205dd2465e9bec", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/dc23d1d1e2e0413a3707d5dd90d8c43cb6c7521b", + "reference": "dc23d1d1e2e0413a3707d5dd90d8c43cb6c7521b", "shasum": "" }, "require": { @@ -151,9 +151,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.294.4" + "source": "https://github.com/aws/aws-sdk-php/tree/3.295.8" }, - "time": "2023-12-20T19:21:19+00:00" + "time": "2024-01-08T19:04:58+00:00" }, { "name": "brick/math", @@ -5243,23 +5243,23 @@ }, { "name": "phenx/php-font-lib", - "version": "0.5.4", + "version": "0.5.5", "source": { "type": "git", "url": "https://github.com/dompdf/php-font-lib.git", - "reference": "dd448ad1ce34c63d09baccd05415e361300c35b4" + "reference": "671df0f3516252011aa94f9e8e3b3b66199339f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/dd448ad1ce34c63d09baccd05415e361300c35b4", - "reference": "dd448ad1ce34c63d09baccd05415e361300c35b4", + "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/671df0f3516252011aa94f9e8e3b3b66199339f8", + "reference": "671df0f3516252011aa94f9e8e3b3b66199339f8", "shasum": "" }, "require": { "ext-mbstring": "*" }, "require-dev": { - "symfony/phpunit-bridge": "^3 || ^4 || ^5" + "symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6" }, "type": "library", "autoload": { @@ -5269,7 +5269,7 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0" + "LGPL-2.1-or-later" ], "authors": [ { @@ -5281,9 +5281,9 @@ "homepage": "https://github.com/PhenX/php-font-lib", "support": { "issues": "https://github.com/dompdf/php-font-lib/issues", - "source": "https://github.com/dompdf/php-font-lib/tree/0.5.4" + "source": "https://github.com/dompdf/php-font-lib/tree/0.5.5" }, - "time": "2021-12-17T19:44:54+00:00" + "time": "2024-01-07T18:13:29+00:00" }, { "name": "phenx/php-svg-lib", @@ -5717,16 +5717,16 @@ }, { "name": "php-http/promise", - "version": "1.2.1", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/php-http/promise.git", - "reference": "44a67cb59f708f826f3bec35f22030b3edb90119" + "reference": "2916a606d3b390f4e9e8e2b8dd68581508be0f07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/promise/zipball/44a67cb59f708f826f3bec35f22030b3edb90119", - "reference": "44a67cb59f708f826f3bec35f22030b3edb90119", + "url": "https://api.github.com/repos/php-http/promise/zipball/2916a606d3b390f4e9e8e2b8dd68581508be0f07", + "reference": "2916a606d3b390f4e9e8e2b8dd68581508be0f07", "shasum": "" }, "require": { @@ -5763,9 +5763,9 @@ ], "support": { "issues": "https://github.com/php-http/promise/issues", - "source": "https://github.com/php-http/promise/tree/1.2.1" + "source": "https://github.com/php-http/promise/tree/1.3.0" }, - "time": "2023-11-08T12:57:08+00:00" + "time": "2024-01-04T18:49:48+00:00" }, { "name": "phpoffice/phpspreadsheet", @@ -5949,16 +5949,16 @@ }, { "name": "propaganistas/laravel-disposable-email", - "version": "2.2.15", + "version": "2.2.16", "source": { "type": "git", "url": "https://github.com/Propaganistas/Laravel-Disposable-Email.git", - "reference": "79332c5d02d81d4e03d3e7ee0fb80b6a9ffde391" + "reference": "6ddd3a8d8fc7fbee44672e7ba37a73d966489971" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Propaganistas/Laravel-Disposable-Email/zipball/79332c5d02d81d4e03d3e7ee0fb80b6a9ffde391", - "reference": "79332c5d02d81d4e03d3e7ee0fb80b6a9ffde391", + "url": "https://api.github.com/repos/Propaganistas/Laravel-Disposable-Email/zipball/6ddd3a8d8fc7fbee44672e7ba37a73d966489971", + "reference": "6ddd3a8d8fc7fbee44672e7ba37a73d966489971", "shasum": "" }, "require": { @@ -6012,7 +6012,7 @@ ], "support": { "issues": "https://github.com/Propaganistas/Laravel-Disposable-Email/issues", - "source": "https://github.com/Propaganistas/Laravel-Disposable-Email/tree/2.2.15" + "source": "https://github.com/Propaganistas/Laravel-Disposable-Email/tree/2.2.16" }, "funding": [ { @@ -6020,7 +6020,7 @@ "type": "github" } ], - "time": "2023-12-01T01:15:32+00:00" + "time": "2024-01-01T01:15:04+00:00" }, { "name": "psr/cache", @@ -7730,16 +7730,16 @@ }, { "name": "spatie/temporary-directory", - "version": "2.2.0", + "version": "2.2.1", "source": { "type": "git", "url": "https://github.com/spatie/temporary-directory.git", - "reference": "efc258c9f4da28f0c7661765b8393e4ccee3d19c" + "reference": "76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/efc258c9f4da28f0c7661765b8393e4ccee3d19c", - "reference": "efc258c9f4da28f0c7661765b8393e4ccee3d19c", + "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a", + "reference": "76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a", "shasum": "" }, "require": { @@ -7775,7 +7775,7 @@ ], "support": { "issues": "https://github.com/spatie/temporary-directory/issues", - "source": "https://github.com/spatie/temporary-directory/tree/2.2.0" + "source": "https://github.com/spatie/temporary-directory/tree/2.2.1" }, "funding": [ { @@ -7787,7 +7787,7 @@ "type": "github" } ], - "time": "2023-09-25T07:13:36+00:00" + "time": "2023-12-25T11:46:58+00:00" }, { "name": "stevebauman/purify", @@ -7917,16 +7917,16 @@ }, { "name": "symfony/console", - "version": "v6.4.1", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a550a7c99daeedef3f9d23fb82e3531525ff11fd" + "reference": "0254811a143e6bc6c8deea08b589a7e68a37f625" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a550a7c99daeedef3f9d23fb82e3531525ff11fd", - "reference": "a550a7c99daeedef3f9d23fb82e3531525ff11fd", + "url": "https://api.github.com/repos/symfony/console/zipball/0254811a143e6bc6c8deea08b589a7e68a37f625", + "reference": "0254811a143e6bc6c8deea08b589a7e68a37f625", "shasum": "" }, "require": { @@ -7991,7 +7991,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.1" + "source": "https://github.com/symfony/console/tree/v6.4.2" }, "funding": [ { @@ -8007,7 +8007,7 @@ "type": "tidelift" } ], - "time": "2023-11-30T10:54:28+00:00" + "time": "2023-12-10T16:15:48+00:00" }, { "name": "symfony/css-selector", @@ -8285,16 +8285,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.0.0", + "version": "v7.0.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "c459b40ffe67c49af6fd392aac374c9edf8a027e" + "reference": "098b62ae81fdd6cbf941f355059f617db28f4f9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c459b40ffe67c49af6fd392aac374c9edf8a027e", - "reference": "c459b40ffe67c49af6fd392aac374c9edf8a027e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/098b62ae81fdd6cbf941f355059f617db28f4f9a", + "reference": "098b62ae81fdd6cbf941f355059f617db28f4f9a", "shasum": "" }, "require": { @@ -8345,7 +8345,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.2" }, "funding": [ { @@ -8361,7 +8361,7 @@ "type": "tidelift" } ], - "time": "2023-07-27T16:29:09+00:00" + "time": "2023-12-27T22:24:19+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -8505,16 +8505,16 @@ }, { "name": "symfony/http-client", - "version": "v7.0.0", + "version": "v7.0.2", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "c3e90d09b3c45a5d47170e81a712d51c352cbc68" + "reference": "db714986d3b84330bb6196fdb201c9f79b3a8853" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/c3e90d09b3c45a5d47170e81a712d51c352cbc68", - "reference": "c3e90d09b3c45a5d47170e81a712d51c352cbc68", + "url": "https://api.github.com/repos/symfony/http-client/zipball/db714986d3b84330bb6196fdb201c9f79b3a8853", + "reference": "db714986d3b84330bb6196fdb201c9f79b3a8853", "shasum": "" }, "require": { @@ -8577,7 +8577,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.0.0" + "source": "https://github.com/symfony/http-client/tree/v7.0.2" }, "funding": [ { @@ -8593,7 +8593,7 @@ "type": "tidelift" } ], - "time": "2023-11-29T08:40:23+00:00" + "time": "2023-12-02T12:51:19+00:00" }, { "name": "symfony/http-client-contracts", @@ -8675,16 +8675,16 @@ }, { "name": "symfony/http-foundation", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "44a6d39a9cc11e154547d882d5aac1e014440771" + "reference": "172d807f9ef3fc3fbed8377cc57c20d389269271" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/44a6d39a9cc11e154547d882d5aac1e014440771", - "reference": "44a6d39a9cc11e154547d882d5aac1e014440771", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/172d807f9ef3fc3fbed8377cc57c20d389269271", + "reference": "172d807f9ef3fc3fbed8377cc57c20d389269271", "shasum": "" }, "require": { @@ -8732,7 +8732,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.0" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.2" }, "funding": [ { @@ -8748,20 +8748,20 @@ "type": "tidelift" } ], - "time": "2023-11-20T16:41:16+00:00" + "time": "2023-12-27T22:16:42+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.1", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "2953274c16a229b3933ef73a6898e18388e12e1b" + "reference": "13e8387320b5942d0dc408440c888e2d526efef4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2953274c16a229b3933ef73a6898e18388e12e1b", - "reference": "2953274c16a229b3933ef73a6898e18388e12e1b", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/13e8387320b5942d0dc408440c888e2d526efef4", + "reference": "13e8387320b5942d0dc408440c888e2d526efef4", "shasum": "" }, "require": { @@ -8845,7 +8845,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.4.1" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.2" }, "funding": [ { @@ -8861,20 +8861,20 @@ "type": "tidelift" } ], - "time": "2023-12-01T17:02:02+00:00" + "time": "2023-12-30T15:31:44+00:00" }, { "name": "symfony/mailer", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba" + "reference": "6da89e5c9202f129717a770a03183fb140720168" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba", - "reference": "ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba", + "url": "https://api.github.com/repos/symfony/mailer/zipball/6da89e5c9202f129717a770a03183fb140720168", + "reference": "6da89e5c9202f129717a770a03183fb140720168", "shasum": "" }, "require": { @@ -8925,7 +8925,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.0" + "source": "https://github.com/symfony/mailer/tree/v6.4.2" }, "funding": [ { @@ -8941,7 +8941,7 @@ "type": "tidelift" } ], - "time": "2023-11-12T18:02:22+00:00" + "time": "2023-12-19T09:12:31+00:00" }, { "name": "symfony/mime", @@ -9989,16 +9989,16 @@ }, { "name": "symfony/process", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "191703b1566d97a5425dc969e4350d32b8ef17aa" + "reference": "c4b1ef0bc80533d87a2e969806172f1c2a980241" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/191703b1566d97a5425dc969e4350d32b8ef17aa", - "reference": "191703b1566d97a5425dc969e4350d32b8ef17aa", + "url": "https://api.github.com/repos/symfony/process/zipball/c4b1ef0bc80533d87a2e969806172f1c2a980241", + "reference": "c4b1ef0bc80533d87a2e969806172f1c2a980241", "shasum": "" }, "require": { @@ -10030,7 +10030,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.0" + "source": "https://github.com/symfony/process/tree/v6.4.2" }, "funding": [ { @@ -10046,7 +10046,7 @@ "type": "tidelift" } ], - "time": "2023-11-17T21:06:49+00:00" + "time": "2023-12-22T16:42:54+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -10139,16 +10139,16 @@ }, { "name": "symfony/routing", - "version": "v6.4.1", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "0c95c164fdba18b12523b75e64199ca3503e6d40" + "reference": "98eab13a07fddc85766f1756129c69f207ffbc21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/0c95c164fdba18b12523b75e64199ca3503e6d40", - "reference": "0c95c164fdba18b12523b75e64199ca3503e6d40", + "url": "https://api.github.com/repos/symfony/routing/zipball/98eab13a07fddc85766f1756129c69f207ffbc21", + "reference": "98eab13a07fddc85766f1756129c69f207ffbc21", "shasum": "" }, "require": { @@ -10202,7 +10202,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.1" + "source": "https://github.com/symfony/routing/tree/v6.4.2" }, "funding": [ { @@ -10218,25 +10218,25 @@ "type": "tidelift" } ], - "time": "2023-12-01T14:54:37+00:00" + "time": "2023-12-29T15:34:34+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.4.0", + "version": "v3.4.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838" + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838", - "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^2.0" + "psr/container": "^1.1|^2.0" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -10284,7 +10284,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" }, "funding": [ { @@ -10300,20 +10300,20 @@ "type": "tidelift" } ], - "time": "2023-07-30T20:28:31+00:00" + "time": "2023-12-26T14:02:43+00:00" }, { "name": "symfony/string", - "version": "v7.0.0", + "version": "v7.0.2", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "92bd2bfbba476d4a1838e5e12168bef2fd1e6620" + "reference": "cc78f14f91f5e53b42044d0620961c48028ff9f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/92bd2bfbba476d4a1838e5e12168bef2fd1e6620", - "reference": "92bd2bfbba476d4a1838e5e12168bef2fd1e6620", + "url": "https://api.github.com/repos/symfony/string/zipball/cc78f14f91f5e53b42044d0620961c48028ff9f5", + "reference": "cc78f14f91f5e53b42044d0620961c48028ff9f5", "shasum": "" }, "require": { @@ -10370,7 +10370,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.0.0" + "source": "https://github.com/symfony/string/tree/v7.0.2" }, "funding": [ { @@ -10386,20 +10386,20 @@ "type": "tidelift" } ], - "time": "2023-11-29T08:40:23+00:00" + "time": "2023-12-10T16:54:46+00:00" }, { "name": "symfony/translation", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "b1035dbc2a344b21f8fa8ac451c7ecec4ea45f37" + "reference": "a2ab2ec1a462e53016de8e8d5e8912bfd62ea681" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/b1035dbc2a344b21f8fa8ac451c7ecec4ea45f37", - "reference": "b1035dbc2a344b21f8fa8ac451c7ecec4ea45f37", + "url": "https://api.github.com/repos/symfony/translation/zipball/a2ab2ec1a462e53016de8e8d5e8912bfd62ea681", + "reference": "a2ab2ec1a462e53016de8e8d5e8912bfd62ea681", "shasum": "" }, "require": { @@ -10465,7 +10465,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.4.0" + "source": "https://github.com/symfony/translation/tree/v6.4.2" }, "funding": [ { @@ -10481,20 +10481,20 @@ "type": "tidelift" } ], - "time": "2023-11-29T08:14:36+00:00" + "time": "2023-12-18T09:25:29+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.4.0", + "version": "v3.4.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5" + "reference": "06450585bf65e978026bda220cdebca3f867fde7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dee0c6e5b4c07ce851b462530088e64b255ac9c5", - "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/06450585bf65e978026bda220cdebca3f867fde7", + "reference": "06450585bf65e978026bda220cdebca3f867fde7", "shasum": "" }, "require": { @@ -10543,7 +10543,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.4.1" }, "funding": [ { @@ -10559,7 +10559,7 @@ "type": "tidelift" } ], - "time": "2023-07-25T15:08:44+00:00" + "time": "2023-12-26T14:02:43+00:00" }, { "name": "symfony/uid", @@ -10637,16 +10637,16 @@ }, { "name": "symfony/var-dumper", - "version": "v6.4.0", + "version": "v6.4.2", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "c40f7d17e91d8b407582ed51a2bbf83c52c367f6" + "reference": "68d6573ec98715ddcae5a0a85bee3c1c27a4c33f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c40f7d17e91d8b407582ed51a2bbf83c52c367f6", - "reference": "c40f7d17e91d8b407582ed51a2bbf83c52c367f6", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/68d6573ec98715ddcae5a0a85bee3c1c27a4c33f", + "reference": "68d6573ec98715ddcae5a0a85bee3c1c27a4c33f", "shasum": "" }, "require": { @@ -10702,7 +10702,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.0" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.2" }, "funding": [ { @@ -10718,7 +10718,7 @@ "type": "tidelift" } ], - "time": "2023-11-09T08:28:32+00:00" + "time": "2023-12-28T19:16:56+00:00" }, { "name": "symfony/yaml", @@ -11671,16 +11671,16 @@ }, { "name": "fakerphp/faker", - "version": "v1.23.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/FakerPHP/Faker.git", - "reference": "e3daa170d00fde61ea7719ef47bb09bb8f1d9b01" + "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e3daa170d00fde61ea7719ef47bb09bb8f1d9b01", - "reference": "e3daa170d00fde61ea7719ef47bb09bb8f1d9b01", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b", + "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b", "shasum": "" }, "require": { @@ -11706,11 +11706,6 @@ "ext-mbstring": "Required for multibyte Unicode string functionality." }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "v1.21-dev" - } - }, "autoload": { "psr-4": { "Faker\\": "src/Faker/" @@ -11733,9 +11728,9 @@ ], "support": { "issues": "https://github.com/FakerPHP/Faker/issues", - "source": "https://github.com/FakerPHP/Faker/tree/v1.23.0" + "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1" }, - "time": "2023-06-12T08:44:38+00:00" + "time": "2024-01-02T13:46:09+00:00" }, { "name": "fidry/cpu-core-counter", @@ -12978,16 +12973,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.24.5", + "version": "1.25.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc" + "reference": "bd84b629c8de41aa2ae82c067c955e06f1b00240" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fedf211ff14ec8381c9bf5714e33a7a552dd1acc", - "reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/bd84b629c8de41aa2ae82c067c955e06f1b00240", + "reference": "bd84b629c8de41aa2ae82c067c955e06f1b00240", "shasum": "" }, "require": { @@ -13019,29 +13014,29 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.5" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.25.0" }, - "time": "2023-12-16T09:33:33+00:00" + "time": "2024-01-04T17:06:16+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.29", + "version": "9.2.30", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089", + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -13091,7 +13086,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.30" }, "funding": [ { @@ -13099,7 +13094,7 @@ "type": "github" } ], - "time": "2023-09-19T04:57:46+00:00" + "time": "2023-12-22T06:47:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -13741,20 +13736,20 @@ }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -13786,7 +13781,7 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" }, "funding": [ { @@ -13794,7 +13789,7 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2023-12-22T06:19:30+00:00" }, { "name": "sebastian/diff", @@ -14068,20 +14063,20 @@ }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -14113,7 +14108,7 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" }, "funding": [ { @@ -14121,7 +14116,7 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-12-22T06:20:34+00:00" }, { "name": "sebastian/object-enumerator", @@ -14596,16 +14591,16 @@ }, { "name": "spatie/ignition", - "version": "1.11.3", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/spatie/ignition.git", - "reference": "3d886de644ff7a5b42e4d27c1e1f67c8b5f00044" + "reference": "5b6f801c605a593106b623e45ca41496a6e7d56d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/ignition/zipball/3d886de644ff7a5b42e4d27c1e1f67c8b5f00044", - "reference": "3d886de644ff7a5b42e4d27c1e1f67c8b5f00044", + "url": "https://api.github.com/repos/spatie/ignition/zipball/5b6f801c605a593106b623e45ca41496a6e7d56d", + "reference": "5b6f801c605a593106b623e45ca41496a6e7d56d", "shasum": "" }, "require": { @@ -14675,7 +14670,7 @@ "type": "github" } ], - "time": "2023-10-18T14:09:40+00:00" + "time": "2024-01-03T15:49:39+00:00" }, { "name": "spatie/laravel-ignition", @@ -14769,16 +14764,16 @@ }, { "name": "spatie/laravel-ray", - "version": "1.33.0", + "version": "1.33.1", "source": { "type": "git", "url": "https://github.com/spatie/laravel-ray.git", - "reference": "5028ae44a09451b26eb44490e3471998650788e3" + "reference": "b9574cec543b932d99e68247eaeb37876c71c8eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-ray/zipball/5028ae44a09451b26eb44490e3471998650788e3", - "reference": "5028ae44a09451b26eb44490e3471998650788e3", + "url": "https://api.github.com/repos/spatie/laravel-ray/zipball/b9574cec543b932d99e68247eaeb37876c71c8eb", + "reference": "b9574cec543b932d99e68247eaeb37876c71c8eb", "shasum": "" }, "require": { @@ -14790,7 +14785,7 @@ "php": "^7.4|^8.0", "spatie/backtrace": "^1.0", "spatie/ray": "^1.37", - "symfony/stopwatch": "4.2|^5.1|^6.0", + "symfony/stopwatch": "4.2|^5.1|^6.0|^7.0", "zbateson/mail-mime-parser": "^1.3.1|^2.0" }, "require-dev": { @@ -14838,7 +14833,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-ray/issues", - "source": "https://github.com/spatie/laravel-ray/tree/1.33.0" + "source": "https://github.com/spatie/laravel-ray/tree/1.33.1" }, "funding": [ { @@ -14850,7 +14845,7 @@ "type": "other" } ], - "time": "2023-09-04T10:16:53+00:00" + "time": "2024-01-04T21:36:17+00:00" }, { "name": "spatie/macroable",