]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/window/LoginWindow.js
fix #2177: use getValue() to get otp value
[pve-manager.git] / www / manager6 / window / LoginWindow.js
1 /*global u2f*/
2 Ext.define('PVE.window.LoginWindow', {
3 extend: 'Ext.window.Window',
4
5 controller: {
6
7 xclass: 'Ext.app.ViewController',
8
9 onLogon: function() {
10 var me = this;
11
12 var form = this.lookupReference('loginForm');
13 var unField = this.lookupReference('usernameField');
14 var saveunField = this.lookupReference('saveunField');
15 var view = this.getView();
16
17 if (!form.isValid()) {
18 return;
19 }
20
21 view.el.mask(gettext('Please wait...'), 'x-mask-loading');
22
23 // set or clear username
24 var sp = Ext.state.Manager.getProvider();
25 if (saveunField.getValue() === true) {
26 sp.set(unField.getStateId(), unField.getValue());
27 } else {
28 sp.clear(unField.getStateId());
29 }
30 sp.set(saveunField.getStateId(), saveunField.getValue());
31
32 form.submit({
33 failure: function(f, resp){
34 me.failure(resp);
35 },
36 success: function(f, resp){
37 view.el.unmask();
38
39 var data = resp.result.data;
40 if (Ext.isDefined(data.NeedTFA)) {
41 // Store first factor login information first:
42 data.LoggedOut = true;
43 Proxmox.Utils.setAuthData(data);
44
45 if (Ext.isDefined(data.U2FChallenge)) {
46 me.perform_u2f(data);
47 } else {
48 me.perform_otp();
49 }
50 } else {
51 me.success(data);
52 }
53 }
54 });
55
56 },
57 failure: function(resp) {
58 var me = this;
59 var view = me.getView();
60 view.el.unmask();
61 var handler = function() {
62 var uf = me.lookupReference('usernameField');
63 uf.focus(true, true);
64 };
65
66 Ext.MessageBox.alert(gettext('Error'),
67 gettext("Login failed. Please try again"),
68 handler);
69 },
70 success: function(data) {
71 var me = this;
72 var view = me.getView();
73 var handler = view.handler || Ext.emptyFn;
74 handler.call(me, data);
75 view.close();
76 },
77
78 perform_otp: function() {
79 var me = this;
80 var win = Ext.create('PVE.window.TFALoginWindow', {
81 onLogin: function(value) {
82 me.finish_tfa(value);
83 },
84 onCancel: function() {
85 Proxmox.LoggedOut = false;
86 Proxmox.Utils.authClear();
87 me.getView().show();
88 }
89 });
90 win.show();
91 },
92
93 perform_u2f: function(data) {
94 var me = this;
95 // Show the message:
96 var msg = Ext.Msg.show({
97 title: 'U2F: '+gettext('Verification'),
98 message: gettext('Please press the button on your U2F Device'),
99 buttons: []
100 });
101 var chlg = data.U2FChallenge;
102 var key = {
103 version: chlg.version,
104 keyHandle: chlg.keyHandle
105 };
106 u2f.sign(chlg.appId, chlg.challenge, [key], function(res) {
107 msg.close();
108 if (res.errorCode) {
109 Proxmox.Utils.authClear();
110 Ext.Msg.alert(gettext('Error'), PVE.Utils.render_u2f_error(res.errorCode));
111 return;
112 }
113 delete res.errorCode;
114 me.finish_tfa(JSON.stringify(res));
115 });
116 },
117 finish_tfa: function(res) {
118 var me = this;
119 var view = me.getView();
120 view.el.mask(gettext('Please wait...'), 'x-mask-loading');
121 var params = { response: res };
122 Proxmox.Utils.API2Request({
123 url: '/api2/extjs/access/tfa',
124 params: params,
125 method: 'POST',
126 timeout: 5000, // it'll delay both success & failure
127 success: function(resp, opts) {
128 view.el.unmask();
129 // Fill in what we copy over from the 1st factor:
130 var data = resp.result.data;
131 data.CSRFPreventionToken = Proxmox.CSRFPreventionToken;
132 data.username = Proxmox.UserName;
133 // Finish logging in:
134 me.success(data);
135 },
136 failure: function(resp, opts) {
137 Proxmox.Utils.authClear();
138 me.failure(resp);
139 }
140 });
141 },
142
143 control: {
144 'field[name=username]': {
145 specialkey: function(f, e) {
146 if (e.getKey() === e.ENTER) {
147 var pf = this.lookupReference('passwordField');
148 if (!pf.getValue()) {
149 pf.focus(false);
150 }
151 }
152 }
153 },
154 'field[name=lang]': {
155 change: function(f, value) {
156 var dt = Ext.Date.add(new Date(), Ext.Date.YEAR, 10);
157 Ext.util.Cookies.set('PVELangCookie', value, dt);
158 this.getView().mask(gettext('Please wait...'), 'x-mask-loading');
159 window.location.reload();
160 }
161 },
162 'button[reference=loginButton]': {
163 click: 'onLogon'
164 },
165 '#': {
166 show: function() {
167 var sp = Ext.state.Manager.getProvider();
168 var checkboxField = this.lookupReference('saveunField');
169 var unField = this.lookupReference('usernameField');
170
171 var checked = sp.get(checkboxField.getStateId());
172 checkboxField.setValue(checked);
173
174 if(checked === true) {
175 var username = sp.get(unField.getStateId());
176 unField.setValue(username);
177 var pwField = this.lookupReference('passwordField');
178 pwField.focus();
179 }
180 }
181 }
182 }
183 },
184
185 width: 400,
186
187 modal: true,
188
189 border: false,
190
191 draggable: true,
192
193 closable: false,
194
195 resizable: false,
196
197 layout: 'auto',
198
199 title: gettext('Proxmox VE Login'),
200
201 defaultFocus: 'usernameField',
202
203 defaultButton: 'loginButton',
204
205 items: [{
206 xtype: 'form',
207 layout: 'form',
208 url: '/api2/extjs/access/ticket',
209 reference: 'loginForm',
210
211 fieldDefaults: {
212 labelAlign: 'right',
213 allowBlank: false
214 },
215
216 items: [
217 {
218 xtype: 'textfield',
219 fieldLabel: gettext('User name'),
220 name: 'username',
221 itemId: 'usernameField',
222 reference: 'usernameField',
223 stateId: 'login-username'
224 },
225 {
226 xtype: 'textfield',
227 inputType: 'password',
228 fieldLabel: gettext('Password'),
229 name: 'password',
230 reference: 'passwordField'
231 },
232 {
233 xtype: 'pveRealmComboBox',
234 name: 'realm'
235 },
236 {
237 xtype: 'proxmoxLanguageSelector',
238 fieldLabel: gettext('Language'),
239 value: Ext.util.Cookies.get('PVELangCookie') || Proxmox.defaultLang || 'en',
240 name: 'lang',
241 reference: 'langField',
242 submitValue: false
243 }
244 ],
245 buttons: [
246 {
247 xtype: 'checkbox',
248 fieldLabel: gettext('Save User name'),
249 name: 'saveusername',
250 reference: 'saveunField',
251 stateId: 'login-saveusername',
252 labelWidth: 'auto',
253 labelAlign: 'right',
254 submitValue: false
255 },
256 {
257 text: gettext('Login'),
258 reference: 'loginButton'
259 }
260 ]
261 }]
262 });
263 Ext.define('PVE.window.TFALoginWindow', {
264 extend: 'Ext.window.Window',
265
266 modal: true,
267 resizable: false,
268 title: 'Two-Factor Authentication',
269 layout: 'form',
270 defaultButton: 'loginButton',
271 defaultFocus: 'otpField',
272
273 controller: {
274 xclass: 'Ext.app.ViewController',
275 login: function() {
276 var me = this;
277 var view = me.getView();
278 view.onLogin(me.lookup('otpField').getValue());
279 view.close();
280 },
281 cancel: function() {
282 var me = this;
283 var view = me.getView();
284 view.onCancel();
285 view.close();
286 }
287 },
288
289 items: [
290 {
291 xtype: 'textfield',
292 fieldLabel: gettext('Please enter your OTP verification code:'),
293 name: 'otp',
294 itemId: 'otpField',
295 reference: 'otpField',
296 allowBlank: false
297 }
298 ],
299
300 buttons: [
301 {
302 text: gettext('Login'),
303 reference: 'loginButton',
304 handler: 'login'
305 },
306 {
307 text: gettext('Cancel'),
308 handler: 'cancel'
309 }
310 ]
311 });