coolify/app/Livewire/Team/InviteLink.php
2024-07-24 12:27:21 +00:00

107 lines
3.6 KiB
PHP

<?php
namespace App\Livewire\Team;
use App\Models\TeamInvitation;
use App\Models\User;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Livewire\Component;
use Visus\Cuid2\Cuid2;
class InviteLink extends Component
{
public string $email;
public string $role = 'member';
protected $rules = [
'email' => 'required|email',
'role' => 'required|string',
];
public function mount()
{
$this->email = isDev() ? 'test3@example.com' : '';
}
public function viaEmail()
{
$this->generate_invite_link(sendEmail: true);
}
public function viaLink()
{
$this->generate_invite_link(sendEmail: false);
}
private function generate_invite_link(bool $sendEmail = false)
{
try {
$this->validate();
$member_emails = currentTeam()->members()->get()->pluck('email');
if ($member_emails->contains($this->email)) {
return handleError(livewire: $this, customErrorMessage: "$this->email is already a member of ".currentTeam()->name.'.');
}
$uuid = new Cuid2(32);
$link = url('/').config('constants.invitation.link.base_url').$uuid;
$user = User::whereEmail($this->email)->first();
if (is_null($user)) {
$password = Str::password();
$user = User::create([
'name' => str($this->email)->before('@'),
'email' => $this->email,
'password' => Hash::make($password),
'force_password_reset' => true,
]);
$token = Crypt::encryptString("{$user->email}@@@$password");
$link = route('auth.link', ['token' => $token]);
}
$invitation = TeamInvitation::whereEmail($this->email)->first();
if (! is_null($invitation)) {
$invitationValid = $invitation->isValid();
if ($invitationValid) {
return handleError(livewire: $this, customErrorMessage: "Pending invitation already exists for $this->email.");
} else {
$invitation->delete();
}
}
$invitation = TeamInvitation::firstOrCreate([
'team_id' => currentTeam()->id,
'uuid' => $uuid,
'email' => $this->email,
'role' => $this->role,
'link' => $link,
'via' => $sendEmail ? 'email' : 'link',
]);
if ($sendEmail) {
$mail = new MailMessage;
$mail->view('emails.invitation-link', [
'team' => currentTeam()->name,
'invitation_link' => $link,
]);
$mail->subject('You have been invited to '.currentTeam()->name.' on '.config('app.name').'.');
send_user_an_email($mail, $this->email);
$this->dispatch('success', 'Invitation sent via email.');
$this->dispatch('refreshInvitations');
return;
} else {
$this->dispatch('success', 'Invitation link generated.');
$this->dispatch('refreshInvitations');
}
} catch (\Throwable $e) {
$error_message = $e->getMessage();
if ($e->getCode() === '23505') {
$error_message = 'Invitation already sent.';
}
return handleError(error: $e, livewire: $this, customErrorMessage: $error_message);
}
}
}