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