]> git.proxmox.com Git - proxmox-backup.git/blame - www/LoginView.js
bump proxmox-rrd to 0.2 and proxmox-time to 2.0
[proxmox-backup.git] / www / LoginView.js
CommitLineData
34f956bc
DM
1Ext.define('PBS.LoginView', {
2 extend: 'Ext.container.Container',
3 xtype: 'loginview',
4
cd975e57
DM
5 viewModel: {
6 data: {
7 openid: false,
8 },
9 formulas: {
10 button_text: function(get) {
11 if (get("openid") === true) {
12 return gettext("Login (OpenID redirect)");
13 } else {
14 return gettext("Login");
15 }
16 },
17 },
18 },
19
34f956bc
DM
20 controller: {
21 xclass: 'Ext.app.ViewController',
22
fbeac4ea 23 submitForm: async function() {
34f956bc 24 var me = this;
34f956bc 25 var loginForm = me.lookupReference('loginForm');
9abcae1b
DM
26 var unField = me.lookupReference('usernameField');
27 var saveunField = me.lookupReference('saveunField');
34f956bc 28
9abcae1b
DM
29 if (!loginForm.isValid()) {
30 return;
31 }
32
e1d85f18 33 let creds = loginForm.getValues();
9abcae1b 34
cd975e57 35 if (this.getViewModel().data.openid === true) {
e1d85f18 36 const redirectURL = location.origin;
cd975e57 37 try {
3006d70e 38 let resp = await Proxmox.Async.api2({
cd975e57
DM
39 url: '/api2/extjs/access/openid/auth-url',
40 params: {
e1d85f18
TL
41 realm: creds.realm,
42 "redirect-url": redirectURL,
cd975e57
DM
43 },
44 method: 'POST',
45 });
46 window.location = resp.result.data;
3006d70e 47 } catch (response) {
cd975e57
DM
48 Proxmox.Utils.authClear();
49 loginForm.unmask();
50 Ext.MessageBox.alert(
51 gettext('Error'),
3006d70e 52 gettext('OpenID redirect failed, please try again') + `<br>${response.result.message}`,
cd975e57
DM
53 );
54 }
55 return;
56 }
57
e1d85f18
TL
58 creds.username = `${creds.username}@${creds.realm}`;
59 delete creds.realm;
9abcae1b
DM
60
61 if (loginForm.isVisible()) {
62 loginForm.mask(gettext('Please wait...'), 'x-mask-loading');
34f956bc 63 }
9abcae1b
DM
64
65 // set or clear username
66 var sp = Ext.state.Manager.getProvider();
67 if (saveunField.getValue() === true) {
68 sp.set(unField.getStateId(), unField.getValue());
69 } else {
70 sp.clear(unField.getStateId());
71 }
72 sp.set(saveunField.getStateId(), saveunField.getValue());
73
fbeac4ea 74 try {
3006d70e 75 let resp = await Proxmox.Async.api2({
fbeac4ea 76 url: '/api2/extjs/access/ticket',
e1d85f18 77 params: creds,
fbeac4ea
WB
78 method: 'POST',
79 });
80
81 let data = resp.result.data;
82 if (data.ticket.startsWith("PBS:!tfa!")) {
83 data = await me.performTFAChallenge(data);
84 }
85
86 PBS.Utils.updateLoginData(data);
87 PBS.app.changeView('mainview');
88 } catch (error) {
fbeac4ea
WB
89 Proxmox.Utils.authClear();
90 loginForm.unmask();
91 Ext.MessageBox.alert(
92 gettext('Error'),
93 gettext('Login failed. Please try again'),
94 );
95 }
96 },
97
98 performTFAChallenge: async function(data) {
99 let me = this;
100
101 let userid = data.username;
102 let ticket = data.ticket;
103 let challenge = JSON.parse(decodeURIComponent(
104 ticket.split(':')[1].slice("!tfa!".length),
105 ));
106
107 let resp = await new Promise((resolve, reject) => {
9a7431e2 108 Ext.create('Proxmox.window.TfaLoginWindow', {
fbeac4ea
WB
109 userid,
110 ticket,
111 challenge,
112 onResolve: value => resolve(value),
113 onReject: reject,
114 }).show();
9abcae1b 115 });
fbeac4ea
WB
116
117 return resp.result.data;
34f956bc
DM
118 },
119
120 control: {
9abcae1b
DM
121 'field[name=username]': {
122 specialkey: function(f, e) {
123 if (e.getKey() === e.ENTER) {
124 var pf = this.lookupReference('passwordField');
125 if (!pf.getValue()) {
126 pf.focus(false);
127 }
128 }
8acd4d9a 129 },
9abcae1b
DM
130 },
131 'field[name=lang]': {
132 change: function(f, value) {
133 var dt = Ext.Date.add(new Date(), Ext.Date.YEAR, 10);
134 Ext.util.Cookies.set('PBSLangCookie', value, dt);
135 this.getView().mask(gettext('Please wait...'), 'x-mask-loading');
136 window.location.reload();
8acd4d9a 137 },
9abcae1b 138 },
cd975e57
DM
139 'field[name=realm]': {
140 change: function(f, value) {
141 let record = f.store.getById(value);
142 if (record === undefined) return;
143 let data = record.data;
144 this.getViewModel().set("openid", data.type === "openid");
145 },
146 },
34f956bc 147 'button[reference=loginButton]': {
8acd4d9a 148 click: 'submitForm',
9abcae1b
DM
149 },
150 'window[reference=loginwindow]': {
151 show: function() {
152 var sp = Ext.state.Manager.getProvider();
153 var checkboxField = this.lookupReference('saveunField');
154 var unField = this.lookupReference('usernameField');
155
156 var checked = sp.get(checkboxField.getStateId());
157 checkboxField.setValue(checked);
158
8acd4d9a 159 if (checked === true) {
9abcae1b
DM
160 var username = sp.get(unField.getStateId());
161 unField.setValue(username);
162 var pwField = this.lookupReference('passwordField');
163 pwField.focus();
164 }
cd975e57 165
e1d85f18
TL
166 let auth = Proxmox.Utils.getOpenIDRedirectionAuthorization();
167 if (auth !== undefined) {
cd975e57
DM
168 Proxmox.Utils.authClear();
169
170 let loginForm = this.lookupReference('loginForm');
171 loginForm.mask(gettext('OpenID login - please wait...'), 'x-mask-loading');
172
e1d85f18
TL
173 // openID checks the original redirection URL we used, so pass that too
174 const redirectURL = location.origin;
cd975e57
DM
175
176 Proxmox.Utils.API2Request({
177 url: '/api2/extjs/access/openid/login',
178 params: {
e1d85f18
TL
179 state: auth.state,
180 code: auth.code,
181 "redirect-url": redirectURL,
cd975e57
DM
182 },
183 method: 'POST',
184 failure: function(response) {
185 loginForm.unmask();
85b6c4ea 186 let error = response.htmlStatus;
cd975e57
DM
187 Ext.MessageBox.alert(
188 gettext('Error'),
85b6c4ea
TL
189 gettext('OpenID login failed, please try again') + `<br>${error}`,
190 () => { window.location = redirectURL; },
cd975e57
DM
191 );
192 },
193 success: function(response, options) {
194 loginForm.unmask();
e1d85f18
TL
195 let creds = response.result.data;
196 PBS.Utils.updateLoginData(creds);
cd975e57 197 PBS.app.changeView('mainview');
e1d85f18 198 history.replaceState(null, '', `${redirectURL}#pbsDashboard`);
cd975e57
DM
199 },
200 });
201 }
8acd4d9a
TL
202 },
203 },
204 },
34f956bc
DM
205 },
206
207 plugins: 'viewport',
208
209 layout: {
8acd4d9a 210 type: 'border',
34f956bc
DM
211 },
212
213 items: [
214 {
215 region: 'north',
216 xtype: 'container',
217 layout: {
218 type: 'hbox',
8acd4d9a 219 align: 'middle',
34f956bc
DM
220 },
221 margin: '2 5 2 5',
222 height: 38,
223 items: [
224 {
1d8ef0dc
DC
225 xtype: 'proxmoxlogo',
226 prefix: '',
34f956bc
DM
227 },
228 {
229 xtype: 'versioninfo',
8acd4d9a
TL
230 makeApiCall: false,
231 },
232 ],
34f956bc
DM
233 },
234 {
8acd4d9a 235 region: 'center',
34f956bc
DM
236 },
237 {
238 xtype: 'window',
239 closable: false,
240 resizable: false,
241 reference: 'loginwindow',
242 autoShow: true,
243 modal: true,
9abcae1b 244 width: 400,
34f956bc 245
9abcae1b 246 defaultFocus: 'usernameField',
34f956bc
DM
247
248 layout: {
8acd4d9a 249 type: 'auto',
34f956bc
DM
250 },
251
252 title: gettext('Proxmox Backup Server Login'),
253
254 items: [
255 {
256 xtype: 'form',
257 layout: {
8acd4d9a 258 type: 'form',
34f956bc
DM
259 },
260 defaultButton: 'loginButton',
261 url: '/api2/extjs/access/ticket',
262 reference: 'loginForm',
263
264 fieldDefaults: {
265 labelAlign: 'right',
8acd4d9a 266 allowBlank: false,
34f956bc
DM
267 },
268
269 items: [
270 {
271 xtype: 'textfield',
272 fieldLabel: gettext('User name'),
273 name: 'username',
274 itemId: 'usernameField',
9abcae1b 275 reference: 'usernameField',
8acd4d9a 276 stateId: 'login-username',
24b1c641 277 inputAttrTpl: 'autocomplete=username',
cd975e57
DM
278 bind: {
279 visible: "{!openid}",
280 disabled: "{openid}",
281 },
34f956bc
DM
282 },
283 {
284 xtype: 'textfield',
285 inputType: 'password',
286 fieldLabel: gettext('Password'),
287 name: 'password',
3a841004
TL
288 itemId: 'passwordField',
289 reference: 'passwordField',
24b1c641 290 inputAttrTpl: 'autocomplete=current-password',
cd975e57
DM
291 bind: {
292 visible: "{!openid}",
293 disabled: "{openid}",
294 },
9abcae1b 295 },
1d8ef0dc
DC
296 {
297 xtype: 'pmxRealmComboBox',
8acd4d9a 298 name: 'realm',
1d8ef0dc 299 },
9abcae1b
DM
300 {
301 xtype: 'proxmoxLanguageSelector',
302 fieldLabel: gettext('Language'),
a554ac19 303 value: Ext.util.Cookies.get('PBSLangCookie') || Proxmox.defaultLang || '__default__',
9abcae1b
DM
304 name: 'lang',
305 reference: 'langField',
8acd4d9a
TL
306 submitValue: false,
307 },
34f956bc
DM
308 ],
309 buttons: [
9abcae1b
DM
310 {
311 xtype: 'checkbox',
312 fieldLabel: gettext('Save User name'),
313 name: 'saveusername',
314 reference: 'saveunField',
315 stateId: 'login-saveusername',
316 labelWidth: 250,
317 labelAlign: 'right',
8acd4d9a 318 submitValue: false,
cd975e57
DM
319 bind: {
320 visible: "{!openid}",
321 },
9abcae1b 322 },
34f956bc 323 {
cd975e57
DM
324 bind: {
325 text: "{button_text}",
326 },
34f956bc 327 reference: 'loginButton',
8acd4d9a
TL
328 formBind: true,
329 },
330 ],
331 },
332 ],
333 },
334 ],
34f956bc 335});