feat: add email verification for cloud
This commit is contained in:
@@ -58,6 +58,11 @@ class CreateNewUser implements CreatesNewUsers
|
||||
'password' => Hash::make($input['password']),
|
||||
]);
|
||||
$team = $user->teams()->first();
|
||||
if (isCloud()) {
|
||||
$user->sendVerificationEmail();
|
||||
} else {
|
||||
$user->markEmailAsVerified();
|
||||
}
|
||||
}
|
||||
// Set session variable
|
||||
session(['currentTeam' => $user->currentTeam = $team]);
|
||||
|
||||
@@ -38,8 +38,7 @@ class Kernel extends HttpKernel
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\CheckForcePasswordReset::class,
|
||||
\App\Http\Middleware\IsSubscriptionValid::class,
|
||||
\App\Http\Middleware\IsBoardingFlow::class,
|
||||
\App\Http\Middleware\DecideWhatToDoWithUser::class,
|
||||
|
||||
],
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@ namespace App\Http\Livewire;
|
||||
use App\Actions\Server\UpdateCoolify;
|
||||
use App\Models\InstanceSettings;
|
||||
use Livewire\Component;
|
||||
use Masmerise\Toaster\Toaster;
|
||||
use DanHarrin\LivewireRateLimiting\WithRateLimiting;
|
||||
|
||||
class Upgrade extends Component
|
||||
{
|
||||
use WithRateLimiting;
|
||||
public bool $showProgress = false;
|
||||
public bool $isUpgradeAvailable = false;
|
||||
public string $latestVersion = '';
|
||||
@@ -31,6 +32,7 @@ class Upgrade extends Component
|
||||
public function upgrade()
|
||||
{
|
||||
try {
|
||||
$this->rateLimit(1, 30);
|
||||
if ($this->showProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
26
app/Http/Livewire/VerifyEmail.php
Normal file
26
app/Http/Livewire/VerifyEmail.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use DanHarrin\LivewireRateLimiting\WithRateLimiting;
|
||||
|
||||
class VerifyEmail extends Component
|
||||
{
|
||||
use WithRateLimiting;
|
||||
public function again() {
|
||||
try {
|
||||
$this->rateLimit(1, 300);
|
||||
auth()->user()->sendVerificationEmail();
|
||||
$this->emit('success', 'Email verification link sent!');
|
||||
|
||||
} catch(\Exception $e) {
|
||||
ray($e);
|
||||
return handleError($e,$this);
|
||||
}
|
||||
}
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.verify-email');
|
||||
}
|
||||
}
|
||||
45
app/Http/Middleware/DecideWhatToDoWithUser.php
Normal file
45
app/Http/Middleware/DecideWhatToDoWithUser.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DecideWhatToDoWithUser
|
||||
{
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
if (!auth()->user() || !isCloud()) {
|
||||
return $next($request);
|
||||
}
|
||||
if (!auth()->user()->hasVerifiedEmail()) {
|
||||
if ($request->path() === 'verify' || in_array($request->path(), allowedPathsForInvalidAccounts()) || $request->routeIs('verify.verify')) {
|
||||
return $next($request);
|
||||
}
|
||||
return redirect('/verify');
|
||||
}
|
||||
if (!isSubscriptionActive() && !isSubscriptionOnGracePeriod()) {
|
||||
if (!in_array($request->path(), allowedPathsForUnsubscribedAccounts())) {
|
||||
if (Str::startsWith($request->path(), 'invitations')) {
|
||||
return $next($request);
|
||||
}
|
||||
return redirect('subscription');
|
||||
}
|
||||
}
|
||||
if (showBoarding() && !in_array($request->path(), allowedPathsForBoardingAccounts())) {
|
||||
if (Str::startsWith($request->path(), 'invitations')) {
|
||||
return $next($request);
|
||||
}
|
||||
return redirect('boarding');
|
||||
}
|
||||
if (auth()->user()->hasVerifiedEmail() && $request->path() === 'verify') {
|
||||
return redirect('/');
|
||||
}
|
||||
if (isSubscriptionActive() && $request->path() === 'subscription') {
|
||||
return redirect('/');
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ class Subscription extends Model
|
||||
}
|
||||
if (isStripe()) {
|
||||
if (!$this->stripe_plan_id) {
|
||||
return 'zero';
|
||||
return 'zero';
|
||||
}
|
||||
$subscription = Subscription::where('id', $this->id)->first();
|
||||
if (!$subscription) {
|
||||
|
||||
@@ -6,8 +6,12 @@ use App\Notifications\Channels\SendsEmail;
|
||||
use App\Notifications\TransactionalEmails\ResetPassword as TransactionalEmailsResetPassword;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Laravel\Fortify\TwoFactorAuthenticatable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
@@ -54,6 +58,23 @@ class User extends Authenticatable implements SendsEmail
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function sendVerificationEmail()
|
||||
{
|
||||
$mail = new MailMessage();
|
||||
$url = Url::temporarySignedRoute(
|
||||
'verify.verify',
|
||||
Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),
|
||||
[
|
||||
'id' => $this->getKey(),
|
||||
'hash' => sha1($this->getEmailForVerification()),
|
||||
]
|
||||
);
|
||||
$mail->view('emails.email-verification', [
|
||||
'url' => $url,
|
||||
]);
|
||||
$mail->subject('Coolify Cloud: Verify your email.');
|
||||
send_user_an_email($mail, $this->email);
|
||||
}
|
||||
public function sendPasswordResetNotification($token): void
|
||||
{
|
||||
$this->notify(new TransactionalEmailsResetPassword($token));
|
||||
@@ -61,7 +82,7 @@ class User extends Authenticatable implements SendsEmail
|
||||
|
||||
public function isAdmin()
|
||||
{
|
||||
return data_get($this->pivot,'role') === 'admin' || data_get($this->pivot,'role') === 'owner';
|
||||
return data_get($this->pivot, 'role') === 'admin' || data_get($this->pivot, 'role') === 'owner';
|
||||
}
|
||||
|
||||
public function isAdminFromSession()
|
||||
@@ -79,7 +100,7 @@ class User extends Authenticatable implements SendsEmail
|
||||
return true;
|
||||
}
|
||||
$team = $teams->where('id', session('currentTeam')->id)->first();
|
||||
$role = data_get($team,'pivot.role');
|
||||
$role = data_get($team, 'pivot.role');
|
||||
return $role === 'admin' || $role === 'owner';
|
||||
}
|
||||
|
||||
@@ -96,7 +117,7 @@ class User extends Authenticatable implements SendsEmail
|
||||
|
||||
public function currentTeam()
|
||||
{
|
||||
return Cache::remember('team:' . auth()->user()->id, 3600, function() {
|
||||
return Cache::remember('team:' . auth()->user()->id, 3600, function () {
|
||||
return Team::find(session('currentTeam')->id);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user