diff --git a/.gitignore b/.gitignore index b666520a4..cdbd7bf66 100644 --- a/.gitignore +++ b/.gitignore @@ -20,10 +20,8 @@ yarn-error.log /.npm /.bash_history /_data - -# Temp while developing Proxy deployment -resources/recipes - +_testing_hosts/ +_volumes/ .lesshst psysh_history .psql_history diff --git a/app/Http/Livewire/Settings/DiscordNotifications.php b/app/Http/Livewire/Settings/DiscordNotifications.php new file mode 100644 index 000000000..01388a238 --- /dev/null +++ b/app/Http/Livewire/Settings/DiscordNotifications.php @@ -0,0 +1,38 @@ + 'nullable|url', + ]; + protected $validationAttributes = [ + 'settings.extra_attributes.discord_webhook' => 'Discord Webhook', + ]; + public function mount($settings) + { + // + } + public function submit() + { + $this->resetErrorBag(); + $this->validate(); + $this->settings->save(); + } + public function sentTestMessage() + { + // @TODO figure out how to do it in runtime + } + public function render() + { + return view('livewire.settings.discord-notifications'); + } +} diff --git a/app/Http/Livewire/Settings/EmailNotifications.php b/app/Http/Livewire/Settings/EmailNotifications.php new file mode 100644 index 000000000..639fb11cd --- /dev/null +++ b/app/Http/Livewire/Settings/EmailNotifications.php @@ -0,0 +1,49 @@ + 'nullable', + 'settings.extra_attributes.smtp_port' => 'nullable', + 'settings.extra_attributes.smtp_encryption' => 'nullable', + 'settings.extra_attributes.smtp_username' => 'nullable', + 'settings.extra_attributes.smtp_password' => 'nullable', + 'settings.extra_attributes.smtp_timeout' => 'nullable', + ]; + protected $validationAttributes = [ + 'settings.extra_attributes.smtp_host' => 'Host', + 'settings.extra_attributes.smtp_port' => 'Port', + 'settings.extra_attributes.smtp_encryption' => 'Encryption', + 'settings.extra_attributes.smtp_username' => 'Username', + 'settings.extra_attributes.smtp_password' => 'Password', + 'settings.extra_attributes.smtp_timeout' => 'Timeout', + ]; + public function mount($settings) + { + ray($settings); + // + } + public function submit() + { + $this->resetErrorBag(); + $this->validate(); + $this->settings->save(); + } + public function sentTestMessage() + { + Notification::send(auth()->user(), new TestMessage); + } + public function render() + { + return view('livewire.settings.email-notifications'); + } +} diff --git a/app/Jobs/SendMessageToDiscordJob.php b/app/Jobs/SendMessageToDiscordJob.php new file mode 100644 index 000000000..8f1962829 --- /dev/null +++ b/app/Jobs/SendMessageToDiscordJob.php @@ -0,0 +1,45 @@ + $this->text, + ]; + + Http::post($this->webhookUrl, $payload); + } +} diff --git a/app/Models/InstanceSettings.php b/app/Models/InstanceSettings.php index c2394a008..445d07477 100644 --- a/app/Models/InstanceSettings.php +++ b/app/Models/InstanceSettings.php @@ -2,10 +2,21 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; +use Spatie\SchemalessAttributes\Casts\SchemalessAttributes; class InstanceSettings extends Model { + public $casts = [ + 'extra_attributes' => SchemalessAttributes::class, + ]; + + public function scopeWithExtraAttributes(): Builder + { + return $this->extra_attributes->modelScope(); + } + public static function get() { return InstanceSettings::findOrFail(0); diff --git a/app/Notifications/Channels/DiscordChannel.php b/app/Notifications/Channels/DiscordChannel.php new file mode 100644 index 000000000..77709ec0b --- /dev/null +++ b/app/Notifications/Channels/DiscordChannel.php @@ -0,0 +1,25 @@ +toDiscord($notifiable); + + $webhookUrl = data_get( + InstanceSettings::get(), + 'extra_attributes.discord_webhook' + ); + + dispatch(new SendMessageToDiscordJob($message, $webhookUrl)); + } +} diff --git a/app/Notifications/TestMessage.php b/app/Notifications/TestMessage.php new file mode 100644 index 000000000..8e8929f10 --- /dev/null +++ b/app/Notifications/TestMessage.php @@ -0,0 +1,60 @@ + + */ + public function via(object $notifiable): array + { + return ['mail', DiscordChannel::class]; + } + + /** + * Get the mail representation of the notification. + */ + public function toMail(object $notifiable): MailMessage + { + return (new MailMessage) + ->line('Welcome to Coolify!') + ->action('Go to dashboard', url('/')) + ->line('We need your attention for disk usage.'); + } + + public function toDiscord(object $notifiable): string + { + return 'Welcome to Coolify! We need your attention for disk usage. [Go to dashboard]('.url('/').')'; + } + + /** + * Get the array representation of the notification. + * + * @return array + */ + public function toArray(object $notifiable): array + { + return [ + // + ]; + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index be599237a..3129c24ce 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -3,11 +3,13 @@ namespace App\Providers; use App\Jobs\CoolifyTask; +use Illuminate\Mail\MailManager; use Illuminate\Queue\Events\JobProcessed; use Illuminate\Support\Facades\Process; use Illuminate\Support\Facades\Queue; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Str; +use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport; class AppServiceProvider extends ServiceProvider { @@ -26,6 +28,10 @@ public function register(): void */ public function boot(): void { + if (! $this->app->environment('production')) { + \Illuminate\Support\Facades\Mail::alwaysTo('noone@example.com'); + } + Queue::after(function (JobProcessed $event) { // @TODO: Remove `coolify-builder` container after the remoteProcess job is finishged and remoteProcess->type == `deployment`. if ($event->job->resolveName() === CoolifyTask::class) { diff --git a/database/migrations/2023_03_20_112813_create_instance_settings_table.php b/database/migrations/2023_03_20_112813_create_instance_settings_table.php index d68649e7a..2d1826d30 100644 --- a/database/migrations/2023_03_20_112813_create_instance_settings_table.php +++ b/database/migrations/2023_03_20_112813_create_instance_settings_table.php @@ -27,6 +27,9 @@ public function up(): void // $table->boolean('is_dns_check_enabled')->default(true); $table->boolean('is_registration_enabled')->default(true); $table->boolean('is_https_forced')->default(true); + + $table->schemalessAttributes('extra_attributes'); + $table->timestamps(); }); } diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index a59dd6abd..76065370c 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -64,3 +64,10 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock - "./_data/coolify/proxy/testing-host-2:/data/coolify/proxy" + mailpit: + image: 'axllent/mailpit:latest' + ports: + - '${FORWARD_MAILPIT_PORT:-1025}:1025' + - '${FORWARD_MAILPIT_DASHBOARD_PORT:-8025}:8025' + networks: + - coolify diff --git a/resources/views/components/inputs/button.blade.php b/resources/views/components/inputs/button.blade.php index a323d620f..d09fb0cd7 100644 --- a/resources/views/components/inputs/button.blade.php +++ b/resources/views/components/inputs/button.blade.php @@ -5,26 +5,26 @@ 'confirmAction' => null, ]) @if ($type === 'submit') - @elseif($type === 'button') - @endif diff --git a/resources/views/livewire/settings/discord-notifications.blade.php b/resources/views/livewire/settings/discord-notifications.blade.php new file mode 100644 index 000000000..d13e26e27 --- /dev/null +++ b/resources/views/livewire/settings/discord-notifications.blade.php @@ -0,0 +1,15 @@ +
+
+
+ +
+
+ + Submit + + + Send test message + +
+
+
diff --git a/resources/views/livewire/settings/email-notifications.blade.php b/resources/views/livewire/settings/email-notifications.blade.php new file mode 100644 index 000000000..6bfc53506 --- /dev/null +++ b/resources/views/livewire/settings/email-notifications.blade.php @@ -0,0 +1,24 @@ +
+
+
+
+ + + +
+
+ + + +
+
+
+ + Submit + + + Send test message + +
+
+
diff --git a/resources/views/settings.blade.php b/resources/views/settings.blade.php index 389f8be41..f0155603d 100644 --- a/resources/views/settings.blade.php +++ b/resources/views/settings.blade.php @@ -1,4 +1,12 @@

Settings

+ +

General

+ +
+ +

Notifications

+ +
diff --git a/resources/views/team.blade.php b/resources/views/team.blade.php index c6265e32c..135c131d8 100644 --- a/resources/views/team.blade.php +++ b/resources/views/team.blade.php @@ -1,7 +1,8 @@

Current Team

-

Name: {{ session('currentTeam')->name }}

- +

Name: {{ session('currentTeam.name') }}

+ +
diff --git a/routes/console.php b/routes/console.php index d2977bec5..34f661adb 100644 --- a/routes/console.php +++ b/routes/console.php @@ -2,6 +2,7 @@ use Illuminate\Foundation\Inspiring; use Illuminate\Support\Facades\Artisan; +use Symfony\Component\Mailer\Mailer; /* |-------------------------------------------------------------------------- @@ -14,19 +15,27 @@ | */ -// Artisan::command('inspire', function () { +Artisan::command('inspire', function () { -// $activity = Spatie\Activitylog\Models\Activity::latest()->first(); + $smtp = [ + "transport" => "smtp", + "host" => "mailpit", + "port" => 1025, + "encryption" => 'tls', + "username" => null, + "password" => null, + "timeout" => null, + "local_domain" => null, + ]; + config()->set('mail.mailers.smtp', $smtp); -// $this->info( -// collect( -// json_decode(data_get($activity, 'description'), associative: true, flags: JSON_THROW_ON_ERROR) -// ) -// ->sortBy('order') -// ->map(fn($i) => $i['output']) -// ->implode("\n") -// ); +// \Illuminate\Support\Facades\Mail::mailer('smtp') +// ->to('ask@me.com') +// ->send(new \App\Mail\TestMail); + \Illuminate\Support\Facades\Notification::send( + \App\Models\User::find(1), + new \App\Notifications\TestMessage + ); - -// })->purpose('Display an inspiring quote'); +})->purpose('Display an inspiring quote');