fix: invitation
This commit is contained in:
		
							parent
							
								
									82c235d5af
								
							
						
					
					
						commit
						b07cc500e7
					
				| @ -24,7 +24,7 @@ use Illuminate\Console\Command; | |||||||
| use Illuminate\Mail\Message; | use Illuminate\Mail\Message; | ||||||
| use Illuminate\Notifications\Messages\MailMessage; | use Illuminate\Notifications\Messages\MailMessage; | ||||||
| use Mail; | use Mail; | ||||||
| use Str; | use Illuminate\Support\Str; | ||||||
| 
 | 
 | ||||||
| use function Laravel\Prompts\confirm; | use function Laravel\Prompts\confirm; | ||||||
| use function Laravel\Prompts\select; | use function Laravel\Prompts\select; | ||||||
| @ -62,7 +62,7 @@ class Emails extends Command | |||||||
|                 'application-status-changed' => 'Application - Status Changed', |                 'application-status-changed' => 'Application - Status Changed', | ||||||
|                 'backup-success' => 'Database - Backup Success', |                 'backup-success' => 'Database - Backup Success', | ||||||
|                 'backup-failed' => 'Database - Backup Failed', |                 'backup-failed' => 'Database - Backup Failed', | ||||||
|                 'invitation-link' => 'Invitation Link', |                 // 'invitation-link' => 'Invitation Link',
 | ||||||
|                 'waitlist-invitation-link' => 'Waitlist Invitation Link', |                 'waitlist-invitation-link' => 'Waitlist Invitation Link', | ||||||
|                 'waitlist-confirmation' => 'Waitlist Confirmation', |                 'waitlist-confirmation' => 'Waitlist Confirmation', | ||||||
|                 'realusers-before-trial' => 'REAL - Registered Users Before Trial without Subscription', |                 'realusers-before-trial' => 'REAL - Registered Users Before Trial without Subscription', | ||||||
| @ -141,20 +141,20 @@ class Emails extends Command | |||||||
|                 $this->mail = (new BackupSuccess($backup, $db))->toMail(); |                 $this->mail = (new BackupSuccess($backup, $db))->toMail(); | ||||||
|                 $this->sendEmail(); |                 $this->sendEmail(); | ||||||
|                 break; |                 break; | ||||||
|             case 'invitation-link': |             // case 'invitation-link':
 | ||||||
|                 $user = User::all()->first(); |             //     $user = User::all()->first();
 | ||||||
|                 $invitation = TeamInvitation::whereEmail($user->email)->first(); |             //     $invitation = TeamInvitation::whereEmail($user->email)->first();
 | ||||||
|                 if (!$invitation) { |             //     if (!$invitation) {
 | ||||||
|                     $invitation = TeamInvitation::create([ |             //         $invitation = TeamInvitation::create([
 | ||||||
|                         'uuid' => Str::uuid(), |             //             'uuid' => Str::uuid(),
 | ||||||
|                         'email' => $user->email, |             //             'email' => $user->email,
 | ||||||
|                         'team_id' => 1, |             //             'team_id' => 1,
 | ||||||
|                         'link' => 'http://example.com', |             //             'link' => 'http://example.com',
 | ||||||
|                     ]); |             //         ]);
 | ||||||
|                 } |             //     }
 | ||||||
|                 $this->mail = (new InvitationLink($user))->toMail(); |             //     $this->mail = (new InvitationLink($user))->toMail();
 | ||||||
|                 $this->sendEmail(); |             //     $this->sendEmail();
 | ||||||
|                 break; |             //     break;
 | ||||||
|             case 'waitlist-invitation-link': |             case 'waitlist-invitation-link': | ||||||
|                 $this->mail = new MailMessage(); |                 $this->mail = new MailMessage(); | ||||||
|                 $this->mail->view('emails.waitlist-invitation', [ |                 $this->mail->view('emails.waitlist-invitation', [ | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ class Kernel extends ConsoleKernel | |||||||
|         if (isDev()) { |         if (isDev()) { | ||||||
|             // $schedule->job(new ContainerStatusJob(Server::find(0)))->everyTenMinutes()->onOneServer();
 |             // $schedule->job(new ContainerStatusJob(Server::find(0)))->everyTenMinutes()->onOneServer();
 | ||||||
|             // $schedule->command('horizon:snapshot')->everyMinute();
 |             // $schedule->command('horizon:snapshot')->everyMinute();
 | ||||||
|             // $schedule->job(new CleanupInstanceStuffsJob)->everyMinute();
 |             $schedule->job(new CleanupInstanceStuffsJob)->everyMinute()->onOneServer(); | ||||||
|             // $schedule->job(new CheckResaleLicenseJob)->hourly();
 |             // $schedule->job(new CheckResaleLicenseJob)->hourly();
 | ||||||
|             // $schedule->job(new DockerCleanupJob)->everyOddHour();
 |             // $schedule->job(new DockerCleanupJob)->everyOddHour();
 | ||||||
|             // $this->instance_auto_update($schedule);
 |             // $this->instance_auto_update($schedule);
 | ||||||
| @ -29,7 +29,7 @@ class Kernel extends ConsoleKernel | |||||||
|             $this->check_resources($schedule); |             $this->check_resources($schedule); | ||||||
|         } else { |         } else { | ||||||
|             $schedule->command('horizon:snapshot')->everyFiveMinutes(); |             $schedule->command('horizon:snapshot')->everyFiveMinutes(); | ||||||
|             $schedule->job(new CleanupInstanceStuffsJob)->everyTenMinutes()->onOneServer(); |             $schedule->job(new CleanupInstanceStuffsJob)->everyTwoMinutes()->onOneServer(); | ||||||
|             $schedule->job(new CheckResaleLicenseJob)->hourly()->onOneServer(); |             $schedule->job(new CheckResaleLicenseJob)->hourly()->onOneServer(); | ||||||
|             $schedule->job(new DockerCleanupJob)->everyTenMinutes()->onOneServer(); |             $schedule->job(new DockerCleanupJob)->everyTenMinutes()->onOneServer(); | ||||||
|             $this->instance_auto_update($schedule); |             $this->instance_auto_update($schedule); | ||||||
|  | |||||||
| @ -3,21 +3,18 @@ | |||||||
| namespace App\Http\Controllers; | namespace App\Http\Controllers; | ||||||
| 
 | 
 | ||||||
| use App\Models\InstanceSettings; | use App\Models\InstanceSettings; | ||||||
| use App\Models\Project; |  | ||||||
| use App\Models\S3Storage; | use App\Models\S3Storage; | ||||||
| use App\Models\StandalonePostgresql; | use App\Models\StandalonePostgresql; | ||||||
| use App\Models\TeamInvitation; | use App\Models\TeamInvitation; | ||||||
| use App\Models\User; | use App\Models\User; | ||||||
| use Auth; |  | ||||||
| use Illuminate\Foundation\Auth\Access\AuthorizesRequests; | use Illuminate\Foundation\Auth\Access\AuthorizesRequests; | ||||||
| use Illuminate\Foundation\Validation\ValidatesRequests; | use Illuminate\Foundation\Validation\ValidatesRequests; | ||||||
| use Illuminate\Routing\Controller as BaseController; | use Illuminate\Routing\Controller as BaseController; | ||||||
|  | use Illuminate\Support\Facades\Auth; | ||||||
| use Illuminate\Support\Facades\Crypt; | use Illuminate\Support\Facades\Crypt; | ||||||
| use Illuminate\Support\Facades\Hash; | use Illuminate\Support\Facades\Hash; | ||||||
| use Illuminate\Support\Facades\Http; | use Illuminate\Support\Str; | ||||||
| use Throwable; | use Throwable; | ||||||
| use Str; |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| class Controller extends BaseController | class Controller extends BaseController | ||||||
| { | { | ||||||
| @ -35,8 +32,15 @@ class Controller extends BaseController | |||||||
|                 return redirect()->route('login'); |                 return redirect()->route('login'); | ||||||
|             } |             } | ||||||
|             if (Hash::check($password, $user->password)) { |             if (Hash::check($password, $user->password)) { | ||||||
|                 Auth::login($user); |                 $invitation = TeamInvitation::whereEmail($email); | ||||||
|  |                 if ($invitation->exists()) { | ||||||
|  |                     $team = $invitation->first()->team; | ||||||
|  |                     $user->teams()->attach($team->id, ['role' => $invitation->first()->role]); | ||||||
|  |                     $invitation->delete(); | ||||||
|  |                 } else { | ||||||
|                     $team = $user->teams()->first(); |                     $team = $user->teams()->first(); | ||||||
|  |                 } | ||||||
|  |                 Auth::login($user); | ||||||
|                 session(['currentTeam' => $team]); |                 session(['currentTeam' => $team]); | ||||||
|                 return redirect()->route('dashboard'); |                 return redirect()->route('dashboard'); | ||||||
|             } |             } | ||||||
| @ -137,24 +141,20 @@ class Controller extends BaseController | |||||||
|         try { |         try { | ||||||
|             $invitation = TeamInvitation::whereUuid(request()->route('uuid'))->firstOrFail(); |             $invitation = TeamInvitation::whereUuid(request()->route('uuid'))->firstOrFail(); | ||||||
|             $user = User::whereEmail($invitation->email)->firstOrFail(); |             $user = User::whereEmail($invitation->email)->firstOrFail(); | ||||||
|             if (is_null(auth()->user())) { |  | ||||||
|                 return redirect()->route('login'); |  | ||||||
|             } |  | ||||||
|             if (auth()->user()->id !== $user->id) { |             if (auth()->user()->id !== $user->id) { | ||||||
|                 abort(401); |                 abort(401); | ||||||
|             } |             } | ||||||
| 
 |             $invitationValid = $invitation->isValid(); | ||||||
|             $createdAt = $invitation->created_at; |             if ($invitationValid) { | ||||||
|             $diff = $createdAt->diffInMinutes(now()); |  | ||||||
|             if ($diff <= config('constants.invitation.link.expiration')) { |  | ||||||
|                 $user->teams()->attach($invitation->team->id, ['role' => $invitation->role]); |                 $user->teams()->attach($invitation->team->id, ['role' => $invitation->role]); | ||||||
|  |                 refreshSession($invitation->team); | ||||||
|                 $invitation->delete(); |                 $invitation->delete(); | ||||||
|                 return redirect()->route('team.index'); |                 return redirect()->route('team.index'); | ||||||
|             } else { |             } else { | ||||||
|                 $invitation->delete(); |  | ||||||
|                 abort(401); |                 abort(401); | ||||||
|             } |             } | ||||||
|         } catch (Throwable $e) { |         } catch (Throwable $e) { | ||||||
|  |             ray($e->getMessage()); | ||||||
|             throw $e; |             throw $e; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ namespace App\Http\Livewire\Project\Shared\EnvironmentVariable; | |||||||
| use App\Models\EnvironmentVariable; | use App\Models\EnvironmentVariable; | ||||||
| use Livewire\Component; | use Livewire\Component; | ||||||
| use Visus\Cuid2\Cuid2; | use Visus\Cuid2\Cuid2; | ||||||
| use Str; | use Illuminate\Support\Str; | ||||||
| 
 | 
 | ||||||
| class All extends Component | class All extends Component | ||||||
| { | { | ||||||
|  | |||||||
| @ -4,9 +4,13 @@ namespace App\Http\Livewire\Team; | |||||||
| 
 | 
 | ||||||
| use App\Models\TeamInvitation; | use App\Models\TeamInvitation; | ||||||
| use App\Models\User; | use App\Models\User; | ||||||
| use App\Notifications\TransactionalEmails\InvitationLink; | use Illuminate\Notifications\Messages\MailMessage; | ||||||
|  | use Illuminate\Support\Facades\Artisan; | ||||||
| use Livewire\Component; | use Livewire\Component; | ||||||
| use Visus\Cuid2\Cuid2; | use Visus\Cuid2\Cuid2; | ||||||
|  | use Illuminate\Support\Facades\Crypt; | ||||||
|  | use Illuminate\Support\Facades\Hash; | ||||||
|  | use Illuminate\Support\Str; | ||||||
| 
 | 
 | ||||||
| class InviteLink extends Component | class InviteLink extends Component | ||||||
| { | { | ||||||
| @ -20,53 +24,68 @@ class InviteLink extends Component | |||||||
| 
 | 
 | ||||||
|     public function viaEmail() |     public function viaEmail() | ||||||
|     { |     { | ||||||
|         $this->generate_invite_link(isEmail: true); |         $this->generate_invite_link(sendEmail: true); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private function generate_invite_link(bool $isEmail = false) |     public function viaLink() | ||||||
|  |     { | ||||||
|  |         $this->generate_invite_link(sendEmail: false); | ||||||
|  |     } | ||||||
|  |     private function generate_invite_link(bool $sendEmail = false) | ||||||
|     { |     { | ||||||
|         try { |         try { | ||||||
|             $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)."); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             $member_emails = currentTeam()->members()->get()->pluck('email'); |             $member_emails = currentTeam()->members()->get()->pluck('email'); | ||||||
|             if ($member_emails->contains($this->email)) { |             if ($member_emails->contains($this->email)) { | ||||||
|                 return general_error_handler(that: $this, customErrorMessage: "$this->email is already a member of " . currentTeam()->name . "."); |                 return general_error_handler(that: $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(); | ||||||
| 
 | 
 | ||||||
|             $invitation = TeamInvitation::whereEmail($this->email); |             if (is_null($user)) { | ||||||
| 
 |                 $password = Str::password(); | ||||||
|             if ($invitation->exists()) { |                 $user = User::create([ | ||||||
|                 $created_at = $invitation->first()->created_at; |                     'name' => Str::of($this->email)->before('@'), | ||||||
|                 $diff = $created_at->diffInMinutes(now()); |                     'email' => $this->email, | ||||||
|                 if ($diff <= config('constants.invitation.link.expiration')) { |                     'password' => Hash::make($password), | ||||||
|                     return general_error_handler(that: $this, customErrorMessage: "Invitation already sent to $this->email and waiting for action."); |                     '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 general_error_handler(that: $this, customErrorMessage: "Pending invitation already exists for $this->email."); | ||||||
|                 } else { |                 } else { | ||||||
|                     $invitation->delete(); |                     $invitation->delete(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             TeamInvitation::firstOrCreate([ |             $invitation = TeamInvitation::firstOrCreate([ | ||||||
|                 'team_id' => currentTeam()->id, |                 'team_id' => currentTeam()->id, | ||||||
|                 'uuid' => $uuid, |                 'uuid' => $uuid, | ||||||
|                 'email' => $this->email, |                 'email' => $this->email, | ||||||
|                 'role' => $this->role, |                 'role' => $this->role, | ||||||
|                 'link' => $link, |                 'link' => $link, | ||||||
|                 'via' => $isEmail ? 'email' : 'link', |                 'via' => $sendEmail ? 'email' : 'link', | ||||||
|             ]); |             ]); | ||||||
|             if ($isEmail) { |             if ($sendEmail) { | ||||||
|                 $user->first()->notify(new InvitationLink); |                 $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->emit('success', 'Invitation sent via email successfully.'); |                 $this->emit('success', 'Invitation sent via email successfully.'); | ||||||
|  |                 $this->emit('refreshInvitations'); | ||||||
|  |                 return; | ||||||
|             } else { |             } else { | ||||||
|                 $this->emit('success', 'Invitation link generated.'); |                 $this->emit('success', 'Invitation link generated.'); | ||||||
|             } |  | ||||||
|                 $this->emit('refreshInvitations'); |                 $this->emit('refreshInvitations'); | ||||||
|  |             } | ||||||
|         } catch (\Throwable $e) { |         } catch (\Throwable $e) { | ||||||
|             $error_message = $e->getMessage(); |             $error_message = $e->getMessage(); | ||||||
|             if ($e->getCode() === '23505') { |             if ($e->getCode() === '23505') { | ||||||
| @ -75,9 +94,4 @@ class InviteLink extends Component | |||||||
|             return general_error_handler(err: $e, that: $this, customErrorMessage: $error_message); |             return general_error_handler(err: $e, that: $this, customErrorMessage: $error_message); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     public function viaLink() |  | ||||||
|     { |  | ||||||
|         $this->generate_invite_link(); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| namespace App\Http\Livewire\Team; | namespace App\Http\Livewire\Team; | ||||||
| 
 | 
 | ||||||
| use App\Models\User; | use App\Models\User; | ||||||
|  | use Illuminate\Support\Facades\Cache; | ||||||
| use Livewire\Component; | use Livewire\Component; | ||||||
| 
 | 
 | ||||||
| class Member extends Component | class Member extends Component | ||||||
| @ -24,6 +25,10 @@ class Member extends Component | |||||||
|     public function remove() |     public function remove() | ||||||
|     { |     { | ||||||
|         $this->member->teams()->detach(currentTeam()); |         $this->member->teams()->detach(currentTeam()); | ||||||
|  |         Cache::forget("team:{$this->member->id}"); | ||||||
|  |         Cache::remember('team:' . $this->member->id, 3600, function() { | ||||||
|  |             return $this->member->teams()->first(); | ||||||
|  |         }); | ||||||
|         $this->emit('reloadWindow'); |         $this->emit('reloadWindow'); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ use App\Jobs\SendConfirmationForWaitlistJob; | |||||||
| use App\Models\User; | use App\Models\User; | ||||||
| use App\Models\Waitlist; | use App\Models\Waitlist; | ||||||
| use Livewire\Component; | use Livewire\Component; | ||||||
| use Str; | use Illuminate\Support\Str; | ||||||
| 
 | 
 | ||||||
| class Index extends Component | class Index extends Component | ||||||
| { | { | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ namespace App\Http\Middleware; | |||||||
| use Closure; | use Closure; | ||||||
| use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||||
| use Symfony\Component\HttpFoundation\Response; | use Symfony\Component\HttpFoundation\Response; | ||||||
|  | use Illuminate\Support\Str; | ||||||
| 
 | 
 | ||||||
| class IsBoardingFlow | class IsBoardingFlow | ||||||
| { | { | ||||||
| @ -17,6 +18,9 @@ class IsBoardingFlow | |||||||
|     { |     { | ||||||
|         // ray()->showQueries()->color('orange');
 |         // ray()->showQueries()->color('orange');
 | ||||||
|         if (showBoarding() && !in_array($request->path(), allowedPathsForBoardingAccounts())) { |         if (showBoarding() && !in_array($request->path(), allowedPathsForBoardingAccounts())) { | ||||||
|  |             if (Str::startsWith($request->path(), 'invitations')) { | ||||||
|  |                 return $next($request); | ||||||
|  |             } | ||||||
|             return redirect('boarding'); |             return redirect('boarding'); | ||||||
|         } |         } | ||||||
|         return $next($request); |         return $next($request); | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ namespace App\Http\Middleware; | |||||||
| use Closure; | use Closure; | ||||||
| use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||||
| use Symfony\Component\HttpFoundation\Response; | use Symfony\Component\HttpFoundation\Response; | ||||||
|  | use Illuminate\Support\Str; | ||||||
| 
 | 
 | ||||||
| class IsSubscriptionValid | class IsSubscriptionValid | ||||||
| { | { | ||||||
| @ -31,6 +32,9 @@ class IsSubscriptionValid | |||||||
|         if (!isSubscriptionActive() && !isSubscriptionOnGracePeriod()) { |         if (!isSubscriptionActive() && !isSubscriptionOnGracePeriod()) { | ||||||
|             // ray('SubscriptionValid Middleware');
 |             // ray('SubscriptionValid Middleware');
 | ||||||
|             if (!in_array($request->path(), allowedPathsForUnsubscribedAccounts())) { |             if (!in_array($request->path(), allowedPathsForUnsubscribedAccounts())) { | ||||||
|  |                 if (Str::startsWith($request->path(), 'invitations')) { | ||||||
|  |                     return $next($request); | ||||||
|  |                 } | ||||||
|                 return redirect('subscription'); |                 return redirect('subscription'); | ||||||
|             } else { |             } else { | ||||||
|                 return $next($request); |                 return $next($request); | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| 
 | 
 | ||||||
| namespace App\Jobs; | namespace App\Jobs; | ||||||
| 
 | 
 | ||||||
|  | use App\Models\TeamInvitation; | ||||||
| use App\Models\Waitlist; | use App\Models\Waitlist; | ||||||
| use Illuminate\Bus\Queueable; | use Illuminate\Bus\Queueable; | ||||||
| use Illuminate\Contracts\Queue\ShouldBeEncrypted; | use Illuminate\Contracts\Queue\ShouldBeEncrypted; | ||||||
| @ -32,7 +33,12 @@ class CleanupInstanceStuffsJob implements ShouldQueue, ShouldBeUnique, ShouldBeE | |||||||
|         } catch (\Throwable $e) { |         } catch (\Throwable $e) { | ||||||
|             send_internal_notification('CleanupInstanceStuffsJob failed with error: ' . $e->getMessage()); |             send_internal_notification('CleanupInstanceStuffsJob failed with error: ' . $e->getMessage()); | ||||||
|             ray($e->getMessage()); |             ray($e->getMessage()); | ||||||
|             throw $e; |         } | ||||||
|  |         try { | ||||||
|  |             $this->cleanup_invitation_link(); | ||||||
|  |         } catch (\Throwable $e) { | ||||||
|  |             send_internal_notification('CleanupInstanceStuffsJob failed with error: ' . $e->getMessage()); | ||||||
|  |             ray($e->getMessage()); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -43,4 +49,11 @@ class CleanupInstanceStuffsJob implements ShouldQueue, ShouldBeUnique, ShouldBeE | |||||||
|             $item->delete(); |             $item->delete(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |     private function cleanup_invitation_link() | ||||||
|  |     { | ||||||
|  |         $invitation = TeamInvitation::all(); | ||||||
|  |         foreach ($invitation as $item) { | ||||||
|  |             $item->isValid(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ use Illuminate\Foundation\Bus\Dispatchable; | |||||||
| use Illuminate\Queue\InteractsWithQueue; | use Illuminate\Queue\InteractsWithQueue; | ||||||
| use Illuminate\Queue\Middleware\WithoutOverlapping; | use Illuminate\Queue\Middleware\WithoutOverlapping; | ||||||
| use Illuminate\Queue\SerializesModels; | use Illuminate\Queue\SerializesModels; | ||||||
| use Str; | use Illuminate\Support\Str; | ||||||
| 
 | 
 | ||||||
| class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted | class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted | ||||||
| { | { | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ use Illuminate\Foundation\Bus\Dispatchable; | |||||||
| use Illuminate\Queue\InteractsWithQueue; | use Illuminate\Queue\InteractsWithQueue; | ||||||
| use Illuminate\Queue\SerializesModels; | use Illuminate\Queue\SerializesModels; | ||||||
| use Illuminate\Support\Facades\Http; | use Illuminate\Support\Facades\Http; | ||||||
| use Str; | use Illuminate\Support\Str; | ||||||
| 
 | 
 | ||||||
| class SendMessageToTelegramJob implements ShouldQueue, ShouldBeEncrypted | class SendMessageToTelegramJob implements ShouldQueue, ShouldBeEncrypted | ||||||
| { | { | ||||||
|  | |||||||
| @ -19,4 +19,13 @@ class TeamInvitation extends Model | |||||||
|     { |     { | ||||||
|         return $this->belongsTo(Team::class); |         return $this->belongsTo(Team::class); | ||||||
|     } |     } | ||||||
|  |     public function isValid() { | ||||||
|  |         $createdAt = $this->created_at; | ||||||
|  |         $diff = $createdAt->diffInMinutes(now()); | ||||||
|  |         if ($diff <= config('constants.invitation.link.expiration')) { | ||||||
|  |             return true; | ||||||
|  |         } else { | ||||||
|  |             $this->delete(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -4,10 +4,10 @@ namespace App\Models; | |||||||
| 
 | 
 | ||||||
| use App\Notifications\Channels\SendsEmail; | use App\Notifications\Channels\SendsEmail; | ||||||
| use App\Notifications\TransactionalEmails\ResetPassword as TransactionalEmailsResetPassword; | use App\Notifications\TransactionalEmails\ResetPassword as TransactionalEmailsResetPassword; | ||||||
| use Cache; |  | ||||||
| use Illuminate\Database\Eloquent\Factories\HasFactory; | use Illuminate\Database\Eloquent\Factories\HasFactory; | ||||||
| use Illuminate\Foundation\Auth\User as Authenticatable; | use Illuminate\Foundation\Auth\User as Authenticatable; | ||||||
| use Illuminate\Notifications\Notifiable; | use Illuminate\Notifications\Notifiable; | ||||||
|  | use Illuminate\Support\Facades\Cache; | ||||||
| use Laravel\Fortify\TwoFactorAuthenticatable; | use Laravel\Fortify\TwoFactorAuthenticatable; | ||||||
| use Laravel\Sanctum\HasApiTokens; | use Laravel\Sanctum\HasApiTokens; | ||||||
| 
 | 
 | ||||||
| @ -61,7 +61,7 @@ class User extends Authenticatable implements SendsEmail | |||||||
| 
 | 
 | ||||||
|     public function isAdmin() |     public function isAdmin() | ||||||
|     { |     { | ||||||
|         return $this->pivot->role === 'admin' || $this->pivot->role === 'owner'; |         return data_get($this->pivot,'role') === 'admin' || data_get($this->pivot,'role') === 'owner'; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function isAdminFromSession() |     public function isAdminFromSession() | ||||||
| @ -78,7 +78,8 @@ class User extends Authenticatable implements SendsEmail | |||||||
|         if ($is_part_of_root_team && $is_admin_of_root_team) { |         if ($is_part_of_root_team && $is_admin_of_root_team) { | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|         $role = $teams->where('id', session('currentTeam')->id)->first()->pivot->role; |         $team = $teams->where('id', session('currentTeam')->id)->first(); | ||||||
|  |         $role = data_get($team,'pivot.role'); | ||||||
|         return $role === 'admin' || $role === 'owner'; |         return $role === 'admin' || $role === 'owner'; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ use DanHarrin\LivewireRateLimiting\Exceptions\TooManyRequestsException; | |||||||
| use Illuminate\Database\QueryException; | use Illuminate\Database\QueryException; | ||||||
| use Illuminate\Mail\Message; | use Illuminate\Mail\Message; | ||||||
| use Illuminate\Notifications\Messages\MailMessage; | use Illuminate\Notifications\Messages\MailMessage; | ||||||
|  | use Illuminate\Support\Facades\Cache; | ||||||
| use Illuminate\Support\Facades\Http; | use Illuminate\Support\Facades\Http; | ||||||
| use Illuminate\Support\Facades\Mail; | use Illuminate\Support\Facades\Mail; | ||||||
| use Illuminate\Support\Facades\Route; | use Illuminate\Support\Facades\Route; | ||||||
|  | |||||||
| @ -56,7 +56,7 @@ function isSubscriptionActive() | |||||||
|     } |     } | ||||||
|     $subscription = $team?->subscription; |     $subscription = $team?->subscription; | ||||||
| 
 | 
 | ||||||
|     if (!$subscription) { |     if (is_null($subscription)) { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|     if (isLemon()) { |     if (isLemon()) { | ||||||
|  | |||||||
| @ -0,0 +1,29 @@ | |||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | use Illuminate\Database\Migrations\Migration; | ||||||
|  | use Illuminate\Database\Schema\Blueprint; | ||||||
|  | use Illuminate\Support\Facades\Schema; | ||||||
|  | 
 | ||||||
|  | return new class extends Migration | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Run the migrations. | ||||||
|  |      */ | ||||||
|  |     public function up(): void | ||||||
|  |     { | ||||||
|  |         Schema::table('team_invitations', function (Blueprint $table) { | ||||||
|  |             $table->text('link')->change(); | ||||||
|  | 
 | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Reverse the migrations. | ||||||
|  |      */ | ||||||
|  |     public function down(): void | ||||||
|  |     { | ||||||
|  |         Schema::table('team_invitations', function (Blueprint $table) { | ||||||
|  |             $table->string('link')->change(); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | }; | ||||||
| @ -6,6 +6,5 @@ Please [click here]({{ $invitation_link }}) to accept the invitation. | |||||||
| 
 | 
 | ||||||
| If you have any questions, please contact the team owner.<br><br> | If you have any questions, please contact the team owner.<br><br> | ||||||
| 
 | 
 | ||||||
| If it was not you who requested this invitation, please ignore this email, or instantly revoke the invitation by clicking [here]({{ $invitation_link }}/revoke). | If it was not you who requested this invitation, please ignore this email. | ||||||
| 
 |  | ||||||
| </x-emails.layout> | </x-emails.layout> | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| <x-layout-subscription> | <x-layout-subscription> | ||||||
|     @if ($settings->is_resale_license_active) |     @if ($settings->is_resale_license_active) | ||||||
|  |         @if (auth()->user()->isAdminFromSession()) | ||||||
|             <div class="flex justify-center mx-10"> |             <div class="flex justify-center mx-10"> | ||||||
|                 <div x-data> |                 <div x-data> | ||||||
|                     <div class="flex gap-2"> |                     <div class="flex gap-2"> | ||||||
| @ -17,7 +18,8 @@ | |||||||
|                                 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" |                                 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" | ||||||
|                                     d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /> |                                     d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /> | ||||||
|                             </svg> |                             </svg> | ||||||
|                         <span>Something went wrong with your subscription. Please try again or contact support.</span> |                             <span>Something went wrong with your subscription. Please try again or contact | ||||||
|  |                                 support.</span> | ||||||
|                         </div> |                         </div> | ||||||
|                     @endif |                     @endif | ||||||
|                     @if (config('subscription.provider') !== null) |                     @if (config('subscription.provider') !== null) | ||||||
| @ -26,6 +28,19 @@ | |||||||
|                 </div> |                 </div> | ||||||
|             </div> |             </div> | ||||||
|         @else |         @else | ||||||
|         <div class="px-10">Resale license is not active. Please contact your instance admin.</div> |             <div class="flex flex-col justify-center mx-10"> | ||||||
|  |                 <div class="flex gap-2"> | ||||||
|  |                     <h1>Subscription</h1> | ||||||
|  |                     <livewire:switch-team /> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="flex items-center pb-8"> | ||||||
|  |                     <span>Currently active team: <span | ||||||
|  |                             class="text-warning">{{ session('currentTeam.name') }}</span></span> | ||||||
|  |                 </div> | ||||||
|  |                 <div>You are not an admin or have been removed from this team. If this does not make sense, please <span class="text-white underline cursor-pointer" wire:click="help" onclick="help.showModal()">contact us</span>.</div> | ||||||
|  |             </div> | ||||||
|  |         @endif | ||||||
|  |     @else | ||||||
|  |         <div class="px-10" >Resale license is not active. Please contact your instance admin.</div> | ||||||
|     @endif |     @endif | ||||||
| </x-layout-subscription> | </x-layout-subscription> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user