mirror of
https://github.com/Bubka/2FAuth.git
synced 2025-06-24 05:51:48 +02:00
Replace the useWebauthnAsDefault option by a client side form toggle
This commit is contained in:
parent
f359a1ade3
commit
4d8180a8c1
@ -58,7 +58,6 @@ class WebAuthnManageController extends Controller
|
|||||||
// no more registered device exists.
|
// no more registered device exists.
|
||||||
// See #110
|
// See #110
|
||||||
if (blank($user->webAuthnCredentials()->WhereEnabled()->get())) {
|
if (blank($user->webAuthnCredentials()->WhereEnabled()->get())) {
|
||||||
Settings::delete('useWebauthnAsDefault');
|
|
||||||
Settings::delete('useWebauthnOnly');
|
Settings::delete('useWebauthnOnly');
|
||||||
Log::notice('No Webauthn credential enabled, Webauthn settings reset to default');
|
Log::notice('No Webauthn credential enabled, Webauthn settings reset to default');
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,6 @@ return [
|
|||||||
'defaultGroup' => 0,
|
'defaultGroup' => 0,
|
||||||
'defaultCaptureMode' => 'livescan',
|
'defaultCaptureMode' => 'livescan',
|
||||||
'useDirectCapture' => false,
|
'useDirectCapture' => false,
|
||||||
'useWebauthnAsDefault' => false,
|
|
||||||
'useWebauthnOnly' => false,
|
'useWebauthnOnly' => false,
|
||||||
'getOfficialIcons' => true,
|
'getOfficialIcons' => true,
|
||||||
'theme' => 'system',
|
'theme' => 'system',
|
||||||
|
@ -24,6 +24,11 @@ return new class extends Migration
|
|||||||
|
|
||||||
DB::table('users')->update(['is_admin' => 1]);
|
DB::table('users')->update(['is_admin' => 1]);
|
||||||
|
|
||||||
|
// The 'useWebauthnAsDefault' option is replaced by a local storage record
|
||||||
|
// so we delete it form the Options table to prevent its conversion to
|
||||||
|
// a user preference
|
||||||
|
DB::table('options')->where('key', 'useWebauthnAsDefault')->delete();
|
||||||
|
|
||||||
// User options are converted as user preferences
|
// User options are converted as user preferences
|
||||||
$options = DB::table('options')->get();
|
$options = DB::table('options')->get();
|
||||||
$preferences = config('2fauth.preferences');
|
$preferences = config('2fauth.preferences');
|
||||||
|
8
resources/js/mixins.js
vendored
8
resources/js/mixins.js
vendored
@ -20,11 +20,17 @@ Vue.mixin({
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
await this.axios.get('/user/logout')
|
await this.axios.get('/user/logout')
|
||||||
this.$storage.clear()
|
this.clearStorage()
|
||||||
this.$router.push({ name: 'login', params: { forceRefresh: true } })
|
this.$router.push({ name: 'login', params: { forceRefresh: true } })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clearStorage() {
|
||||||
|
this.$storage.set('accounts')
|
||||||
|
this.$storage.set('groups')
|
||||||
|
this.$storage.set('lastRoute')
|
||||||
|
},
|
||||||
|
|
||||||
exitSettings: function (event) {
|
exitSettings: function (event) {
|
||||||
if (event) {
|
if (event) {
|
||||||
this.$notify({ clean: true })
|
this.$notify({ clean: true })
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
// there is nothing to do, we simply catch the error to avoid redondant navigation
|
// there is nothing to do, we simply catch the error to avoid redondant navigation
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$storage.clear()
|
this.clearStorage()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
@ -12,7 +12,7 @@
|
|||||||
<div class="nav-links">
|
<div class="nav-links">
|
||||||
<p>{{ $t('auth.webauthn.lost_your_device') }} <router-link id="lnkRecoverAccount" :to="{ name: 'webauthn.lost' }" class="is-link">{{ $t('auth.webauthn.recover_your_account') }}</router-link></p>
|
<p>{{ $t('auth.webauthn.lost_your_device') }} <router-link id="lnkRecoverAccount" :to="{ name: 'webauthn.lost' }" class="is-link">{{ $t('auth.webauthn.recover_your_account') }}</router-link></p>
|
||||||
<p v-if="!this.$root.userPreferences.useWebauthnOnly">{{ $t('auth.sign_in_using') }}
|
<p v-if="!this.$root.userPreferences.useWebauthnOnly">{{ $t('auth.sign_in_using') }}
|
||||||
<a id="lnkSignWithLegacy" role="button" class="is-link" @keyup.enter="showWebauthn = false" @click="showWebauthn = false" tabindex="0">{{ $t('auth.login_and_password') }}</a>
|
<a id="lnkSignWithLegacy" role="button" class="is-link" @keyup.enter="toggleForm" @click="toggleForm" tabindex="0">{{ $t('auth.login_and_password') }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</form-wrapper>
|
</form-wrapper>
|
||||||
@ -28,7 +28,7 @@
|
|||||||
<div class="nav-links">
|
<div class="nav-links">
|
||||||
<p>{{ $t('auth.forms.forgot_your_password') }} <router-link id="lnkResetPwd" :to="{ name: 'password.request' }" class="is-link" :aria-label="$t('auth.forms.reset_your_password')">{{ $t('auth.forms.request_password_reset') }}</router-link></p>
|
<p>{{ $t('auth.forms.forgot_your_password') }} <router-link id="lnkResetPwd" :to="{ name: 'password.request' }" class="is-link" :aria-label="$t('auth.forms.reset_your_password')">{{ $t('auth.forms.request_password_reset') }}</router-link></p>
|
||||||
<p >{{ $t('auth.sign_in_using') }}
|
<p >{{ $t('auth.sign_in_using') }}
|
||||||
<a id="lnkSignWithWebauthn" role="button" class="is-link" @keyup.enter="showWebauthn = true" @click="showWebauthn = true" tabindex="0" :aria-label="$t('auth.sign_in_using_security_device')">{{ $t('auth.webauthn.security_device') }}</a>
|
<a id="lnkSignWithWebauthn" role="button" class="is-link" @keyup.enter="toggleForm" @click="toggleForm" tabindex="0" :aria-label="$t('auth.sign_in_using_security_device')">{{ $t('auth.webauthn.security_device') }}</a>
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-4">{{ $t('auth.forms.dont_have_account_yet') }} <router-link id="lnkRegister" :to="{ name: 'register' }" class="is-link">{{ $t('auth.register') }}</router-link></p>
|
<p class="mt-4">{{ $t('auth.forms.dont_have_account_yet') }} <router-link id="lnkRegister" :to="{ name: 'register' }" class="is-link">{{ $t('auth.register') }}</router-link></p>
|
||||||
</div>
|
</div>
|
||||||
@ -53,17 +53,26 @@
|
|||||||
password: ''
|
password: ''
|
||||||
}),
|
}),
|
||||||
isBusy: false,
|
isBusy: false,
|
||||||
showWebauthn: this.$root.userPreferences.useWebauthnAsDefault || this.$root.userPreferences.useWebauthnOnly,
|
showWebauthn: this.$root.userPreferences.useWebauthnOnly,
|
||||||
csrfRefresher: null,
|
csrfRefresher: null,
|
||||||
webauthn: new WebAuthn()
|
webauthn: new WebAuthn()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted: function() {
|
mounted: function() {
|
||||||
this.csrfRefresher = setInterval(this.refreshToken, 300000); // 5 min
|
this.csrfRefresher = setInterval(this.refreshToken, 300000) // 5 min
|
||||||
|
this.showWebauthn = this.$storage.get('showWebauthnForm', false)
|
||||||
},
|
},
|
||||||
|
|
||||||
methods : {
|
methods : {
|
||||||
|
/**
|
||||||
|
* Toggle the form between legacy and webauthn method
|
||||||
|
*/
|
||||||
|
toggleForm() {
|
||||||
|
this.showWebauthn = ! this.showWebauthn
|
||||||
|
this.$storage.set('showWebauthnForm', this.showWebauthn)
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign in using the login/password form
|
* Sign in using the login/password form
|
||||||
*/
|
*/
|
||||||
|
@ -42,8 +42,6 @@
|
|||||||
<form>
|
<form>
|
||||||
<!-- use webauthn only -->
|
<!-- use webauthn only -->
|
||||||
<form-checkbox v-on:useWebauthnOnly="savePreference('useWebauthnOnly', $event)" :form="form" fieldName="useWebauthnOnly" :label="$t('auth.webauthn.use_webauthn_only.label')" :help="$t('auth.webauthn.use_webauthn_only.help')" :disabled="isRemoteUser || credentials.length === 0" />
|
<form-checkbox v-on:useWebauthnOnly="savePreference('useWebauthnOnly', $event)" :form="form" fieldName="useWebauthnOnly" :label="$t('auth.webauthn.use_webauthn_only.label')" :help="$t('auth.webauthn.use_webauthn_only.help')" :disabled="isRemoteUser || credentials.length === 0" />
|
||||||
<!-- default sign in method -->
|
|
||||||
<form-checkbox v-on:useWebauthnAsDefault="savePreference('useWebauthnAsDefault', $event)" :form="form" fieldName="useWebauthnAsDefault" :label="$t('auth.webauthn.use_webauthn_as_default.label')" :help="$t('auth.webauthn.use_webauthn_as_default.help')" :disabled="isRemoteUser || credentials.length === 0" />
|
|
||||||
</form>
|
</form>
|
||||||
<!-- footer -->
|
<!-- footer -->
|
||||||
<vue-footer :showButtons="true">
|
<vue-footer :showButtons="true">
|
||||||
@ -67,7 +65,6 @@
|
|||||||
return {
|
return {
|
||||||
form: new Form({
|
form: new Form({
|
||||||
useWebauthnOnly: null,
|
useWebauthnOnly: null,
|
||||||
useWebauthnAsDefault: null,
|
|
||||||
}),
|
}),
|
||||||
credentials: [],
|
credentials: [],
|
||||||
isFetching: false,
|
isFetching: false,
|
||||||
@ -193,9 +190,7 @@
|
|||||||
|
|
||||||
if (this.credentials.length == 0) {
|
if (this.credentials.length == 0) {
|
||||||
this.form.useWebauthnOnly = false
|
this.form.useWebauthnOnly = false
|
||||||
this.form.useWebauthnAsDefault = false
|
|
||||||
this.$root.userPreferences['useWebauthnOnly'] = false
|
this.$root.userPreferences['useWebauthnOnly'] = false
|
||||||
this.$root.userPreferences['useWebauthnAsDefault'] = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$notify({ type: 'is-success', text: this.$t('auth.webauthn.device_revoked') })
|
this.$notify({ type: 'is-success', text: this.$t('auth.webauthn.device_revoked') })
|
||||||
|
@ -68,15 +68,11 @@ return [
|
|||||||
'unknown_device' => 'Unknown device',
|
'unknown_device' => 'Unknown device',
|
||||||
'use_webauthn_only' => [
|
'use_webauthn_only' => [
|
||||||
'label' => 'Use WebAuthn only',
|
'label' => 'Use WebAuthn only',
|
||||||
'help' => 'Make WebAuthn the only available method to sign in 2FAuth. This is the recommended setup to take advantage of the WebAuthn enhanced security.<br />
|
'help' => 'Make WebAuthn the only authorized method to log into your 2FAuth account. This is the recommended setup to take advantage of the WebAuthn enhanced security.<br /><br />
|
||||||
In case of device lost, you will be able to recover your account by resetting this option and signing in using your email and password.'
|
In case of device lost, you will be able to recover your account by resetting this option and signing in using your email and password.<br /><br />
|
||||||
],
|
Attention! The Email & Password form remains available despite this option being enabled, but it will always return an \'Authentication failed\' response.'
|
||||||
'need_a_security_device_to_enable_options' => 'Set at least one device to enable these options',
|
|
||||||
'use_webauthn_as_default' => [
|
|
||||||
'label' => 'Use WebAuthn as default sign in method',
|
|
||||||
'help' => 'Set the 2FAuth sign in form to propose the WebAuthn authentication at first. The Login/password method is then available as an alternative/fallback solution.<br />
|
|
||||||
This has no effect if you only use WebAuthn.'
|
|
||||||
],
|
],
|
||||||
|
'need_a_security_device_to_enable_options' => 'Set at least one device to enable the following options',
|
||||||
],
|
],
|
||||||
'forms' => [
|
'forms' => [
|
||||||
'name' => 'Name',
|
'name' => 'Name',
|
||||||
|
@ -95,7 +95,6 @@ class UserControllerTest extends FeatureTestCase
|
|||||||
'defaultGroup' => 1,
|
'defaultGroup' => 1,
|
||||||
'defaultCaptureMode' => 'advancedForm',
|
'defaultCaptureMode' => 'advancedForm',
|
||||||
'useDirectCapture' => true,
|
'useDirectCapture' => true,
|
||||||
'useWebauthnAsDefault' => true,
|
|
||||||
'useWebauthnOnly' => true,
|
'useWebauthnOnly' => true,
|
||||||
'getOfficialIcons' => false,
|
'getOfficialIcons' => false,
|
||||||
'theme' => 'dark',
|
'theme' => 'dark',
|
||||||
@ -116,7 +115,6 @@ class UserControllerTest extends FeatureTestCase
|
|||||||
$this->user['preferences->defaultGroup'] = $userPrefs['defaultGroup'];
|
$this->user['preferences->defaultGroup'] = $userPrefs['defaultGroup'];
|
||||||
$this->user['preferences->defaultCaptureMode'] = $userPrefs['defaultCaptureMode'];
|
$this->user['preferences->defaultCaptureMode'] = $userPrefs['defaultCaptureMode'];
|
||||||
$this->user['preferences->useDirectCapture'] = $userPrefs['useDirectCapture'];
|
$this->user['preferences->useDirectCapture'] = $userPrefs['useDirectCapture'];
|
||||||
$this->user['preferences->useWebauthnAsDefault'] = $userPrefs['useWebauthnAsDefault'];
|
|
||||||
$this->user['preferences->useWebauthnOnly'] = $userPrefs['useWebauthnOnly'];
|
$this->user['preferences->useWebauthnOnly'] = $userPrefs['useWebauthnOnly'];
|
||||||
$this->user['preferences->getOfficialIcons'] = $userPrefs['getOfficialIcons'];
|
$this->user['preferences->getOfficialIcons'] = $userPrefs['getOfficialIcons'];
|
||||||
$this->user['preferences->theme'] = $userPrefs['theme'];
|
$this->user['preferences->theme'] = $userPrefs['theme'];
|
||||||
|
@ -81,7 +81,6 @@ class SystemControllerTest extends FeatureTestCase
|
|||||||
'defaultGroup',
|
'defaultGroup',
|
||||||
'defaultCaptureMode',
|
'defaultCaptureMode',
|
||||||
'useDirectCapture',
|
'useDirectCapture',
|
||||||
'useWebauthnAsDefault',
|
|
||||||
'useWebauthnOnly',
|
'useWebauthnOnly',
|
||||||
'getOfficialIcons',
|
'getOfficialIcons',
|
||||||
'lang',
|
'lang',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user