chore:simplify connected account verifications

This commit is contained in:
hackerESQ
2024-10-22 21:24:04 -05:00
parent b6a123a90f
commit 5a04c33f13
9 changed files with 50 additions and 88 deletions
@@ -8,8 +8,8 @@ use App\Models\ConnectedAccount;
use Illuminate\Support\MessageBag;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Blade;
use Laravel\Socialite\Facades\Socialite;
use App\Models\ConnectedAccountVerification;
use App\Notifications\VerifyConnectedAccountNotification;
class ConnectedAccountController extends Controller
@@ -52,11 +52,16 @@ class ConnectedAccountController extends Controller
'token' => $providerUser->token,
'secret' => $providerUser->tokenSecret,
'refresh_token' => $providerUser->refreshToken,
'expires_at' => $providerUser->expiresIn
'expires_at' => $providerUser->expiresIn,
'verified_at' => false
]);
// already linked, let's go login
if ($connected_account->exists) {
// already linked and verified, let's go login!
if (
$connected_account->exists
&& !is_null($connected_account->verified_at)
) {
Auth::login($connected_account->user, true);
return redirect(route('dashboard'));
@@ -72,6 +77,7 @@ class ConnectedAccountController extends Controller
]);
$connected_account->user_id = $user->id;
$connected_account->verified_at = now();
$connected_account->save();
Auth::login($user, true);
@@ -80,16 +86,10 @@ class ConnectedAccountController extends Controller
}
// email exists already, send verification link
$verification = ConnectedAccountVerification::updateOrCreate([
'email' => $providerUser->email,
'provider' => $provider,
'verified_at' => null
], [
'provider_id' => $providerUser->id,
'connected_account' => $connected_account
]);
$connected_account->user_id = $user->id;
$connected_account->save();
$user->notify(new VerifyConnectedAccountNotification($verification->id));
$user->notify(new VerifyConnectedAccountNotification($connected_account->id));
return redirect(route('login'))
->with('status', __(
@@ -106,34 +106,30 @@ class ConnectedAccountController extends Controller
}
}
public function verify(string $verification_id)
public function verify(ConnectedAccount $connected_account)
{
$verification = ConnectedAccountVerification::findOrFail($verification_id);
if (!$verification->verified_at) {
if (!$connected_account->verified_at) {
// mark request as verified
$verification->verified_at = now();
$verification->save();
$connected_account->verified_at = now();
$connected_account->save();
// mark user as verified
$user = User::where('email', $verification->email)->firstOrFail();
$user->email_verified_at = now();
$user->save();
$connected_account->user->email_verified_at = now();
$connected_account->user->save();
// add connected account
$user->connectedAccounts()->create([
...$verification->connected_account,
...[
'provider' => $verification->provider,
'provider_id' => $verification->provider_id,
]
]);
Auth::login($user, true);
Auth::login($connected_account->user, true);
}
return redirect(route('dashboard'));
return redirect(route('dashboard'))->with('toast', json_encode([
'toast' => [
'title' => __('Your :provider account has been connected.', ['provider' => config("services.{$connected_account->provider}.name")]),
'description' => null,
'css' => 'alert-success',
'icon' => Blade::render("<x-mary-icon class='w-7 h-7' name='o-check-circle' />"),
'position' => 'toast-top toast-end',
'timeout' => '5000'
]
]));
}
}
@@ -24,11 +24,6 @@ class HoldingController extends Controller
->portfolio($portfolio->id)
->firstOrFail();
// if ($holding->quantity <= 0) {
// return redirect(route('portfolio.show', ['portfolio' => $portfolio->id]));
// }
return view('holding.show', compact(['portfolio', 'holding']));
}
}
@@ -1,29 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Model;
class ConnectedAccountVerification extends Model
{
use HasUuids;
protected $fillable = [
'provider',
'provider_id',
'email',
'connected_account'
];
protected function casts(): array
{
return [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'verified_at' => 'datetime',
'connected_account' => 'json'
];
}
}
@@ -2,11 +2,11 @@
namespace App\Notifications;
use App\Models\ConnectedAccountVerification;
use Illuminate\Bus\Queueable;
use App\Models\ConnectedAccount;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class VerifyConnectedAccountNotification extends Notification implements ShouldQueue
{
@@ -16,7 +16,7 @@ class VerifyConnectedAccountNotification extends Notification implements ShouldQ
* Create a new notification instance.
*/
public function __construct(
public string $verification_id
public string $connected_account_id
) { }
/**
@@ -34,10 +34,10 @@ class VerifyConnectedAccountNotification extends Notification implements ShouldQ
*/
public function toMail(object $notifiable): MailMessage
{
$verification = ConnectedAccountVerification::find($this->verification_id);
$provider = config("services.$verification->provider.name");
$connected_account = ConnectedAccount::find($this->connected_account_id);
$provider = config("services.$connected_account->provider.name");
$url = url()->signedRoute('oauth.verify_connected_account', ['verification_id' => $this->verification_id], now()->days($days = 7));
$url = url()->signedRoute('oauth.verify_connected_account', ['connected_account' => $this->connected_account_id], now()->days($days = 7));
return (new MailMessage)
->greeting('Welcome back!')
+9
View File
@@ -16,6 +16,7 @@ class AppLayout extends Component
<x-slot:body class="min-h-screen font-sans antialiased bg-base-200/50 dark:bg-base-200" x-data>
<div>
<x-partials.nav-bar />
<x-main with-nav full-width>
@@ -27,11 +28,19 @@ class AppLayout extends Component
</x-slot:sidebar>
<x-slot:content>
{{ $slot }}
</x-slot:content>
</x-main>
@if(session('toast'))
<script lang="text/javascript">
window.addEventListener('DOMContentLoaded', function () {
window.toast(JSON.parse(@json(session('toast'))))
});
</script>
@endif
<x-toast />
</div>
@@ -25,21 +25,12 @@ return new class extends Migration
$table->string('secret')->nullable(); // OAuth1
$table->string('refresh_token', 1000)->nullable(); // OAuth2
$table->dateTime('expires_at')->nullable(); // OAuth2
$table->dateTime('verified_at')->nullable(); // OAuth2
$table->timestamps();
$table->index(['user_id', 'id']);
$table->index(['provider', 'provider_id']);
});
Schema::create('connected_account_verifications', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('email');
$table->string('provider');
$table->string('provider_id');
$table->json('connected_account');
$table->timestamps();
$table->timestamp('verified_at')->nullable();
});
}
/**
@@ -48,8 +39,6 @@ return new class extends Migration
public function down(): void
{
Schema::dropIfExists('connected_account_verifications');
Schema::dropIfExists('connected_accounts');
}
};
+1
View File
@@ -52,6 +52,7 @@
"Token Name": "Token Name",
"Permissions": "Permissions",
"Profile Information": "Profile Information",
"Your :provider account has been connected.": "Your :provider account has been connected.",
"Account already exists. Check your email to connect your :provider account.": "Account already exists. Check your email to connect your :provider account.",
"Could not login using :provider. Try again later.": "Could not login using :provider. Try again later.",
"Update your account\\'s profile information and email address.": "Update your account\\'s profile information and email address.",
+1
View File
@@ -52,6 +52,7 @@
"Token Name": "Nombre del Token",
"Permissions": "Permisos",
"Profile Information": "Información del Perfil",
"Your :provider account has been connected.": "Su cuenta :provider ha sido conectada.",
"Account already exists. Check your email to connect your :provider account.": "La cuenta ya existe. Revisa tu correo electrónico para conectar tu cuenta :provider.",
"Could not login using :provider. Try again later.": "No se pudo iniciar sesión con :provider. Inténtalo nuevamente más tarde.",
"Update your account's profile information and email address.": "Actualiza la información de perfil y la dirección de correo electrónico de tu cuenta.",
+1 -1
View File
@@ -44,7 +44,7 @@ Route::get('/terms', [TermsOfServiceController::class, 'show'])->name('terms.sho
Route::get('/privacy', [PrivacyPolicyController::class, 'show'])->name('policy.show');
// social login routes
Route::get('auth/verify/{verification_id}', [ConnectedAccountController::class, 'verify'])->name('oauth.verify_connected_account');
Route::get('auth/verify/{connected_account}', [ConnectedAccountController::class, 'verify'])->name('oauth.verify_connected_account');
Route::get('auth/{provider}', [ConnectedAccountController::class, 'redirectToProvider'])->name('oauth.redirect');
Route::get('auth/{provider}/callback', [ConnectedAccountController::class, 'handleProviderCallback']);