This commit is contained in:
Andras Bacsai
2023-06-12 12:00:01 +02:00
parent b097842d01
commit a97d22b81b
36 changed files with 364 additions and 202 deletions

View File

@@ -2,9 +2,12 @@
namespace App\Http\Controllers;
use App\Http\Livewire\Team\Invitations;
use App\Models\InstanceSettings;
use App\Models\Project;
use App\Models\Server;
use App\Models\TeamInvitation;
use App\Models\User;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
@@ -53,14 +56,56 @@ class Controller extends BaseController
}
public function team()
{
ray(auth()->user()->isAdmin());
$invitations = [];
if (auth()->user()->isAdmin()) {
$invitations = auth()->user()->currentTeam()->invitations;
$invitations = TeamInvitation::whereTeamId(auth()->user()->currentTeam()->id)->get();
}
return view('team.show', [
'transactional_emails_active' => data_get(InstanceSettings::get(), 'extra_attributes.smtp_host') ? true : false,
'transactional_emails_active' => is_transactional_emails_active(),
'invitations' => $invitations,
]);
}
public function accept_invitation()
{
try {
$invitation = TeamInvitation::whereUuid(request()->route('uuid'))->firstOrFail();
$user = User::whereEmail($invitation->email)->firstOrFail();
if (is_null(auth()->user())) {
return redirect()->route('login');
}
if (auth()->user()->id !== $user->id) {
abort(401);
}
$created_at = $invitation->created_at;
$diff = $created_at->diffInMinutes(now());
if ($diff <= config('constants.invitation.link.expiration')) {
$user->teams()->attach($invitation->team->id, ['role' => $invitation->role]);
$invitation->delete();
return redirect()->route('team.show');
} else {
$invitation->delete();
abort(401);
}
} catch (\Throwable $th) {
throw $th;
}
}
public function revoke_invitation()
{
try {
$invitation = TeamInvitation::whereUuid(request()->route('uuid'))->firstOrFail();
$user = User::whereEmail($invitation->email)->firstOrFail();
if (is_null(auth()->user())) {
return redirect()->route('login');
}
if (auth()->user()->id !== $user->id) {
abort(401);
}
$invitation->delete();
return redirect()->route('team.show');
} catch (\Throwable $th) {
throw $th;
}
}
}

View File

@@ -2,10 +2,8 @@
namespace App\Http\Livewire\Settings;
use App\Mail\TestTransactionalEmail;
use App\Models\InstanceSettings;
use App\Notifications\TestTransactionEmail;
use Illuminate\Support\Facades\Mail;
use App\Notifications\TransactionalEmails\TestEmail;
use Illuminate\Support\Facades\Notification;
use Livewire\Component;
@@ -20,46 +18,17 @@ class Email extends Component
'settings.extra_attributes.smtp_username' => 'nullable',
'settings.extra_attributes.smtp_password' => 'nullable',
'settings.extra_attributes.smtp_timeout' => 'nullable',
'settings.extra_attributes.smtp_recipients' => 'required',
'settings.extra_attributes.smtp_test_recipients' => 'nullable',
'settings.extra_attributes.smtp_from_address' => 'required|email',
'settings.extra_attributes.smtp_from_name' => 'required',
];
public function test_email()
{
Notification::send($this->settings, new TestTransactionEmail);
Notification::send($this->settings, new TestEmail);
}
// public function test_email()
// {
// config()->set('mail.default', 'smtp');
// config()->set('mail.mailers.smtp', [
// "transport" => "smtp",
// "host" => $this->settings->smtp_host,
// "port" => $this->settings->smtp_port,
// "encryption" => $this->settings->smtp_encryption,
// "username" => $this->settings->smtp_username,
// "password" => $this->settings->smtp_password,
// ]);
// $this->send_email();
// }
// public function test_email_local()
// {
// config()->set('mail.default', 'smtp');
// config()->set('mail.mailers.smtp', [
// "transport" => "smtp",
// "host" => 'coolify-mail',
// "port" => 1025,
// ]);
// $this->send_email();
// }
// private function send_email()
// {
// }
public function submit()
{
$this->validate();
$this->settings->extra_attributes->smtp_recipients = str_replace(' ', '', $this->settings->extra_attributes->smtp_recipients);
$this->settings->extra_attributes->smtp_test_recipients = str_replace(' ', '', $this->settings->extra_attributes->smtp_test_recipients);
$this->settings->save();
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Http\Livewire\Team;
use App\Models\TeamInvitation;
use Livewire\Component;
class Invitations extends Component
{
public $invitations;
protected $listeners = ['refreshInvitations'];
public function refreshInvitations()
{
$this->invitations = TeamInvitation::whereTeamId(auth()->user()->currentTeam()->id)->get();
}
public function deleteInvitation(int $invitation_id)
{
TeamInvitation::find($invitation_id)->delete();
$this->refreshInvitations();
}
}

View File

@@ -4,42 +4,64 @@ namespace App\Http\Livewire\Team;
use App\Models\TeamInvitation;
use App\Models\User;
use App\Notifications\TransactionalEmails\InvitationLinkEmail;
use Livewire\Component;
use Visus\Cuid2\Cuid2;
class InviteLink extends Component
{
public string $email;
public string $role = 'member';
public function mount()
{
$this->email = config('app.env') === 'local' ? 'test@example.com' : '';
$this->email = config('app.env') === 'local' ? 'test3@example.com' : '';
}
public function inviteByLink()
public function viaEmail()
{
$this->generate_invite_link(isEmail: true);
}
private function generate_invite_link(bool $isEmail = false)
{
$uuid = new Cuid2(32);
$link = url('/') . '/api/invitation/' . $uuid;
try {
$user_exists = User::whereEmail($this->email)->exists();
if (!$user_exists) {
$uuid = new Cuid2(32);
$link = url('/') . config('constants.invitation.link.base_url') . $uuid;
$user = User::whereEmail($this->email);
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);
$member_emails = session('currentTeam')->members()->get()->pluck('email');
if ($member_emails->contains($this->email)) {
return general_error_handler(that: $this, customErrorMessage: "$this->email is already a member of " . session('currentTeam')->name . ".");
}
$invitation = TeamInvitation::whereEmail($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.");
if ($diff <= config('constants.invitation.link.expiration')) {
return general_error_handler(that: $this, customErrorMessage: "Invitation already sent to $this->email and waiting for action.");
} else {
$invitation->delete();
}
}
$invitation = TeamInvitation::firstOrCreate([
TeamInvitation::firstOrCreate([
'team_id' => session('currentTeam')->id,
'uuid' => $uuid,
'email' => $this->email,
'role' => 'readonly',
'role' => $this->role,
'link' => $link,
'via' => $isEmail ? 'email' : 'link',
]);
$this->emit('reloadWindow');
if ($isEmail) {
$user->first()->notify(new InvitationLinkEmail());
}
$this->emit('refreshInvitations');
$this->emit('message', 'Invitation sent successfully.');
} catch (\Throwable $e) {
$error_message = $e->getMessage();
if ($e->getCode() === '23505') {
@@ -48,4 +70,8 @@ class InviteLink extends Component
return general_error_handler(err: $e, that: $this, customErrorMessage: $error_message);
}
}
public function inviteByLink()
{
$this->generate_invite_link();
}
}

View File

@@ -15,7 +15,7 @@ class Member extends Component
}
public function makeReadonly()
{
$this->member->teams()->updateExistingPivot(session('currentTeam')->id, ['role' => 'readonly']);
$this->member->teams()->updateExistingPivot(session('currentTeam')->id, ['role' => 'member']);
$this->emit('reloadWindow');
}
public function remove()