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