redirect(); } /** * Callback received from Discord */ public function callback(): RedirectResponse { $discordUser = Socialite::driver('discord')->user(); $user = User::where('discord_id', $discordUser->id)->first(); if (! $user) { // link by email if it already exists $user = User::where('email', $discordUser->email)->first(); if ($user) { $user->update([ 'discord_id' => $discordUser->id, 'discord_name' => $discordUser->nickname ?? $discordUser->name, 'discord_avatar' => $discordUser->avatar, ]); } else { // Create new user $user = User::create([ 'name' => $discordUser->name, 'email' => $discordUser->email, 'discord_id' => $discordUser->id, 'discord_name' => $discordUser->nickname ?? $discordUser->name, 'discord_avatar' => $discordUser->avatar, 'password' => bcrypt(Str::random(40)), ]); } } $this->checkDiscordRoles($user); Auth::login($user, true); return redirect()->route('home.index'); } /** * Check Discord Roles if user is Patreon member */ private function checkDiscordRoles(User $user): void { // Should not ever happen if (!$user->discord_id) { return; } $guildId = config('discord.guild_id'); $response = Http::withToken(config('discord.discord_bot_token'), 'Bot') ->timeout(5) ->get("https://discord.com/api/v10/guilds/{$guildId}/members/{$user->discord_id}"); // User is not in the guild if ($response->status() === 404) { $user->update([ 'is_patreon' => false, ]); return; } // Something else failed if ($response->failed()) { Log::warning('Discord role check failed', [ 'user_id' => $user->id, 'discord_id' => $user->discord_id, 'status' => $response->status(), 'body' => $response->body(), ]); return; } $discordRoles = $response->json('roles', []); $patreonRoles = config('discord.patreon_roles', []); $isPatreon = false; foreach($patreonRoles as $patreonRole) { if (in_array($patreonRole, $discordRoles, true)) { $isPatreon = true; break; } } // Only update if something actually changed if ($user->is_patreon !== $isPatreon) { $user->update([ 'is_patreon' => $isPatreon, ]); } } }