diff --git a/app/Http/Controllers/Auth/DiscordController.php b/app/Http/Controllers/Auth/DiscordController.php index 8c60ed7..cea1910 100755 --- a/app/Http/Controllers/Auth/DiscordController.php +++ b/app/Http/Controllers/Auth/DiscordController.php @@ -26,8 +26,10 @@ use App\Http\Controllers\Controller; use App\User; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Crypt; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; use Laravel\Socialite\Facades\Socialite; +use Laravel\Socialite\Two\InvalidStateException; class DiscordController extends Controller { @@ -41,7 +43,20 @@ class DiscordController extends Controller public function discordCallback() { - $discordUser = Socialite::driver('discord')->user(); + + try { + + $discordUser = Socialite::driver('discord')->user(); + + } catch (InvalidStateException $stateException) { + Log::warning('Invalid state for social authentication: ', [ + 'message' => $stateException->getMessage(), + 'ua' => request()->userAgent(), + 'ip' => request()->ip() + ]); + return redirect(route('discordRedirect')); + } + $appUser = User::where('email', $discordUser->getEmail())->first(); if ($appUser) { diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index f0b4bb6..27ed7d0 100755 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -45,8 +45,11 @@ use App\Traits\HandlesAccountDeletion; use App\Traits\ReceivesAccountTokens; use App\User; use Google2FA; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Http\Client\RequestException; +use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Routing\Redirector; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Log; @@ -248,6 +251,32 @@ class UserController extends Controller } + /** + * Sets a new password for the user. + * + * @param SetNewPasswordRequest $request + * @return Application|RedirectResponse|Redirector + */ + public function setPassword(SetNewPasswordRequest $request) { + + if (!Auth::user()->hasPassword()) { + + Auth::user()->password = Hash::make($request->newpass); + Auth::user()->save(); + + Auth::logout(); + $request->session()->invalidate(); + $request->session()->regenerateToken(); + + return redirect(route('login')); + } + + return redirect() + ->back() + ->with('error', __('Your account already has a password.')); + } + + /** * Sets a user's password and removes their discord information from storage * @@ -255,35 +284,34 @@ class UserController extends Controller * @param SetNewPasswordRequest $request * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ - public function setUnlinkPassword(SetNewPasswordRequest $request, DiscordService $discordService) + public function unlinkDiscordAccount(Request $request, DiscordService $discordService) { - Auth::user()->password = Hash::make($request->newpass); - Auth::user()->save(); + if ($request->user()->hasPassword()) { + try { + $discordService->revokeAccountTokens(Auth::user()); + Log::warning('Revoking social account tokens, user initiated', [ + 'user' => Auth::user()->email + ]); + } catch (RequestException $requestException) { - try { - $discordService->revokeAccountTokens(Auth::user()); - Log::warning('Revoking social account tokens, user initiated', [ - 'user' => Auth::user()->email - ]); - } catch (RequestException $requestException) { + if ($requestException->getCode() == 401) { + return redirect(route('discordRedirect')); + } - if ($requestException->getCode() == 401) { - return redirect(route('discordRedirect')); + Log::error('Error while trying to revoke Discord credentials', [$requestException->getMessage()]); + return redirect() + ->back() + ->with('error', __('An unknown error ocurred. Please try again later.')); } - Log::error('Error while trying to revoke Discord credentials', [$requestException->getMessage()]); - return redirect() - ->back() - ->with('error', __('An unknown error ocurred. Please try again later.')); + $request->session()->flash('success', __('Discord account unlinked successfully. Link it again by re-authorizing the app with the same account in the login screen, or through your account settings.')); + return redirect()->back(); } + return redirect() + ->back() + ->with('error', __('Please set a password for your account first before trying to unlink Discord.')); - Auth::logout(); - $request->session()->invalidate(); - $request->session()->regenerateToken(); - - $request->session()->flash('success', 'Discord account unlinked! You may now login with your Discord email and brand new password.'); - return redirect(route('login')); } diff --git a/app/Http/Requests/SetNewPasswordRequest.php b/app/Http/Requests/SetNewPasswordRequest.php index 9e41dc8..2baadc8 100644 --- a/app/Http/Requests/SetNewPasswordRequest.php +++ b/app/Http/Requests/SetNewPasswordRequest.php @@ -28,7 +28,7 @@ class SetNewPasswordRequest extends FormRequest public function rules() { return [ - 'newpass' => 'required|string|min:10|confirmed' + 'newpass' => 'required|string|min:10|confirmed', ]; } } diff --git a/app/User.php b/app/User.php index aa03134..c0c9210 100755 --- a/app/User.php +++ b/app/User.php @@ -190,4 +190,14 @@ class User extends Authenticatable implements MustVerifyEmail return !is_null($this->discord_token) && !is_null($this->discord_refresh_token); } + + /** + * Check if user has a password + * + * @return bool + */ + public function hasPassword(): bool { + return !is_null($this->password); + } + } diff --git a/public/img/small_logo_blurple_RGB.svg b/public/img/small_logo_blurple_RGB.svg new file mode 100644 index 0000000..1bc7f8f --- /dev/null +++ b/public/img/small_logo_blurple_RGB.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/views/dashboard/user/profile/useraccount.blade.php b/resources/views/dashboard/user/profile/useraccount.blade.php index a4f521a..62423c6 100755 --- a/resources/views/dashboard/user/profile/useraccount.blade.php +++ b/resources/views/dashboard/user/profile/useraccount.blade.php @@ -33,7 +33,7 @@
{{ __('Deleting your account is an irreversible process. The following data will be deleted (including personally identifiable data):') }}
{!! __('Your account is linked to Discord, which means you only need your Discord account credentials and two-factor code (if enabled) to sign in. If you would like to change your password, you will need to do so in your Discord account settings. Please read this article to learn more.', ['articleLink' => 'https://support.discord.com/hc/en-us/articles/218410947-I-forgot-my-Password-Where-can-I-set-a-new-one-']) !!}
- -{{ __('Alternatively, you can unlink your Discord account and set a password which you can use to sign in. Please note that any roles and/or privileges you may have been given as a result of this integration may be automatically removed until you link your Discord account again.') }}
+{!! __('Because your account is linked to one or more OAuth providers (such as Discord), there is no need for your account to use a password.', ['oAuthExplanationLink' => 'https://en.wikipedia.org/wiki/OAuth']) !!}
+{{ __('Because several sensitive actions on the app require you to confirm your password, you may define one below. This will also allow you to unlink your accounts and login with a password.') }}
{{__('Manage your connected external accounts here.')}}
+ + @if(Auth::user()->hasDiscordConnection()) +{{ __('Your account is currently connected to Discord.') }}
+ @if(!Auth::user()->hasPassword()) +{{ __("If you choose to disconnect your Discord account, we'll let Discord know by revoking your authorization. This means you will no longer be able to apply for positions that require a linked Discord account, and you may also lose any server privileges/roles that may have been granted through your linked account.") }}
+{{ __(" You'll be able to link your account again through this page or by signing in with Discord again, but remember that if you changed your Discord email address, you will no longer have access to your old account.") }}
+{{ __('Your Discord account is not connected. Connect your Discord account below in order to apply for positions that require it.') }}
+