coolify/app/Actions/Fortify/CreateNewUser.php
rosslh b9174f8d09 feat(auth): notify MapleDeploy on first-user registration
After the first user registers, clears the setup token and dispatches
NotifySetupCompleteJob to POST the token to MapleDeploy's callback URL.
Adds setup_callback_url column to instance_settings.
2026-03-14 00:18:29 -04:00

90 lines
3 KiB
PHP

<?php
namespace App\Actions\Fortify;
use App\Jobs\NotifySetupCompleteJob;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\Password;
use Laravel\Fortify\Contracts\CreatesNewUsers;
class CreateNewUser implements CreatesNewUsers
{
/**
* Validate and create a newly registered user.
*
* @param array<string, string> $input
*/
public function create(array $input): User
{
$settings = instanceSettings();
if (! $settings->is_registration_enabled) {
abort(403);
}
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => [
'required',
'string',
'email',
'max:255',
Rule::unique(User::class),
],
'password' => ['required', Password::defaults(), 'confirmed'],
])->validate();
if (User::count() == 0) {
// MapleDeploy: validate setup token for first user registration
if ($settings->setup_token) {
$providedToken = $input['setup_token'] ?? null;
if (! $providedToken || ! hash_equals($settings->setup_token, $providedToken)) {
abort(403);
}
}
// If this is the first user, make them the root user
// Team is already created in the database/seeders/ProductionSeeder.php
$user = User::create([
'id' => 0,
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]);
$team = $user->teams()->first();
// Disable registration after first user is created
$settings = instanceSettings();
$settings->is_registration_enabled = false;
// MapleDeploy: notify control plane that setup is complete
// Capture token before clearing so the job can authenticate with it
$callbackUrl = $settings->setup_callback_url;
$token = $settings->setup_token;
$settings->setup_token = null;
$settings->setup_callback_url = null;
$settings->save();
if ($callbackUrl && $token) {
NotifySetupCompleteJob::dispatch($token, $callbackUrl);
}
} else {
$user = User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]);
$team = $user->teams()->first();
if (isCloud()) {
$user->sendVerificationEmail();
} else {
$user->markEmailAsVerified();
}
}
// Set session variable
session(['currentTeam' => $user->currentTeam = $team]);
return $user;
}
}