]>
git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/window/AddWebauthn.js
1 Ext
.define('Proxmox.window.AddWebauthn', {
2 extend
: 'Ext.window.Window',
3 alias
: 'widget.pmxAddWebauthn',
4 mixins
: ['Proxmox.Mixin.CBind'],
6 onlineHelp
: 'user_mgmt',
10 title
: gettext('Add a Webauthn login token'),
16 initComponent: function() {
19 Ext
.GlobalEvents
.fireEvent('proxmoxShowHelp', me
.onlineHelp
);
30 xclass
: 'Ext.app.ViewController',
34 validitychange: function(field
, valid
) {
36 let viewmodel
= me
.getViewModel();
37 let form
= me
.lookup('webauthn_form');
38 viewmodel
.set('valid', form
.isValid());
44 let view
= me
.getView();
46 if (Proxmox
.UserName
=== 'root@pam') {
47 view
.lookup('password').setVisible(false);
48 view
.lookup('password').setDisabled(true);
54 registerWebauthn
: async
function() {
56 let values
= me
.lookup('webauthn_form').getValues();
57 values
.type
= "webauthn";
59 let userid
= values
.user
;
62 me
.getView().mask(gettext('Please wait...'), 'x-mask-loading');
65 let register_response
= await Proxmox
.Async
.api2({
66 url
: `/api2/extjs/access/tfa/${userid}`,
71 let data
= register_response
.result
.data
;
72 if (!data
.challenge
) {
73 throw "server did not respond with a challenge";
76 let creds
= JSON
.parse(data
.challenge
);
78 // Fix this up before passing it to the browser, but keep a copy of the original
79 // string to pass in the response:
80 let challenge_str
= creds
.publicKey
.challenge
;
81 creds
.publicKey
.challenge
= Proxmox
.Utils
.base64url_to_bytes(challenge_str
);
82 creds
.publicKey
.user
.id
=
83 Proxmox
.Utils
.base64url_to_bytes(creds
.publicKey
.user
.id
);
85 // convert existing authenticators structure
86 creds
.publicKey
.excludeCredentials
=
87 (creds
.publicKey
.excludeCredentials
|| [])
88 .map((credential
) => ({
89 id
: Proxmox
.Utils
.base64url_to_bytes(credential
.id
),
90 type
: credential
.type
,
93 let msg
= Ext
.Msg
.show({
94 title
: `Webauthn: ${gettext('Setup')}`,
95 message
: gettext('Please press the button on your Webauthn Device'),
101 token_response
= await navigator
.credentials
.create(creds
);
103 let errmsg
= error
.message
;
104 if (error
.name
=== 'InvalidStateError') {
105 errmsg
= gettext('Is this token already registered?');
107 throw gettext('An error occurred during token registration.') +
108 `<br>${error.name}: ${errmsg}`;
111 // We cannot pass ArrayBuffers to the API, so extract & convert the data.
113 id
: token_response
.id
,
114 type
: token_response
.type
,
115 rawId
: Proxmox
.Utils
.bytes_to_base64url(token_response
.rawId
),
117 attestationObject
: Proxmox
.Utils
.bytes_to_base64url(
118 token_response
.response
.attestationObject
,
120 clientDataJSON
: Proxmox
.Utils
.bytes_to_base64url(
121 token_response
.response
.clientDataJSON
,
130 challenge
: challenge_str
,
131 value
: JSON
.stringify(response
),
134 if (values
.password
) {
135 params
.password
= values
.password
;
138 await Proxmox
.Async
.api2({
139 url
: `/api2/extjs/access/tfa/${userid}`,
144 let error
= response
;
145 console
.error(error
); // for debugging if it's not displayable...
146 if (typeof error
=== "object") {
147 // in case it came from an api request:
148 error
= error
.result
?.message
;
151 Ext
.Msg
.alert(gettext('Error'), error
);
154 me
.getView().close();
161 reference
: 'webauthn_form',
170 xtype
: 'pmxDisplayEditField',
173 editable
: (get) => !get('fixedUser'),
174 value
: () => Proxmox
.UserName
,
176 fieldLabel
: gettext('User'),
178 xtype
: 'pmxUserSelector',
181 renderer
: Ext
.String
.htmlEncode
,
183 change: function(field
, newValue
, oldValue
) {
184 let vm
= this.up('window').getViewModel();
185 vm
.set('userid', newValue
);
191 fieldLabel
: gettext('Description'),
195 emptyText
: gettext('For example: TFA device ID, required to identify multiple factors.'),
200 reference
: 'password',
201 fieldLabel
: gettext('Verify Password'),
202 inputType
: 'password',
207 hidden
: () => Proxmox
.UserName
=== 'root@pam',
208 disabled
: () => Proxmox
.UserName
=== 'root@pam',
210 Ext
.String
.format(gettext("Confirm your ({0}) password"), Proxmox
.UserName
),
219 xtype
: 'proxmoxHelpButton',
224 text
: gettext('Register Webauthn Device'),
225 handler
: 'registerWebauthn',
227 disabled
: '{!valid}',