Merge branch 'next' into fix-environement-route

This commit is contained in:
Andras Bacsai
2024-12-17 12:17:50 +01:00
committed by GitHub
426 changed files with 11051 additions and 5406 deletions

View File

@@ -0,0 +1,22 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class ApplicationFactory extends Factory
{
public function definition(): array
{
return [
'name' => fake()->unique()->name(),
'destination_id' => 1,
'git_repository' => fake()->url(),
'git_branch' => fake()->word(),
'build_pack' => 'nixpacks',
'ports_exposes' => '3000',
'environment_id' => 1,
'destination_id' => 1,
];
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class ServerFactory extends Factory
{
public function definition(): array
{
return [
'name' => fake()->unique()->name(),
'ip' => fake()->unique()->ipv4(),
'private_key_id' => 1,
];
}
}

View File

@@ -12,7 +12,7 @@ return new class extends Migration
public function up(): void
{
Schema::table('applications', function (Blueprint $table) {
$table->string('redirect')->enum('www', 'non-www', 'both')->default('both')->after('domain');
$table->enum('redirect', ['www', 'non-www', 'both'])->default('both')->after('domain');
});
}

View File

@@ -0,0 +1,60 @@
<?php
use App\Models\PersonalAccessToken;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
try {
$tokens = PersonalAccessToken::all();
foreach ($tokens as $token) {
$abilities = collect();
if (in_array('*', $token->abilities)) {
$abilities->push('root');
}
if (in_array('read-only', $token->abilities)) {
$abilities->push('read');
}
if (in_array('view:sensitive', $token->abilities)) {
$abilities->push('read', 'read:sensitive');
}
$token->abilities = $abilities->unique()->values()->all();
$token->save();
}
} catch (\Exception $e) {
\Log::error('Error renaming token permissions: '.$e->getMessage());
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
try {
$tokens = PersonalAccessToken::all();
foreach ($tokens as $token) {
$abilities = collect();
if (in_array('root', $token->abilities)) {
$abilities->push('*');
} else {
if (in_array('read', $token->abilities)) {
$abilities->push('read-only');
}
if (in_array('read:sensitive', $token->abilities)) {
$abilities->push('view:sensitive');
}
}
$token->abilities = $abilities->unique()->values()->all();
$token->save();
}
} catch (\Exception $e) {
\Log::error('Error renaming token permissions: '.$e->getMessage());
}
}
};

View File

@@ -0,0 +1,22 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('application_settings', function (Blueprint $table) {
$table->boolean('disable_build_cache')->default(false);
});
}
public function down(): void
{
Schema::table('application_settings', function (Blueprint $table) {
$table->dropColumn('disable_build_cache');
});
}
};

View File

@@ -0,0 +1,58 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('email_notification_settings', function (Blueprint $table) {
$table->id();
$table->foreignId('team_id')->constrained()->cascadeOnDelete();
$table->boolean('smtp_enabled')->default(false);
$table->text('smtp_from_address')->nullable();
$table->text('smtp_from_name')->nullable();
$table->text('smtp_recipients')->nullable();
$table->text('smtp_host')->nullable();
$table->integer('smtp_port')->nullable();
$table->string('smtp_encryption')->nullable();
$table->text('smtp_username')->nullable();
$table->text('smtp_password')->nullable();
$table->integer('smtp_timeout')->nullable();
$table->boolean('resend_enabled')->default(false);
$table->text('resend_api_key')->nullable();
$table->boolean('use_instance_email_settings')->default(false);
$table->boolean('deployment_success_email_notifications')->default(false);
$table->boolean('deployment_failure_email_notifications')->default(true);
$table->boolean('status_change_email_notifications')->default(false);
$table->boolean('backup_success_email_notifications')->default(false);
$table->boolean('backup_failure_email_notifications')->default(true);
$table->boolean('scheduled_task_success_email_notifications')->default(false);
$table->boolean('scheduled_task_failure_email_notifications')->default(true);
$table->boolean('docker_cleanup_success_email_notifications')->default(false);
$table->boolean('docker_cleanup_failure_email_notifications')->default(true);
$table->boolean('server_disk_usage_email_notifications')->default(true);
$table->boolean('server_reachable_email_notifications')->default(false);
$table->boolean('server_unreachable_email_notifications')->default(true);
$table->unique(['team_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('email_notification_settings');
}
};

View File

@@ -0,0 +1,45 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('discord_notification_settings', function (Blueprint $table) {
$table->id();
$table->foreignId('team_id')->constrained()->cascadeOnDelete();
$table->boolean('discord_enabled')->default(false);
$table->text('discord_webhook_url')->nullable();
$table->boolean('deployment_success_discord_notifications')->default(false);
$table->boolean('deployment_failure_discord_notifications')->default(true);
$table->boolean('status_change_discord_notifications')->default(false);
$table->boolean('backup_success_discord_notifications')->default(false);
$table->boolean('backup_failure_discord_notifications')->default(true);
$table->boolean('scheduled_task_success_discord_notifications')->default(false);
$table->boolean('scheduled_task_failure_discord_notifications')->default(true);
$table->boolean('docker_cleanup_success_discord_notifications')->default(false);
$table->boolean('docker_cleanup_failure_discord_notifications')->default(true);
$table->boolean('server_disk_usage_discord_notifications')->default(true);
$table->boolean('server_reachable_discord_notifications')->default(false);
$table->boolean('server_unreachable_discord_notifications')->default(true);
$table->unique(['team_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('discord_notification_settings');
}
};

View File

@@ -0,0 +1,59 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('telegram_notification_settings', function (Blueprint $table) {
$table->id();
$table->foreignId('team_id')->constrained()->cascadeOnDelete();
$table->boolean('telegram_enabled')->default(false);
$table->text('telegram_token')->nullable();
$table->text('telegram_chat_id')->nullable();
$table->boolean('deployment_success_telegram_notifications')->default(false);
$table->boolean('deployment_failure_telegram_notifications')->default(true);
$table->boolean('status_change_telegram_notifications')->default(false);
$table->boolean('backup_success_telegram_notifications')->default(false);
$table->boolean('backup_failure_telegram_notifications')->default(true);
$table->boolean('scheduled_task_success_telegram_notifications')->default(false);
$table->boolean('scheduled_task_failure_telegram_notifications')->default(true);
$table->boolean('docker_cleanup_success_telegram_notifications')->default(false);
$table->boolean('docker_cleanup_failure_telegram_notifications')->default(true);
$table->boolean('server_disk_usage_telegram_notifications')->default(true);
$table->boolean('server_reachable_telegram_notifications')->default(false);
$table->boolean('server_unreachable_telegram_notifications')->default(true);
$table->text('telegram_notifications_deployment_success_thread_id')->nullable();
$table->text('telegram_notifications_deployment_failure_thread_id')->nullable();
$table->text('telegram_notifications_status_change_thread_id')->nullable();
$table->text('telegram_notifications_backup_success_thread_id')->nullable();
$table->text('telegram_notifications_backup_failure_thread_id')->nullable();
$table->text('telegram_notifications_scheduled_task_success_thread_id')->nullable();
$table->text('telegram_notifications_scheduled_task_failure_thread_id')->nullable();
$table->text('telegram_notifications_docker_cleanup_success_thread_id')->nullable();
$table->text('telegram_notifications_docker_cleanup_failure_thread_id')->nullable();
$table->text('telegram_notifications_server_disk_usage_thread_id')->nullable();
$table->text('telegram_notifications_server_reachable_thread_id')->nullable();
$table->text('telegram_notifications_server_unreachable_thread_id')->nullable();
$table->unique(['team_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('telegram_notification_settings');
}
};

View File

@@ -0,0 +1,135 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
$teams = DB::table('teams')->get();
foreach ($teams as $team) {
try {
DB::table('email_notification_settings')->updateOrInsert(
['team_id' => $team->id],
[
'smtp_enabled' => $team->smtp_enabled ?? false,
'smtp_from_address' => $team->smtp_from_address ? Crypt::encryptString($team->smtp_from_address) : null,
'smtp_from_name' => $team->smtp_from_name ? Crypt::encryptString($team->smtp_from_name) : null,
'smtp_recipients' => $team->smtp_recipients ? Crypt::encryptString($team->smtp_recipients) : null,
'smtp_host' => $team->smtp_host ? Crypt::encryptString($team->smtp_host) : null,
'smtp_port' => $team->smtp_port,
'smtp_encryption' => $team->smtp_encryption,
'smtp_username' => $team->smtp_username ? Crypt::encryptString($team->smtp_username) : null,
'smtp_password' => $team->smtp_password,
'smtp_timeout' => $team->smtp_timeout,
'use_instance_email_settings' => $team->use_instance_email_settings ?? false,
'resend_enabled' => $team->resend_enabled ?? false,
'resend_api_key' => $team->resend_api_key,
'deployment_success_email_notifications' => $team->smtp_notifications_deployments ?? false,
'deployment_failure_email_notifications' => $team->smtp_notifications_deployments ?? true,
'backup_success_email_notifications' => $team->smtp_notifications_database_backups ?? false,
'backup_failure_email_notifications' => $team->smtp_notifications_database_backups ?? true,
'scheduled_task_success_email_notifications' => $team->smtp_notifications_scheduled_tasks ?? false,
'scheduled_task_failure_email_notifications' => $team->smtp_notifications_scheduled_tasks ?? true,
'status_change_email_notifications' => $team->smtp_notifications_status_changes ?? false,
'server_disk_usage_email_notifications' => $team->smtp_notifications_server_disk_usage ?? true,
]
);
} catch (Exception $e) {
\Log::error('Error migrating email notification settings from teams table: '.$e->getMessage());
}
}
Schema::table('teams', function (Blueprint $table) {
$table->dropColumn([
'smtp_enabled',
'smtp_from_address',
'smtp_from_name',
'smtp_recipients',
'smtp_host',
'smtp_port',
'smtp_encryption',
'smtp_username',
'smtp_password',
'smtp_timeout',
'use_instance_email_settings',
'resend_enabled',
'resend_api_key',
'smtp_notifications_test',
'smtp_notifications_deployments',
'smtp_notifications_database_backups',
'smtp_notifications_scheduled_tasks',
'smtp_notifications_status_changes',
'smtp_notifications_server_disk_usage',
]);
});
}
public function down(): void
{
Schema::table('teams', function (Blueprint $table) {
$table->boolean('smtp_enabled')->default(false);
$table->string('smtp_from_address')->nullable();
$table->string('smtp_from_name')->nullable();
$table->string('smtp_recipients')->nullable();
$table->string('smtp_host')->nullable();
$table->integer('smtp_port')->nullable();
$table->string('smtp_encryption')->nullable();
$table->text('smtp_username')->nullable();
$table->text('smtp_password')->nullable();
$table->integer('smtp_timeout')->nullable();
$table->boolean('use_instance_email_settings')->default(false);
$table->boolean('resend_enabled')->default(false);
$table->text('resend_api_key')->nullable();
$table->boolean('smtp_notifications_test')->default(false);
$table->boolean('smtp_notifications_deployments')->default(false);
$table->boolean('smtp_notifications_database_backups')->default(true);
$table->boolean('smtp_notifications_scheduled_tasks')->default(false);
$table->boolean('smtp_notifications_status_changes')->default(false);
$table->boolean('smtp_notifications_server_disk_usage')->default(true);
});
$settings = DB::table('email_notification_settings')->get();
foreach ($settings as $setting) {
try {
DB::table('teams')
->where('id', $setting->team_id)
->update([
'smtp_enabled' => $setting->smtp_enabled,
'smtp_from_address' => $setting->smtp_from_address ? Crypt::decryptString($setting->smtp_from_address) : null,
'smtp_from_name' => $setting->smtp_from_name ? Crypt::decryptString($setting->smtp_from_name) : null,
'smtp_recipients' => $setting->smtp_recipients ? Crypt::decryptString($setting->smtp_recipients) : null,
'smtp_host' => $setting->smtp_host ? Crypt::decryptString($setting->smtp_host) : null,
'smtp_port' => $setting->smtp_port,
'smtp_encryption' => $setting->smtp_encryption,
'smtp_username' => $setting->smtp_username ? Crypt::decryptString($setting->smtp_username) : null,
'smtp_password' => $setting->smtp_password,
'smtp_timeout' => $setting->smtp_timeout,
'use_instance_email_settings' => $setting->use_instance_email_settings,
'resend_enabled' => $setting->resend_enabled,
'resend_api_key' => $setting->resend_api_key,
'smtp_notifications_deployments' => $setting->deployment_success_email_notifications || $setting->deployment_failure_email_notifications,
'smtp_notifications_database_backups' => $setting->backup_success_email_notifications || $setting->backup_failure_email_notifications,
'smtp_notifications_scheduled_tasks' => $setting->scheduled_task_success_email_notifications || $setting->scheduled_task_failure_email_notifications,
'smtp_notifications_status_changes' => $setting->status_change_email_notifications,
]);
} catch (Exception $e) {
\Log::error('Error migrating email notification settings from teams table: '.$e->getMessage());
}
}
}
};

View File

@@ -0,0 +1,92 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$teams = DB::table('teams')->get();
foreach ($teams as $team) {
try {
DB::table('discord_notification_settings')->updateOrInsert(
['team_id' => $team->id],
[
'discord_enabled' => $team->discord_enabled ?? false,
'discord_webhook_url' => $team->discord_webhook_url ? Crypt::encryptString($team->discord_webhook_url) : null,
'deployment_success_discord_notifications' => $team->discord_notifications_deployments ?? false,
'deployment_failure_discord_notifications' => $team->discord_notifications_deployments ?? true,
'backup_success_discord_notifications' => $team->discord_notifications_database_backups ?? false,
'backup_failure_discord_notifications' => $team->discord_notifications_database_backups ?? true,
'scheduled_task_success_discord_notifications' => $team->discord_notifications_scheduled_tasks ?? false,
'scheduled_task_failure_discord_notifications' => $team->discord_notifications_scheduled_tasks ?? true,
'status_change_discord_notifications' => $team->discord_notifications_status_changes ?? false,
'server_disk_usage_discord_notifications' => $team->discord_notifications_server_disk_usage ?? true,
]
);
} catch (Exception $e) {
\Log::error('Error migrating discord notification settings from teams table: '.$e->getMessage());
}
}
Schema::table('teams', function (Blueprint $table) {
$table->dropColumn([
'discord_enabled',
'discord_webhook_url',
'discord_notifications_test',
'discord_notifications_deployments',
'discord_notifications_status_changes',
'discord_notifications_database_backups',
'discord_notifications_scheduled_tasks',
'discord_notifications_server_disk_usage',
]);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('teams', function (Blueprint $table) {
$table->boolean('discord_enabled')->default(false);
$table->string('discord_webhook_url')->nullable();
$table->boolean('discord_notifications_test')->default(true);
$table->boolean('discord_notifications_deployments')->default(true);
$table->boolean('discord_notifications_status_changes')->default(true);
$table->boolean('discord_notifications_database_backups')->default(true);
$table->boolean('discord_notifications_scheduled_tasks')->default(true);
$table->boolean('discord_notifications_server_disk_usage')->default(true);
});
$settings = DB::table('discord_notification_settings')->get();
foreach ($settings as $setting) {
try {
DB::table('teams')
->where('id', $setting->team_id)
->update([
'discord_enabled' => $setting->discord_enabled,
'discord_webhook_url' => Crypt::decryptString($setting->discord_webhook_url),
'discord_notifications_deployments' => $setting->deployment_success_discord_notifications || $setting->deployment_failure_discord_notifications,
'discord_notifications_status_changes' => $setting->status_change_discord_notifications,
'discord_notifications_database_backups' => $setting->backup_success_discord_notifications || $setting->backup_failure_discord_notifications,
'discord_notifications_scheduled_tasks' => $setting->scheduled_task_success_discord_notifications || $setting->scheduled_task_failure_discord_notifications,
'discord_notifications_server_disk_usage' => $setting->server_disk_usage_discord_notifications,
]);
} catch (Exception $e) {
\Log::error('Error migrating discord notification settings from teams table: '.$e->getMessage());
}
}
}
};

View File

@@ -0,0 +1,115 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
$teams = DB::table('teams')->get();
foreach ($teams as $team) {
try {
DB::table('telegram_notification_settings')->updateOrInsert(
['team_id' => $team->id],
[
'telegram_enabled' => $team->telegram_enabled ?? false,
'telegram_token' => $team->telegram_token ? Crypt::encryptString($team->telegram_token) : null,
'telegram_chat_id' => $team->telegram_chat_id ? Crypt::encryptString($team->telegram_chat_id) : null,
'deployment_success_telegram_notifications' => $team->telegram_notifications_deployments ?? false,
'deployment_failure_telegram_notifications' => $team->telegram_notifications_deployments ?? true,
'backup_success_telegram_notifications' => $team->telegram_notifications_database_backups ?? false,
'backup_failure_telegram_notifications' => $team->telegram_notifications_database_backups ?? true,
'scheduled_task_success_telegram_notifications' => $team->telegram_notifications_scheduled_tasks ?? false,
'scheduled_task_failure_telegram_notifications' => $team->telegram_notifications_scheduled_tasks ?? true,
'status_change_telegram_notifications' => $team->telegram_notifications_status_changes ?? false,
'server_disk_usage_telegram_notifications' => $team->telegram_notifications_server_disk_usage ?? true,
'telegram_notifications_deployment_success_thread_id' => $team->telegram_notifications_deployments_message_thread_id ? Crypt::encryptString($team->telegram_notifications_deployments_message_thread_id) : null,
'telegram_notifications_deployment_failure_thread_id' => $team->telegram_notifications_deployments_message_thread_id ? Crypt::encryptString($team->telegram_notifications_deployments_message_thread_id) : null,
'telegram_notifications_backup_success_thread_id' => $team->telegram_notifications_database_backups_message_thread_id ? Crypt::encryptString($team->telegram_notifications_database_backups_message_thread_id) : null,
'telegram_notifications_backup_failure_thread_id' => $team->telegram_notifications_database_backups_message_thread_id ? Crypt::encryptString($team->telegram_notifications_database_backups_message_thread_id) : null,
'telegram_notifications_scheduled_task_success_thread_id' => $team->telegram_notifications_scheduled_tasks_thread_id ? Crypt::encryptString($team->telegram_notifications_scheduled_tasks_thread_id) : null,
'telegram_notifications_scheduled_task_failure_thread_id' => $team->telegram_notifications_scheduled_tasks_thread_id ? Crypt::encryptString($team->telegram_notifications_scheduled_tasks_thread_id) : null,
'telegram_notifications_status_change_thread_id' => $team->telegram_notifications_status_changes_message_thread_id ? Crypt::encryptString($team->telegram_notifications_status_changes_message_thread_id) : null,
]
);
} catch (Exception $e) {
Log::error('Error migrating telegram notification settings from teams table: '.$e->getMessage());
}
}
Schema::table('teams', function (Blueprint $table) {
$table->dropColumn([
'telegram_enabled',
'telegram_token',
'telegram_chat_id',
'telegram_notifications_test',
'telegram_notifications_deployments',
'telegram_notifications_status_changes',
'telegram_notifications_database_backups',
'telegram_notifications_scheduled_tasks',
'telegram_notifications_server_disk_usage',
'telegram_notifications_test_message_thread_id',
'telegram_notifications_deployments_message_thread_id',
'telegram_notifications_status_changes_message_thread_id',
'telegram_notifications_database_backups_message_thread_id',
'telegram_notifications_scheduled_tasks_thread_id',
]);
});
}
public function down(): void
{
Schema::table('teams', function (Blueprint $table) {
$table->boolean('telegram_enabled')->default(false);
$table->text('telegram_token')->nullable();
$table->text('telegram_chat_id')->nullable();
$table->boolean('telegram_notifications_test')->default(true);
$table->boolean('telegram_notifications_deployments')->default(true);
$table->boolean('telegram_notifications_status_changes')->default(true);
$table->boolean('telegram_notifications_database_backups')->default(true);
$table->boolean('telegram_notifications_scheduled_tasks')->default(true);
$table->boolean('telegram_notifications_server_disk_usage')->default(true);
$table->text('telegram_notifications_test_message_thread_id')->nullable();
$table->text('telegram_notifications_deployments_message_thread_id')->nullable();
$table->text('telegram_notifications_status_changes_message_thread_id')->nullable();
$table->text('telegram_notifications_database_backups_message_thread_id')->nullable();
$table->text('telegram_notifications_scheduled_tasks_thread_id')->nullable();
});
$settings = DB::table('telegram_notification_settings')->get();
foreach ($settings as $setting) {
try {
DB::table('teams')
->where('id', $setting->team_id)
->update([
'telegram_enabled' => $setting->telegram_enabled,
'telegram_token' => $setting->telegram_token ? Crypt::decryptString($setting->telegram_token) : null,
'telegram_chat_id' => $setting->telegram_chat_id ? Crypt::decryptString($setting->telegram_chat_id) : null,
'telegram_notifications_deployments' => $setting->deployment_success_telegram_notifications || $setting->deployment_failure_telegram_notifications,
'telegram_notifications_status_changes' => $setting->status_change_telegram_notifications,
'telegram_notifications_database_backups' => $setting->backup_success_telegram_notifications || $setting->backup_failure_telegram_notifications,
'telegram_notifications_scheduled_tasks' => $setting->scheduled_task_success_telegram_notifications || $setting->scheduled_task_failure_telegram_notifications,
'telegram_notifications_server_disk_usage' => $setting->server_disk_usage_telegram_notifications,
'telegram_notifications_deployments_message_thread_id' => $setting->telegram_notifications_deployment_success_thread_id ? Crypt::decryptString($setting->telegram_notifications_deployment_success_thread_id) : null,
'telegram_notifications_status_changes_message_thread_id' => $setting->telegram_notifications_status_change_thread_id ? Crypt::decryptString($setting->telegram_notifications_status_change_thread_id) : null,
'telegram_notifications_database_backups_message_thread_id' => $setting->telegram_notifications_backup_success_thread_id ? Crypt::decryptString($setting->telegram_notifications_backup_success_thread_id) : null,
'telegram_notifications_scheduled_tasks_thread_id' => $setting->telegram_notifications_scheduled_task_success_thread_id ? Crypt::decryptString($setting->telegram_notifications_scheduled_task_success_thread_id) : null,
]);
} catch (Exception $e) {
Log::error('Error migrating telegram notification settings from teams table: '.$e->getMessage());
}
}
}
};

View File

@@ -0,0 +1,58 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('slack_notification_settings', function (Blueprint $table) {
$table->id();
$table->foreignId('team_id')->constrained()->cascadeOnDelete();
$table->boolean('slack_enabled')->default(false);
$table->text('slack_webhook_url')->nullable();
$table->boolean('deployment_success_slack_notifications')->default(false);
$table->boolean('deployment_failure_slack_notifications')->default(true);
$table->boolean('status_change_slack_notifications')->default(false);
$table->boolean('backup_success_slack_notifications')->default(false);
$table->boolean('backup_failure_slack_notifications')->default(true);
$table->boolean('scheduled_task_success_slack_notifications')->default(false);
$table->boolean('scheduled_task_failure_slack_notifications')->default(true);
$table->boolean('docker_cleanup_success_slack_notifications')->default(false);
$table->boolean('docker_cleanup_failure_slack_notifications')->default(true);
$table->boolean('server_disk_usage_slack_notifications')->default(true);
$table->boolean('server_reachable_slack_notifications')->default(false);
$table->boolean('server_unreachable_slack_notifications')->default(true);
$table->unique(['team_id']);
});
$teams = DB::table('teams')->get();
foreach ($teams as $team) {
try {
DB::table('slack_notification_settings')->insert([
'team_id' => $team->id,
]);
} catch (\Throwable $e) {
Log::error('Error creating slack notification settings for existing teams: '.$e->getMessage());
}
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('slack_notification_settings');
}
};

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::dropIfExists('waitlists');
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::create('waitlists', function (Blueprint $table) {
$table->id();
$table->string('uuid');
$table->string('type');
$table->string('email')->unique();
$table->boolean('verified')->default(false);
$table->timestamps();
});
}
};

View File

@@ -0,0 +1,72 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
if (DB::table('instance_settings')->exists()) {
Schema::table('instance_settings', function (Blueprint $table) {
$table->text('smtp_from_address')->nullable()->change();
$table->text('smtp_from_name')->nullable()->change();
$table->text('smtp_recipients')->nullable()->change();
$table->text('smtp_host')->nullable()->change();
$table->text('smtp_username')->nullable()->change();
});
$settings = DB::table('instance_settings')->get();
foreach ($settings as $setting) {
try {
DB::table('instance_settings')->where('id', $setting->id)->update([
'smtp_from_address' => $setting->smtp_from_address ? Crypt::encryptString($setting->smtp_from_address) : null,
'smtp_from_name' => $setting->smtp_from_name ? Crypt::encryptString($setting->smtp_from_name) : null,
'smtp_recipients' => $setting->smtp_recipients ? Crypt::encryptString($setting->smtp_recipients) : null,
'smtp_host' => $setting->smtp_host ? Crypt::encryptString($setting->smtp_host) : null,
'smtp_username' => $setting->smtp_username ? Crypt::encryptString($setting->smtp_username) : null,
]);
} catch (Exception $e) {
\Log::error('Error encrypting instance settings email columns: '.$e->getMessage());
}
}
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('instance_settings', function (Blueprint $table) {
$table->text('smtp_from_address')->nullable()->change();
$table->text('smtp_from_name')->nullable()->change();
$table->text('smtp_recipients')->nullable()->change();
$table->text('smtp_host')->nullable()->change();
$table->text('smtp_username')->nullable()->change();
});
if (DB::table('instance_settings')->exists()) {
$settings = DB::table('instance_settings')->get();
foreach ($settings as $setting) {
try {
DB::table('instance_settings')->where('id', $setting->id)->update([
'smtp_from_address' => $setting->smtp_from_address ? Crypt::decryptString($setting->smtp_from_address) : null,
'smtp_from_name' => $setting->smtp_from_name ? Crypt::decryptString($setting->smtp_from_name) : null,
'smtp_recipients' => $setting->smtp_recipients ? Crypt::decryptString($setting->smtp_recipients) : null,
'smtp_host' => $setting->smtp_host ? Crypt::decryptString($setting->smtp_host) : null,
'smtp_username' => $setting->smtp_username ? Crypt::decryptString($setting->smtp_username) : null,
]);
} catch (Exception $e) {
\Log::error('Error decrypting instance settings email columns: '.$e->getMessage());
}
}
}
}
};

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('instance_settings', function (Blueprint $table) {
$table->dropColumn('is_resale_license_active');
$table->dropColumn('resale_license');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('instance_settings', function (Blueprint $table) {
$table->boolean('is_resale_license_active')->default(false);
$table->longText('resale_license')->nullable();
});
}
};

View File

@@ -0,0 +1,59 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('pushover_notification_settings', function (Blueprint $table) {
$table->id();
$table->foreignId('team_id')->constrained()->cascadeOnDelete();
$table->boolean('pushover_enabled')->default(false);
$table->text('pushover_user_key')->nullable();
$table->text('pushover_api_token')->nullable();
$table->boolean('deployment_success_pushover_notifications')->default(false);
$table->boolean('deployment_failure_pushover_notifications')->default(true);
$table->boolean('status_change_pushover_notifications')->default(false);
$table->boolean('backup_success_pushover_notifications')->default(false);
$table->boolean('backup_failure_pushover_notifications')->default(true);
$table->boolean('scheduled_task_success_pushover_notifications')->default(false);
$table->boolean('scheduled_task_failure_pushover_notifications')->default(true);
$table->boolean('docker_cleanup_success_pushover_notifications')->default(false);
$table->boolean('docker_cleanup_failure_pushover_notifications')->default(true);
$table->boolean('server_disk_usage_pushover_notifications')->default(true);
$table->boolean('server_reachable_pushover_notifications')->default(false);
$table->boolean('server_unreachable_pushover_notifications')->default(true);
$table->unique(['team_id']);
});
$teams = DB::table('teams')->get();
foreach ($teams as $team) {
try {
DB::table('pushover_notification_settings')->insert([
'team_id' => $team->id,
]);
} catch (\Throwable $e) {
Log::error('Error creating pushover notification settings for existing teams: '.$e->getMessage());
}
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('pushover_notification_settings');
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('oauth_settings', function (Blueprint $table) {
$table->string('base_url')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('oauth_settings', function (Blueprint $table) {
$table->dropColumn('base_url');
});
}
};

View File

@@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
if (DB::table('instance_settings')->exists()) {
$settings = DB::table('instance_settings')->get();
foreach ($settings as $setting) {
try {
DB::table('instance_settings')->where('id', $setting->id)->update([
'resend_api_key' => $setting->resend_api_key ? Crypt::encryptString($setting->resend_api_key) : null,
]);
} catch (Exception $e) {
\Log::error('Error encrypting resend_api_key: '.$e->getMessage());
}
}
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
if (DB::table('instance_settings')->exists()) {
$settings = DB::table('instance_settings')->get();
foreach ($settings as $setting) {
try {
DB::table('instance_settings')->where('id', $setting->id)->update([
'resend_api_key' => $setting->resend_api_key ? Crypt::decryptString($setting->resend_api_key) : null,
]);
} catch (Exception $e) {
\Log::error('Error decrypting resend_api_key: '.$e->getMessage());
}
}
}
}
};

View File

@@ -0,0 +1,165 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('environment_variables', function (Blueprint $table) {
$table->string('resourceable_type')->nullable();
$table->unsignedBigInteger('resourceable_id')->nullable();
$table->index(['resourceable_type', 'resourceable_id']);
});
// Populate the new columns
DB::table('environment_variables')->whereNotNull('application_id')
->update([
'resourceable_type' => 'App\\Models\\Application',
'resourceable_id' => DB::raw('application_id'),
]);
DB::table('environment_variables')->whereNotNull('service_id')
->update([
'resourceable_type' => 'App\\Models\\Service',
'resourceable_id' => DB::raw('service_id'),
]);
DB::table('environment_variables')->whereNotNull('standalone_postgresql_id')
->update([
'resourceable_type' => 'App\\Models\\StandalonePostgresql',
'resourceable_id' => DB::raw('standalone_postgresql_id'),
]);
DB::table('environment_variables')->whereNotNull('standalone_redis_id')
->update([
'resourceable_type' => 'App\\Models\\StandaloneRedis',
'resourceable_id' => DB::raw('standalone_redis_id'),
]);
DB::table('environment_variables')->whereNotNull('standalone_mongodb_id')
->update([
'resourceable_type' => 'App\\Models\\StandaloneMongodb',
'resourceable_id' => DB::raw('standalone_mongodb_id'),
]);
DB::table('environment_variables')->whereNotNull('standalone_mysql_id')
->update([
'resourceable_type' => 'App\\Models\\StandaloneMysql',
'resourceable_id' => DB::raw('standalone_mysql_id'),
]);
DB::table('environment_variables')->whereNotNull('standalone_mariadb_id')
->update([
'resourceable_type' => 'App\\Models\\StandaloneMariadb',
'resourceable_id' => DB::raw('standalone_mariadb_id'),
]);
DB::table('environment_variables')->whereNotNull('standalone_keydb_id')
->update([
'resourceable_type' => 'App\\Models\\StandaloneKeydb',
'resourceable_id' => DB::raw('standalone_keydb_id'),
]);
DB::table('environment_variables')->whereNotNull('standalone_dragonfly_id')
->update([
'resourceable_type' => 'App\\Models\\StandaloneDragonfly',
'resourceable_id' => DB::raw('standalone_dragonfly_id'),
]);
DB::table('environment_variables')->whereNotNull('standalone_clickhouse_id')
->update([
'resourceable_type' => 'App\\Models\\StandaloneClickhouse',
'resourceable_id' => DB::raw('standalone_clickhouse_id'),
]);
// After successful migration, we can drop the old foreign key columns
Schema::table('environment_variables', function (Blueprint $table) {
$table->dropColumn([
'application_id',
'service_id',
'standalone_postgresql_id',
'standalone_redis_id',
'standalone_mongodb_id',
'standalone_mysql_id',
'standalone_mariadb_id',
'standalone_keydb_id',
'standalone_dragonfly_id',
'standalone_clickhouse_id',
]);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('environment_variables', function (Blueprint $table) {
// Restore the old columns
$table->unsignedBigInteger('application_id')->nullable();
$table->unsignedBigInteger('service_id')->nullable();
$table->unsignedBigInteger('standalone_postgresql_id')->nullable();
$table->unsignedBigInteger('standalone_redis_id')->nullable();
$table->unsignedBigInteger('standalone_mongodb_id')->nullable();
$table->unsignedBigInteger('standalone_mysql_id')->nullable();
$table->unsignedBigInteger('standalone_mariadb_id')->nullable();
$table->unsignedBigInteger('standalone_keydb_id')->nullable();
$table->unsignedBigInteger('standalone_dragonfly_id')->nullable();
$table->unsignedBigInteger('standalone_clickhouse_id')->nullable();
});
Schema::table('environment_variables', function (Blueprint $table) {
// Restore data from polymorphic relationship
DB::table('environment_variables')
->where('resourceable_type', 'App\\Models\\Application')
->update(['application_id' => DB::raw('resourceable_id')]);
DB::table('environment_variables')
->where('resourceable_type', 'App\\Models\\Service')
->update(['service_id' => DB::raw('resourceable_id')]);
DB::table('environment_variables')
->where('resourceable_type', 'App\\Models\\StandalonePostgresql')
->update(['standalone_postgresql_id' => DB::raw('resourceable_id')]);
DB::table('environment_variables')
->where('resourceable_type', 'App\\Models\\StandaloneRedis')
->update(['standalone_redis_id' => DB::raw('resourceable_id')]);
DB::table('environment_variables')
->where('resourceable_type', 'App\\Models\\StandaloneMongodb')
->update(['standalone_mongodb_id' => DB::raw('resourceable_id')]);
DB::table('environment_variables')
->where('resourceable_type', 'App\\Models\\StandaloneMysql')
->update(['standalone_mysql_id' => DB::raw('resourceable_id')]);
DB::table('environment_variables')
->where('resourceable_type', 'App\\Models\\StandaloneMariadb')
->update(['standalone_mariadb_id' => DB::raw('resourceable_id')]);
DB::table('environment_variables')
->where('resourceable_type', 'App\\Models\\StandaloneKeydb')
->update(['standalone_keydb_id' => DB::raw('resourceable_id')]);
DB::table('environment_variables')
->where('resourceable_type', 'App\\Models\\StandaloneDragonfly')
->update(['standalone_dragonfly_id' => DB::raw('resourceable_id')]);
DB::table('environment_variables')
->where('resourceable_type', 'App\\Models\\StandaloneClickhouse')
->update(['standalone_clickhouse_id' => DB::raw('resourceable_id')]);
// Drop the polymorphic columns
$table->dropIndex(['resourceable_type', 'resourceable_id']);
$table->dropColumn(['resourceable_type', 'resourceable_id']);
});
}
};

View File

@@ -23,6 +23,7 @@ class GithubAppSeeder extends Seeder
GithubApp::create([
'name' => 'coolify-laravel-development-public',
'uuid' => '69420',
'organization' => 'coollabsio',
'api_url' => 'https://api.github.com',
'html_url' => 'https://github.com',
'is_public' => false,

View File

@@ -16,7 +16,6 @@ class InstanceSettingsSeeder extends Seeder
InstanceSettings::create([
'id' => 0,
'is_registration_enabled' => true,
'is_resale_license_active' => true,
'smtp_enabled' => true,
'smtp_host' => 'coolify-mail',
'smtp_port' => 1025,

View File

@@ -4,6 +4,7 @@ namespace Database\Seeders;
use App\Models\OauthSetting;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Log;
class OauthSettingSeeder extends Seeder
{
@@ -12,25 +13,54 @@ class OauthSettingSeeder extends Seeder
*/
public function run(): void
{
OauthSetting::firstOrCreate([
'id' => 0,
'provider' => 'azure',
]);
OauthSetting::firstOrCreate([
'id' => 1,
'provider' => 'bitbucket',
]);
OauthSetting::firstOrCreate([
'id' => 2,
'provider' => 'github',
]);
OauthSetting::firstOrCreate([
'id' => 3,
'provider' => 'gitlab',
]);
OauthSetting::firstOrCreate([
'id' => 4,
'provider' => 'google',
]);
try {
$providers = collect([
'azure',
'bitbucket',
'github',
'gitlab',
'google',
'authentik',
'infomaniak',
]);
$isOauthSeeded = OauthSetting::count() > 0;
// We changed how providers are defined in the database, so we authentik does not exists, we need to recreate all of the auth providers
// Before authentik was a provider, providers started with 0 id
$isOauthAuthentik = OauthSetting::where('provider', 'authentik')->exists();
if (! $isOauthSeeded || $isOauthAuthentik) {
foreach ($providers as $provider) {
OauthSetting::updateOrCreate([
'provider' => $provider,
]);
}
return;
}
$allProviders = OauthSetting::all();
$notFoundProviders = $providers->diff($allProviders->pluck('provider'));
$allProviders->each(function ($provider) {
$provider->delete();
});
$allProviders->each(function ($provider) {
$provider = new OauthSetting;
$provider->provider = $provider->provider;
unset($provider->id);
$provider->save();
});
foreach ($notFoundProviders as $provider) {
OauthSetting::create([
'provider' => $provider,
]);
}
} catch (\Exception $e) {
Log::error($e->getMessage());
}
}
}

View File

@@ -22,9 +22,9 @@ class ProductionSeeder extends Seeder
public function run(): void
{
if (isCloud()) {
echo "[x]: Running in cloud mode.\n";
echo " Running in cloud mode.\n";
} else {
echo "[x]: Running in self-hosted mode.\n";
echo " Running in self-hosted mode.\n";
}
// Fix for 4.0.0-beta.37

View File

@@ -1,42 +0,0 @@
<?php
namespace Database\Seeders;
use App\Models\Team;
use App\Models\User;
use Illuminate\Database\Seeder;
class TestTeamSeeder extends Seeder
{
public function run(): void
{
// User has 2 teams, 1 personal, 1 other where it is the owner and no other members are in the team
$user = User::factory()->create([
'name' => '1 personal, 1 other team, owner, no other members',
'email' => '1@example.com',
]);
$team = Team::create([
'name' => '1@example.com',
'personal_team' => false,
'show_boarding' => true,
]);
$user->teams()->attach($team, ['role' => 'owner']);
// User has 2 teams, 1 personal, 1 other where it is the owner and 1 other member is in the team
$user = User::factory()->create([
'name' => 'owner: 1 personal, 1 other team, owner, 1 other member',
'email' => '2@example.com',
]);
$team = Team::create([
'name' => '2@example.com',
'personal_team' => false,
'show_boarding' => true,
]);
$user->teams()->attach($team, ['role' => 'owner']);
$user = User::factory()->create([
'name' => 'member: 1 personal, 1 other team, owner, 1 other member',
'email' => '3@example.com',
]);
$team->members()->attach($user, ['role' => 'member']);
}
}