diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php
index 90f1bacb4..cd4c63fd8 100644
--- a/app/Actions/Fortify/CreateNewUser.php
+++ b/app/Actions/Fortify/CreateNewUser.php
@@ -43,34 +43,21 @@ class CreateNewUser implements CreatesNewUsers
if (User::count() == 0) {
// If this is the first user, make them the root user
// Team is already created in the database/seeders/ProductionSeeder.php
- $team = Team::find(0);
$user = User::create([
'id' => 0,
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
- 'is_root_user' => true,
]);
+ $team = $user->teams()->first();
} else {
- $team = Team::create([
- 'name' => explode(' ', $input['name'], 2)[0] . "'s Team",
- 'personal_team' => true,
- ]);
$user = User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
- 'is_root_user' => false,
]);
+ $team = $user->teams()->first();
}
-
- // Add user to team
- DB::table('team_user')->insert([
- 'user_id' => $user->id,
- 'team_id' => $team->id,
- 'role' => 'admin',
- ]);
-
// Set session variable
session(['currentTeam' => $user->currentTeam = $team]);
return $user;
diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php
index ab87e2fec..63d24a219 100644
--- a/app/Http/Controllers/Controller.php
+++ b/app/Http/Controllers/Controller.php
@@ -51,4 +51,16 @@ class Controller extends BaseController
return redirect()->route('dashboard');
}
}
+ public function team()
+ {
+ ray(auth()->user()->isAdmin());
+ $invitations = [];
+ if (auth()->user()->isAdmin()) {
+ $invitations = auth()->user()->currentTeam()->invitations;
+ }
+ return view('team.show', [
+ 'transactional_emails_active' => data_get(InstanceSettings::get(), 'extra_attributes.smtp_host') ? true : false,
+ 'invitations' => $invitations,
+ ]);
+ }
}
diff --git a/app/Http/Livewire/Destination/Form.php b/app/Http/Livewire/Destination/Form.php
index bc1c24c88..19ba37cfe 100644
--- a/app/Http/Livewire/Destination/Form.php
+++ b/app/Http/Livewire/Destination/Form.php
@@ -31,7 +31,7 @@ class Form extends Component
$this->destination->delete();
return redirect()->route('dashboard');
} catch (\Exception $e) {
- return general_error_handler($e);
+ return general_error_handler(err: $e);
}
}
}
diff --git a/app/Http/Livewire/ForceUpgrade.php b/app/Http/Livewire/ForceUpgrade.php
index 9642a6af4..a41651bf0 100644
--- a/app/Http/Livewire/ForceUpgrade.php
+++ b/app/Http/Livewire/ForceUpgrade.php
@@ -14,7 +14,7 @@ class ForceUpgrade extends Component
$this->visible = true;
dispatch(new InstanceAutoUpdateJob(force: true));
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Notifications/EmailSettings.php b/app/Http/Livewire/Notifications/EmailSettings.php
index ae2b9a815..5e7c8323c 100644
--- a/app/Http/Livewire/Notifications/EmailSettings.php
+++ b/app/Http/Livewire/Notifications/EmailSettings.php
@@ -26,15 +26,15 @@ class EmailSettings extends Component
'model.extra_attributes.smtp_test_recipients' => 'nullable',
];
protected $validationAttributes = [
- 'model.extra_attributes.smtp_from_address' => '',
- 'model.extra_attributes.smtp_from_name' => '',
- 'model.extra_attributes.smtp_recipients' => '',
- 'model.extra_attributes.smtp_host' => '',
- 'model.extra_attributes.smtp_port' => '',
- 'model.extra_attributes.smtp_encryption' => '',
- 'model.extra_attributes.smtp_username' => '',
- 'model.extra_attributes.smtp_password' => '',
- 'model.extra_attributes.smtp_test_recipients' => '',
+ 'model.extra_attributes.smtp_from_address' => 'From Address',
+ 'model.extra_attributes.smtp_from_name' => 'From Name',
+ 'model.extra_attributes.smtp_recipients' => 'Recipients',
+ 'model.extra_attributes.smtp_host' => 'Host',
+ 'model.extra_attributes.smtp_port' => 'Port',
+ 'model.extra_attributes.smtp_encryption' => 'Encryption',
+ 'model.extra_attributes.smtp_username' => 'Username',
+ 'model.extra_attributes.smtp_password' => 'Password',
+ 'model.extra_attributes.smtp_test_recipients' => 'Test Recipients',
];
public function copySMTP()
{
diff --git a/app/Http/Livewire/PrivateKey/Change.php b/app/Http/Livewire/PrivateKey/Change.php
index 27889feb1..4a7070c7f 100644
--- a/app/Http/Livewire/PrivateKey/Change.php
+++ b/app/Http/Livewire/PrivateKey/Change.php
@@ -35,7 +35,7 @@ class Change extends Component
$this->private_key->save();
session('currentTeam')->privateKeys = PrivateKey::where('team_id', session('currentTeam')->id)->get();
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/PrivateKey/Create.php b/app/Http/Livewire/PrivateKey/Create.php
index e8b22e0af..fda4ca722 100644
--- a/app/Http/Livewire/PrivateKey/Create.php
+++ b/app/Http/Livewire/PrivateKey/Create.php
@@ -38,7 +38,7 @@ class Create extends Component
}
return redirect()->route('private-key.show', ['private_key_uuid' => $private_key->uuid]);
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Profile/Form.php b/app/Http/Livewire/Profile/Form.php
index 4b463b4d3..d09f540da 100644
--- a/app/Http/Livewire/Profile/Form.php
+++ b/app/Http/Livewire/Profile/Form.php
@@ -28,8 +28,8 @@ class Form extends Component
User::where('id', $this->userId)->update([
'name' => $this->name,
]);
- } catch (\Throwable $error) {
- return general_error_handler($error, $this);
+ } catch (\Throwable $e) {
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Project/Application/DeploymentNavbar.php b/app/Http/Livewire/Project/Application/DeploymentNavbar.php
index 20809d2db..8f39ff762 100644
--- a/app/Http/Livewire/Project/Application/DeploymentNavbar.php
+++ b/app/Http/Livewire/Project/Application/DeploymentNavbar.php
@@ -37,8 +37,8 @@ class DeploymentNavbar extends Component
// Remove builder container
instant_remote_process(["docker rm -f {$this->deployment_uuid}"], $this->application->destination->server, throwError: false, repeat: 25);
queue_next_deployment($this->application);
- } catch (\Throwable $th) {
- return general_error_handler($th, $this);
+ } catch (\Throwable $e) {
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Project/Application/EnvironmentVariable/All.php b/app/Http/Livewire/Project/Application/EnvironmentVariable/All.php
index f2d6f9a64..401ec2ed0 100644
--- a/app/Http/Livewire/Project/Application/EnvironmentVariable/All.php
+++ b/app/Http/Livewire/Project/Application/EnvironmentVariable/All.php
@@ -27,7 +27,7 @@ class All extends Component
$this->application->refresh();
$this->emit('clearAddEnv');
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Project/Application/General.php b/app/Http/Livewire/Project/Application/General.php
index 2591482c8..38cc106c5 100644
--- a/app/Http/Livewire/Project/Application/General.php
+++ b/app/Http/Livewire/Project/Application/General.php
@@ -112,7 +112,7 @@ class General extends Component
$this->application->fqdn = $domains->implode(',');
$this->application->save();
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Project/Application/Previews.php b/app/Http/Livewire/Project/Application/Previews.php
index 9e924c0c1..acb7268c5 100644
--- a/app/Http/Livewire/Project/Application/Previews.php
+++ b/app/Http/Livewire/Project/Application/Previews.php
@@ -41,9 +41,9 @@ class Previews extends Component
['rate_limit_remaining' => $rate_limit_remaining, 'data' => $data] = get_from_git_api($this->application->source, "/repos/{$this->application->git_repository}/pulls");
$this->rate_limit_remaining = $rate_limit_remaining;
$this->pull_requests = $data->sortBy('number')->values();
- } catch (\Throwable $th) {
+ } catch (\Throwable $e) {
$this->rate_limit_remaining = 0;
- return general_error_handler($th, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
public function deploy(int $pull_request_id, string|null $pull_request_html_url = null)
@@ -70,8 +70,8 @@ class Previews extends Component
'deployment_uuid' => $this->deployment_uuid,
'environment_name' => $this->parameters['environment_name'],
]);
- } catch (\Throwable $th) {
- return general_error_handler($th, $this);
+ } catch (\Throwable $e) {
+ return general_error_handler(err: $e, that: $this);
}
}
public function stop(int $pull_request_id)
@@ -83,8 +83,8 @@ class Previews extends Component
instant_remote_process(["docker rm -f $container_name"], $this->application->destination->server, throwError: false);
ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->delete();
$this->application->refresh();
- } catch (\Throwable $th) {
- return general_error_handler($th, $this);
+ } catch (\Throwable $e) {
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Project/Application/ResourceLimits.php b/app/Http/Livewire/Project/Application/ResourceLimits.php
index 161d29ecc..2b67f004e 100644
--- a/app/Http/Livewire/Project/Application/ResourceLimits.php
+++ b/app/Http/Livewire/Project/Application/ResourceLimits.php
@@ -44,7 +44,7 @@ class ResourceLimits extends Component
$this->validate();
$this->application->save();
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Project/Application/Rollback.php b/app/Http/Livewire/Project/Application/Rollback.php
index b1bbcec7f..ff89fce70 100644
--- a/app/Http/Livewire/Project/Application/Rollback.php
+++ b/app/Http/Livewire/Project/Application/Rollback.php
@@ -63,7 +63,7 @@ class Rollback extends Component
];
})->toArray();
} catch (\Throwable $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Project/Application/Storages/All.php b/app/Http/Livewire/Project/Application/Storages/All.php
index 0d1d2966b..d6691857e 100644
--- a/app/Http/Livewire/Project/Application/Storages/All.php
+++ b/app/Http/Livewire/Project/Application/Storages/All.php
@@ -27,7 +27,7 @@ class All extends Component
$this->application->refresh();
$this->emit('clearAddStorage');
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepository.php b/app/Http/Livewire/Project/New/GithubPrivateRepository.php
index 4f78ba771..73b07984b 100644
--- a/app/Http/Livewire/Project/New/GithubPrivateRepository.php
+++ b/app/Http/Livewire/Project/New/GithubPrivateRepository.php
@@ -138,7 +138,7 @@ class GithubPrivateRepository extends Component
'project_uuid' => $project->uuid,
]);
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
public function instantSave()
diff --git a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php b/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php
index 71860358c..52baa8790 100644
--- a/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php
+++ b/app/Http/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php
@@ -96,7 +96,7 @@ class GithubPrivateRepositoryDeployKey extends Component
'application_uuid' => $application->uuid,
]);
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Project/New/PublicGitRepository.php b/app/Http/Livewire/Project/New/PublicGitRepository.php
index b5a3b3403..e048b0106 100644
--- a/app/Http/Livewire/Project/New/PublicGitRepository.php
+++ b/app/Http/Livewire/Project/New/PublicGitRepository.php
@@ -68,8 +68,8 @@ class PublicGitRepository extends Component
try {
['data' => $data] = get_from_git_api($this->git_source, "/repos/{$this->git_repository}/branches");
$this->branches = collect($data)->pluck('name')->toArray();
- } catch (\Throwable $th) {
- return general_error_handler($th, $this);
+ } catch (\Throwable $e) {
+ return general_error_handler(err: $e, that: $this);
}
}
private function get_git_source()
@@ -135,7 +135,7 @@ class PublicGitRepository extends Component
'application_uuid' => $application->uuid,
]);
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/RunCommand.php b/app/Http/Livewire/RunCommand.php
index ea5d5596e..187ea3a35 100755
--- a/app/Http/Livewire/RunCommand.php
+++ b/app/Http/Livewire/RunCommand.php
@@ -29,7 +29,7 @@ class RunCommand extends Component
$activity = remote_process([$this->command], Server::where('uuid', $this->server)->first(), ignore_errors: true);
$this->emit('newMonitorActivity', $activity->id);
} catch (\Exception $e) {
- return general_error_handler($e);
+ return general_error_handler(err: $e);
}
}
}
diff --git a/app/Http/Livewire/Server/Form.php b/app/Http/Livewire/Server/Form.php
index 21fc9b281..6680042a2 100644
--- a/app/Http/Livewire/Server/Form.php
+++ b/app/Http/Livewire/Server/Form.php
@@ -55,7 +55,7 @@ class Form extends Component
$this->dockerComposeVersion = 'Not installed.';
}
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
public function delete()
diff --git a/app/Http/Livewire/Server/New/ByIp.php b/app/Http/Livewire/Server/New/ByIp.php
index 632ae89ef..23a76f5f9 100644
--- a/app/Http/Livewire/Server/New/ByIp.php
+++ b/app/Http/Livewire/Server/New/ByIp.php
@@ -61,7 +61,7 @@ class ByIp extends Component
$server->settings->save();
return redirect()->route('server.show', $server->uuid);
} catch (\Exception $e) {
- return general_error_handler($e);
+ return general_error_handler(err: $e);
}
}
}
diff --git a/app/Http/Livewire/Server/Proxy.php b/app/Http/Livewire/Server/Proxy.php
index 5b3f5e119..4a5eb466d 100644
--- a/app/Http/Livewire/Server/Proxy.php
+++ b/app/Http/Livewire/Server/Proxy.php
@@ -64,7 +64,7 @@ class Proxy extends Component
"echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml",
], $server);
} catch (\Exception $e) {
- return general_error_handler($e);
+ return general_error_handler(err: $e);
}
}
public function resetProxy()
@@ -72,7 +72,7 @@ class Proxy extends Component
try {
$this->proxy_settings = resolve(CheckProxySettingsInSync::class)($this->server, true);
} catch (\Exception $e) {
- return general_error_handler($e);
+ return general_error_handler(err: $e);
}
}
public function checkProxySettingsInSync()
@@ -80,7 +80,7 @@ class Proxy extends Component
try {
$this->proxy_settings = resolve(CheckProxySettingsInSync::class)($this->server);
} catch (\Exception $e) {
- return general_error_handler($e);
+ return general_error_handler(err: $e);
}
}
}
diff --git a/app/Http/Livewire/Source/Github/Change.php b/app/Http/Livewire/Source/Github/Change.php
index ee06e1748..f0b922088 100644
--- a/app/Http/Livewire/Source/Github/Change.php
+++ b/app/Http/Livewire/Source/Github/Change.php
@@ -35,7 +35,7 @@ class Change extends Component
$this->validate();
$this->github_app->save();
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
public function instantSave()
@@ -45,7 +45,7 @@ class Change extends Component
$this->github_app->save();
$this->emit('saved', 'GitHub settings updated!');
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
public function mount()
@@ -63,7 +63,7 @@ class Change extends Component
$this->github_app->delete();
redirect()->route('dashboard');
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Source/Github/Create.php b/app/Http/Livewire/Source/Github/Create.php
index d6eb34f40..b95bde919 100644
--- a/app/Http/Livewire/Source/Github/Create.php
+++ b/app/Http/Livewire/Source/Github/Create.php
@@ -43,7 +43,7 @@ class Create extends Component
]);
redirect()->route('source.github.show', ['github_app_uuid' => $github_app->uuid]);
} catch (\Exception $e) {
- return general_error_handler($e, $this);
+ return general_error_handler(err: $e, that: $this);
}
}
}
diff --git a/app/Http/Livewire/Team/InviteLink.php b/app/Http/Livewire/Team/InviteLink.php
new file mode 100644
index 000000000..04159fc15
--- /dev/null
+++ b/app/Http/Livewire/Team/InviteLink.php
@@ -0,0 +1,51 @@
+email = config('app.env') === 'local' ? 'test@example.com' : '';
+ }
+ public function inviteByLink()
+ {
+ $uuid = new Cuid2(32);
+ $link = url('/') . '/api/invitation/' . $uuid;
+ try {
+ $user_exists = User::whereEmail($this->email)->exists();
+ if (!$user_exists) {
+ return general_error_handler(that: $this, customErrorMessage: "$this->email must be registered first (or activate transactional emails to invite via email).");
+ }
+ $invitation = TeamInvitation::where('email', $this->email);
+ if ($invitation->exists()) {
+ $created_at = $invitation->first()->created_at;
+ $diff = $created_at->diffInMinutes(now());
+ if ($diff < 11) {
+ return general_error_handler(that: $this, customErrorMessage: "Invitation already sent and active for $this->email.");
+ } else {
+ $invitation->delete();
+ }
+ }
+ $invitation = TeamInvitation::firstOrCreate([
+ 'team_id' => session('currentTeam')->id,
+ 'email' => $this->email,
+ 'role' => 'readonly',
+ 'link' => $link,
+ ]);
+ $this->emit('reloadWindow');
+ } catch (\Throwable $e) {
+ $error_message = $e->getMessage();
+ if ($e->getCode() === '23505') {
+ $error_message = 'Invitation already sent.';
+ }
+ return general_error_handler(err: $e, that: $this, customErrorMessage: $error_message);
+ }
+ }
+}
diff --git a/app/Http/Livewire/Team/Member.php b/app/Http/Livewire/Team/Member.php
index ad21cc0f4..65cca3038 100644
--- a/app/Http/Livewire/Team/Member.php
+++ b/app/Http/Livewire/Team/Member.php
@@ -8,10 +8,19 @@ use Livewire\Component;
class Member extends Component
{
public User $member;
+ public function makeAdmin()
+ {
+ $this->member->teams()->updateExistingPivot(session('currentTeam')->id, ['role' => 'admin']);
+ $this->emit('reloadWindow');
+ }
+ public function makeReadonly()
+ {
+ $this->member->teams()->updateExistingPivot(session('currentTeam')->id, ['role' => 'readonly']);
+ $this->emit('reloadWindow');
+ }
public function remove()
{
$this->member->teams()->detach(session('currentTeam'));
- session(['currentTeam' => session('currentTeam')->fresh()]);
$this->emit('reloadWindow');
}
}
diff --git a/app/Models/Team.php b/app/Models/Team.php
index a1d7c7c13..64bdf3c1c 100644
--- a/app/Models/Team.php
+++ b/app/Models/Team.php
@@ -62,6 +62,10 @@ class Team extends BaseModel implements SendsDiscord, SendsEmail
}
public function members()
{
- return $this->belongsToMany(User::class, 'team_user', 'team_id', 'user_id');
+ return $this->belongsToMany(User::class, 'team_user', 'team_id', 'user_id')->withPivot('role');
+ }
+ public function invitations()
+ {
+ return $this->hasMany(TeamInvitation::class);
}
}
diff --git a/app/Models/TeamInvitation.php b/app/Models/TeamInvitation.php
new file mode 100644
index 000000000..91ad9837a
--- /dev/null
+++ b/app/Models/TeamInvitation.php
@@ -0,0 +1,19 @@
+belongsTo(Team::class);
+ }
+}
diff --git a/app/Models/User.php b/app/Models/User.php
index 209d1e840..9f64bcd5c 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -33,11 +33,37 @@ class User extends Authenticatable
static::creating(function (Model $model) {
$model->uuid = (string) new Cuid2(7);
});
+ static::created(function (User $user) {
+ $team = [
+ 'name' => $user->name . "'s Team",
+ 'personal_team' => true,
+ ];
+ if ($user->id === 0) {
+ $team['id'] = 0;
+ $team['name'] = 'Root Team';
+ }
+ $new_team = Team::create($team);
+ $user->teams()->attach($new_team, ['role' => 'owner']);
+ });
}
public function isAdmin()
{
- ray(session('currentTeam'));
- return session('currentTeam');
+ if (auth()->user()->id === 0) {
+ ray('is root user');
+ return true;
+ }
+ $teams = $this->teams()->get();
+
+ $is_part_of_root_team = $teams->where('id', 0)->first();
+ $is_admin_of_root_team = $is_part_of_root_team &&
+ ($is_part_of_root_team->pivot->role === 'admin' || $is_part_of_root_team->pivot->role === 'owner');
+
+ if ($is_part_of_root_team && $is_admin_of_root_team) {
+ ray('is admin of root team');
+ return true;
+ }
+ $role = $teams->where('id', session('currentTeam')->id)->first()->pivot->role;
+ return $role === 'admin' || $role === 'owner';
}
public function isInstanceAdmin()
{
@@ -51,14 +77,12 @@ class User extends Authenticatable
}
public function teams()
{
- return $this->belongsToMany(Team::class);
+ return $this->belongsToMany(Team::class)->withPivot('role');
+ }
+ public function currentTeam()
+ {
+ return $this->teams()->where('team_id', session('currentTeam')->id)->first();
}
-
- // public function currentTeam()
- // {
- // return $this->belongsTo(Team::class);
- // }
-
public function otherTeams()
{
$team_id = session('currentTeam')->id;
@@ -66,6 +90,13 @@ class User extends Authenticatable
return $team->id != $team_id;
});
}
+ public function role()
+ {
+ if ($this->teams()->where('team_id', 0)->first()) {
+ return 'admin';
+ }
+ return $this->teams()->where('team_id', session('currentTeam')->id)->first()->pivot->role;
+ }
public function resources()
{
$team_id = session('currentTeam')->id;
diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php
index 89725d0bc..8a7a99af8 100644
--- a/bootstrap/helpers/shared.php
+++ b/bootstrap/helpers/shared.php
@@ -6,30 +6,31 @@ use Illuminate\Support\Facades\Route;
use Visus\Cuid2\Cuid2;
use Illuminate\Support\Str;
-function general_error_handler(\Throwable $e, $that = null, $isJson = false)
+function general_error_handler(\Throwable|null $err = null, $that = null, $isJson = false, $customErrorMessage = null)
{
try {
- ray('ERROR OCCURED: ' . $e->getMessage());
- if ($e instanceof QueryException) {
- if ($e->errorInfo[0] === '23505') {
- throw new \Exception('Duplicate entry found.', '23505');
- } else if (count($e->errorInfo) === 4) {
- throw new \Exception($e->errorInfo[3]);
+ ray('ERROR OCCURED: ' . $err->getMessage());
+ if ($err instanceof QueryException) {
+ if ($err->errorInfo[0] === '23505') {
+ throw new \Exception($customErrorMessage ?? 'Duplicate entry found.', '23505');
+ } else if (count($err->errorInfo) === 4) {
+ throw new \Exception($customErrorMessage ?? $err->errorInfo[3]);
} else {
- throw new \Exception($e->errorInfo[2]);
+ throw new \Exception($customErrorMessage ?? $err->errorInfo[2]);
}
} else {
- throw new \Exception($e->getMessage());
+ throw new \Exception($customErrorMessage ?? $err->getMessage());
}
} catch (\Throwable $error) {
if ($that) {
- return $that->emit('error', $error->getMessage());
+ return $that->emit('error', $customErrorMessage ?? $error->getMessage());
} elseif ($isJson) {
return response()->json([
'code' => $error->getCode(),
'error' => $error->getMessage(),
]);
} else {
+ ray($customErrorMessage);
ray($error);
}
}
diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php
index ff7a7e716..623148331 100644
--- a/database/migrations/2014_10_12_000000_create_users_table.php
+++ b/database/migrations/2014_10_12_000000_create_users_table.php
@@ -14,7 +14,6 @@ return new class extends Migration
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('uuid')->unique();
- $table->boolean('is_root_user')->default(false);
$table->string('name')->default('Your Name Here');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
diff --git a/database/migrations/2023_03_20_112812_create_team_user_table.php b/database/migrations/2023_03_20_112812_create_team_user_table.php
index 3e2787630..e794dc645 100644
--- a/database/migrations/2023_03_20_112812_create_team_user_table.php
+++ b/database/migrations/2023_03_20_112812_create_team_user_table.php
@@ -15,7 +15,7 @@ return new class extends Migration
$table->id();
$table->foreignId('team_id');
$table->foreignId('user_id');
- $table->string('role')->nullable();
+ $table->string('role')->default('readonly');
$table->timestamps();
$table->unique(['team_id', 'user_id']);
diff --git a/database/migrations/2023_03_20_112813_create_team_invitations_table.php b/database/migrations/2023_03_20_112813_create_team_invitations_table.php
new file mode 100644
index 000000000..55be41302
--- /dev/null
+++ b/database/migrations/2023_03_20_112813_create_team_invitations_table.php
@@ -0,0 +1,33 @@
+id();
+ $table->foreignId('team_id')->constrained()->cascadeOnDelete();
+ $table->string('email');
+ $table->string('role')->default('readonly');
+ $table->string('link')->nullable();
+ $table->timestamps();
+
+ $table->unique(['team_id', 'email']);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('team_invitations');
+ }
+};
diff --git a/database/migrations/2023_03_20_112813_create_instance_settings_table.php b/database/migrations/2023_03_20_112814_create_instance_settings_table.php
similarity index 100%
rename from database/migrations/2023_03_20_112813_create_instance_settings_table.php
rename to database/migrations/2023_03_20_112814_create_instance_settings_table.php
diff --git a/database/seeders/ProductionSeeder.php b/database/seeders/ProductionSeeder.php
index d383fc823..253a4ba30 100644
--- a/database/seeders/ProductionSeeder.php
+++ b/database/seeders/ProductionSeeder.php
@@ -46,13 +46,13 @@ class ProductionSeeder extends Seeder
}
// Add first Team if it doesn't exist
- if (Team::find(0) == null) {
- Team::create([
- 'id' => 0,
- 'name' => "Root's Team",
- 'personal_team' => true,
- ]);
- }
+ // if (Team::find(0) == null) {
+ // Team::create([
+ // 'id' => 0,
+ // 'name' => "Root's Team",
+ // 'personal_team' => true,
+ // ]);
+ // }
// Save SSH Keys for the Coolify Host
$coolify_key_name = "id.root@host.docker.internal";
diff --git a/database/seeders/TeamSeeder.php b/database/seeders/TeamSeeder.php
index fa4439540..c2bab6ac5 100644
--- a/database/seeders/TeamSeeder.php
+++ b/database/seeders/TeamSeeder.php
@@ -11,42 +11,13 @@ class TeamSeeder extends Seeder
{
public function run(): void
{
- $root_user = User::find(0);
- $normal_user = User::find(1);
+ $normal_user_in_root_team = User::find(1);
+ $root_user_personal_team = Team::find(0);
- $root_user_personal_team = Team::create([
- 'id' => 0,
- 'name' => "Root Team",
- 'personal_team' => true,
- ]);
- $root_user_other_team = Team::create([
- 'name' => "Root User's Other Team",
- 'personal_team' => false,
- ]);
- $normal_user_personal_team = Team::create([
- 'name' => 'Normal Team',
- 'personal_team' => true,
- ]);
- // $root_user->teams()->attach($root_user_personal_team);
- // $root_user->teams()->attach($root_user_other_team);
- // $normal_user->teams()->attach($normal_user_personal_team);
- // $normal_user->teams()->attach($root_user_personal_team);
- DB::table('team_user')->insert([
- 'team_id' => $root_user_personal_team->id,
- 'user_id' => $root_user->id,
- 'role' => 'admin',
- ]);
- DB::table('team_user')->insert([
- 'team_id' => $root_user_other_team->id,
- 'user_id' => $root_user->id,
- ]);
- DB::table('team_user')->insert([
- 'team_id' => $normal_user_personal_team->id,
- 'user_id' => $normal_user->id,
- ]);
- DB::table('team_user')->insert([
- 'team_id' => $root_user_personal_team->id,
- 'user_id' => $normal_user->id,
- ]);
+ $normal_user_in_root_team->teams()->attach($root_user_personal_team);
+
+ $normal_user_not_in_root_team = User::find(2);
+ $normal_user_in_root_team_personal_team = Team::find(1);
+ $normal_user_not_in_root_team->teams()->attach($normal_user_in_root_team_personal_team, ['role' => 'admin']);
}
}
diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php
index a5ab30dda..19d3aa42e 100644
--- a/database/seeders/UserSeeder.php
+++ b/database/seeders/UserSeeder.php
@@ -13,11 +13,14 @@ class UserSeeder extends Seeder
'id' => 0,
'name' => 'Root User',
'email' => 'test@example.com',
- 'is_root_user' => true,
]);
User::factory()->create([
- 'name' => 'Normal User',
+ 'name' => 'Normal User (but in root team)',
'email' => 'test2@example.com',
]);
+ User::factory()->create([
+ 'name' => 'Normal User (not in root team)',
+ 'email' => 'test3@example.com',
+ ]);
}
}
diff --git a/resources/views/livewire/notifications/discord-settings.blade.php b/resources/views/livewire/notifications/discord-settings.blade.php
index 548a26279..6272608ce 100644
--- a/resources/views/livewire/notifications/discord-settings.blade.php
+++ b/resources/views/livewire/notifications/discord-settings.blade.php
@@ -5,10 +5,12 @@
Name | Role | Actions |
---|