mobile: implement login with OTP based TFA enabled
roughly copied over from the full-fledged manager UI, but enough differences between manager <-> mobile and ExtJS <-> Sencha Touch to just adapt it here instead of having a force-shared implementation with lots of corner case checks and even more callback methods.. Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
ab17ebcdc4
commit
627548d6fb
@ -1,6 +1,67 @@
|
||||
Ext.define('PVE.Login', {
|
||||
extend: 'Ext.form.Panel',
|
||||
alias: "widget.pveLogin",
|
||||
|
||||
handleTFA: function(username, ticketResponse) {
|
||||
let me = this;
|
||||
let errlabel = me.down('#signInFailedLabel');
|
||||
|
||||
// set auth cookie with half-loggedin ticket for TFA
|
||||
ticketResponse.LoggedOut = true;
|
||||
Proxmox.Utils.setAuthData(ticketResponse);
|
||||
|
||||
if (Ext.isDefined(ticketResponse.U2FChallenge)) {
|
||||
Ext.Msg.show({
|
||||
title: 'Error - U2F not implemented',
|
||||
message: 'The U2F two factor authentication is not yet implemented on mobile.',
|
||||
buttons: Ext.MessageBox.CANCEL,
|
||||
});
|
||||
errlabel.show();
|
||||
} else {
|
||||
|
||||
Ext.Msg.show({
|
||||
title: 'Two-Factor Authentication',
|
||||
message: 'Please enter your OTP verification code:',
|
||||
buttons: Ext.MessageBox.OKCANCEL,
|
||||
prompt: {
|
||||
xtype: 'tfacode',
|
||||
},
|
||||
fn: function(buttonId, code) {
|
||||
if (buttonId === "cancel") {
|
||||
Proxmox.LoggedOut = false;
|
||||
Proxmox.Utils.authClear();
|
||||
} else {
|
||||
me.mask({
|
||||
xtype: 'loadmask',
|
||||
message: 'Loading...'
|
||||
});
|
||||
Proxmox.Utils.API2Request({
|
||||
url: '/api2/extjs/access/tfa',
|
||||
params: { response: code },
|
||||
method: 'POST',
|
||||
timeout: 5000, // it'll delay both success & failure
|
||||
success: function(resp, opts) {
|
||||
me.unmask();
|
||||
// Fill in what we copy over from the 1st factor:
|
||||
let authdata = resp.result.data;
|
||||
authdata.CSRFPreventionToken = Proxmox.CSRFPreventionToken;
|
||||
authdata.username = username;
|
||||
// Finish login, sets real cookie and loads page
|
||||
PVE.Workspace.updateLoginData(authdata);
|
||||
},
|
||||
failure: function(resp, opts) {
|
||||
me.unmask();
|
||||
Proxmox.Utils.authClear();
|
||||
errlabel.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
config: {
|
||||
title: 'Login',
|
||||
padding: 10,
|
||||
@ -30,33 +91,10 @@ Ext.define('PVE.Login', {
|
||||
name: 'password',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
itemId: 'otpField',
|
||||
placeHolder: gettext('OTP'),
|
||||
name: 'otp',
|
||||
allowBlank: false,
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
xtype: 'pveRealmSelector',
|
||||
itemId: 'realmSelectorField',
|
||||
name: 'realm',
|
||||
listeners: {
|
||||
change: function(f, value) {
|
||||
var form = this.up('formpanel');
|
||||
|
||||
var otp_field = form.down('#otpField');
|
||||
|
||||
if (f.needOTP(value)) {
|
||||
otp_field.setHidden(false);
|
||||
otp_field.enable();
|
||||
} else {
|
||||
otp_field.setHidden(true);
|
||||
otp_field.disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -75,33 +113,36 @@ Ext.define('PVE.Login', {
|
||||
ui: 'action',
|
||||
text: 'Log In',
|
||||
handler: function() {
|
||||
var form = this.up('formpanel');
|
||||
var form = this.up('formpanel');
|
||||
|
||||
var usernameField = form.down('#userNameTextField'),
|
||||
passwordField = form.down('#passwordTextField'),
|
||||
realmField = form.down('#realmSelectorField'),
|
||||
otpField = form.down('#otpField'),
|
||||
label = form.down('#signInFailedLabel');
|
||||
passwordField = form.down('#passwordTextField'),
|
||||
realmField = form.down('#realmSelectorField'),
|
||||
errlabel = form.down('#signInFailedLabel');
|
||||
|
||||
label.hide();
|
||||
errlabel.hide();
|
||||
|
||||
var username = usernameField.getValue();
|
||||
var password = passwordField.getValue();
|
||||
var realm = realmField.getValue();
|
||||
var otp = otpField.getValue();
|
||||
|
||||
Proxmox.Utils.API2Request({
|
||||
url: '/access/ticket',
|
||||
method: 'POST',
|
||||
waitMsgTarget: form,
|
||||
params: { username: username, password: password, realm: realm, otp: otp},
|
||||
params: { username: username, password: password, realm: realm },
|
||||
failure: function(response, options) {
|
||||
label.show();
|
||||
errlabel.show();
|
||||
},
|
||||
success: function(response, options) {
|
||||
usernameField.setValue('');
|
||||
passwordField.setValue('');
|
||||
PVE.Workspace.updateLoginData(response.result.data);
|
||||
|
||||
let data = response.result.data;
|
||||
if (Ext.isDefined(data.NeedTFA)) {
|
||||
form.handleTFA(username, data);
|
||||
} else {
|
||||
PVE.Workspace.updateLoginData(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -109,3 +150,16 @@ Ext.define('PVE.Login', {
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
Ext.define('PVE.field.TFACode', {
|
||||
extend: 'Ext.field.Text',
|
||||
xtype: 'tfacode',
|
||||
|
||||
config: {
|
||||
component: {
|
||||
type: 'number'
|
||||
},
|
||||
maxLength: 6,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user