From 504c7a0f2f5c6317025a45238d6d8aef92f136b6 Mon Sep 17 00:00:00 2001 From: Chirag Chhatrala <60499540+chiragchhatrala@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:46:20 +0530 Subject: [PATCH] Custom SMTP Settings (#561) * Custom SMTP Settings * Fix lint * Custom SMTP add in Pricing plan * Allow reset email settings * improve custom SMTP using seprate abstract class * test case for custom SMTP * fix test case * UI improvement * add CASHIER_KEY in phpunit for testcase * Attempt to fix tests * Run pint and attempt to fix cache tests * Fix user management tests * Fix code linters * Merged main & fix linting --------- Co-authored-by: Julien Nahum --- .../Http/Controllers/WorkspaceController.php | 20 + .../Workspace/EmailSettingsRequest.php | 65 ++ api/app/Integrations/Google/Google.php | 2 +- .../AbstractEmailIntegrationHandler.php | 47 ++ .../Handlers/EmailIntegration.php | 5 +- .../Handlers/GoogleSheetsIntegration.php | 2 +- .../SubmissionConfirmationIntegration.php | 5 +- .../Jobs/Billing/WorkspaceUsersUpdated.php | 2 +- .../Forms/FormIntegrationCreatedHandler.php | 6 +- .../Mail/Forms/SubmissionConfirmationMail.php | 2 +- api/app/Models/Workspace.php | 5 +- .../Forms/FormSubmissionNotification.php | 7 +- api/app/Rules/IntegrationLogicRule.php | 2 +- api/app/Rules/OneEmailPerLine.php | 2 +- api/app/Rules/StorageFile.php | 2 +- api/app/Rules/ValidHCaptcha.php | 2 +- .../Forms/FormLogicConditionChecker.php | 10 +- api/app/helpers.php | 2 +- api/composer.lock | 768 ++++++++---------- api/config/mail.php | 11 + ...9_04_093826_add_settings_to_workspaces.php | 34 + api/phpunit.xml | 70 +- api/routes/api.php | 1 + api/tests/Feature/Forms/CustomSmtpTest.php | 60 ++ ...rInviteTest.php => UserManagementTest.php} | 45 +- .../open/integrations/EmailIntegration.vue | 10 + .../SubmissionConfirmationIntegration.vue | 14 +- .../components/pages/pricing/PricingTable.vue | 3 +- .../pages/settings/WorkSpaceCustomDomains.vue | 4 +- .../pages/settings/WorkSpaceEmailSettings.vue | 175 ++++ client/pages/settings/workspace.vue | 3 +- 31 files changed, 876 insertions(+), 510 deletions(-) create mode 100644 api/app/Http/Requests/Workspace/EmailSettingsRequest.php create mode 100644 api/app/Integrations/Handlers/AbstractEmailIntegrationHandler.php create mode 100644 api/database/migrations/2024_09_04_093826_add_settings_to_workspaces.php create mode 100644 api/tests/Feature/Forms/CustomSmtpTest.php rename api/tests/Feature/{UserInviteTest.php => UserManagementTest.php} (74%) create mode 100644 client/components/pages/settings/WorkSpaceEmailSettings.vue diff --git a/api/app/Http/Controllers/WorkspaceController.php b/api/app/Http/Controllers/WorkspaceController.php index a5de4e90f..3a1df4766 100644 --- a/api/app/Http/Controllers/WorkspaceController.php +++ b/api/app/Http/Controllers/WorkspaceController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Http\Requests\Workspace\CustomDomainRequest; +use App\Http\Requests\Workspace\EmailSettingsRequest; use App\Http\Resources\WorkspaceResource; use App\Models\Workspace; use Illuminate\Http\Request; @@ -24,12 +25,31 @@ public function index() public function saveCustomDomain(CustomDomainRequest $request) { + if (!$request->workspace->is_pro) { + return $this->error([ + 'message' => 'A Pro plan is required to use this feature.', + ], 403); + } + $request->workspace->custom_domains = $request->customDomains; $request->workspace->save(); return new WorkspaceResource($request->workspace); } + public function saveEmailSettings(EmailSettingsRequest $request) + { + if (!$request->workspace->is_pro) { + return $this->error([ + 'message' => 'A Pro plan is required to use this feature.', + ], 403); + } + + $request->workspace->update(['settings' => array_merge($request->workspace->settings, ['email_settings' => $request->validated()])]); + + return new WorkspaceResource($request->workspace); + } + public function delete($id) { $workspace = Workspace::findOrFail($id); diff --git a/api/app/Http/Requests/Workspace/EmailSettingsRequest.php b/api/app/Http/Requests/Workspace/EmailSettingsRequest.php new file mode 100644 index 000000000..04030bc37 --- /dev/null +++ b/api/app/Http/Requests/Workspace/EmailSettingsRequest.php @@ -0,0 +1,65 @@ +workspace = Workspace::findOrFail($request->workspaceId); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + $allFieldsPresent = $this->filled(['host', 'port', 'username', 'password']); + + return [ + 'host' => [ + $allFieldsPresent ? 'required' : 'nullable', + 'required_with:port,username,password', + 'string', + ], + 'port' => [ + $allFieldsPresent ? 'required' : 'nullable', + 'required_with:host,username,password', + 'integer', + ], + 'username' => [ + $allFieldsPresent ? 'required' : 'nullable', + 'required_with:host,port,password', + 'string', + ], + 'password' => [ + $allFieldsPresent ? 'required' : 'nullable', + 'required_with:host,port,username', + 'string', + ], + ]; + } + + /** + * Get the validation messages that apply to the request. + * + * @return array + */ + public function messages() + { + return [ + 'host.required_with' => 'The host field is required.', + 'port.required_with' => 'The port field is required.', + 'username.required_with' => 'The username field is required.', + 'password.required_with' => 'The password field is required.', + ]; + } +} diff --git a/api/app/Integrations/Google/Google.php b/api/app/Integrations/Google/Google.php index 024c61f26..6910a5bb3 100644 --- a/api/app/Integrations/Google/Google.php +++ b/api/app/Integrations/Google/Google.php @@ -27,7 +27,7 @@ public function __construct( public function getClient(): Client { - if($this->client->isAccessTokenExpired()) { + if ($this->client->isAccessTokenExpired()) { $this->refreshToken(); } diff --git a/api/app/Integrations/Handlers/AbstractEmailIntegrationHandler.php b/api/app/Integrations/Handlers/AbstractEmailIntegrationHandler.php new file mode 100644 index 000000000..d9c7ea68d --- /dev/null +++ b/api/app/Integrations/Handlers/AbstractEmailIntegrationHandler.php @@ -0,0 +1,47 @@ +initializeMailer(); + } + + protected function initializeMailer() + { + $this->mailer = config('mail.default'); + $this->setWorkspaceSMTPSettings(); + + if (!$this->mailer) { + Log::error('Mailer not specified', [ + 'form_id' => $this->form->id + ]); + } + } + + protected function setWorkspaceSMTPSettings() + { + $workspace = $this->form->workspace; + $emailSettings = $workspace->settings['email_settings'] ?? []; + if (!$workspace->is_pro || !$emailSettings || empty($emailSettings['host']) || empty($emailSettings['port']) || empty($emailSettings['username']) || empty($emailSettings['password'])) { + return; + } + + config([ + 'mail.mailers.custom_smtp.host' => $emailSettings['host'], + 'mail.mailers.custom_smtp.port' => $emailSettings['port'], + 'mail.mailers.custom_smtp.username' => $emailSettings['username'], + 'mail.mailers.custom_smtp.password' => $emailSettings['password'] + ]); + $this->mailer = 'custom_smtp'; + } +} diff --git a/api/app/Integrations/Handlers/EmailIntegration.php b/api/app/Integrations/Handlers/EmailIntegration.php index e712eaf17..b4fcd08c3 100644 --- a/api/app/Integrations/Handlers/EmailIntegration.php +++ b/api/app/Integrations/Handlers/EmailIntegration.php @@ -7,7 +7,7 @@ use Illuminate\Support\Facades\Notification; use App\Notifications\Forms\FormSubmissionNotification; -class EmailIntegration extends AbstractIntegrationHandler +class EmailIntegration extends AbstractEmailIntegrationHandler { public static function getValidationRules(): array { @@ -36,10 +36,11 @@ public function handle(): void 'recipients' => $subscribers->toArray(), 'form_id' => $this->form->id, 'form_slug' => $this->form->slug, + 'mailer' => $this->mailer ]); $subscribers->each(function ($subscriber) { Notification::route('mail', $subscriber)->notify( - new FormSubmissionNotification($this->event, $this->integrationData) + new FormSubmissionNotification($this->event, $this->integrationData, $this->mailer) ); }); } diff --git a/api/app/Integrations/Handlers/GoogleSheetsIntegration.php b/api/app/Integrations/Handlers/GoogleSheetsIntegration.php index c04f4c7ae..d2fd3ff7e 100644 --- a/api/app/Integrations/Handlers/GoogleSheetsIntegration.php +++ b/api/app/Integrations/Handlers/GoogleSheetsIntegration.php @@ -58,7 +58,7 @@ public function handle(): void protected function getSpreadsheetId(): string { - if(!isset($this->integrationData->spreadsheet_id)) { + if (!isset($this->integrationData->spreadsheet_id)) { throw new Exception('The spreadsheed is not instantiated'); } diff --git a/api/app/Integrations/Handlers/SubmissionConfirmationIntegration.php b/api/app/Integrations/Handlers/SubmissionConfirmationIntegration.php index 128d8d6cc..8b40fe4a6 100644 --- a/api/app/Integrations/Handlers/SubmissionConfirmationIntegration.php +++ b/api/app/Integrations/Handlers/SubmissionConfirmationIntegration.php @@ -10,7 +10,7 @@ /** * Sends a confirmation to form respondant that form was submitted */ -class SubmissionConfirmationIntegration extends AbstractIntegrationHandler +class SubmissionConfirmationIntegration extends AbstractEmailIntegrationHandler { public const RISKY_USERS_LIMIT = 120; @@ -54,8 +54,9 @@ public function handle(): void 'recipient' => $email, 'form_id' => $this->form->id, 'form_slug' => $this->form->slug, + 'mailer' => $this->mailer ]); - Mail::to($email)->send(new SubmissionConfirmationMail($this->event, $this->integrationData)); + Mail::mailer($this->mailer)->to($email)->send(new SubmissionConfirmationMail($this->event, $this->integrationData)); } private function getRespondentEmail() diff --git a/api/app/Jobs/Billing/WorkspaceUsersUpdated.php b/api/app/Jobs/Billing/WorkspaceUsersUpdated.php index 62f74aeaf..dc052c1c2 100644 --- a/api/app/Jobs/Billing/WorkspaceUsersUpdated.php +++ b/api/app/Jobs/Billing/WorkspaceUsersUpdated.php @@ -38,7 +38,7 @@ public function __construct(public Workspace $workspace) public function handle(): void { // If self-hosted, no need to update billing - if (!pricing_enabled()) { + if (!pricing_enabled() || \App::environment('testing')) { return; } diff --git a/api/app/Listeners/Forms/FormIntegrationCreatedHandler.php b/api/app/Listeners/Forms/FormIntegrationCreatedHandler.php index f0ee9e3ac..35a139051 100644 --- a/api/app/Listeners/Forms/FormIntegrationCreatedHandler.php +++ b/api/app/Listeners/Forms/FormIntegrationCreatedHandler.php @@ -15,17 +15,17 @@ public function handle(FormIntegrationCreated $event) { $integration = FormIntegration::getIntegration($event->formIntegration->integration_id); - if(!$integration) { + if (!$integration) { return; } - if(!isset($integration['file_name'])) { + if (!isset($integration['file_name'])) { return; } $className = 'App\Integrations\Handlers\Events\\' . $integration['file_name'] . 'Created'; - if(!class_exists($className)) { + if (!class_exists($className)) { return; } diff --git a/api/app/Mail/Forms/SubmissionConfirmationMail.php b/api/app/Mail/Forms/SubmissionConfirmationMail.php index de9dd86e7..b50bb9c1e 100644 --- a/api/app/Mail/Forms/SubmissionConfirmationMail.php +++ b/api/app/Mail/Forms/SubmissionConfirmationMail.php @@ -54,7 +54,7 @@ public function build() private function getFromEmail() { - if(config('app.self_hosted')) { + if (config('app.self_hosted')) { return config('mail.from.address'); } diff --git a/api/app/Models/Workspace.php b/api/app/Models/Workspace.php index 3f2e866d1..68a0d8115 100644 --- a/api/app/Models/Workspace.php +++ b/api/app/Models/Workspace.php @@ -25,6 +25,7 @@ class Workspace extends Model implements CachableAttributes 'icon', 'user_id', 'custom_domain', + 'settings' ]; protected $appends = [ @@ -33,10 +34,11 @@ class Workspace extends Model implements CachableAttributes 'is_enterprise', ]; - protected function casts() + protected function casts(): array { return [ 'custom_domains' => 'array', + 'settings' => 'array' ]; } @@ -201,5 +203,4 @@ public function forms() { return $this->hasMany(Form::class); } - } diff --git a/api/app/Notifications/Forms/FormSubmissionNotification.php b/api/app/Notifications/Forms/FormSubmissionNotification.php index 4ff69836f..342098df8 100644 --- a/api/app/Notifications/Forms/FormSubmissionNotification.php +++ b/api/app/Notifications/Forms/FormSubmissionNotification.php @@ -15,15 +15,17 @@ class FormSubmissionNotification extends Notification implements ShouldQueue use Queueable; public FormSubmitted $event; + private $mailer; /** * Create a new notification instance. * * @return void */ - public function __construct(FormSubmitted $event, private $integrationData) + public function __construct(FormSubmitted $event, private $integrationData, string $mailer) { $this->event = $event; + $this->mailer = $mailer; } /** @@ -52,6 +54,7 @@ public function toMail($notifiable) ->useSignedUrlForFiles(); return (new MailMessage()) + ->mailer($this->mailer) ->replyTo($this->getReplyToEmail($notifiable->routes['mail'])) ->from($this->getFromEmail(), config('app.name')) ->subject('New form submission for "' . $this->event->form->title . '"') @@ -63,7 +66,7 @@ public function toMail($notifiable) private function getFromEmail() { - if(config('app.self_hosted')) { + if (config('app.self_hosted')) { return config('mail.from.address'); } $originalFromAddress = Str::of(config('mail.from.address'))->explode('@'); diff --git a/api/app/Rules/IntegrationLogicRule.php b/api/app/Rules/IntegrationLogicRule.php index 4deff5592..45fecc0cf 100644 --- a/api/app/Rules/IntegrationLogicRule.php +++ b/api/app/Rules/IntegrationLogicRule.php @@ -156,7 +156,7 @@ public function passes($attribute, $value) public function validate(string $attribute, mixed $value, Closure $fail): void { - if(!$this->passes($attribute, $value)) { + if (!$this->passes($attribute, $value)) { $fail($this->message()); } } diff --git a/api/app/Rules/OneEmailPerLine.php b/api/app/Rules/OneEmailPerLine.php index 1b61b3ff6..62f4259fb 100644 --- a/api/app/Rules/OneEmailPerLine.php +++ b/api/app/Rules/OneEmailPerLine.php @@ -41,7 +41,7 @@ public function passes($attribute, $value) public function validate(string $attribute, mixed $value, Closure $fail): void { - if(!$this->passes($attribute, $value)) { + if (!$this->passes($attribute, $value)) { $fail($this->message()); } } diff --git a/api/app/Rules/StorageFile.php b/api/app/Rules/StorageFile.php index 327fff1f8..189bd39e9 100644 --- a/api/app/Rules/StorageFile.php +++ b/api/app/Rules/StorageFile.php @@ -69,7 +69,7 @@ public function passes($attribute, $value): bool public function validate(string $attribute, mixed $value, Closure $fail): void { - if(!$this->passes($attribute, $value)) { + if (!$this->passes($attribute, $value)) { $fail($this->message()); } } diff --git a/api/app/Rules/ValidHCaptcha.php b/api/app/Rules/ValidHCaptcha.php index c591b2a13..b535690ce 100644 --- a/api/app/Rules/ValidHCaptcha.php +++ b/api/app/Rules/ValidHCaptcha.php @@ -34,7 +34,7 @@ public function passes($attribute, $value) } public function validate(string $attribute, mixed $value, Closure $fail): void { - if(!$this->passes($attribute, $value)) { + if (!$this->passes($attribute, $value)) { $fail($this->message()); } } diff --git a/api/app/Service/Forms/FormLogicConditionChecker.php b/api/app/Service/Forms/FormLogicConditionChecker.php index 44e347b46..11fb18206 100644 --- a/api/app/Service/Forms/FormLogicConditionChecker.php +++ b/api/app/Service/Forms/FormLogicConditionChecker.php @@ -95,11 +95,11 @@ private function checkContains($condition, $fieldValue): bool private function checkMatrixContains($condition, $fieldValue): bool { - foreach($condition['value'] as $key => $value) { - if(!(array_key_exists($key, $condition['value']) && array_key_exists($key, $fieldValue))) { + foreach ($condition['value'] as $key => $value) { + if (!(array_key_exists($key, $condition['value']) && array_key_exists($key, $fieldValue))) { return false; } - if($condition['value'][$key] == $fieldValue[$key]) { + if ($condition['value'][$key] == $fieldValue[$key]) { return true; } } @@ -108,8 +108,8 @@ private function checkMatrixContains($condition, $fieldValue): bool private function checkMatrixEquals($condition, $fieldValue): bool { - foreach($condition['value'] as $key => $value) { - if($condition['value'][$key] !== $fieldValue[$key]) { + foreach ($condition['value'] as $key => $value) { + if ($condition['value'][$key] !== $fieldValue[$key]) { return false; } } diff --git a/api/app/helpers.php b/api/app/helpers.php index cde9eb52a..5890076ff 100644 --- a/api/app/helpers.php +++ b/api/app/helpers.php @@ -15,6 +15,6 @@ function front_url($path = '') if (!function_exists('pricing_enabled')) { function pricing_enabled(): bool { - return App::environment() !== 'testing' && !is_null(config('cashier.key')); + return !is_null(config('cashier.key')); } } diff --git a/api/composer.lock b/api/composer.lock index ea00b88d4..36196cf74 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -921,16 +921,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.320.9", + "version": "3.322.3", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "1284cecc00d4ac80815c542ef3882d3a7a25ac50" + "reference": "9a94b9a123e0a14cacd72a34c24624ab728aa398" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/1284cecc00d4ac80815c542ef3882d3a7a25ac50", - "reference": "1284cecc00d4ac80815c542ef3882d3a7a25ac50", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/9a94b9a123e0a14cacd72a34c24624ab728aa398", + "reference": "9a94b9a123e0a14cacd72a34c24624ab728aa398", "shasum": "" }, "require": { @@ -1013,9 +1013,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.320.9" + "source": "https://github.com/aws/aws-sdk-php/tree/3.322.3" }, - "time": "2024-08-27T18:06:27+00:00" + "time": "2024-09-23T18:11:39+00:00" }, { "name": "brick/math", @@ -1148,24 +1148,24 @@ }, { "name": "composer/semver", - "version": "3.4.2", + "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6" + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/c51258e759afdb17f1fd1fe83bc12baaef6309d6", - "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", "extra": { @@ -1209,7 +1209,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.2" + "source": "https://github.com/composer/semver/tree/3.4.3" }, "funding": [ { @@ -1225,7 +1225,7 @@ "type": "tidelift" } ], - "time": "2024-07-12T11:35:52+00:00" + "time": "2024-09-19T14:15:21+00:00" }, { "name": "daverandom/libdns", @@ -1348,16 +1348,16 @@ }, { "name": "doctrine/dbal", - "version": "4.1.0", + "version": "4.1.1", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "2377cd41609aa51bee822c8d207317a3f363a558" + "reference": "7a8252418689feb860ea8dfeab66d64a56a64df8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/2377cd41609aa51bee822c8d207317a3f363a558", - "reference": "2377cd41609aa51bee822c8d207317a3f363a558", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/7a8252418689feb860ea8dfeab66d64a56a64df8", + "reference": "7a8252418689feb860ea8dfeab66d64a56a64df8", "shasum": "" }, "require": { @@ -1370,16 +1370,16 @@ "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.2", - "phpstan/phpstan": "1.11.7", + "phpstan/phpstan": "1.12.0", "phpstan/phpstan-phpunit": "1.4.0", "phpstan/phpstan-strict-rules": "^1.6", - "phpunit/phpunit": "10.5.28", + "phpunit/phpunit": "10.5.30", "psalm/plugin-phpunit": "0.19.0", "slevomat/coding-standard": "8.13.1", "squizlabs/php_codesniffer": "3.10.2", "symfony/cache": "^6.3.8|^7.0", "symfony/console": "^5.4|^6.3|^7.0", - "vimeo/psalm": "5.24.0" + "vimeo/psalm": "5.25.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -1436,7 +1436,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/4.1.0" + "source": "https://github.com/doctrine/dbal/tree/4.1.1" }, "funding": [ { @@ -1452,7 +1452,7 @@ "type": "tidelift" } ], - "time": "2024-08-15T07:37:07+00:00" + "time": "2024-09-03T08:58:39+00:00" }, { "name": "doctrine/deprecations", @@ -2057,16 +2057,16 @@ }, { "name": "giggsey/libphonenumber-for-php", - "version": "8.13.43", + "version": "8.13.45", "source": { "type": "git", "url": "https://github.com/giggsey/libphonenumber-for-php.git", - "reference": "62250ef492ea8afedf534381844194f43ff1f7f2" + "reference": "142ccdd603e4eeef7de9a7ddbd9ae18c2651dbd6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/giggsey/libphonenumber-for-php/zipball/62250ef492ea8afedf534381844194f43ff1f7f2", - "reference": "62250ef492ea8afedf534381844194f43ff1f7f2", + "url": "https://api.github.com/repos/giggsey/libphonenumber-for-php/zipball/142ccdd603e4eeef7de9a7ddbd9ae18c2651dbd6", + "reference": "142ccdd603e4eeef7de9a7ddbd9ae18c2651dbd6", "shasum": "" }, "require": { @@ -2128,7 +2128,7 @@ "issues": "https://github.com/giggsey/libphonenumber-for-php/issues", "source": "https://github.com/giggsey/libphonenumber-for-php" }, - "time": "2024-08-13T12:17:37+00:00" + "time": "2024-09-06T11:22:54+00:00" }, { "name": "giggsey/locale", @@ -2255,16 +2255,16 @@ }, { "name": "google/apiclient-services", - "version": "v0.370.0", + "version": "v0.374.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "25ad8515701dd832313d0f5f0a828670d60e541a" + "reference": "5f6060df419f4f72dcc970197f9a9b1613cecc62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/25ad8515701dd832313d0f5f0a828670d60e541a", - "reference": "25ad8515701dd832313d0f5f0a828670d60e541a", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/5f6060df419f4f72dcc970197f9a9b1613cecc62", + "reference": "5f6060df419f4f72dcc970197f9a9b1613cecc62", "shasum": "" }, "require": { @@ -2293,9 +2293,9 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client-services/issues", - "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.370.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.374.0" }, - "time": "2024-08-26T01:04:18+00:00" + "time": "2024-09-23T01:02:23+00:00" }, { "name": "google/auth", @@ -3138,16 +3138,16 @@ }, { "name": "laravel/cashier", - "version": "v15.4.2", + "version": "v15.4.3", "source": { "type": "git", "url": "https://github.com/laravel/cashier-stripe.git", - "reference": "6b5c938675d11ab8bd7b4b38124ae5d4562ccc0c" + "reference": "a934a85540f21c60f55e47c226f8ef9e8f201384" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/cashier-stripe/zipball/6b5c938675d11ab8bd7b4b38124ae5d4562ccc0c", - "reference": "6b5c938675d11ab8bd7b4b38124ae5d4562ccc0c", + "url": "https://api.github.com/repos/laravel/cashier-stripe/zipball/a934a85540f21c60f55e47c226f8ef9e8f201384", + "reference": "a934a85540f21c60f55e47c226f8ef9e8f201384", "shasum": "" }, "require": { @@ -3222,20 +3222,20 @@ "issues": "https://github.com/laravel/cashier/issues", "source": "https://github.com/laravel/cashier" }, - "time": "2024-08-20T15:24:41+00:00" + "time": "2024-09-03T14:51:03+00:00" }, { "name": "laravel/framework", - "version": "v11.21.0", + "version": "v11.23.5", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "9d9d36708d56665b12185493f684abce38ad2d30" + "reference": "16b31ab0e1dad5cb2ed6dcc1818c02f02fc48453" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/9d9d36708d56665b12185493f684abce38ad2d30", - "reference": "9d9d36708d56665b12185493f684abce38ad2d30", + "url": "https://api.github.com/repos/laravel/framework/zipball/16b31ab0e1dad5cb2ed6dcc1818c02f02fc48453", + "reference": "16b31ab0e1dad5cb2ed6dcc1818c02f02fc48453", "shasum": "" }, "require": { @@ -3297,6 +3297,7 @@ "illuminate/bus": "self.version", "illuminate/cache": "self.version", "illuminate/collections": "self.version", + "illuminate/concurrency": "self.version", "illuminate/conditionable": "self.version", "illuminate/config": "self.version", "illuminate/console": "self.version", @@ -3339,7 +3340,7 @@ "league/flysystem-sftp-v3": "^3.0", "mockery/mockery": "^1.6", "nyholm/psr7": "^1.2", - "orchestra/testbench-core": "^9.1.5", + "orchestra/testbench-core": "^9.4.0", "pda/pheanstalk": "^5.0", "phpstan/phpstan": "^1.11.5", "phpunit/phpunit": "^10.5|^11.0", @@ -3397,6 +3398,7 @@ "src/Illuminate/Events/functions.php", "src/Illuminate/Filesystem/functions.php", "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Log/functions.php", "src/Illuminate/Support/helpers.php" ], "psr-4": { @@ -3428,20 +3430,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-08-20T15:00:52+00:00" + "time": "2024-09-13T13:36:30+00:00" }, { "name": "laravel/horizon", - "version": "v5.27.1", + "version": "v5.28.1", "source": { "type": "git", "url": "https://github.com/laravel/horizon.git", - "reference": "184449be3eb296ab16c13a69ce22049f32d0fc2c" + "reference": "9d2c4eaeb11408384401f8a7d1b0ea4c76554f3f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/horizon/zipball/184449be3eb296ab16c13a69ce22049f32d0fc2c", - "reference": "184449be3eb296ab16c13a69ce22049f32d0fc2c", + "url": "https://api.github.com/repos/laravel/horizon/zipball/9d2c4eaeb11408384401f8a7d1b0ea4c76554f3f", + "reference": "9d2c4eaeb11408384401f8a7d1b0ea4c76554f3f", "shasum": "" }, "require": { @@ -3505,9 +3507,9 @@ ], "support": { "issues": "https://github.com/laravel/horizon/issues", - "source": "https://github.com/laravel/horizon/tree/v5.27.1" + "source": "https://github.com/laravel/horizon/tree/v5.28.1" }, - "time": "2024-08-05T14:23:30+00:00" + "time": "2024-09-04T14:06:50+00:00" }, { "name": "laravel/prompts", @@ -3694,16 +3696,16 @@ }, { "name": "laravel/socialite", - "version": "v5.15.1", + "version": "v5.16.0", "source": { "type": "git", "url": "https://github.com/laravel/socialite.git", - "reference": "cc02625f0bd1f95dc3688eb041cce0f1e709d029" + "reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/socialite/zipball/cc02625f0bd1f95dc3688eb041cce0f1e709d029", - "reference": "cc02625f0bd1f95dc3688eb041cce0f1e709d029", + "url": "https://api.github.com/repos/laravel/socialite/zipball/40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf", + "reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf", "shasum": "" }, "require": { @@ -3762,7 +3764,7 @@ "issues": "https://github.com/laravel/socialite/issues", "source": "https://github.com/laravel/socialite" }, - "time": "2024-06-28T20:09:34+00:00" + "time": "2024-09-03T09:46:57+00:00" }, { "name": "laravel/tinker", @@ -4556,16 +4558,16 @@ }, { "name": "league/mime-type-detection", - "version": "1.15.0", + "version": "1.16.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301" + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301", - "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9", "shasum": "" }, "require": { @@ -4596,7 +4598,7 @@ "description": "Mime-type detection for Flysystem", "support": { "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.15.0" + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0" }, "funding": [ { @@ -4608,7 +4610,7 @@ "type": "tidelift" } ], - "time": "2024-01-28T23:22:08+00:00" + "time": "2024-09-21T08:32:55+00:00" }, { "name": "league/oauth1-client", @@ -4862,16 +4864,16 @@ }, { "name": "maatwebsite/excel", - "version": "3.1.56", + "version": "3.1.58", "source": { "type": "git", "url": "https://github.com/SpartnerNL/Laravel-Excel.git", - "reference": "0381d0225b42c3f328d90f0dd05ca071fca3953f" + "reference": "18495a71b112f43af8ffab35111a58b4e4ba4a4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/0381d0225b42c3f328d90f0dd05ca071fca3953f", - "reference": "0381d0225b42c3f328d90f0dd05ca071fca3953f", + "url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/18495a71b112f43af8ffab35111a58b4e4ba4a4d", + "reference": "18495a71b112f43af8ffab35111a58b4e4ba4a4d", "shasum": "" }, "require": { @@ -4879,7 +4881,7 @@ "ext-json": "*", "illuminate/support": "5.8.*||^6.0||^7.0||^8.0||^9.0||^10.0||^11.0", "php": "^7.0||^8.0", - "phpoffice/phpspreadsheet": "^1.18", + "phpoffice/phpspreadsheet": "^1.29.1", "psr/simple-cache": "^1.0||^2.0||^3.0" }, "require-dev": { @@ -4927,7 +4929,7 @@ ], "support": { "issues": "https://github.com/SpartnerNL/Laravel-Excel/issues", - "source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.56" + "source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.58" }, "funding": [ { @@ -4939,7 +4941,7 @@ "type": "github" } ], - "time": "2024-08-19T09:40:43+00:00" + "time": "2024-09-07T13:53:36+00:00" }, { "name": "maennchen/zipstream-php", @@ -5387,16 +5389,16 @@ }, { "name": "mtdowling/jmespath.php", - "version": "2.7.0", + "version": "2.8.0", "source": { "type": "git", "url": "https://github.com/jmespath/jmespath.php.git", - "reference": "bbb69a935c2cbb0c03d7f481a238027430f6440b" + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/bbb69a935c2cbb0c03d7f481a238027430f6440b", - "reference": "bbb69a935c2cbb0c03d7f481a238027430f6440b", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/a2a865e05d5f420b50cc2f85bb78d565db12a6bc", + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc", "shasum": "" }, "require": { @@ -5413,7 +5415,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -5447,9 +5449,9 @@ ], "support": { "issues": "https://github.com/jmespath/jmespath.php/issues", - "source": "https://github.com/jmespath/jmespath.php/tree/2.7.0" + "source": "https://github.com/jmespath/jmespath.php/tree/2.8.0" }, - "time": "2023-08-25T10:54:48+00:00" + "time": "2024-09-04T18:46:31+00:00" }, { "name": "nesbot/carbon", @@ -5761,16 +5763,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.1.0", + "version": "v5.2.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1" + "reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1", - "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb", + "reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb", "shasum": "" }, "require": { @@ -5813,22 +5815,22 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.2.0" }, - "time": "2024-07-01T20:03:41+00:00" + "time": "2024-09-15T16:40:33+00:00" }, { "name": "nunomaduro/termwind", - "version": "v2.0.1", + "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/termwind.git", - "reference": "58c4c58cf23df7f498daeb97092e34f5259feb6a" + "reference": "e5f21eade88689536c0cdad4c3cd75f3ed26e01a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/58c4c58cf23df7f498daeb97092e34f5259feb6a", - "reference": "58c4c58cf23df7f498daeb97092e34f5259feb6a", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/e5f21eade88689536c0cdad4c3cd75f3ed26e01a", + "reference": "e5f21eade88689536c0cdad4c3cd75f3ed26e01a", "shasum": "" }, "require": { @@ -5838,11 +5840,11 @@ }, "require-dev": { "ergebnis/phpstan-rules": "^2.2.0", - "illuminate/console": "^11.0.0", - "laravel/pint": "^1.14.0", - "mockery/mockery": "^1.6.7", - "pestphp/pest": "^2.34.1", - "phpstan/phpstan": "^1.10.59", + "illuminate/console": "^11.1.1", + "laravel/pint": "^1.15.0", + "mockery/mockery": "^1.6.11", + "pestphp/pest": "^2.34.6", + "phpstan/phpstan": "^1.10.66", "phpstan/phpstan-strict-rules": "^1.5.2", "symfony/var-dumper": "^7.0.4", "thecodingmachine/phpstan-strict-rules": "^1.0.0" @@ -5887,7 +5889,7 @@ ], "support": { "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v2.0.1" + "source": "https://github.com/nunomaduro/termwind/tree/v2.1.0" }, "funding": [ { @@ -5903,20 +5905,20 @@ "type": "github" } ], - "time": "2024-03-06T16:17:14+00:00" + "time": "2024-09-05T15:25:50+00:00" }, { "name": "nyholm/psr7", - "version": "1.8.1", + "version": "1.8.2", "source": { "type": "git", "url": "https://github.com/Nyholm/psr7.git", - "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e" + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nyholm/psr7/zipball/aa5fc277a4f5508013d571341ade0c3886d4d00e", - "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/a71f2b11690f4b24d099d6b16690a90ae14fc6f3", + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3", "shasum": "" }, "require": { @@ -5969,7 +5971,7 @@ ], "support": { "issues": "https://github.com/Nyholm/psr7/issues", - "source": "https://github.com/Nyholm/psr7/tree/1.8.1" + "source": "https://github.com/Nyholm/psr7/tree/1.8.2" }, "funding": [ { @@ -5981,7 +5983,7 @@ "type": "github" } ], - "time": "2023-11-13T09:31:12+00:00" + "time": "2024-09-09T07:06:30+00:00" }, { "name": "openai-php/client", @@ -6401,16 +6403,16 @@ }, { "name": "php-http/multipart-stream-builder", - "version": "1.3.1", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/php-http/multipart-stream-builder.git", - "reference": "ed56da23b95949ae4747378bed8a5b61a2fdae24" + "reference": "10086e6de6f53489cca5ecc45b6f468604d3460e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/ed56da23b95949ae4747378bed8a5b61a2fdae24", - "reference": "ed56da23b95949ae4747378bed8a5b61a2fdae24", + "url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/10086e6de6f53489cca5ecc45b6f468604d3460e", + "reference": "10086e6de6f53489cca5ecc45b6f468604d3460e", "shasum": "" }, "require": { @@ -6451,9 +6453,9 @@ ], "support": { "issues": "https://github.com/php-http/multipart-stream-builder/issues", - "source": "https://github.com/php-http/multipart-stream-builder/tree/1.3.1" + "source": "https://github.com/php-http/multipart-stream-builder/tree/1.4.2" }, - "time": "2024-06-10T14:51:55+00:00" + "time": "2024-09-04T13:22:54+00:00" }, { "name": "phpdocumentor/reflection", @@ -6699,16 +6701,16 @@ }, { "name": "phpoffice/phpspreadsheet", - "version": "1.29.0", + "version": "1.29.1", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "fde2ccf55eaef7e86021ff1acce26479160a0fa0" + "reference": "59ee38f7480904cd6487e5cbdea4d80ff2758719" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/fde2ccf55eaef7e86021ff1acce26479160a0fa0", - "reference": "fde2ccf55eaef7e86021ff1acce26479160a0fa0", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/59ee38f7480904cd6487e5cbdea4d80ff2758719", + "reference": "59ee38f7480904cd6487e5cbdea4d80ff2758719", "shasum": "" }, "require": { @@ -6743,7 +6745,7 @@ "phpcompatibility/php-compatibility": "^9.3", "phpstan/phpstan": "^1.1", "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^8.5 || ^9.0 || ^10.0", + "phpunit/phpunit": "^8.5 || ^9.0", "squizlabs/php_codesniffer": "^3.7", "tecnickcom/tcpdf": "^6.5" }, @@ -6798,9 +6800,9 @@ ], "support": { "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", - "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.0" + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.1" }, - "time": "2023-06-14T22:48:31+00:00" + "time": "2024-09-03T00:55:32+00:00" }, { "name": "phpoption/phpoption", @@ -6879,16 +6881,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.41", + "version": "3.0.42", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "621c73f7dcb310b61de34d1da4c4204e8ace6ceb" + "reference": "db92f1b1987b12b13f248fe76c3a52cadb67bb98" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/621c73f7dcb310b61de34d1da4c4204e8ace6ceb", - "reference": "621c73f7dcb310b61de34d1da4c4204e8ace6ceb", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/db92f1b1987b12b13f248fe76c3a52cadb67bb98", + "reference": "db92f1b1987b12b13f248fe76c3a52cadb67bb98", "shasum": "" }, "require": { @@ -6969,7 +6971,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.41" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.42" }, "funding": [ { @@ -6985,20 +6987,20 @@ "type": "tidelift" } ], - "time": "2024-08-12T00:13:54+00:00" + "time": "2024-09-16T03:06:04+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.1", + "version": "1.31.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" + "reference": "249f15fb843bf240cf058372dad29e100cee6c17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/249f15fb843bf240cf058372dad29e100cee6c17", + "reference": "249f15fb843bf240cf058372dad29e100cee6c17", "shasum": "" }, "require": { @@ -7030,22 +7032,22 @@ "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.29.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.31.0" }, - "time": "2024-05-31T08:52:43+00:00" + "time": "2024-09-22T11:32:18+00:00" }, { "name": "phpstan/phpstan", - "version": "1.12.0", + "version": "1.12.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "384af967d35b2162f69526c7276acadce534d0e1" + "reference": "ffa517cb918591b93acc9b95c0bebdcd0e4538bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/384af967d35b2162f69526c7276acadce534d0e1", - "reference": "384af967d35b2162f69526c7276acadce534d0e1", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ffa517cb918591b93acc9b95c0bebdcd0e4538bd", + "reference": "ffa517cb918591b93acc9b95c0bebdcd0e4538bd", "shasum": "" }, "require": { @@ -7090,20 +7092,20 @@ "type": "github" } ], - "time": "2024-08-27T09:18:05+00:00" + "time": "2024-09-19T07:58:01+00:00" }, { "name": "propaganistas/laravel-disposable-email", - "version": "2.4.4", + "version": "2.4.5", "source": { "type": "git", "url": "https://github.com/Propaganistas/Laravel-Disposable-Email.git", - "reference": "4da37844d0dfcf5f7a0a1ff0793fe2ce9bf8ea9b" + "reference": "87a717f696a5167111833dff659fddbccc638f9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Propaganistas/Laravel-Disposable-Email/zipball/4da37844d0dfcf5f7a0a1ff0793fe2ce9bf8ea9b", - "reference": "4da37844d0dfcf5f7a0a1ff0793fe2ce9bf8ea9b", + "url": "https://api.github.com/repos/Propaganistas/Laravel-Disposable-Email/zipball/87a717f696a5167111833dff659fddbccc638f9b", + "reference": "87a717f696a5167111833dff659fddbccc638f9b", "shasum": "" }, "require": { @@ -7159,7 +7161,7 @@ ], "support": { "issues": "https://github.com/Propaganistas/Laravel-Disposable-Email/issues", - "source": "https://github.com/Propaganistas/Laravel-Disposable-Email/tree/2.4.4" + "source": "https://github.com/Propaganistas/Laravel-Disposable-Email/tree/2.4.5" }, "funding": [ { @@ -7167,7 +7169,7 @@ "type": "github" } ], - "time": "2024-08-01T00:41:48+00:00" + "time": "2024-09-01T00:48:21+00:00" }, { "name": "psr/cache", @@ -7531,16 +7533,16 @@ }, { "name": "psr/log", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "79dff0b268932c640297f5208d6298f71855c03e" + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e", - "reference": "79dff0b268932c640297f5208d6298f71855c03e", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { @@ -7575,9 +7577,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.1" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, - "time": "2024-08-21T13:31:24+00:00" + "time": "2024-09-11T13:17:53+00:00" }, { "name": "psr/simple-cache", @@ -7936,21 +7938,21 @@ }, { "name": "rector/rector", - "version": "1.2.4", + "version": "1.2.5", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "42a4aa23b48b4cfc8ebfeac2b570364e27744381" + "reference": "e98aa793ca3fcd17e893cfaf9103ac049775d339" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/42a4aa23b48b4cfc8ebfeac2b570364e27744381", - "reference": "42a4aa23b48b4cfc8ebfeac2b570364e27744381", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/e98aa793ca3fcd17e893cfaf9103ac049775d339", + "reference": "e98aa793ca3fcd17e893cfaf9103ac049775d339", "shasum": "" }, "require": { "php": "^7.2|^8.0", - "phpstan/phpstan": "^1.11.11" + "phpstan/phpstan": "^1.12.2" }, "conflict": { "rector/rector-doctrine": "*", @@ -7983,7 +7985,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/1.2.4" + "source": "https://github.com/rectorphp/rector/tree/1.2.5" }, "funding": [ { @@ -7991,7 +7993,7 @@ "type": "github" } ], - "time": "2024-08-23T09:03:01+00:00" + "time": "2024-09-08T17:43:24+00:00" }, { "name": "revolt/event-loop", @@ -8212,16 +8214,16 @@ }, { "name": "sentry/sentry-laravel", - "version": "4.8.0", + "version": "4.9.0", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-laravel.git", - "reference": "2bbcb7e81097993cf64d5b296eaa6d396cddd5a7" + "reference": "73078e1f26d57f7a10e3bee2a2f543a02f6493c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/2bbcb7e81097993cf64d5b296eaa6d396cddd5a7", - "reference": "2bbcb7e81097993cf64d5b296eaa6d396cddd5a7", + "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/73078e1f26d57f7a10e3bee2a2f543a02f6493c3", + "reference": "73078e1f26d57f7a10e3bee2a2f543a02f6493c3", "shasum": "" }, "require": { @@ -8285,7 +8287,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-laravel/issues", - "source": "https://github.com/getsentry/sentry-laravel/tree/4.8.0" + "source": "https://github.com/getsentry/sentry-laravel/tree/4.9.0" }, "funding": [ { @@ -8297,7 +8299,7 @@ "type": "custom" } ], - "time": "2024-08-15T19:03:01+00:00" + "time": "2024-09-19T12:58:53+00:00" }, { "name": "spatie/backtrace", @@ -8500,16 +8502,16 @@ }, { "name": "spatie/laravel-data", - "version": "4.8.1", + "version": "4.9.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-data.git", - "reference": "597961b02b2f7722246f21dad432bf24c2abb9d6" + "reference": "1b7c105deddcb1331f245cccddd5b6f397213a86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-data/zipball/597961b02b2f7722246f21dad432bf24c2abb9d6", - "reference": "597961b02b2f7722246f21dad432bf24c2abb9d6", + "url": "https://api.github.com/repos/spatie/laravel-data/zipball/1b7c105deddcb1331f245cccddd5b6f397213a86", + "reference": "1b7c105deddcb1331f245cccddd5b6f397213a86", "shasum": "" }, "require": { @@ -8572,7 +8574,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-data/issues", - "source": "https://github.com/spatie/laravel-data/tree/4.8.1" + "source": "https://github.com/spatie/laravel-data/tree/4.9.0" }, "funding": [ { @@ -8580,7 +8582,7 @@ "type": "github" } ], - "time": "2024-08-13T13:53:42+00:00" + "time": "2024-09-10T13:25:26+00:00" }, { "name": "spatie/laravel-package-tools", @@ -8913,16 +8915,16 @@ }, { "name": "spatie/php-structure-discoverer", - "version": "2.1.2", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/spatie/php-structure-discoverer.git", - "reference": "0bfebf609b2047360cdca102d2c08fb78b393927" + "reference": "271542206169d95dd2ffe346ddf11f37672553a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/php-structure-discoverer/zipball/0bfebf609b2047360cdca102d2c08fb78b393927", - "reference": "0bfebf609b2047360cdca102d2c08fb78b393927", + "url": "https://api.github.com/repos/spatie/php-structure-discoverer/zipball/271542206169d95dd2ffe346ddf11f37672553a2", + "reference": "271542206169d95dd2ffe346ddf11f37672553a2", "shasum": "" }, "require": { @@ -8981,7 +8983,7 @@ ], "support": { "issues": "https://github.com/spatie/php-structure-discoverer/issues", - "source": "https://github.com/spatie/php-structure-discoverer/tree/2.1.2" + "source": "https://github.com/spatie/php-structure-discoverer/tree/2.2.0" }, "funding": [ { @@ -8989,7 +8991,7 @@ "type": "github" } ], - "time": "2024-08-13T15:00:59+00:00" + "time": "2024-08-29T10:43:45+00:00" }, { "name": "spatie/ray", @@ -9398,16 +9400,16 @@ }, { "name": "symfony/console", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9" + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9", - "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9", + "url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee", + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee", "shasum": "" }, "require": { @@ -9471,7 +9473,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.3" + "source": "https://github.com/symfony/console/tree/v7.1.5" }, "funding": [ { @@ -9487,7 +9489,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/css-selector", @@ -9623,16 +9625,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v7.1.1", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "01ce8174447f1f1dd33a5854b01beef79061d9fa" + "reference": "b92af238457a7cdd2738f941cd525d76313e8283" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/01ce8174447f1f1dd33a5854b01beef79061d9fa", - "reference": "01ce8174447f1f1dd33a5854b01beef79061d9fa", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b92af238457a7cdd2738f941cd525d76313e8283", + "reference": "b92af238457a7cdd2738f941cd525d76313e8283", "shasum": "" }, "require": { @@ -9670,7 +9672,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v7.1.1" + "source": "https://github.com/symfony/dom-crawler/tree/v7.1.5" }, "funding": [ { @@ -9686,7 +9688,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-09-15T06:48:17+00:00" }, { "name": "symfony/error-handler", @@ -9921,16 +9923,16 @@ }, { "name": "symfony/finder", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "717c6329886f32dc65e27461f80f2a465412fdca" + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/717c6329886f32dc65e27461f80f2a465412fdca", - "reference": "717c6329886f32dc65e27461f80f2a465412fdca", + "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", "shasum": "" }, "require": { @@ -9965,7 +9967,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.1.3" + "source": "https://github.com/symfony/finder/tree/v7.1.4" }, "funding": [ { @@ -9981,20 +9983,20 @@ "type": "tidelift" } ], - "time": "2024-07-24T07:08:44+00:00" + "time": "2024-08-13T14:28:19+00:00" }, { "name": "symfony/http-foundation", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a" + "reference": "e30ef73b1e44eea7eb37ba69600a354e553f694b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f602d5c17d1fa02f8019ace2687d9d136b7f4a1a", - "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e30ef73b1e44eea7eb37ba69600a354e553f694b", + "reference": "e30ef73b1e44eea7eb37ba69600a354e553f694b", "shasum": "" }, "require": { @@ -10042,7 +10044,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.1.3" + "source": "https://github.com/symfony/http-foundation/tree/v7.1.5" }, "funding": [ { @@ -10058,20 +10060,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186" + "reference": "44204d96150a9df1fc57601ec933d23fefc2d65b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/db9702f3a04cc471ec8c70e881825db26ac5f186", - "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/44204d96150a9df1fc57601ec933d23fefc2d65b", + "reference": "44204d96150a9df1fc57601ec933d23fefc2d65b", "shasum": "" }, "require": { @@ -10156,7 +10158,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/v7.1.3" + "source": "https://github.com/symfony/http-kernel/tree/v7.1.5" }, "funding": [ { @@ -10172,20 +10174,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T14:58:15+00:00" + "time": "2024-09-21T06:09:21+00:00" }, { "name": "symfony/mailer", - "version": "v7.1.2", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "8fcff0af9043c8f8a8e229437cea363e282f9aee" + "reference": "bbf21460c56f29810da3df3e206e38dfbb01e80b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/8fcff0af9043c8f8a8e229437cea363e282f9aee", - "reference": "8fcff0af9043c8f8a8e229437cea363e282f9aee", + "url": "https://api.github.com/repos/symfony/mailer/zipball/bbf21460c56f29810da3df3e206e38dfbb01e80b", + "reference": "bbf21460c56f29810da3df3e206e38dfbb01e80b", "shasum": "" }, "require": { @@ -10236,7 +10238,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.1.2" + "source": "https://github.com/symfony/mailer/tree/v7.1.5" }, "funding": [ { @@ -10252,20 +10254,20 @@ "type": "tidelift" } ], - "time": "2024-06-28T08:00:31+00:00" + "time": "2024-09-08T12:32:26+00:00" }, { "name": "symfony/mime", - "version": "v7.1.2", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc" + "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/26a00b85477e69a4bab63b66c5dce64f18b0cbfc", - "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc", + "url": "https://api.github.com/repos/symfony/mime/zipball/711d2e167e8ce65b05aea6b258c449671cdd38ff", + "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff", "shasum": "" }, "require": { @@ -10320,7 +10322,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.1.2" + "source": "https://github.com/symfony/mime/tree/v7.1.5" }, "funding": [ { @@ -10336,7 +10338,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T10:03:55+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/options-resolver", @@ -10407,20 +10409,20 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "0424dff1c58f028c451efff2045f5d92410bd540" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540", - "reference": "0424dff1c58f028c451efff2045f5d92410bd540", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -10466,7 +10468,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" }, "funding": [ { @@ -10482,24 +10484,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "c027e6a3c6aee334663ec21f5852e89738abc805" + "reference": "48becf00c920479ca2e910c22a5a39e5d47ca956" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/c027e6a3c6aee334663ec21f5852e89738abc805", - "reference": "c027e6a3c6aee334663ec21f5852e89738abc805", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/48becf00c920479ca2e910c22a5a39e5d47ca956", + "reference": "48becf00c920479ca2e910c22a5a39e5d47ca956", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-iconv": "*" @@ -10546,7 +10548,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-iconv/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.31.0" }, "funding": [ { @@ -10562,24 +10564,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a" + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/64647a7c30b2283f5d49b874d84a18fc22054b7a", - "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -10624,7 +10626,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { @@ -10640,24 +10642,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-icu", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "e76343c631b453088e2260ac41dfebe21954de81" + "reference": "d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/e76343c631b453088e2260ac41dfebe21954de81", - "reference": "e76343c631b453088e2260ac41dfebe21954de81", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78", + "reference": "d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance and support of other locales than \"en\"" @@ -10708,7 +10710,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.31.0" }, "funding": [ { @@ -10724,26 +10726,25 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c" + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a6e83bdeb3c84391d1dfe16f42e40727ce524a5c", - "reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773", + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773", "shasum": "" }, "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" }, "suggest": { "ext-intl": "For best performance" @@ -10792,7 +10793,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0" }, "funding": [ { @@ -10808,24 +10809,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb", - "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -10873,7 +10874,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -10889,24 +10890,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", - "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -10953,7 +10954,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -10969,97 +10970,24 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:30:46+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.30.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "10112722600777e02d2745716b70c5db4ca70442" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/10112722600777e02d2745716b70c5db4ca70442", - "reference": "10112722600777e02d2745716b70c5db4ca70442", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.30.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-06-19T12:30:46+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -11106,7 +11034,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -11122,24 +11050,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9" + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9", - "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -11182,7 +11110,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0" }, "funding": [ { @@ -11198,24 +11126,24 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:35:24+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-uuid", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "2ba1f33797470debcda07fe9dce20a0003df18e9" + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/2ba1f33797470debcda07fe9dce20a0003df18e9", - "reference": "2ba1f33797470debcda07fe9dce20a0003df18e9", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-uuid": "*" @@ -11261,7 +11189,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.31.0" }, "funding": [ { @@ -11277,20 +11205,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/process", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca" + "reference": "5c03ee6369281177f07f7c68252a280beccba847" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/7f2f542c668ad6c313dc4a5e9c3321f733197eca", - "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca", + "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847", + "reference": "5c03ee6369281177f07f7c68252a280beccba847", "shasum": "" }, "require": { @@ -11322,7 +11250,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.3" + "source": "https://github.com/symfony/process/tree/v7.1.5" }, "funding": [ { @@ -11338,20 +11266,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:44:47+00:00" + "time": "2024-09-19T21:48:23+00:00" }, { "name": "symfony/psr-http-message-bridge", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "1365d10f5476f74a27cf9c2d1eee70c069019db0" + "reference": "405a7bcd872f1563966f64be19f1362d94ce71ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/1365d10f5476f74a27cf9c2d1eee70c069019db0", - "reference": "1365d10f5476f74a27cf9c2d1eee70c069019db0", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/405a7bcd872f1563966f64be19f1362d94ce71ab", + "reference": "405a7bcd872f1563966f64be19f1362d94ce71ab", "shasum": "" }, "require": { @@ -11405,7 +11333,7 @@ "psr-7" ], "support": { - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.1.3" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.1.4" }, "funding": [ { @@ -11421,20 +11349,20 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:10:24+00:00" + "time": "2024-08-15T22:48:53+00:00" }, { "name": "symfony/routing", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0" + "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/8a908a3f22d5a1b5d297578c2ceb41b02fa916d0", - "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0", + "url": "https://api.github.com/repos/symfony/routing/zipball/1500aee0094a3ce1c92626ed8cf3c2037e86f5a7", + "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7", "shasum": "" }, "require": { @@ -11486,7 +11414,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.1.3" + "source": "https://github.com/symfony/routing/tree/v7.1.4" }, "funding": [ { @@ -11502,7 +11430,7 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:10:24+00:00" + "time": "2024-08-29T08:16:25+00:00" }, { "name": "symfony/service-contracts", @@ -11651,16 +11579,16 @@ }, { "name": "symfony/string", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "ea272a882be7f20cad58d5d78c215001617b7f07" + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/ea272a882be7f20cad58d5d78c215001617b7f07", - "reference": "ea272a882be7f20cad58d5d78c215001617b7f07", + "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", "shasum": "" }, "require": { @@ -11718,7 +11646,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.3" + "source": "https://github.com/symfony/string/tree/v7.1.5" }, "funding": [ { @@ -11734,20 +11662,20 @@ "type": "tidelift" } ], - "time": "2024-07-22T10:25:37+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/translation", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1" + "reference": "235535e3f84f3dfbdbde0208ede6ca75c3a489ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/8d5e50c813ba2859a6dfc99a0765c550507934a1", - "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1", + "url": "https://api.github.com/repos/symfony/translation/zipball/235535e3f84f3dfbdbde0208ede6ca75c3a489ea", + "reference": "235535e3f84f3dfbdbde0208ede6ca75c3a489ea", "shasum": "" }, "require": { @@ -11812,7 +11740,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.1.3" + "source": "https://github.com/symfony/translation/tree/v7.1.5" }, "funding": [ { @@ -11828,7 +11756,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-09-16T06:30:38+00:00" }, { "name": "symfony/translation-contracts", @@ -11910,16 +11838,16 @@ }, { "name": "symfony/uid", - "version": "v7.1.1", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277" + "reference": "8c7bb8acb933964055215d89f9a9871df0239317" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/bb59febeecc81528ff672fad5dab7f06db8c8277", - "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277", + "url": "https://api.github.com/repos/symfony/uid/zipball/8c7bb8acb933964055215d89f9a9871df0239317", + "reference": "8c7bb8acb933964055215d89f9a9871df0239317", "shasum": "" }, "require": { @@ -11964,7 +11892,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.1.1" + "source": "https://github.com/symfony/uid/tree/v7.1.5" }, "funding": [ { @@ -11980,20 +11908,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-09-17T09:16:35+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f" + "reference": "e20e03889539fd4e4211e14d2179226c513c010d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/86af4617cca75a6e28598f49ae0690f3b9d4591f", - "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e20e03889539fd4e4211e14d2179226c513c010d", + "reference": "e20e03889539fd4e4211e14d2179226c513c010d", "shasum": "" }, "require": { @@ -12047,7 +11975,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.1.3" + "source": "https://github.com/symfony/var-dumper/tree/v7.1.5" }, "funding": [ { @@ -12063,20 +11991,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-09-16T10:07:02+00:00" }, { "name": "symfony/yaml", - "version": "v7.1.1", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "fa34c77015aa6720469db7003567b9f772492bf2" + "reference": "4e561c316e135e053bd758bf3b3eb291d9919de4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/fa34c77015aa6720469db7003567b9f772492bf2", - "reference": "fa34c77015aa6720469db7003567b9f772492bf2", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4e561c316e135e053bd758bf3b3eb291d9919de4", + "reference": "4e561c316e135e053bd758bf3b3eb291d9919de4", "shasum": "" }, "require": { @@ -12118,7 +12046,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.1.1" + "source": "https://github.com/symfony/yaml/tree/v7.1.5" }, "funding": [ { @@ -12134,7 +12062,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-09-17T12:49:58+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -13160,16 +13088,16 @@ }, { "name": "fidry/cpu-core-counter", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" + "reference": "8520451a140d3f46ac33042715115e290cf5785f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", "shasum": "" }, "require": { @@ -13209,7 +13137,7 @@ ], "support": { "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0" + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" }, "funding": [ { @@ -13217,7 +13145,7 @@ "type": "github" } ], - "time": "2024-02-07T09:43:46+00:00" + "time": "2024-08-06T10:04:20+00:00" }, { "name": "filp/whoops", @@ -13415,16 +13343,16 @@ }, { "name": "laravel/pint", - "version": "v1.17.2", + "version": "v1.17.3", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "e8a88130a25e3f9d4d5785e6a1afca98268ab110" + "reference": "9d77be916e145864f10788bb94531d03e1f7b482" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/e8a88130a25e3f9d4d5785e6a1afca98268ab110", - "reference": "e8a88130a25e3f9d4d5785e6a1afca98268ab110", + "url": "https://api.github.com/repos/laravel/pint/zipball/9d77be916e145864f10788bb94531d03e1f7b482", + "reference": "9d77be916e145864f10788bb94531d03e1f7b482", "shasum": "" }, "require": { @@ -13435,13 +13363,13 @@ "php": "^8.1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.61.1", - "illuminate/view": "^10.48.18", + "friendsofphp/php-cs-fixer": "^3.64.0", + "illuminate/view": "^10.48.20", "larastan/larastan": "^2.9.8", "laravel-zero/framework": "^10.4.0", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^1.15.1", - "pestphp/pest": "^2.35.0" + "pestphp/pest": "^2.35.1" }, "bin": [ "builds/pint" @@ -13477,20 +13405,20 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-08-06T15:11:54+00:00" + "time": "2024-09-03T15:00:28+00:00" }, { "name": "laravel/sail", - "version": "v1.31.1", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "3d06dd18cee8059baa7b388af00ba47f6d96bd85" + "reference": "4a7e41d280861ca7e35710cea011a07669b4003b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/3d06dd18cee8059baa7b388af00ba47f6d96bd85", - "reference": "3d06dd18cee8059baa7b388af00ba47f6d96bd85", + "url": "https://api.github.com/repos/laravel/sail/zipball/4a7e41d280861ca7e35710cea011a07669b4003b", + "reference": "4a7e41d280861ca7e35710cea011a07669b4003b", "shasum": "" }, "require": { @@ -13540,7 +13468,7 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2024-08-02T07:45:47+00:00" + "time": "2024-09-11T20:14:29+00:00" }, { "name": "mockery/mockery", diff --git a/api/config/mail.php b/api/config/mail.php index 31bace80f..053abc4fd 100644 --- a/api/config/mail.php +++ b/api/config/mail.php @@ -45,6 +45,17 @@ 'auth_mode' => null, ], + // Use the custom_smtp mailer for the user's own SMTP server. + // This configuration will be set dynamically by the AbstractEmailIntegrationHandler class. + 'custom_smtp' => [ + 'transport' => 'smtp', + 'host' => null, + 'port' => 587, + 'encryption' => 'tls', + 'username' => null, + 'password' => null, + ], + 'ses' => [ 'transport' => 'ses', ], diff --git a/api/database/migrations/2024_09_04_093826_add_settings_to_workspaces.php b/api/database/migrations/2024_09_04_093826_add_settings_to_workspaces.php new file mode 100644 index 000000000..f8b0541c8 --- /dev/null +++ b/api/database/migrations/2024_09_04_093826_add_settings_to_workspaces.php @@ -0,0 +1,34 @@ +json('settings')->default(new Expression('(JSON_OBJECT())'))->nullable(true); + } else { + $table->json('settings')->default('{}')->nullable(true); + } + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('workspaces', function (Blueprint $table) { + $table->dropColumn(['settings']); + }); + } +}; diff --git a/api/phpunit.xml b/api/phpunit.xml index 739dc89b6..52e0c90b0 100644 --- a/api/phpunit.xml +++ b/api/phpunit.xml @@ -1,38 +1,36 @@ - - - - ./tests/Unit - - - ./tests/Feature - - - - - - - - ./app - - - - - - - - - - - - - - - - - + + + + ./tests/Unit + + + ./tests/Feature + + + + + + + + + + + + + + + + + + + + + + + + + ./app + + diff --git a/api/routes/api.php b/api/routes/api.php index 7712602f0..fd205aa6a 100644 --- a/api/routes/api.php +++ b/api/routes/api.php @@ -142,6 +142,7 @@ [FormController::class, 'index'] )->name('forms.index'); Route::put('/custom-domains', [WorkspaceController::class, 'saveCustomDomain'])->name('save-custom-domains'); + Route::put('/email-settings', [WorkspaceController::class, 'saveEmailSettings'])->name('save-email-settings'); Route::delete('/', [WorkspaceController::class, 'delete'])->name('delete'); Route::middleware('pro-form')->group(function () { diff --git a/api/tests/Feature/Forms/CustomSmtpTest.php b/api/tests/Feature/Forms/CustomSmtpTest.php new file mode 100644 index 000000000..065e77e9f --- /dev/null +++ b/api/tests/Feature/Forms/CustomSmtpTest.php @@ -0,0 +1,60 @@ +actingAsUser(); + $workspace = $this->createUserWorkspace($user); + + $this->putJson(route('open.workspaces.save-email-settings', [$workspace->id]), [ + 'host' => 'custom.smtp.host', + 'port' => '587', + 'username' => 'custom_username', + 'password' => 'custom_password', + ])->assertStatus(403); +}); + +it('creates confirmation emails with custom SMTP settings', function () { + $user = $this->actingAsProUser(); + $workspace = $this->createUserWorkspace($user); + $form = $this->createForm($user, $workspace); + + // Set custom SMTP settings + $this->putJson(route('open.workspaces.save-email-settings', [$workspace->id]), [ + 'host' => 'custom.smtp.host', + 'port' => '587', + 'username' => 'custom_username', + 'password' => 'custom_password', + ])->assertSuccessful(); + + $integrationData = $this->createFormIntegration('submission_confirmation', $form->id, [ + 'respondent_email' => true, + 'notifications_include_submission' => true, + 'notification_sender' => 'Custom Sender', + 'notification_subject' => 'Custom SMTP Test', + 'notification_body' => 'This email was sent using custom SMTP settings', + ]); + + $formData = [ + collect($form->properties)->first(function ($property) { + return $property['type'] == 'email'; + })['id'] => 'test@test.com', + ]; + + Mail::fake(); + + $this->postJson(route('forms.answer', $form->slug), $formData) + ->assertSuccessful() + ->assertJson([ + 'type' => 'success', + 'message' => 'Form submission saved.', + ]); + + Mail::assertQueued( + SubmissionConfirmationMail::class, + function (SubmissionConfirmationMail $mail) { + return $mail->hasTo('test@test.com') && $mail->mailer === 'custom_smtp'; + } + ); +}); diff --git a/api/tests/Feature/UserInviteTest.php b/api/tests/Feature/UserManagementTest.php similarity index 74% rename from api/tests/Feature/UserInviteTest.php rename to api/tests/Feature/UserManagementTest.php index 7b70033c5..3113b4e24 100644 --- a/api/tests/Feature/UserInviteTest.php +++ b/api/tests/Feature/UserManagementTest.php @@ -3,16 +3,19 @@ use App\Models\UserInvite; use Carbon\Carbon; +beforeEach(function () { + $this->user = $this->actingAsProUser(); + $this->workspace = $this->createUserWorkspace($this->user); +}); + + it('can register with invite token', function () { - $this->withoutExceptionHandling(); - $user = $this->actingAsUser(); - $workspace = $this->createUserWorkspace($user); $email = 'invitee@gmail.com'; $inviteData = ['email' => $email, 'role' => 'user']; - $this->postJson(route('open.workspaces.users.add', $workspace->id), $inviteData) + $this->postJson(route('open.workspaces.users.add', $this->workspace->id), $inviteData) ->assertSuccessful(); - expect($workspace->invites()->count())->toBe(1); + expect($this->workspace->invites()->count())->toBe(1); $userInvite = UserInvite::latest()->first(); $token = $userInvite->token; @@ -30,18 +33,16 @@ 'invite_token' => $token, ]); $response->assertSuccessful(); - expect($workspace->users()->count())->toBe(2); + expect($this->workspace->users()->count())->toBe(2); }); it('cannot register with expired invite token', function () { - $user = $this->actingAsUser(); - $workspace = $this->createUserWorkspace($user); $email = 'invitee@gmail.com'; $inviteData = ['email' => $email, 'role' => 'user']; - $this->postJson(route('open.workspaces.users.add', $workspace->id), $inviteData) + $this->postJson(route('open.workspaces.users.add', $this->workspace->id), $inviteData) ->assertSuccessful(); - expect($workspace->invites()->count())->toBe(1); + expect($this->workspace->invites()->count())->toBe(1); $userInvite = UserInvite::latest()->first(); $token = $userInvite->token; @@ -62,18 +63,16 @@ $response->assertStatus(400)->assertJson([ 'message' => 'Invite token has expired.', ]); - expect($workspace->users()->count())->toBe(1); + expect($this->workspace->users()->count())->toBe(1); }); it('cannot re-register with accepted invite token', function () { - $user = $this->actingAsUser(); - $workspace = $this->createUserWorkspace($user); $email = 'invitee@gmail.com'; $inviteData = ['email' => $email, 'role' => 'user']; - $this->postJson(route('open.workspaces.users.add', $workspace->id), $inviteData) + $this->postJson(route('open.workspaces.users.add', $this->workspace->id), $inviteData) ->assertSuccessful(); - expect($workspace->invites()->count())->toBe(1); + expect($this->workspace->invites()->count())->toBe(1); $userInvite = UserInvite::latest()->first(); $token = $userInvite->token; @@ -91,10 +90,10 @@ 'invite_token' => $token, ]); $response->assertSuccessful(); - expect($workspace->users()->count())->toBe(2); + expect($this->workspace->users()->count())->toBe(2); $this->postJson('/logout') - ->assertSuccessful(); + ->assertSuccessful(); // Register again with same used token $response = $this->postJson('/register', [ @@ -110,23 +109,21 @@ $response->assertStatus(422)->assertJson([ 'message' => 'The email has already been taken.', ]); - expect($workspace->users()->count())->toBe(2); + expect($this->workspace->users()->count())->toBe(2); }); it('can cancel user invite', function () { - $user = $this->actingAsUser(); - $workspace = $this->createUserWorkspace($user); $email = 'invitee@gmail.com'; $inviteData = ['email' => $email, 'role' => 'user']; - $response = $this->postJson(route('open.workspaces.users.add', $workspace->id), $inviteData) + $response = $this->postJson(route('open.workspaces.users.add', $this->workspace->id), $inviteData) ->assertSuccessful(); - expect($workspace->invites()->count())->toBe(1); + expect($this->workspace->invites()->count())->toBe(1); $userInvite = UserInvite::latest()->first(); $token = $userInvite->token; // Cancel the invite - $this->deleteJson(route('open.workspaces.invites.cancel', ['workspaceId' => $workspace->id, 'inviteId' => $userInvite->id])) + $this->deleteJson(route('open.workspaces.invites.cancel', ['workspaceId' => $this->workspace->id, 'inviteId' => $userInvite->id])) ->assertSuccessful(); $this->postJson('/logout') @@ -146,5 +143,5 @@ 'message' => 'Invite token is invalid.', ]); - expect($workspace->users()->count())->toBe(1); + expect($this->workspace->users()->count())->toBe(1); }); diff --git a/client/components/open/integrations/EmailIntegration.vue b/client/components/open/integrations/EmailIntegration.vue index 679bf67d2..03c352578 100644 --- a/client/components/open/integrations/EmailIntegration.vue +++ b/client/components/open/integrations/EmailIntegration.vue @@ -4,6 +4,16 @@ :integration="props.integration" :form="form" > +

+ You can + use our custom SMTP feature + to send emails from your own domain. +

+ -
{{ emailSubmissionConfirmationHelp }}
+
+ {{ emailSubmissionConfirmationHelp }} +
+ +

+ You can + use our custom SMTP feature + to send emails from your own domain. +

@@ -16,7 +16,7 @@ @close="showCustomDomainModal = false" >

- Manage your custom domains + Custom Domains Settings

+
+ + + +

+ Email Settings +

+

+ Customize email sender - connect your SMTP server. +

+ + + + + + + + + +
+ + Update + + + Clear + +
+
+
+ + + diff --git a/client/pages/settings/workspace.vue b/client/pages/settings/workspace.vue index cceb459d1..75718b25e 100644 --- a/client/pages/settings/workspace.vue +++ b/client/pages/settings/workspace.vue @@ -8,8 +8,9 @@ You're currently editing the settings for the workspace "{{ workspace.name }}". You can switch to another workspace in top left corner of the page.
-
+
+