]> git.localhorst.tv Git - alttp.git/blob - app/Http/Controllers/DiscordController.php
protocol chat bot messages
[alttp.git] / app / Http / Controllers / DiscordController.php
1 <?php
2
3 namespace App\Http\Controllers;
4
5 use App\Models\User;
6 use App\Providers\RouteServiceProvider;
7 use Illuminate\Http\Request;
8 use Illuminate\Support\Facades\Auth;
9 use Illuminate\Support\Facades\Http;
10
11 class DiscordController extends \Jakyeru\Larascord\Http\Controllers\DiscordController
12 {
13
14         /**
15          * Handles the Discord OAuth2 login.
16          *
17          * @param Request $request
18          * @return \Illuminate\Http\JsonResponse
19          */
20         public function handle(Request $request)//: \Illuminate\Http\JsonResponse
21         {
22                 // Checking if the authorization code is present in the request.
23                 if ($request->missing('code')) {
24                         if (env('APP_DEBUG')) {
25                                 return response()->json([
26                                         'larascord_message' => config('larascord.error_messages.missing_code', 'The authorization code is missing.'),
27                                         'code' => 400
28                                 ]);
29                         } else {
30                                 return redirect('/')->with('error', config('larascord.error_messages.missing_code', 'The authorization code is missing.'));
31                         }
32                 }
33
34                 // Getting the access_token from the Discord API.
35                 try {
36                         $accessToken = $this->getDiscordAccessToken($request->get('code'));
37                 } catch (\Exception $e) {
38                         if (env('APP_DEBUG')) {
39                                 return response()->json([
40                                         'larascord_message' => config('larascord.error_messages.invalid_code', 'The authorization code is invalid.'),
41                                         'message' => $e->getMessage(),
42                                         'code' => $e->getCode()
43                                 ]);
44                         } else {
45                                 return redirect('/')->with('error', config('larascord.error_messages.invalid_code', 'The authorization code is invalid.'));
46                         }
47                 }
48
49                 // Using the access_token to get the user's Discord ID.
50                 try {
51                         $user = $this->getDiscordUser($accessToken->access_token);
52                 } catch (\Exception $e) {
53                         if (env('APP_DEBUG')) {
54                                 return response()->json([
55                                         'larascord_message' => config('larascord.error_messages.authorization_failed', 'The authorization failed.'),
56                                         'message' => $e->getMessage(),
57                                         'code' => $e->getCode()
58                                 ]);
59                         } else {
60                                 return redirect('/')->with('error', config('larascord.error_messages.authorization_failed', 'The authorization failed.'));
61                         }
62                 }
63
64                 // Making sure the current logged-in user's ID is matching the ID retrieved from the Discord API.
65                 if (Auth::check() && (Auth::id() !== $user->id)) {
66                         Auth::logout();
67                         return redirect('/')->with('error', config('larascord.error_messages.invalid_user', 'The user ID doesn\'t match the logged-in user.'));
68                 }
69
70                 // Confirming the session in case the user was redirected from the password.confirm middleware.
71                 if (Auth::check()) {
72                         $request->session()->put('auth.password_confirmed_at', time());
73                 }
74
75                 // Trying to create or update the user in the database.
76                 try {
77                         $user = $this->createOrUpdateUser($user, $accessToken->refresh_token);
78                 } catch (\Exception $e) {
79                         if (env('APP_DEBUG')) {
80                                 return response()->json([
81                                         'larascord_message' => config('larascord.error_messages.database_error', 'There was an error while trying to create or update the user.'),
82                                         'message' => $e->getMessage(),
83                                         'code' => $e->getCode()
84                                 ]);
85                         } else {
86                                 return redirect('/')->with('error', config('larascord.error_messages.database_error', 'There was an error while trying to create or update the user.'));
87                         }
88                 }
89
90                 // Authenticating the user if the user is not logged in.
91                 if (!Auth::check()) {
92                         Auth::login($user);
93                 }
94
95                 // Redirecting the user to the intended page or to the home page.
96                 return redirect()->intended(RouteServiceProvider::HOME);
97         }
98
99         /**
100          * Handles the Discord OAuth2 callback.
101          *
102          * @param string $code
103          * @return object
104          * @throws \Illuminate\Http\Client\RequestException
105          */
106         private function getDiscordAccessToken(string $code): object
107         {
108                 $this->tokenData['code'] = $code;
109
110                 $response = Http::asForm()->post($this->tokenURL, $this->tokenData);
111
112                 $response->throw();
113
114                 return json_decode($response->body());
115         }
116
117         /**
118          * Handles the Discord OAuth2 login.
119          *
120          * @param string $access_token
121          * @return object
122          * @throws \Illuminate\Http\Client\RequestException
123          */
124         private function getDiscordUser(string $access_token): object
125         {
126                 $response = Http::withToken($access_token)->get($this->apiURLBase);
127
128                 $response->throw();
129
130                 return json_decode($response->body());
131         }
132
133         /**
134          * Handles the creation or update of the user.
135          *
136          * @param object $user
137          * @param string $refresh_token
138          * @return User
139          * @throws \Exception
140          */
141         private function createOrUpdateUser(object $user, string $refresh_token): User
142         {
143                 return User::updateOrCreate(
144                         [
145                                 'id' => $user->id,
146                         ],
147                         [
148                                 'username' => $user->username,
149                                 'discord_nickname' => isset($user->global_name) ? $user->global_name : NULL,
150                                 'discriminator' => $user->discriminator,
151                                 'email' => isset($user->email) ? $user->email : NULL,
152                                 'avatar' => $user->avatar ?: NULL,
153                                 'verified' => isset($user->verified) ? $user->verified : 0,
154                                 'locale' => $user->locale,
155                                 'mfa_enabled' => $user->mfa_enabled,
156                                 'refresh_token' => $refresh_token
157                         ]
158                 );
159         }
160
161 }