mirror of
https://github.com/Bubka/2FAuth.git
synced 2025-01-22 22:30:05 +01:00
Add possibility to delete the registered user and reset 2FAuth data
This commit is contained in:
parent
984e6d253c
commit
cdfda1591b
@ -2,20 +2,36 @@
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Services\TwoFAccountService;
|
||||
use App\Http\Requests\UserUpdateRequest;
|
||||
use App\Http\Requests\UserDeleteRequest;
|
||||
use App\Api\v1\Resources\UserResource;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use App\Exceptions\UnsupportedWithReverseProxyException;
|
||||
use Exception;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
* The TwoFAccount Service instance.
|
||||
*/
|
||||
public function __construct()
|
||||
protected $twofaccountService;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @param \App\Services\TwoFAccountService $twofaccountService
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(TwoFAccountService $twofaccountService)
|
||||
{
|
||||
$this->twofaccountService = $twofaccountService;
|
||||
$authGuard = config('auth.defaults.guard');
|
||||
|
||||
if ($authGuard === 'reverse-proxy-guard') {
|
||||
@ -27,7 +43,7 @@ public function __construct()
|
||||
/**
|
||||
* Update the user's profile information.
|
||||
*
|
||||
* @param \App\Api\v1\Requests\UserUpdateRequest $request
|
||||
* @param \App\Http\Requests\UserUpdateRequest $request
|
||||
* @return \App\Api\v1\Resources\UserResource
|
||||
*/
|
||||
public function update(UserUpdateRequest $request)
|
||||
@ -48,4 +64,45 @@ public function update(UserUpdateRequest $request)
|
||||
|
||||
return new UserResource($user);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete the user's account.
|
||||
*
|
||||
* @param \App\Http\Requests\UserDeleteRequest $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function delete(UserDeleteRequest $request)
|
||||
{
|
||||
$validated = $request->validated();
|
||||
|
||||
if (!Hash::check( $validated['password'], Auth::user()->password) ) {
|
||||
return response()->json(['message' => __('errors.wrong_current_password')], 400);
|
||||
}
|
||||
|
||||
try {
|
||||
DB::transaction(function () {
|
||||
DB::table('twofaccounts')->delete();
|
||||
DB::table('groups')->delete();
|
||||
DB::table('options')->delete();
|
||||
DB::table('web_authn_credentials')->delete();
|
||||
DB::table('web_authn_recoveries')->delete();
|
||||
DB::table('oauth_access_tokens')->delete();
|
||||
DB::table('oauth_auth_codes')->delete();
|
||||
DB::table('oauth_clients')->delete();
|
||||
DB::table('oauth_personal_access_clients')->delete();
|
||||
DB::table('oauth_refresh_tokens')->delete();
|
||||
DB::table('password_resets')->delete();
|
||||
DB::table('users')->delete();
|
||||
});
|
||||
|
||||
Artisan::call('passport:install --force');
|
||||
Artisan::call('config:clear');
|
||||
}
|
||||
catch (\Throwable $e) {
|
||||
return response()->json(['message' => __('errors.user_deletion_failed')], 400);
|
||||
}
|
||||
|
||||
return response()->json(null, 204);
|
||||
}
|
||||
}
|
32
app/Http/Requests/UserDeleteRequest.php
Normal file
32
app/Http/Requests/UserDeleteRequest.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
|
||||
class UserDeleteRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'password' => 'required|string',
|
||||
];
|
||||
}
|
||||
}
|
@ -6,6 +6,9 @@
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Laravel\Passport\Console\ClientCommand;
|
||||
use Laravel\Passport\Console\InstallCommand;
|
||||
use Laravel\Passport\Console\KeysCommand;
|
||||
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
@ -30,5 +33,11 @@ public function boot()
|
||||
Blade::withoutComponentTags();
|
||||
Schema::defaultStringLength(191);
|
||||
JsonResource::withoutWrapping();
|
||||
|
||||
$this->commands([
|
||||
InstallCommand::class,
|
||||
ClientCommand::class,
|
||||
KeysCommand::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<v-button :isLoading="isBusy" :disabled="isDisabled" >{{ caption }}</v-button>
|
||||
<v-button :color="color" :isLoading="isBusy" :disabled="isDisabled" >{{ caption }}</v-button>
|
||||
</div>
|
||||
<div class="control" v-if="showCancelButton">
|
||||
<router-link :to="{ name: cancelLandingView }" class="button is-text">{{ $t('commons.cancel') }}</router-link>
|
||||
@ -44,6 +44,11 @@
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
|
||||
color: {
|
||||
type: String,
|
||||
default: 'is-link'
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
@ -22,6 +22,16 @@
|
||||
<form-buttons :isBusy="formPassword.isBusy" :caption="$t('auth.forms.change_password')" />
|
||||
</fieldset>
|
||||
</form>
|
||||
<form @submit.prevent="submitDelete" @keydown="formDelete.onKeydown($event)">
|
||||
<h4 class="title is-4 pt-6 has-text-danger">{{ $t('auth.forms.delete_account') }}</h4>
|
||||
<div class="field is-size-7-mobile">
|
||||
{{ $t('auth.forms.delete_your_account_and_reset_all_data')}}
|
||||
</div>
|
||||
<fieldset :disabled="isRemoteUser">
|
||||
<form-field :form="formDelete" fieldName="password" inputType="password" :label="$t('auth.forms.current_password.label')" :help="$t('auth.forms.current_password.help')" />
|
||||
<form-buttons :isBusy="formDelete.isBusy" :caption="$t('auth.forms.delete_your_account')" :color="'is-danger'" />
|
||||
</fieldset>
|
||||
</form>
|
||||
</form-wrapper>
|
||||
</div>
|
||||
<vue-footer :showButtons="true">
|
||||
@ -52,6 +62,9 @@
|
||||
password : '',
|
||||
password_confirmation : '',
|
||||
}),
|
||||
formDelete: new Form({
|
||||
password : '',
|
||||
}),
|
||||
isRemoteUser: false,
|
||||
}
|
||||
},
|
||||
@ -101,7 +114,31 @@
|
||||
this.$router.push({ name: 'genericError', params: { err: error.response } });
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
submitDelete(e) {
|
||||
e.preventDefault()
|
||||
|
||||
if(confirm(this.$t('auth.confirm.delete_account'))) {
|
||||
|
||||
this.formDelete.delete('/user', {returnError: true})
|
||||
.then(response => {
|
||||
|
||||
this.$notify({ type: 'is-success', text: this.$t('auth.forms.user_account_successfully_deleted') })
|
||||
this.$router.push({ name: 'register' });
|
||||
})
|
||||
.catch(error => {
|
||||
if( error.response.status === 400 ) {
|
||||
|
||||
this.$notify({ type: 'is-danger', text: error.response.data.message })
|
||||
}
|
||||
else if( error.response.status !== 422 ) {
|
||||
|
||||
this.$router.push({ name: 'genericError', params: { err: error.response } });
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
@ -33,6 +33,7 @@
|
||||
'confirm' => [
|
||||
'logout' => 'Are you sure you want to log out?',
|
||||
'revoke_device' => 'Are you sure you want to revoke this device?',
|
||||
'delete_account' => 'Are you sure you want to delete your account?',
|
||||
],
|
||||
'webauthn' => [
|
||||
'security_device' => 'a security device',
|
||||
@ -96,6 +97,10 @@
|
||||
'register_punchline' => 'Welcome to 2FAuth.<br/>You need an account to go further. Fill this form to register yourself, and please, choose a strong password, 2FA data are sensitives.',
|
||||
'reset_punchline' => '2FAuth will send you a password reset link to this address. Click the link in the received email to set a new password.',
|
||||
'name_this_device' => 'Name this device',
|
||||
'delete_account' => 'Delete account',
|
||||
'delete_your_account' => 'Delete your account',
|
||||
'delete_your_account_and_reset_all_data' => 'This will reset 2FAuth. Your user account will be deleted as well as all 2FA data. There is no going back.',
|
||||
'user_account_successfully_deleted' => 'User account successfully deleted',
|
||||
],
|
||||
|
||||
];
|
||||
|
@ -36,4 +36,5 @@
|
||||
'aborted_by_user' => 'Aborted by user',
|
||||
'security_device_unsupported' => 'Security device unsupported',
|
||||
'unsupported_with_reverseproxy' => 'Not applicable when using an auth proxy',
|
||||
'user_deletion_failed' => 'User account deletion failed, no data have been deleted',
|
||||
];
|
@ -42,6 +42,7 @@
|
||||
Route::put('user', 'Auth\UserController@update')->name('user.update');
|
||||
Route::patch('user/password', 'Auth\PasswordController@update')->name('user.password.update');
|
||||
Route::get('user/logout', 'Auth\LoginController@logout')->name('user.logout');
|
||||
Route::delete('user', 'Auth\UserController@delete')->name('user.delete')->middleware('disableInDemoMode');
|
||||
|
||||
Route::get('oauth/personal-access-tokens', 'Auth\PersonalAccessTokenController@forUser')->name('passport.personal.tokens.index');
|
||||
Route::post('oauth/personal-access-tokens', 'Auth\PersonalAccessTokenController@store')->name('passport.personal.tokens.store');
|
||||
|
Loading…
Reference in New Issue
Block a user