all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH manager 7/7] www: redirect user TFA button to TFA view
Date: Tue,  9 Nov 2021 12:27:14 +0100	[thread overview]
Message-ID: <20211109112721.130935-26-w.bumiller@proxmox.com> (raw)
In-Reply-To: <20211109112721.130935-1-w.bumiller@proxmox.com>

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
---
 www/manager6/Makefile         |   1 -
 www/manager6/StateProvider.js |   1 +
 www/manager6/Workspace.js     |   6 +-
 www/manager6/dc/TFAEdit.js    | 545 ----------------------------------
 www/manager6/dc/UserView.js   |  27 --
 5 files changed, 3 insertions(+), 577 deletions(-)
 delete mode 100644 www/manager6/dc/TFAEdit.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 4011d4e5..584c1f2a 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -149,7 +149,6 @@ JSSRC= 							\
 	dc/Summary.js					\
 	dc/Support.js					\
 	dc/SyncWindow.js				\
-	dc/TFAEdit.js					\
 	dc/Tasks.js					\
 	dc/TokenEdit.js					\
 	dc/TokenView.js					\
diff --git a/www/manager6/StateProvider.js b/www/manager6/StateProvider.js
index e835f402..fafbb112 100644
--- a/www/manager6/StateProvider.js
+++ b/www/manager6/StateProvider.js
@@ -47,6 +47,7 @@ Ext.define('PVE.StateProvider', {
     hprefix: 'v1',
 
     compDict: {
+        tfa: 54,
 	sdn: 53,
 	cloudinit: 52,
 	replication: 51,
diff --git a/www/manager6/Workspace.js b/www/manager6/Workspace.js
index 0e2a750b..37d772b8 100644
--- a/www/manager6/Workspace.js
+++ b/www/manager6/Workspace.js
@@ -386,10 +386,8 @@ Ext.define('PVE.StdWorkspace', {
 				    itemId: 'tfaitem',
 				    iconCls: 'fa fa-fw fa-lock',
 				    handler: function(btn, event, rec) {
-					var win = Ext.create('PVE.window.TFAEdit', {
-					    userid: Proxmox.UserName,
-					});
-					win.show();
+					Ext.state.Manager.getProvider().set('dctab', { value: 'tfa' }, true);
+					me.selectById('root');
 				    },
 				},
 				{
diff --git a/www/manager6/dc/TFAEdit.js b/www/manager6/dc/TFAEdit.js
deleted file mode 100644
index 57a73b39..00000000
--- a/www/manager6/dc/TFAEdit.js
+++ /dev/null
@@ -1,545 +0,0 @@
-/*global u2f,QRCode*/
-Ext.define('PVE.window.TFAEdit', {
-    extend: 'Ext.window.Window',
-    mixins: ['Proxmox.Mixin.CBind'],
-
-    onlineHelp: 'pveum_tfa_auth', // fake to ensure this gets a link target
-
-    modal: true,
-    resizable: false,
-    title: gettext('Two Factor Authentication'),
-    subject: 'TFA',
-    url: '/api2/extjs/access/tfa',
-    width: 512,
-
-    layout: {
-	type: 'vbox',
-	align: 'stretch',
-    },
-
-    updateQrCode: function() {
-	var me = this;
-	var values = me.lookup('totp_form').getValues();
-	var algorithm = values.algorithm;
-	if (!algorithm) {
-	    algorithm = 'SHA1';
-	}
-
-	me.qrcode.makeCode(
-	    'otpauth://totp/' +
-	    encodeURIComponent(values.issuer) +
-	    ':' +
-	    encodeURIComponent(me.userid) +
-	    '?secret=' + values.secret +
-	    '&period=' + values.step +
-	    '&digits=' + values.digits +
-	    '&algorithm=' + algorithm +
-	    '&issuer=' + encodeURIComponent(values.issuer),
-	);
-
-	me.lookup('challenge').setVisible(true);
-	me.down('#qrbox').setVisible(true);
-    },
-
-    showError: function(error) {
-	Ext.Msg.alert(
-	    gettext('Error'),
-	    Proxmox.Utils.render_u2f_error(error),
-	);
-    },
-
-    doU2FChallenge: function(res) {
-	let me = this;
-
-	let challenge = res.result.data;
-	me.lookup('password').setDisabled(true);
-	let msg = Ext.Msg.show({
-	    title: 'U2F: ' + gettext('Setup'),
-	    message: gettext('Please press the button on your U2F Device'),
-	    buttons: [],
-	});
-	Ext.Function.defer(function() {
-	    u2f.register(challenge.appId, [challenge], [], function(response) {
-		msg.close();
-		if (response.errorCode) {
-		    me.showError(response.errorCode);
-		} else {
-		    me.respondToU2FChallenge(response);
-		}
-	    });
-	}, 500, me);
-    },
-
-    respondToU2FChallenge: function(data) {
-	var me = this;
-	var params = {
-	    userid: me.userid,
-	    action: 'confirm',
-	    response: JSON.stringify(data),
-	};
-	if (Proxmox.UserName !== 'root@pam') {
-	    params.password = me.lookup('password').value;
-	}
-	Proxmox.Utils.API2Request({
-	    url: '/api2/extjs/access/tfa',
-	    params: params,
-	    method: 'PUT',
-	    success: function() {
-		me.close();
-		Ext.Msg.show({
-		    title: gettext('Success'),
-		    message: gettext('U2F Device successfully connected.'),
-		    buttons: Ext.Msg.OK,
-		});
-	    },
-	    failure: function(response, opts) {
-		Ext.Msg.alert(gettext('Error'), response.htmlStatus);
-	    },
-	});
-    },
-
-    viewModel: {
-	data: {
-	    in_totp_tab: true,
-	    tfa_required: false,
-	    tfa_type: null, // dependencies of formulas should not be undefined
-	    valid: false,
-	    u2f_available: true,
-	    secret: "",
-	},
-	formulas: {
-	    showTOTPVerifiction: function(get) {
-		return get('secret').length > 0 && get('canSetupTOTP');
-	    },
-	    canDeleteTFA: function(get) {
-		return get('tfa_type') !== null && !get('tfa_required');
-	    },
-	    canSetupTOTP: function(get) {
-		var tfa = get('tfa_type');
-		return tfa === null || tfa === 'totp' || tfa === 1;
-	    },
-	    canSetupU2F: function(get) {
-		var tfa = get('tfa_type');
-		return get('u2f_available') && (tfa === null || tfa === 'u2f' || tfa === 1);
-	    },
-	    secretEmpty: function(get) {
-		return get('secret').length === 0;
-	    },
-	    selectedTab: function(get) {
-		return (get('tfa_type') || 'totp') + '-panel';
-	    },
-	},
-    },
-
-    afterLoading: function(realm_tfa_type, user_tfa_type) {
-	var me = this;
-	var viewmodel = me.getViewModel();
-	if (user_tfa_type === 'oath') {
-	    user_tfa_type = 'totp';
-	    viewmodel.set('secret', '');
-	}
-
-	// if the user has no tfa, generate a secret for him
-	if (!user_tfa_type) {
-	    me.getController().randomizeSecret();
-	}
-
-	viewmodel.set('tfa_type', user_tfa_type || null);
-	if (!realm_tfa_type) {
-	    // There's no TFA enforced by the realm, everything works.
-	    viewmodel.set('u2f_available', true);
-	    viewmodel.set('tfa_required', false);
-	} else if (realm_tfa_type === 'oath') {
-	    // The realm explicitly requires TOTP
-	    if (user_tfa_type !== 'totp' && user_tfa_type !== null) {
-		// user had a different tfa method, so
-		// we have to change back to the totp tab and
-		// generate a secret
-		viewmodel.set('tfa_type', 'totp');
-		me.getController().randomizeSecret();
-	    }
-	    viewmodel.set('tfa_required', true);
-	    viewmodel.set('u2f_available', false);
-	} else {
-	    // The realm enforces some other TFA type (yubico)
-	    me.close();
-	    Ext.Msg.alert(
-		gettext('Error'),
-		Ext.String.format(
-		    gettext("Custom 2nd factor configuration is not supported on realms with '{0}' TFA."),
-		    realm_tfa_type,
-		),
-	    );
-	}
-    },
-
-    controller: {
-	xclass: 'Ext.app.ViewController',
-	control: {
-	    'field[qrupdate=true]': {
-		change: function() {
-		    this.getView().updateQrCode();
-		},
-	    },
-	    'field': {
-		validitychange: function(field, valid) {
-		    var me = this;
-		    var viewModel = me.getViewModel();
-		    var form = me.lookup('totp_form');
-		    var challenge = me.lookup('challenge');
-		    var password = me.lookup('password');
-		    viewModel.set('valid', form.isValid() && challenge.isValid() && password.isValid());
-		},
-	    },
-	    '#': {
-		show: function() {
-		    let view = this.getView();
-
-		    Proxmox.Utils.API2Request({
-			url: '/access/users/' + encodeURIComponent(view.userid) + '/tfa',
-			waitMsgTarget: view.down('#tfatabs'),
-			method: 'GET',
-			success: function(response, opts) {
-			    let data = response.result.data;
-			    view.afterLoading(data.realm, data.user);
-			},
-			failure: function(response, opts) {
-			    view.close();
-			    Ext.Msg.alert(gettext('Error'), response.htmlStatus);
-			},
-		    });
-
-		    view.qrdiv = document.createElement('center');
-		    view.qrcode = new QRCode(view.qrdiv, {
-			width: 256,
-			height: 256,
-			correctLevel: QRCode.CorrectLevel.M,
-		    });
-		    view.down('#qrbox').getEl().appendChild(view.qrdiv);
-
-		    if (Proxmox.UserName === 'root@pam') {
-			view.lookup('password').setVisible(false);
-			view.lookup('password').setDisabled(true);
-		    }
-		},
-	    },
-	    '#tfatabs': {
-		tabchange: function(panel, newcard) {
-		    this.getViewModel().set('in_totp_tab', newcard.itemId === 'totp-panel');
-		},
-	    },
-	},
-
-	applySettings: function() {
-	    let me = this;
-	    let values = me.lookup('totp_form').getValues();
-	    let params = {
-		userid: me.getView().userid,
-		action: 'new',
-		key: 'v2-' + values.secret,
-		config: PVE.Parser.printPropertyString({
-		    type: 'oath',
-		    digits: values.digits,
-		    step: values.step,
-		}),
-		// this is used to verify that the client generates the correct codes:
-		response: me.lookup('challenge').value,
-	    };
-
-	    if (Proxmox.UserName !== 'root@pam') {
-		params.password = me.lookup('password').value;
-	    }
-
-	    Proxmox.Utils.API2Request({
-		url: '/api2/extjs/access/tfa',
-		params: params,
-		method: 'PUT',
-		waitMsgTarget: me.getView(),
-		success: function(response, opts) {
-		    me.getView().close();
-		},
-		failure: function(response, opts) {
-		    Ext.Msg.alert(gettext('Error'), response.htmlStatus);
-		},
-	    });
-	},
-
-	deleteTFA: function() {
-	    let me = this;
-	    let params = {
-		userid: me.getView().userid,
-		action: 'delete',
-	    };
-
-	    if (Proxmox.UserName !== 'root@pam') {
-		params.password = me.lookup('password').value;
-	    }
-
-	    Proxmox.Utils.API2Request({
-		url: '/api2/extjs/access/tfa',
-		params: params,
-		method: 'PUT',
-		waitMsgTarget: me.getView(),
-		success: function(response, opts) {
-		    me.getView().close();
-		},
-		failure: function(response, opts) {
-		    Ext.Msg.alert(gettext('Error'), response.htmlStatus);
-		},
-	    });
-	},
-
-	randomizeSecret: function() {
-	    let me = this;
-	    let rnd = new Uint8Array(32);
-	    window.crypto.getRandomValues(rnd);
-	    let data = '';
-	    rnd.forEach(function(b) {
-		// secret must be base32, so just use the first 5 bits
-		b = b & 0x1f;
-		if (b < 26) {
-		    data += String.fromCharCode(b + 0x41); // A..Z
-		} else {
-		    data += String.fromCharCode(b-26 + 0x32); // 2..7
-		}
-	    });
-	    me.getViewModel().set('secret', data);
-	},
-
-	startU2FRegistration: function() {
-	    let me = this;
-
-	    let params = {
-		userid: me.getView().userid,
-		action: 'new',
-	    };
-
-	    if (Proxmox.UserName !== 'root@pam') {
-		params.password = me.lookup('password').value;
-	    }
-
-	    Proxmox.Utils.API2Request({
-		url: '/api2/extjs/access/tfa',
-		params: params,
-		method: 'PUT',
-		waitMsgTarget: me.getView(),
-		success: function(response) {
-		    me.getView().doU2FChallenge(response);
-		},
-		failure: function(response, opts) {
-		    Ext.Msg.alert(gettext('Error'), response.htmlStatus);
-		},
-	    });
-	},
-    },
-
-    items: [
-	{
-	    xtype: 'tabpanel',
-	    itemId: 'tfatabs',
-	    reference: 'tfatabs',
-	    border: false,
-	    bind: {
-		activeTab: '{selectedTab}',
-	    },
-	    items: [
-		{
-		    xtype: 'panel',
-		    title: 'TOTP',
-		    itemId: 'totp-panel',
-		    reference: 'totp_panel',
-		    tfa_type: 'totp',
-		    border: false,
-		    bind: {
-			disabled: '{!canSetupTOTP}',
-		    },
-		    layout: {
-			type: 'vbox',
-			align: 'stretch',
-		    },
-		    items: [
-			{
-			    xtype: 'form',
-			    layout: 'anchor',
-			    border: false,
-			    reference: 'totp_form',
-			    fieldDefaults: {
-				anchor: '100%',
-				padding: '0 5',
-			    },
-			    items: [
-				{
-				    xtype: 'displayfield',
-				    fieldLabel: gettext('User name'),
-				    renderer: Ext.String.htmlEncode,
-				    cbind: {
-					value: '{userid}',
-				    },
-				},
-				{
-				    layout: 'hbox',
-				    border: false,
-				    padding: '0 0 5 0',
-				    items: [{
-					xtype: 'textfield',
-					fieldLabel: gettext('Secret'),
-					emptyText: gettext('Unchanged'),
-					name: 'secret',
-					reference: 'tfa_secret',
-					regex: /^[A-Z2-7=]+$/,
-					regexText: 'Must be base32 [A-Z2-7=]',
-					maskRe: /[A-Z2-7=]/,
-					qrupdate: true,
-					bind: {
-					    value: "{secret}",
-					},
-					flex: 4,
-				    },
-				    {
-					xtype: 'button',
-					text: gettext('Randomize'),
-					reference: 'randomize_button',
-					handler: 'randomizeSecret',
-					flex: 1,
-				    }],
-				},
-				{
-				    xtype: 'numberfield',
-				    fieldLabel: gettext('Time period'),
-				    name: 'step',
-				    // Google Authenticator ignores this and generates bogus data
-				    hidden: true,
-				    value: 30,
-				    minValue: 10,
-				    qrupdate: true,
-				},
-				{
-				    xtype: 'numberfield',
-				    fieldLabel: gettext('Digits'),
-				    name: 'digits',
-				    value: 6,
-				    // Google Authenticator ignores this and generates bogus data
-				    hidden: true,
-				    minValue: 6,
-				    maxValue: 8,
-				    qrupdate: true,
-				},
-				{
-				    xtype: 'textfield',
-				    fieldLabel: gettext('Issuer Name'),
-				    name: 'issuer',
-				    value: 'Proxmox Web UI',
-				    qrupdate: true,
-				},
-			    ],
-			},
-			{
-			    xtype: 'box',
-			    itemId: 'qrbox',
-			    visible: false, // will be enabled when generating a qr code
-			    bind: {
-				visible: '{!secretEmpty}',
-			    },
-			    style: {
-				'background-color': 'white',
-				padding: '5px',
-				width: '266px',
-				height: '266px',
-			    },
-			},
-			{
-			    xtype: 'textfield',
-			    fieldLabel: gettext('Verification Code'),
-			    allowBlank: false,
-			    reference: 'challenge',
-			    bind: {
-				disabled: '{!showTOTPVerifiction}',
-				visible: '{showTOTPVerifiction}',
-			    },
-			    padding: '0 5',
-			    emptyText: gettext('Scan QR code and enter TOTP auth. code to verify'),
-			},
-		    ],
-		},
-		{
-		    title: 'U2F',
-		    itemId: 'u2f-panel',
-		    reference: 'u2f_panel',
-		    tfa_type: 'u2f',
-		    border: false,
-		    padding: '5 5',
-		    layout: {
-			type: 'vbox',
-			align: 'middle',
-		    },
-		    bind: {
-			disabled: '{!canSetupU2F}',
-		    },
-		    items: [
-			{
-			    xtype: 'label',
-			    width: 500,
-			    text: gettext('To register a U2F device, connect the device, then click the button and follow the instructions.'),
-			},
-		    ],
-		},
-	    ],
-	},
-	{
-	    xtype: 'textfield',
-	    inputType: 'password',
-	    fieldLabel: gettext('Password'),
-	    minLength: 5,
-	    reference: 'password',
-	    allowBlank: false,
-	    validateBlank: true,
-	    padding: '0 0 5 5',
-	    emptyText: gettext('verify current password'),
-	},
-    ],
-
-    buttons: [
-	{
-	    xtype: 'proxmoxHelpButton',
-	},
-	'->',
-	{
-	    text: gettext('Apply'),
-	    handler: 'applySettings',
-	    bind: {
-		hidden: '{!in_totp_tab}',
-		disabled: '{!valid}',
-	    },
-	},
-	{
-	    xtype: 'button',
-	    text: gettext('Register U2F Device'),
-	    handler: 'startU2FRegistration',
-	    bind: {
-		hidden: '{in_totp_tab}',
-		disabled: '{tfa_type}',
-	    },
-	},
-	{
-	    text: gettext('Delete'),
-	    reference: 'delete_button',
-	    disabled: true,
-	    handler: 'deleteTFA',
-	    bind: {
-		disabled: '{!canDeleteTFA}',
-	    },
-	},
-    ],
-
-    initComponent: function() {
-	var me = this;
-
-	if (!me.userid) {
-	    throw "no userid given";
-	}
-
-	me.callParent();
-
-	Ext.GlobalEvents.fireEvent('proxmoxShowHelp', 'pveum_tfa_auth');
-    },
-});
diff --git a/www/manager6/dc/UserView.js b/www/manager6/dc/UserView.js
index 9c84bf7d..f397731d 100644
--- a/www/manager6/dc/UserView.js
+++ b/www/manager6/dc/UserView.js
@@ -77,32 +77,6 @@ Ext.define('PVE.dc.UserView', {
 		});
 	    },
 	});
-	let tfachange_btn = new Proxmox.button.Button({
-	    text: 'TFA',
-	    disabled: true,
-	    selModel: sm,
-	    enableFn: function(record) {
-		let type = record.data['realm-type'];
-		if (type) {
-		    if (PVE.Utils.authSchema[type]) {
-			return !!PVE.Utils.authSchema[type].tfa;
-		    }
-		}
-		return false;
-	    },
-	    handler: function(btn, event, rec) {
-		var d = rec.data;
-		var tfa_type = PVE.Parser.parseTfaType(d.keys);
-		Ext.create('PVE.window.TFAEdit', {
-		    tfa_type: tfa_type,
-		    userid: d.userid,
-		    autoShow: true,
-		    listeners: {
-			destroy: () => reload(),
-		    },
-		});
-	    },
-	});
 
 	var perm_btn = new Proxmox.button.Button({
 	    text: gettext('Permissions'),
@@ -140,7 +114,6 @@ Ext.define('PVE.dc.UserView', {
 		remove_btn,
 		'-',
 		pwchange_btn,
-		tfachange_btn,
 		'-',
 		perm_btn,
 	    ],
-- 
2.30.2





  parent reply	other threads:[~2021-11-09 11:28 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-09 11:26 [pve-devel] [PATCH multiple 0/9] PBS-like TFA support in PVE Wolfgang Bumiller
2021-11-09 11:26 ` [pve-devel] [PATCH proxmox-perl-rs 1/6] import basic skeleton Wolfgang Bumiller
2021-11-09 11:26 ` [pve-devel] [PATCH proxmox-perl-rs 2/6] import pve-rs Wolfgang Bumiller
2021-11-09 11:26 ` [pve-devel] [PATCH proxmox-perl-rs 3/6] move apt to /perl-apt, use PERLMOD_PRODUCT env var Wolfgang Bumiller
2021-11-09 11:26 ` [pve-devel] [PATCH proxmox-perl-rs 4/6] pve: add tfa api Wolfgang Bumiller
2021-11-09 11:26 ` [pve-devel] [PATCH proxmox-perl-rs 5/6] build fix: pmg-rs is not here yet Wolfgang Bumiller
2021-11-09 11:26 ` [pve-devel] [PATCH proxmox-perl-rs 6/6] Add some dev tips to a README Wolfgang Bumiller
2021-11-09 11:26 ` [pve-devel] [PATCH access-control 01/10] use rust parser for TFA config Wolfgang Bumiller
2021-11-09 11:26 ` [pve-devel] [PATCH access-control 02/10] update read_user_tfa_type call Wolfgang Bumiller
2021-11-09 11:26 ` [pve-devel] [PATCH access-control 03/10] use PBS-like auth api call flow Wolfgang Bumiller
2021-11-09 11:26 ` [pve-devel] [PATCH access-control 04/10] handle yubico authentication in new path Wolfgang Bumiller
2021-11-09 11:27 ` [pve-devel] [PATCH access-control 05/10] move TFA api path into its own module Wolfgang Bumiller
2021-11-09 11:27 ` [pve-devel] [PATCH access-control 06/10] add pbs-style TFA API implementation Wolfgang Bumiller
2021-11-09 11:27 ` [pve-devel] [PATCH access-control 07/10] support registering yubico otp keys Wolfgang Bumiller
2021-11-09 11:27 ` [pve-devel] [PATCH access-control 08/10] update tfa cleanup when deleting users Wolfgang Bumiller
2021-11-09 11:27 ` [pve-devel] [PATCH access-control 09/10] pveum: update tfa delete command Wolfgang Bumiller
2021-11-09 11:27 ` [pve-devel] [PATCH access-control 10/10] set/remove 'x' for tfa keys in user.cfg in new api Wolfgang Bumiller
2021-11-09 11:27 ` [pve-devel] [PATCH cluster] add webauthn configuration to datacenter.cfg Wolfgang Bumiller
2021-11-10 10:12   ` [pve-devel] applied: " Thomas Lamprecht
2021-11-09 11:27 ` [pve-devel] [PATCH common] Ticket: uri-escape colons Wolfgang Bumiller
2021-11-09 12:26   ` [pve-devel] applied: " Thomas Lamprecht
2021-11-09 11:27 ` [pve-devel] [PATCH manager 1/7] www: use render_u2f_error from wtk Wolfgang Bumiller
2021-11-09 11:27 ` [pve-devel] [PATCH manager 2/7] www: use UserSelector " Wolfgang Bumiller
2021-11-09 11:27 ` [pve-devel] [PATCH manager 3/7] use u2f-api.js and qrcode.min.js " Wolfgang Bumiller
2021-11-09 11:27 ` [pve-devel] [PATCH manager 4/7] www: switch to new tfa login format Wolfgang Bumiller
2021-11-09 11:27 ` [pve-devel] [PATCH manager 5/7] www: use af-address-book-o for realms Wolfgang Bumiller
2021-11-09 11:27 ` [pve-devel] [PATCH manager 6/7] www: add TFA view to config Wolfgang Bumiller
2021-11-09 11:27 ` Wolfgang Bumiller [this message]
2021-11-09 11:27 ` [pve-devel] [PATCH widget-toolkit 1/7] add pmxUserSelector Wolfgang Bumiller
2021-11-10  8:29   ` [pve-devel] applied: " Dominik Csapak
2021-11-09 11:27 ` [pve-devel] [PATCH widget-toolkit 2/7] add Utils used for u2f and webauthn Wolfgang Bumiller
2021-11-10  8:30   ` [pve-devel] applied: " Dominik Csapak
2021-11-09 11:27 ` [pve-devel] [PATCH widget-toolkit 3/7] add u2f-api.js and qrcode.min.js Wolfgang Bumiller
2021-11-10  8:31   ` Dominik Csapak
2021-11-09 11:27 ` [pve-devel] [PATCH widget-toolkit 4/7] add Proxmox.window.TfaLoginWindow Wolfgang Bumiller
2021-11-10  8:30   ` [pve-devel] applied: " Dominik Csapak
2021-11-09 11:27 ` [pve-devel] [PATCH widget-toolkit 5/7] add totp, wa and recovery creation and tfa edit windows Wolfgang Bumiller
2021-11-10  8:30   ` [pve-devel] applied: " Dominik Csapak
2021-11-09 11:27 ` [pve-devel] [PATCH widget-toolkit 6/7] add Proxmox.panel.TfaView Wolfgang Bumiller
2021-11-10  8:30   ` [pve-devel] applied: " Dominik Csapak
2021-11-09 11:27 ` [pve-devel] [PATCH widget-toolkit 7/7] add yubico otp windows & login support Wolfgang Bumiller
2021-11-10  8:30   ` [pve-devel] applied: " Dominik Csapak
2021-11-11 15:52 ` [pve-devel] applied-series: [PATCH multiple 0/9] PBS-like TFA support in PVE Thomas Lamprecht

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211109112721.130935-26-w.bumiller@proxmox.com \
    --to=w.bumiller@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal