diff --git a/app/Http/Controllers/ServerController.php b/app/Http/Controllers/ServerController.php
index b01a2dd5e..21ca2ba77 100644
--- a/app/Http/Controllers/ServerController.php
+++ b/app/Http/Controllers/ServerController.php
@@ -12,20 +12,21 @@ class ServerController extends Controller
public function new_server()
{
+ $privateKeys = PrivateKey::ownedByCurrentTeam()->get();
if (!isCloud()) {
return view('server.create', [
'limit_reached' => false,
- 'private_keys' => PrivateKey::ownedByCurrentTeam()->get(),
+ 'private_keys' => $privateKeys,
]);
}
- $servers = currentTeam()->servers->count();
- $subscription = currentTeam()?->subscription->type();
- $your_limit = config('constants.limits.server')[strtolower($subscription)];
- $limit_reached = $servers >= $your_limit;
+ $team = currentTeam();
+ $servers = $team->servers->count();
+ ['serverLimit' => $serverLimit] = $team->limits;
+ $limit_reached = $servers >= $serverLimit;
return view('server.create', [
'limit_reached' => $limit_reached,
- 'private_keys' => PrivateKey::ownedByCurrentTeam()->get(),
+ 'private_keys' => $privateKeys,
]);
}
}
diff --git a/app/Http/Livewire/Dashboard.php b/app/Http/Livewire/Dashboard.php
index 874e389e0..98c330847 100644
--- a/app/Http/Livewire/Dashboard.php
+++ b/app/Http/Livewire/Dashboard.php
@@ -6,6 +6,7 @@
use App\Models\S3Storage;
use App\Models\Server;
use Livewire\Component;
+use Log;
class Dashboard extends Component
{
diff --git a/app/Http/Livewire/Notifications/EmailSettings.php b/app/Http/Livewire/Notifications/EmailSettings.php
index a2887f989..bf805e5ec 100644
--- a/app/Http/Livewire/Notifications/EmailSettings.php
+++ b/app/Http/Livewire/Notifications/EmailSettings.php
@@ -6,55 +6,143 @@
use App\Models\Team;
use App\Notifications\Test;
use Livewire\Component;
+use Log;
class EmailSettings extends Component
{
- public Team $model;
+ public Team $team;
public string $emails;
+ public bool $sharedEmailEnabled = false;
protected $rules = [
- 'model.smtp_enabled' => 'nullable|boolean',
- 'model.smtp_from_address' => 'required|email',
- 'model.smtp_from_name' => 'required',
- 'model.smtp_recipients' => 'nullable',
- 'model.smtp_host' => 'required',
- 'model.smtp_port' => 'required',
- 'model.smtp_encryption' => 'nullable',
- 'model.smtp_username' => 'nullable',
- 'model.smtp_password' => 'nullable',
- 'model.smtp_timeout' => 'nullable',
- 'model.smtp_notifications_test' => 'nullable|boolean',
- 'model.smtp_notifications_deployments' => 'nullable|boolean',
- 'model.smtp_notifications_status_changes' => 'nullable|boolean',
- 'model.smtp_notifications_database_backups' => 'nullable|boolean',
+ 'team.smtp_enabled' => 'nullable|boolean',
+ 'team.smtp_from_address' => 'required|email',
+ 'team.smtp_from_name' => 'required',
+ 'team.smtp_recipients' => 'nullable',
+ 'team.smtp_host' => 'required',
+ 'team.smtp_port' => 'required',
+ 'team.smtp_encryption' => 'nullable',
+ 'team.smtp_username' => 'nullable',
+ 'team.smtp_password' => 'nullable',
+ 'team.smtp_timeout' => 'nullable',
+ 'team.smtp_notifications_test' => 'nullable|boolean',
+ 'team.smtp_notifications_deployments' => 'nullable|boolean',
+ 'team.smtp_notifications_status_changes' => 'nullable|boolean',
+ 'team.smtp_notifications_database_backups' => 'nullable|boolean',
+ 'team.use_instance_email_settings' => 'boolean',
+ 'team.resend_enabled' => 'nullable|boolean',
+ 'team.resend_api_key' => 'nullable',
];
protected $validationAttributes = [
- 'model.smtp_from_address' => 'From Address',
- 'model.smtp_from_name' => 'From Name',
- 'model.smtp_recipients' => 'Recipients',
- 'model.smtp_host' => 'Host',
- 'model.smtp_port' => 'Port',
- 'model.smtp_encryption' => 'Encryption',
- 'model.smtp_username' => 'Username',
- 'model.smtp_password' => 'Password',
+ 'team.smtp_from_address' => 'From Address',
+ 'team.smtp_from_name' => 'From Name',
+ 'team.smtp_recipients' => 'Recipients',
+ 'team.smtp_host' => 'Host',
+ 'team.smtp_port' => 'Port',
+ 'team.smtp_encryption' => 'Encryption',
+ 'team.smtp_username' => 'Username',
+ 'team.smtp_password' => 'Password',
+ 'team.smtp_timeout' => 'Timeout',
+ 'team.resend_enabled' => 'Resend Enabled',
+ 'team.resend_api_key' => 'Resend API Key',
];
public function mount()
{
- $this->decrypt();
+ ['sharedEmailEnabled' => $this->sharedEmailEnabled] = $this->team->limits;
$this->emails = auth()->user()->email;
}
-
- private function decrypt()
+ public function submitFromFields()
{
- if (data_get($this->model, 'smtp_password')) {
- try {
- $this->model->smtp_password = decrypt($this->model->smtp_password);
- } catch (\Exception $e) {
+ try {
+ $this->resetErrorBag();
+ $this->validate([
+ 'team.smtp_from_address' => 'required|email',
+ 'team.smtp_from_name' => 'required',
+ ]);
+ $this->team->save();
+ $this->emit('success', 'Settings saved successfully.');
+ } catch (\Exception $e) {
+ return general_error_handler($e, $this);
+ }
+ }
+ public function sendTestNotification()
+ {
+ $this->team->notify(new Test($this->emails));
+ $this->emit('success', 'Test Email sent successfully.');
+ }
+ public function instantSaveInstance()
+ {
+ try {
+ if (!$this->sharedEmailEnabled) {
+ throw new \Exception('Not allowed to change settings. Please upgrade your subscription.');
}
+ $this->team->smtp_enabled = false;
+ $this->team->resend_enabled = false;
+ $this->team->save();
+ $this->emit('success', 'Settings saved successfully.');
+ } catch (\Exception $e) {
+ return general_error_handler($e, $this);
}
}
+ public function instantSaveResend()
+ {
+ try {
+ $this->team->smtp_enabled = false;
+ $this->submitResend();
+ } catch (\Exception $e) {
+ $this->team->smtp_enabled = false;
+ return general_error_handler($e, $this);
+ }
+ }
+ public function instantSave()
+ {
+ try {
+ $this->team->resend_enabled = false;
+ $this->submit();
+ } catch (\Exception $e) {
+ $this->team->smtp_enabled = false;
+ return general_error_handler($e, $this);
+ }
+ }
+
+ public function submit()
+ {
+ try {
+ $this->resetErrorBag();
+ $this->validate([
+ 'team.smtp_from_address' => 'required|email',
+ 'team.smtp_from_name' => 'required',
+ 'team.smtp_host' => 'required',
+ 'team.smtp_port' => 'required|numeric',
+ 'team.smtp_encryption' => 'nullable',
+ 'team.smtp_username' => 'nullable',
+ 'team.smtp_password' => 'nullable',
+ 'team.smtp_timeout' => 'nullable',
+ ]);
+ $this->team->save();
+ $this->emit('success', 'Settings saved successfully.');
+ } catch (\Exception $e) {
+ $this->team->smtp_enabled = false;
+ return general_error_handler($e, $this);
+ }
+ }
+ public function submitResend()
+ {
+ try {
+ $this->resetErrorBag();
+ $this->validate([
+ 'team.resend_api_key' => 'required'
+ ]);
+ $this->team->save();
+ refreshSession();
+ $this->emit('success', 'Settings saved successfully.');
+ } catch (\Exception $e) {
+ $this->team->resend_enabled = false;
+ return general_error_handler($e, $this);
+ }
+ }
public function copyFromInstanceSettings()
{
$settings = InstanceSettings::get();
@@ -72,55 +160,22 @@ public function copyFromInstanceSettings()
'smtp_password' => $settings->smtp_password,
'smtp_timeout' => $settings->smtp_timeout,
]);
- $this->decrypt();
- if (is_a($team, Team::class)) {
- refreshSession();
- }
- $this->model = $team;
- $this->emit('success', 'Settings saved.');
- } else {
- $this->emit('error', 'Instance SMTP settings are not enabled.');
- }
- }
-
- public function sendTestNotification()
- {
- $this->model->notify(new Test($this->emails));
- $this->emit('success', 'Test Email sent successfully.');
- }
-
- public function instantSave()
- {
- try {
- $this->submit();
- } catch (\Exception $e) {
- $this->model->smtp_enabled = false;
- $this->validate();
- }
- }
-
- public function submit()
- {
- $this->resetErrorBag();
- $this->validate();
-
- if ($this->model->smtp_password) {
- $this->model->smtp_password = encrypt($this->model->smtp_password);
- } else {
- $this->model->smtp_password = null;
- }
-
- $this->model->smtp_recipients = str_replace(' ', '', $this->model->smtp_recipients);
- $this->saveModel();
- }
-
- public function saveModel()
- {
- $this->model->save();
- $this->decrypt();
- if (is_a($this->model, Team::class)) {
refreshSession();
+ $this->team = $team;
+ $this->emit('success', 'Settings saved.');
+ return;
}
- $this->emit('success', 'Settings saved.');
+ if ($settings->resend_enabled) {
+ $team = currentTeam();
+ $team->update([
+ 'resend_enabled' => $settings->resend_enabled,
+ 'resend_api_key' => $settings->resend_api_key,
+ ]);
+ refreshSession();
+ $this->team = $team;
+ $this->emit('success', 'Settings saved.');
+ return;
+ }
+ $this->emit('error', 'Instance SMTP/Resend settings are not enabled.');
}
}
diff --git a/app/Http/Livewire/Settings/Email.php b/app/Http/Livewire/Settings/Email.php
index 0256b6021..c0e80f020 100644
--- a/app/Http/Livewire/Settings/Email.php
+++ b/app/Http/Livewire/Settings/Email.php
@@ -54,14 +54,6 @@ public function submitFromFields() {
return general_error_handler($e, $this);
}
}
- public function instantSaveResend()
- {
- try {
- $this->submitResend();
- } catch (\Exception $e) {
- return general_error_handler($e, $this);
- }
- }
public function submitResend() {
try {
$this->resetErrorBag();
diff --git a/app/Http/Livewire/Team/Invitations.php b/app/Http/Livewire/Team/Invitations.php
index ba6c1e91f..f52701e34 100644
--- a/app/Http/Livewire/Team/Invitations.php
+++ b/app/Http/Livewire/Team/Invitations.php
@@ -14,6 +14,7 @@ public function deleteInvitation(int $invitation_id)
{
TeamInvitation::find($invitation_id)->delete();
$this->refreshInvitations();
+ $this->emit('success', 'Invitation revoked.');
}
public function refreshInvitations()
diff --git a/app/Models/Team.php b/app/Models/Team.php
index d8d486fec..b75772569 100644
--- a/app/Models/Team.php
+++ b/app/Models/Team.php
@@ -4,6 +4,7 @@
use App\Notifications\Channels\SendsDiscord;
use App\Notifications\Channels\SendsEmail;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
@@ -14,6 +15,8 @@ class Team extends Model implements SendsDiscord, SendsEmail
protected $guarded = [];
protected $casts = [
'personal_team' => 'boolean',
+ 'smtp_password' => 'encrypted',
+ 'resend_api_key' => 'encrypted',
];
public function routeNotificationForDiscord()
@@ -30,6 +33,27 @@ public function getRecepients($notification)
}
return explode(',', $recipients);
}
+ public function limits(): Attribute
+ {
+ return Attribute::make(
+ get: function () {
+ if (config('coolify.self_hosted') || $this->id === 0) {
+ $subscription = 'self-hosted';
+ } else {
+ $subscription = data_get($this, 'subscription');
+ if (is_null($subscription)) {
+ $subscription = 'zero';
+ } else {
+ $subscription = $subscription->type();
+ }
+ }
+ $serverLimit = config('constants.limits.server')[strtolower($subscription)];
+ $sharedEmailEnabled = config('constants.limits.email')[strtolower($subscription)];
+ return ['serverLimit' => $serverLimit, 'sharedEmailEnabled' => $sharedEmailEnabled];
+ }
+
+ );
+ }
public function members()
{
diff --git a/app/Notifications/Application/DeploymentFailed.php b/app/Notifications/Application/DeploymentFailed.php
index bc7f5dfde..fdd4beabf 100644
--- a/app/Notifications/Application/DeploymentFailed.php
+++ b/app/Notifications/Application/DeploymentFailed.php
@@ -44,7 +44,7 @@ public function __construct(Application $application, string $deployment_uuid, A
public function via(object $notifiable): array
{
$channels = [];
- $isEmailEnabled = data_get($notifiable, 'smtp_enabled');
+ $isEmailEnabled = isEmailEnabled($notifiable);
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
$isSubscribedToEmailEvent = data_get($notifiable, 'smtp_notifications_deployments');
$isSubscribedToDiscordEvent = data_get($notifiable, 'discord_notifications_deployments');
diff --git a/app/Notifications/Channels/EmailChannel.php b/app/Notifications/Channels/EmailChannel.php
index afb30d0c9..aaf059149 100644
--- a/app/Notifications/Channels/EmailChannel.php
+++ b/app/Notifications/Channels/EmailChannel.php
@@ -21,7 +21,7 @@ public function send(SendsEmail $notifiable, Notification $notification): void
$mailMessage = $notification->toMail($notifiable);
if ($this->isResend) {
- foreach($recepients as $receipient) {
+ foreach ($recepients as $receipient) {
Mail::send(
[],
[],
@@ -35,7 +35,6 @@ public function send(SendsEmail $notifiable, Notification $notification): void
->html((string)$mailMessage->render())
);
}
-
} else {
Mail::send(
[],
@@ -50,22 +49,26 @@ public function send(SendsEmail $notifiable, Notification $notification): void
->html((string)$mailMessage->render())
);
}
-
}
private function bootConfigs($notifiable): void
{
- if (data_get($notifiable, 'resend_enabled')) {
- $resendAPIKey = data_get($notifiable, 'resend_api_key');
- if ($resendAPIKey) {
- $this->isResend = true;
- config()->set('mail.default', 'resend');
- config()->set('resend.api_key', $resendAPIKey);
+ if (data_get($notifiable, 'use_instance_email_settings')) {
+ $type = set_transanctional_email_settings();
+ if (!$type) {
+ throw new Exception('No email settings found.');
}
+ if ($type === 'resend') {
+ $this->isResend = true;
+ }
+ return;
+ }
+ if (data_get($notifiable, 'resend_enabled')) {
+ $this->isResend = true;
+ config()->set('mail.default', 'resend');
+ config()->set('resend.api_key', data_get($notifiable, 'resend_api_key'));
}
if (data_get($notifiable, 'smtp_enabled')) {
- $password = data_get($notifiable, 'smtp_password');
- if ($password) $password = decrypt($password);
config()->set('mail.default', 'smtp');
config()->set('mail.mailers.smtp', [
"transport" => "smtp",
@@ -73,7 +76,7 @@ private function bootConfigs($notifiable): void
"port" => data_get($notifiable, 'smtp_port'),
"encryption" => data_get($notifiable, 'smtp_encryption'),
"username" => data_get($notifiable, 'smtp_username'),
- "password" => $password,
+ "password" => data_get($notifiable, 'smtp_password'),
"timeout" => data_get($notifiable, 'smtp_timeout'),
"local_domain" => null,
]);
diff --git a/app/Notifications/Channels/TransactionalEmailChannel.php b/app/Notifications/Channels/TransactionalEmailChannel.php
index bf968eb3f..23fe28700 100644
--- a/app/Notifications/Channels/TransactionalEmailChannel.php
+++ b/app/Notifications/Channels/TransactionalEmailChannel.php
@@ -4,16 +4,20 @@
use App\Models\InstanceSettings;
use App\Models\User;
+use Exception;
use Illuminate\Mail\Message;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Mail;
+use Log;
class TransactionalEmailChannel
{
+ private bool $isResend = false;
public function send(User $notifiable, Notification $notification): void
{
$settings = InstanceSettings::get();
- if (data_get($settings, 'smtp_enabled') !== true) {
+ if (!data_get($settings, 'smtp_enabled') && !data_get($settings, 'resend_enabled')) {
+ Log::info('SMTP/Resend not enabled');
return;
}
$email = $notifiable->email;
@@ -22,22 +26,43 @@ public function send(User $notifiable, Notification $notification): void
}
$this->bootConfigs();
$mailMessage = $notification->toMail($notifiable);
- Mail::send(
- [],
- [],
- fn (Message $message) => $message
- ->from(
- data_get($settings, 'smtp_from_address'),
- data_get($settings, 'smtp_from_name')
- )
- ->to($email)
- ->subject($mailMessage->subject)
- ->html((string)$mailMessage->render())
- );
+ if ($this->isResend) {
+ Mail::send(
+ [],
+ [],
+ fn (Message $message) => $message
+ ->from(
+ data_get($settings, 'smtp_from_address'),
+ data_get($settings, 'smtp_from_name'),
+ )
+ ->to($email)
+ ->subject($mailMessage->subject)
+ ->html((string)$mailMessage->render())
+ );
+ } else {
+ Mail::send(
+ [],
+ [],
+ fn (Message $message) => $message
+ ->from(
+ data_get($settings, 'smtp_from_address'),
+ data_get($settings, 'smtp_from_name'),
+ )
+ ->bcc($email)
+ ->subject($mailMessage->subject)
+ ->html((string)$mailMessage->render())
+ );
+ }
}
private function bootConfigs(): void
{
- set_transanctional_email_settings();
+ $type = set_transanctional_email_settings();
+ if (!$type) {
+ throw new Exception('No email settings found.');
+ }
+ if ($type === 'resend') {
+ $this->isResend = true;
+ }
}
}
diff --git a/app/Notifications/Database/BackupFailed.php b/app/Notifications/Database/BackupFailed.php
index b47f03291..dda0b4884 100644
--- a/app/Notifications/Database/BackupFailed.php
+++ b/app/Notifications/Database/BackupFailed.php
@@ -25,7 +25,7 @@ public function __construct(ScheduledDatabaseBackup $backup, public $database, p
public function via(object $notifiable): array
{
$channels = [];
- $isEmailEnabled = data_get($notifiable, 'smtp_enabled');
+ $isEmailEnabled = isEmailEnabled($notifiable);
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
$isSubscribedToEmailEvent = data_get($notifiable, 'smtp_notifications_database_backups');
$isSubscribedToDiscordEvent = data_get($notifiable, 'discord_notifications_database_backups');
diff --git a/app/Notifications/Database/BackupSuccess.php b/app/Notifications/Database/BackupSuccess.php
index 82b521019..dad3ee060 100644
--- a/app/Notifications/Database/BackupSuccess.php
+++ b/app/Notifications/Database/BackupSuccess.php
@@ -25,7 +25,7 @@ public function __construct(ScheduledDatabaseBackup $backup, public $database)
public function via(object $notifiable): array
{
$channels = [];
- $isEmailEnabled = data_get($notifiable, 'smtp_enabled');
+ $isEmailEnabled = isEmailEnabled($notifiable);
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
$isSubscribedToEmailEvent = data_get($notifiable, 'smtp_notifications_database_backups');
$isSubscribedToDiscordEvent = data_get($notifiable, 'discord_notifications_database_backups');
diff --git a/app/Notifications/Server/NotReachable.php b/app/Notifications/Server/NotReachable.php
index 0b5f71569..bc97d033e 100644
--- a/app/Notifications/Server/NotReachable.php
+++ b/app/Notifications/Server/NotReachable.php
@@ -23,7 +23,7 @@ public function __construct(public Server $server)
public function via(object $notifiable): array
{
$channels = [];
- $isEmailEnabled = data_get($notifiable, 'smtp_enabled');
+ $isEmailEnabled = isEmailEnabled($notifiable);
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
$isSubscribedToEmailEvent = data_get($notifiable, 'smtp_notifications_status_changes');
$isSubscribedToDiscordEvent = data_get($notifiable, 'discord_notifications_status_changes');
diff --git a/app/Notifications/Test.php b/app/Notifications/Test.php
index 4cec28cfd..eb266d0f9 100644
--- a/app/Notifications/Test.php
+++ b/app/Notifications/Test.php
@@ -20,7 +20,7 @@ public function __construct(public string|null $emails = null)
public function via(object $notifiable): array
{
$channels = [];
- $isEmailEnabled = data_get($notifiable, 'smtp_enabled');
+ $isEmailEnabled = isEmailEnabled($notifiable);
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
if ($isDiscordEnabled && empty($this->emails)) {
diff --git a/app/Notifications/TransactionalEmails/ResetPassword.php b/app/Notifications/TransactionalEmails/ResetPassword.php
index e9baa16d1..6844aa705 100644
--- a/app/Notifications/TransactionalEmails/ResetPassword.php
+++ b/app/Notifications/TransactionalEmails/ResetPassword.php
@@ -31,24 +31,11 @@ public static function toMailUsing($callback)
public function via($notifiable)
{
- if ($this->settings->smtp_enabled) {
- $password = data_get($this->settings, 'smtp_password');
- if ($password) $password = decrypt($password);
-
- config()->set('mail.default', 'smtp');
- config()->set('mail.mailers.smtp', [
- "transport" => "smtp",
- "host" => data_get($this->settings, 'smtp_host'),
- "port" => data_get($this->settings, 'smtp_port'),
- "encryption" => data_get($this->settings, 'smtp_encryption'),
- "username" => data_get($this->settings, 'smtp_username'),
- "password" => $password,
- "timeout" => data_get($this->settings, 'smtp_timeout'),
- "local_domain" => null,
- ]);
- return ['mail'];
+ $type = set_transanctional_email_settings();
+ if (!$type) {
+ throw new \Exception('No email settings found.');
}
- throw new \Exception('SMTP is not enabled');
+ return ['mail'];
}
public function toMail($notifiable)
diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php
index 8eb557ec1..249f76920 100644
--- a/bootstrap/helpers/shared.php
+++ b/bootstrap/helpers/shared.php
@@ -73,7 +73,7 @@ function general_error_handler(Throwable | null $err = null, $that = null, $isJs
throw new Exception($customErrorMessage ?? "Too many requests. Please try again in {$err->secondsUntilAvailable} seconds.");
} else {
if ($err->getMessage() === 'This action is unauthorized.') {
- return redirect()->route('dashboard')->with('error', $customErrorMessage ?? $err->getMessage());
+ return redirect()->route('dashboard')->with('error', $customErrorMessage ?? $err->getMessage());
}
throw new Exception($customErrorMessage ?? $err->getMessage());
}
@@ -122,10 +122,11 @@ function generateSSHKey()
$key = RSA::createKey();
return [
'private' => $key->toString('PKCS1'),
- 'public' => $key->getPublicKey()->toString('OpenSSH',['comment' => 'coolify-generated-ssh-key'])
+ 'public' => $key->getPublicKey()->toString('OpenSSH', ['comment' => 'coolify-generated-ssh-key'])
];
}
-function formatPrivateKey(string $privateKey) {
+function formatPrivateKey(string $privateKey)
+{
$privateKey = trim($privateKey);
if (!str_ends_with($privateKey, "\n")) {
$privateKey .= "\n";
@@ -140,30 +141,34 @@ function generate_application_name(string $git_repository, string $git_branch):
function is_transactional_emails_active(): bool
{
- return data_get(InstanceSettings::get(), 'smtp_enabled');
+ return isEmailEnabled(InstanceSettings::get());
}
-function set_transanctional_email_settings(InstanceSettings | null $settings = null): void
+function set_transanctional_email_settings(InstanceSettings | null $settings = null): string|null
{
if (!$settings) {
$settings = InstanceSettings::get();
}
- $password = data_get($settings, 'smtp_password');
- if (isset($password)) {
- $password = decrypt($password);
+ if (data_get($settings, 'resend_enabled')) {
+ config()->set('mail.default', 'resend');
+ config()->set('resend.api_key', data_get($settings, 'resend_api_key'));
+ return 'resend';
}
-
- config()->set('mail.default', 'smtp');
- config()->set('mail.mailers.smtp', [
- "transport" => "smtp",
- "host" => data_get($settings, 'smtp_host'),
- "port" => data_get($settings, 'smtp_port'),
- "encryption" => data_get($settings, 'smtp_encryption'),
- "username" => data_get($settings, 'smtp_username'),
- "password" => $password,
- "timeout" => data_get($settings, 'smtp_timeout'),
- "local_domain" => null,
- ]);
+ if (data_get($settings, 'smtp_enabled')) {
+ config()->set('mail.default', 'smtp');
+ config()->set('mail.mailers.smtp', [
+ "transport" => "smtp",
+ "host" => data_get($settings, 'smtp_host'),
+ "port" => data_get($settings, 'smtp_port'),
+ "encryption" => data_get($settings, 'smtp_encryption'),
+ "username" => data_get($settings, 'smtp_username'),
+ "password" => data_get($settings, 'smtp_password'),
+ "timeout" => data_get($settings, 'smtp_timeout'),
+ "local_domain" => null,
+ ]);
+ return 'smtp';
+ }
+ return null;
}
function base_ip(): string
@@ -246,7 +251,10 @@ function send_internal_notification(string $message): void
function send_user_an_email(MailMessage $mail, string $email): void
{
$settings = InstanceSettings::get();
- set_transanctional_email_settings($settings);
+ $type = set_transanctional_email_settings($settings);
+ if (!$type) {
+ throw new Exception('No email settings found.');
+ }
Mail::send(
[],
[],
@@ -259,5 +267,9 @@ function send_user_an_email(MailMessage $mail, string $email): void
->subject($mail->subject)
->html((string) $mail->render())
);
-}
+}
+function isEmailEnabled($notifiable)
+{
+ return data_get($notifiable, 'smtp_enabled') || data_get($notifiable, 'resend_enabled') || data_get($notifiable, 'use_instance_email_settings');
+}
diff --git a/bootstrap/helpers/subscriptions.php b/bootstrap/helpers/subscriptions.php
index 4ca32acae..7691ca7d6 100644
--- a/bootstrap/helpers/subscriptions.php
+++ b/bootstrap/helpers/subscriptions.php
@@ -66,7 +66,6 @@ function isSubscriptionActive()
return $subscription->stripe_invoice_paid === true && $subscription->stripe_cancel_at_period_end === false;
}
return false;
-
}
function isSubscriptionOnGracePeriod()
{
@@ -92,13 +91,16 @@ function subscriptionProvider()
{
return config('subscription.provider');
}
-function isLemon () {
+function isLemon()
+{
return config('subscription.provider') === 'lemon';
}
-function isStripe() {
+function isStripe()
+{
return config('subscription.provider') === 'stripe';
}
-function isPaddle() {
+function isPaddle()
+{
return config('subscription.provider') === 'paddle';
}
function getStripeCustomerPortalSession(Team $team)
diff --git a/config/constants.php b/config/constants.php
index 209e9254b..0021f8a5c 100644
--- a/config/constants.php
+++ b/config/constants.php
@@ -11,11 +11,15 @@
],
'limits' => [
'server' => [
+ 'zero' => 0,
+ 'self-hosted' => 999999999999,
'basic' => 1,
'pro' => 10,
'ultimate' => 25,
],
- 'smtp' => [
+ 'email' => [
+ 'zero' => false,
+ 'self-hosted' => true,
'basic' => false,
'pro' => true,
'ultimate' => true,
diff --git a/database/migrations/2023_08_22_071053_add_resend_as_email_to_teams.php b/database/migrations/2023_08_22_071053_add_resend_as_email_to_teams.php
new file mode 100644
index 000000000..72be88b2c
--- /dev/null
+++ b/database/migrations/2023_08_22_071053_add_resend_as_email_to_teams.php
@@ -0,0 +1,32 @@
+boolean('resend_enabled')->default(false);
+ $table->text('resend_api_key')->nullable();
+ $table->boolean('use_instance_email_settings')->default(false);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('teams', function (Blueprint $table) {
+ $table->dropColumn('resend_enabled');
+ $table->dropColumn('resend_api_key');
+ $table->dropColumn('use_instance_email_settings');
+ });
+ }
+};
diff --git a/resources/views/emails/waitlist-invitation.blade.php b/resources/views/emails/waitlist-invitation.blade.php
index 7c941d925..4274fba13 100644
--- a/resources/views/emails/waitlist-invitation.blade.php
+++ b/resources/views/emails/waitlist-invitation.blade.php
@@ -1,14 +1,13 @@
-Congratulations!
-Congratulations!
-
You have been invited to join the Coolify Cloud. Login here
-Credentials:
-
-Email: {{ $email }}
-
-Password: {{ $password }}
+Here is your initial login information.
+Email:
+{{ $email }}
+
+Password:
+{{ $password }}
+
(You will forced to change it on first login.)
diff --git a/resources/views/layouts/base.blade.php b/resources/views/layouts/base.blade.php
index 9ea6c6e7c..7d352f1b9 100644
--- a/resources/views/layouts/base.blade.php
+++ b/resources/views/layouts/base.blade.php
@@ -52,7 +52,7 @@ function changePasswordFieldType(event) {
function copyToClipboard(text) {
navigator.clipboard.writeText(text);
- Livewire.emit('message', 'Copied to clipboard.');
+ Livewire.emit('success', 'Copied to clipboard.');
}
Livewire.on('reloadWindow', (timeout) => {
diff --git a/resources/views/livewire/notifications/email-settings.blade.php b/resources/views/livewire/notifications/email-settings.blade.php
index 2de6ec223..1185ad290 100644
--- a/resources/views/livewire/notifications/email-settings.blade.php
+++ b/resources/views/livewire/notifications/email-settings.blade.php
@@ -16,59 +16,106 @@