diff --git a/www/LoginView.js b/www/LoginView.js index 1c7a977c..a3ffec77 100644 --- a/www/LoginView.js +++ b/www/LoginView.js @@ -390,6 +390,11 @@ Ext.define('PBS.login.TfaWindow', { // Byte array fixup, keep challenge string: challenge.string = challenge.publicKey.challenge; challenge.publicKey.challenge = PBS.Utils.base64url_to_bytes(challenge.string); + let userVerification = Ext.state.Manager.getProvider().get('webauthn-user-verification'); + if (userVerification !== undefined) { + challenge.publicKey.userVerification = userVerification; + } + for (const cred of challenge.publicKey.allowCredentials) { cred.id = PBS.Utils.base64url_to_bytes(cred.id); } diff --git a/www/window/AddWebauthn.js b/www/window/AddWebauthn.js index 16731a63..d2434f2c 100644 --- a/www/window/AddWebauthn.js +++ b/www/window/AddWebauthn.js @@ -79,6 +79,13 @@ Ext.define('PBS.window.AddWebauthn', { // string to pass in the response: let challenge_str = challenge_obj.publicKey.challenge; challenge_obj.publicKey.challenge = PBS.Utils.base64url_to_bytes(challenge_str); + let userVerification = Ext.state.Manager.getProvider().get('webauthn-user-verification'); + if (userVerification !== undefined) { + challenge_obj.publicKey.authenticatorSelection = { + userVerification, + }; + } + challenge_obj.publicKey.user.id = PBS.Utils.base64url_to_bytes(challenge_obj.publicKey.user.id); diff --git a/www/window/Settings.js b/www/window/Settings.js index ee8464be..7059605c 100644 --- a/www/window/Settings.js +++ b/www/window/Settings.js @@ -30,6 +30,9 @@ Ext.define('PBS.window.Settings', { let username = sp.get('login-username') || Proxmox.Utils.noneText; me.lookupReference('savedUserName').setValue(Ext.String.htmlEncode(username)); + let userverification= sp.get('webauthn-user-verification') || '__default__'; + me.lookupReference('webauthnUserVerification').setValue(userverification); + let settings = ['fontSize', 'fontFamily', 'letterSpacing', 'lineHeight']; settings.forEach(function(setting) { let val = localStorage.getItem('pve-xterm-' + setting); @@ -91,7 +94,7 @@ Ext.define('PBS.window.Settings', { }, 'button[name=reset]': { click: function() { - let blacklist = ['login-username']; + let blacklist = ['login-username', 'webauthn-user-verification']; let sp = Ext.state.Manager.getProvider(); for (const state of Object.values(sp.state)) { if (blacklist.indexOf(state) !== -1) { @@ -114,6 +117,14 @@ Ext.define('PBS.window.Settings', { sp.clear('login-username'); }, }, + 'field[reference=webauthnUserVerification]': { + change: function(e, v) { + if (v === '__default__') { + v = undefined; + } + Ext.state.Manager.getProvider().set('webauthn-user-verification', v); + }, + }, }, }, @@ -174,6 +185,23 @@ Ext.define('PBS.window.Settings', { }, ], }, + { + xtype: 'box', + autoEl: { tag: 'hr' }, + }, + { + xtype: 'proxmoxKVComboBox', + fieldLabel: gettext('WebAuthn User Verification') + ':', + labelWidth: 150, + stateId: 'webauthn-user-verification', + reference: 'webauthnUserVerification', + value: '__default__', + comboItems: [ + ['__default__', Proxmox.Utils.defaultText], + ['discouraged', gettext('Discouraged')], + ['preferred', gettext('Preferred')], + ], + }, ], }, {