diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 953abf6..9ebe74e 100755 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -30,11 +30,13 @@ use App\Http\Requests\ChangePasswordRequest; use App\Http\Requests\DeleteUserRequest; use App\Http\Requests\FlushSessionsRequest; use App\Http\Requests\Remove2FASecretRequest; +use App\Http\Requests\Reset2FASecretRequest; use App\Http\Requests\SearchPlayerRequest; use App\Http\Requests\UpdateUserRequest; use App\Notifications\ChangedPassword; use App\Notifications\EmailChanged; use App\Notifications\PasswordAdminResetNotification; +use App\Notifications\TwoFactorResetNotification; use App\Services\AccountSuspensionService; use App\Traits\DisablesFeatures; use App\Traits\HandlesAccountDeletion; @@ -446,6 +448,39 @@ class UserController extends Controller } + /** + * Remove the given user's two factor secret key + * + * @param Reset2FASecretRequest $request + * @param User $user + * @return \Illuminate\Http\RedirectResponse + */ + public function reset2FASecret(Reset2FASecretRequest $request, User $user) { + + if ($user->has2FA()) { + Log::warning('SECURITY: Disabling two factor authentication (admin initiated)', [ + 'initiator' => $request->user()->email, + 'target' => $user->email, + 'ip' => $request->ip(), + ]); + + $user->twofa_secret = null; + $user->password = null; + $user->save(); + + $user->notify(new TwoFactorResetNotification()); + + return redirect() + ->back() + ->with('success', __('Two factor removed & user notified.')); + } + + return redirect() + ->back() + ->with('error', 'This user does not have two-factor authentication enabled.'); + } + + /** * Demote the given user's privileges * diff --git a/app/Http/Requests/Remove2FASecretRequest.php b/app/Http/Requests/Remove2FASecretRequest.php index 136d283..ee9652b 100755 --- a/app/Http/Requests/Remove2FASecretRequest.php +++ b/app/Http/Requests/Remove2FASecretRequest.php @@ -44,7 +44,6 @@ class Remove2FASecretRequest extends FormRequest { return [ 'currentPassword' => 'required|current_password', - 'consent' => 'required|accepted', ]; } } diff --git a/app/Http/Requests/Reset2FASecretRequest.php b/app/Http/Requests/Reset2FASecretRequest.php new file mode 100644 index 0000000..ac416ca --- /dev/null +++ b/app/Http/Requests/Reset2FASecretRequest.php @@ -0,0 +1,20 @@ + 'required|current_password', + ]; + } + + public function authorize(): bool + { + return true; + } +} diff --git a/app/Notifications/TwoFactorResetNotification.php b/app/Notifications/TwoFactorResetNotification.php new file mode 100644 index 0000000..78fcd1c --- /dev/null +++ b/app/Notifications/TwoFactorResetNotification.php @@ -0,0 +1,35 @@ +from(config('notification.sender.address'), config('notification.sender.name')) + ->subject(config('app.name').' - your second factor has been reset') + ->markdown('mail.two-factor-reset', ['name' => $notifiable->name]); + } + + public function toArray($notifiable): array + { + return []; + } +} diff --git a/resources/views/breadcrumbs/header.blade.php b/resources/views/breadcrumbs/header.blade.php index a27dee4..22144d3 100755 --- a/resources/views/breadcrumbs/header.blade.php +++ b/resources/views/breadcrumbs/header.blade.php @@ -59,9 +59,6 @@ - - - @@ -113,7 +110,7 @@

{{config('app.name')}}

-
{{ __('Welcome to the Games Club Recruitment Portal!') }}
+
{{ __('Welcome to the :appName Recruitment Portal!', ['appName' => config('app.name')]) }}

{{ __('We process applications for our Discord server\'s management team here. If you have any questions, don\'t hesistate to contact our support team! Take a look at the open jobs below.') }}

{!! __('If you\'d like to learn more about our community, make sure to visit our main website!', ['mainWebsiteUrlConfigValue' => config('app.sitehomepage')]) !!}

diff --git a/resources/views/components/confirm-second-factor.blade.php b/resources/views/components/confirm-second-factor.blade.php index 5eecd54..acfd9e1 100755 --- a/resources/views/components/confirm-second-factor.blade.php +++ b/resources/views/components/confirm-second-factor.blade.php @@ -3,7 +3,7 @@ -

$slot

+

{{ $slot }}

@endif diff --git a/resources/views/dashboard/user/manage.blade.php b/resources/views/dashboard/user/manage.blade.php index 8279f89..53985ec 100755 --- a/resources/views/dashboard/user/manage.blade.php +++ b/resources/views/dashboard/user/manage.blade.php @@ -15,9 +15,37 @@ @section('content') - + @if($user->has2FA()) -

{{ __('Please confirm that you want to invalidate this account\'s password. Since this is a sensitive operation, you\'ll need to confirm your own password and provide a 2FA code, if enabled.') }}

+ + +

{{ __('Resetting an account\'s two-factor authentication secret will automatically notify the account holder. Additionally, the user\'s password will also be forcefully reset during this process. Please confirm this action by verifying your identity below.') }}

+ +
+ @csrf + @method('PATCH') + + + {{ __('Please re-enter your password.') }} + + + + {{ __('Please enter your two-factor authentication code.') }} + + +
+ + + + + +
+ + @endif + + + +

{{ __('Forcing a password reset will automatically notify the account holder and send them a password reset link. Please confirm this action by verifying your identity below.') }}

@csrf @@ -34,7 +62,7 @@
- +
@@ -388,7 +416,9 @@ @endif - + @if($user->has2FA()) + + @endif
diff --git a/resources/views/mail/two-factor-reset.blade.php b/resources/views/mail/two-factor-reset.blade.php new file mode 100644 index 0000000..c9219ec --- /dev/null +++ b/resources/views/mail/two-factor-reset.blade.php @@ -0,0 +1,12 @@ +@component('mail::message') +# Hi {{ $name }}, + +Important security notification regarding your account at {{ config('app.name') }}: + +Your account was previously secured with two-factor authentication. This is no longer the case. An administrator has disabled two-factor authentication for your account. Admins only reset two-factor authentication after an identity verification is complete. + +As a result of this action and as an additional security measure, your password has also been voided, which means you'll need to [reset it]({{ route('password.email') }}) if you want to keep using the app. + +Thank you,
+The team at {{ config('app.name') }} +@endcomponent diff --git a/routes/web.php b/routes/web.php index 7004844..f651813 100755 --- a/routes/web.php +++ b/routes/web.php @@ -302,6 +302,9 @@ Route::group(['prefix' => LaravelLocalization::setLocale(), 'middleware' => ['lo Route::patch('accounts/force-reset/{user}', [UserController::class, 'forcePasswordReset']) ->name('force-reset-user'); + Route::patch('accounts/reset-twofa/{user}', [UserController::class, 'reset2FASecret']) + ->name('reset-twofa'); + Route::patch('accounts/update/{user}', [UserController::class, 'update']) ->name('updateUser');