From b6633f083ee56d38c4ff4db92eaf20feae192387 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 16 Jan 2025 17:19:38 +0100 Subject: [PATCH 01/11] feat: Root user envs and seeding --- .env.production | 4 ++++ database/seeders/ProductionSeeder.php | 3 +++ database/seeders/RootUserSeeder.php | 28 +++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 database/seeders/RootUserSeeder.php diff --git a/.env.production b/.env.production index d3a1b17c5..b35208e8d 100644 --- a/.env.production +++ b/.env.production @@ -2,6 +2,10 @@ APP_ID= APP_NAME=Coolify APP_KEY= +ROOT_USER_NAME= +ROOT_USER_EMAIL= +ROOT_USER_PASSWORD= + DB_USERNAME=coolify DB_PASSWORD= diff --git a/database/seeders/ProductionSeeder.php b/database/seeders/ProductionSeeder.php index 9a301aa67..34b622069 100644 --- a/database/seeders/ProductionSeeder.php +++ b/database/seeders/ProductionSeeder.php @@ -39,6 +39,9 @@ class ProductionSeeder extends Seeder ]); } } + // Seed root user first + $this->call(RootUserSeeder::class); + if (InstanceSettings::find(0) == null) { InstanceSettings::create([ 'id' => 0, diff --git a/database/seeders/RootUserSeeder.php b/database/seeders/RootUserSeeder.php new file mode 100644 index 000000000..cf4dd76e5 --- /dev/null +++ b/database/seeders/RootUserSeeder.php @@ -0,0 +1,28 @@ + 0], + [ + 'name' => env('ROOT_USER_NAME', 'Root User'), + 'email' => env('ROOT_USER_EMAIL'), + 'password' => Hash::make(env('ROOT_USER_PASSWORD')), + ] + ); + echo " Root user created/updated successfully.\n"; + } else { + echo " Warning: ROOT_USER_EMAIL and ROOT_USER_PASSWORD environment variables are required for root user creation.\n"; + } + } +} From 3927e4850b2204c86bd8fc6c376ba7bcbf04ea3d Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 16 Jan 2025 17:34:46 +0100 Subject: [PATCH 02/11] fix: disable registration after creating the root user --- .env.production | 8 ++++---- database/seeders/ProductionSeeder.php | 5 +++-- database/seeders/RootUserSeeder.php | 9 ++++++++- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.env.production b/.env.production index b35208e8d..96833c253 100644 --- a/.env.production +++ b/.env.production @@ -2,10 +2,6 @@ APP_ID= APP_NAME=Coolify APP_KEY= -ROOT_USER_NAME= -ROOT_USER_EMAIL= -ROOT_USER_PASSWORD= - DB_USERNAME=coolify DB_PASSWORD= @@ -14,3 +10,7 @@ REDIS_PASSWORD= PUSHER_APP_ID= PUSHER_APP_KEY= PUSHER_APP_SECRET= + +ROOT_USERNAME= +ROOT_USER_EMAIL= +ROOT_USER_PASSWORD= diff --git a/database/seeders/ProductionSeeder.php b/database/seeders/ProductionSeeder.php index 34b622069..ecf840c1e 100644 --- a/database/seeders/ProductionSeeder.php +++ b/database/seeders/ProductionSeeder.php @@ -39,14 +39,15 @@ class ProductionSeeder extends Seeder ]); } } - // Seed root user first - $this->call(RootUserSeeder::class); if (InstanceSettings::find(0) == null) { InstanceSettings::create([ 'id' => 0, ]); } + + $this->call(RootUserSeeder::class); + if (GithubApp::find(0) == null) { GithubApp::create([ 'id' => 0, diff --git a/database/seeders/RootUserSeeder.php b/database/seeders/RootUserSeeder.php index cf4dd76e5..2e841503d 100644 --- a/database/seeders/RootUserSeeder.php +++ b/database/seeders/RootUserSeeder.php @@ -2,6 +2,7 @@ namespace Database\Seeders; +use App\Models\InstanceSettings; use App\Models\User; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\Hash; @@ -10,7 +11,6 @@ class RootUserSeeder extends Seeder { public function run(): void { - // Only seed if we have the required environment variables if (env('ROOT_USER_EMAIL') && env('ROOT_USER_PASSWORD')) { User::updateOrCreate( ['id' => 0], @@ -20,7 +20,14 @@ class RootUserSeeder extends Seeder 'password' => Hash::make(env('ROOT_USER_PASSWORD')), ] ); + + InstanceSettings::updateOrCreate( + ['id' => 0], + ['is_registration_enabled' => false] + ); + echo " Root user created/updated successfully.\n"; + echo " Registration has been disabled.\n"; } else { echo " Warning: ROOT_USER_EMAIL and ROOT_USER_PASSWORD environment variables are required for root user creation.\n"; } From 4b6690e5999a56f4fea7c3636bb096a10bd26e3f Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 16 Jan 2025 17:51:26 +0100 Subject: [PATCH 03/11] fix: RootUserSeeder - ensure that the existing root user is not overwritten - ensure that the seeder can only be run once - creating the initial root user --- database/seeders/RootUserSeeder.php | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/database/seeders/RootUserSeeder.php b/database/seeders/RootUserSeeder.php index 2e841503d..b356d8cf2 100644 --- a/database/seeders/RootUserSeeder.php +++ b/database/seeders/RootUserSeeder.php @@ -11,22 +11,26 @@ class RootUserSeeder extends Seeder { public function run(): void { + if (User::where('id', 0)->exists()) { + echo " Root user already exists. Skipping creation.\n"; + + return; + } + if (env('ROOT_USER_EMAIL') && env('ROOT_USER_PASSWORD')) { - User::updateOrCreate( - ['id' => 0], - [ - 'name' => env('ROOT_USER_NAME', 'Root User'), - 'email' => env('ROOT_USER_EMAIL'), - 'password' => Hash::make(env('ROOT_USER_PASSWORD')), - ] - ); + User::create([ + 'id' => 0, + 'name' => env('ROOT_USERNAME', 'Root User'), + 'email' => env('ROOT_USER_EMAIL'), + 'password' => Hash::make(env('ROOT_USER_PASSWORD')), + ]); InstanceSettings::updateOrCreate( ['id' => 0], ['is_registration_enabled' => false] ); - echo " Root user created/updated successfully.\n"; + echo " Root user created successfully.\n"; echo " Registration has been disabled.\n"; } else { echo " Warning: ROOT_USER_EMAIL and ROOT_USER_PASSWORD environment variables are required for root user creation.\n"; From 9288e60174dead52e2738f61fc8c63229e9ef2ba Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:07:40 +0100 Subject: [PATCH 04/11] feat: email, username and password validation when they are set via envs --- database/seeders/RootUserSeeder.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/database/seeders/RootUserSeeder.php b/database/seeders/RootUserSeeder.php index b356d8cf2..6cc877b0a 100644 --- a/database/seeders/RootUserSeeder.php +++ b/database/seeders/RootUserSeeder.php @@ -6,6 +6,8 @@ use App\Models\InstanceSettings; use App\Models\User; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Facades\Validator; +use Illuminate\Validation\Rules\Password; class RootUserSeeder extends Seeder { @@ -18,6 +20,25 @@ class RootUserSeeder extends Seeder } if (env('ROOT_USER_EMAIL') && env('ROOT_USER_PASSWORD')) { + $validator = Validator::make([ + 'email' => env('ROOT_USER_EMAIL'), + 'username' => env('ROOT_USERNAME', 'Root User'), + 'password' => env('ROOT_USER_PASSWORD'), + ], [ + 'email' => ['required', 'email:rfc,dns', 'max:255'], + 'username' => ['required', 'string', 'min:3', 'max:255', 'regex:/^[a-zA-Z0-9\s-_]+$/'], + 'password' => ['required', 'string', 'min:8', Password::min(8)->mixedCase()->letters()->numbers()->symbols()->uncompromised()], + ]); + + if ($validator->fails()) { + echo " Validation failed:\n"; + foreach ($validator->errors()->all() as $error) { + echo " - {$error}\n"; + } + + return; + } + User::create([ 'id' => 0, 'name' => env('ROOT_USERNAME', 'Root User'), From c925ff049ddcaf825bae42e555425edb0ca08532 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:14:45 +0100 Subject: [PATCH 05/11] fix: regex username validation --- database/seeders/RootUserSeeder.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/database/seeders/RootUserSeeder.php b/database/seeders/RootUserSeeder.php index 6cc877b0a..a4eb0d4a0 100644 --- a/database/seeders/RootUserSeeder.php +++ b/database/seeders/RootUserSeeder.php @@ -26,14 +26,14 @@ class RootUserSeeder extends Seeder 'password' => env('ROOT_USER_PASSWORD'), ], [ 'email' => ['required', 'email:rfc,dns', 'max:255'], - 'username' => ['required', 'string', 'min:3', 'max:255', 'regex:/^[a-zA-Z0-9\s-_]+$/'], + 'username' => ['required', 'string', 'min:3', 'max:255', 'regex:/^[\w\s-]+$/'], 'password' => ['required', 'string', 'min:8', Password::min(8)->mixedCase()->letters()->numbers()->symbols()->uncompromised()], ]); if ($validator->fails()) { - echo " Validation failed:\n"; + echo " Error: Invalid ROOT User Environment Variables\n"; foreach ($validator->errors()->all() as $error) { - echo " - {$error}\n"; + echo " → {$error}\n"; } return; From 0ced6a4376f8c3b4cc1325e36e7962d2e3419867 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:29:00 +0100 Subject: [PATCH 06/11] feat: improved error handling and log output --- database/seeders/RootUserSeeder.php | 55 ++++++++++++++++++----------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/database/seeders/RootUserSeeder.php b/database/seeders/RootUserSeeder.php index a4eb0d4a0..7e961d025 100644 --- a/database/seeders/RootUserSeeder.php +++ b/database/seeders/RootUserSeeder.php @@ -13,13 +13,19 @@ class RootUserSeeder extends Seeder { public function run(): void { - if (User::where('id', 0)->exists()) { - echo " Root user already exists. Skipping creation.\n"; + try { + if (User::where('id', 0)->exists()) { + echo " INFO Root user already exists. Skipping creation.\n"; - return; - } + return; + } + + if (! env('ROOT_USER_EMAIL') || ! env('ROOT_USER_PASSWORD')) { + echo " ERROR ROOT_USER_EMAIL and ROOT_USER_PASSWORD environment variables are required for root user creation.\n"; + + return; + } - if (env('ROOT_USER_EMAIL') && env('ROOT_USER_PASSWORD')) { $validator = Validator::make([ 'email' => env('ROOT_USER_EMAIL'), 'username' => env('ROOT_USERNAME', 'Root User'), @@ -31,7 +37,7 @@ class RootUserSeeder extends Seeder ]); if ($validator->fails()) { - echo " Error: Invalid ROOT User Environment Variables\n"; + echo " ERROR Invalid Root User Environment Variables\n"; foreach ($validator->errors()->all() as $error) { echo " → {$error}\n"; } @@ -39,22 +45,31 @@ class RootUserSeeder extends Seeder return; } - User::create([ - 'id' => 0, - 'name' => env('ROOT_USERNAME', 'Root User'), - 'email' => env('ROOT_USER_EMAIL'), - 'password' => Hash::make(env('ROOT_USER_PASSWORD')), - ]); + try { + User::create([ + 'id' => 0, + 'name' => env('ROOT_USERNAME', 'Root User'), + 'email' => env('ROOT_USER_EMAIL'), + 'password' => Hash::make(env('ROOT_USER_PASSWORD')), + ]); + echo " SUCCESS Root user created successfully.\n"; + } catch (\Exception $e) { + echo " ERROR Failed to create root user: {$e->getMessage()}\n"; - InstanceSettings::updateOrCreate( - ['id' => 0], - ['is_registration_enabled' => false] - ); + return; + } - echo " Root user created successfully.\n"; - echo " Registration has been disabled.\n"; - } else { - echo " Warning: ROOT_USER_EMAIL and ROOT_USER_PASSWORD environment variables are required for root user creation.\n"; + try { + InstanceSettings::updateOrCreate( + ['id' => 0], + ['is_registration_enabled' => false] + ); + echo " SUCCESS Registration has been disabled.\n"; + } catch (\Exception $e) { + echo " ERROR Failed to update instance settings: {$e->getMessage()}\n"; + } + } catch (\Exception $e) { + echo " ERROR An unexpected error occurred: {$e->getMessage()}\n"; } } } From e9d688d5ee86e83058d61ed14c66413d0afe7d10 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:33:54 +0100 Subject: [PATCH 07/11] fix: add spacing around echo outputs --- database/seeders/RootUserSeeder.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/database/seeders/RootUserSeeder.php b/database/seeders/RootUserSeeder.php index 7e961d025..e4b8b03dd 100644 --- a/database/seeders/RootUserSeeder.php +++ b/database/seeders/RootUserSeeder.php @@ -15,13 +15,13 @@ class RootUserSeeder extends Seeder { try { if (User::where('id', 0)->exists()) { - echo " INFO Root user already exists. Skipping creation.\n"; + echo "\n INFO Root user already exists. Skipping creation.\n\n"; return; } if (! env('ROOT_USER_EMAIL') || ! env('ROOT_USER_PASSWORD')) { - echo " ERROR ROOT_USER_EMAIL and ROOT_USER_PASSWORD environment variables are required for root user creation.\n"; + echo "\n ERROR ROOT_USER_EMAIL and ROOT_USER_PASSWORD environment variables are required for root user creation.\n\n"; return; } @@ -37,10 +37,11 @@ class RootUserSeeder extends Seeder ]); if ($validator->fails()) { - echo " ERROR Invalid Root User Environment Variables\n"; + echo "\n ERROR Invalid Root User Environment Variables\n"; foreach ($validator->errors()->all() as $error) { echo " → {$error}\n"; } + echo "\n"; return; } @@ -52,9 +53,9 @@ class RootUserSeeder extends Seeder 'email' => env('ROOT_USER_EMAIL'), 'password' => Hash::make(env('ROOT_USER_PASSWORD')), ]); - echo " SUCCESS Root user created successfully.\n"; + echo "\n SUCCESS Root user created successfully.\n\n"; } catch (\Exception $e) { - echo " ERROR Failed to create root user: {$e->getMessage()}\n"; + echo "\n ERROR Failed to create root user: {$e->getMessage()}\n\n"; return; } @@ -64,12 +65,12 @@ class RootUserSeeder extends Seeder ['id' => 0], ['is_registration_enabled' => false] ); - echo " SUCCESS Registration has been disabled.\n"; + echo "\n SUCCESS Registration has been disabled.\n\n"; } catch (\Exception $e) { - echo " ERROR Failed to update instance settings: {$e->getMessage()}\n"; + echo "\n ERROR Failed to update instance settings: {$e->getMessage()}\n\n"; } } catch (\Exception $e) { - echo " ERROR An unexpected error occurred: {$e->getMessage()}\n"; + echo "\n ERROR An unexpected error occurred: {$e->getMessage()}\n\n"; } } } From 3f3b782e603c809c6555c2e59b98d306c9b65098 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:39:50 +0100 Subject: [PATCH 08/11] disable existing user check to check the full functionality of the seeder --- database/seeders/RootUserSeeder.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/database/seeders/RootUserSeeder.php b/database/seeders/RootUserSeeder.php index e4b8b03dd..efda25757 100644 --- a/database/seeders/RootUserSeeder.php +++ b/database/seeders/RootUserSeeder.php @@ -14,11 +14,11 @@ class RootUserSeeder extends Seeder public function run(): void { try { - if (User::where('id', 0)->exists()) { - echo "\n INFO Root user already exists. Skipping creation.\n\n"; + // if (User::where('id', 0)->exists()) { + // echo "\n INFO Root user already exists. Skipping creation.\n\n"; - return; - } + // return; + // } if (! env('ROOT_USER_EMAIL') || ! env('ROOT_USER_PASSWORD')) { echo "\n ERROR ROOT_USER_EMAIL and ROOT_USER_PASSWORD environment variables are required for root user creation.\n\n"; From 5f581a8eacfa2f8605fb740bf9f7f00bc8862d94 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:43:40 +0100 Subject: [PATCH 09/11] Update RootUserSeeder.php --- database/seeders/RootUserSeeder.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/database/seeders/RootUserSeeder.php b/database/seeders/RootUserSeeder.php index efda25757..e4b8b03dd 100644 --- a/database/seeders/RootUserSeeder.php +++ b/database/seeders/RootUserSeeder.php @@ -14,11 +14,11 @@ class RootUserSeeder extends Seeder public function run(): void { try { - // if (User::where('id', 0)->exists()) { - // echo "\n INFO Root user already exists. Skipping creation.\n\n"; + if (User::where('id', 0)->exists()) { + echo "\n INFO Root user already exists. Skipping creation.\n\n"; - // return; - // } + return; + } if (! env('ROOT_USER_EMAIL') || ! env('ROOT_USER_PASSWORD')) { echo "\n ERROR ROOT_USER_EMAIL and ROOT_USER_PASSWORD environment variables are required for root user creation.\n\n"; From ca56b1462d34814db045ea725cc7e9ed4298d694 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 16 Jan 2025 19:09:18 +0100 Subject: [PATCH 10/11] fix: success message --- database/seeders/RootUserSeeder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/seeders/RootUserSeeder.php b/database/seeders/RootUserSeeder.php index e4b8b03dd..4fa593e4d 100644 --- a/database/seeders/RootUserSeeder.php +++ b/database/seeders/RootUserSeeder.php @@ -65,7 +65,7 @@ class RootUserSeeder extends Seeder ['id' => 0], ['is_registration_enabled' => false] ); - echo "\n SUCCESS Registration has been disabled.\n\n"; + echo "\n SUCCESS Registration has been disabled successfully.\n\n"; } catch (\Exception $e) { echo "\n ERROR Failed to update instance settings: {$e->getMessage()}\n\n"; } From a43805e24b17a4b34d233fe547f3e209fb280da3 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 16 Jan 2025 22:02:02 +0100 Subject: [PATCH 11/11] fix: silent return if envs are empty or not set. --- database/seeders/RootUserSeeder.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/database/seeders/RootUserSeeder.php b/database/seeders/RootUserSeeder.php index 4fa593e4d..e3968a1c9 100644 --- a/database/seeders/RootUserSeeder.php +++ b/database/seeders/RootUserSeeder.php @@ -21,8 +21,6 @@ class RootUserSeeder extends Seeder } if (! env('ROOT_USER_EMAIL') || ! env('ROOT_USER_PASSWORD')) { - echo "\n ERROR ROOT_USER_EMAIL and ROOT_USER_PASSWORD environment variables are required for root user creation.\n\n"; - return; }