pve-manager/www/manager6/dc/UserView.js
Thomas Lamprecht 22fcd0069a ui: user view: fix calling order of gettext
One must not call gettext on the already formatted string, as we
cannot translate it for any possible value, rather the format string
it self needs to be gettext'd, then the translator can position the
variable template placeholders however it's correct for their
language without having to care about any value this could be called
with.

Fixes: d057929f ("ui: user view: fix calling order of gettext")
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2023-06-09 09:53:03 +02:00

239 lines
5.2 KiB
JavaScript

Ext.define('PVE.dc.UserView', {
extend: 'Ext.grid.GridPanel',
alias: ['widget.pveUserView'],
onlineHelp: 'pveum_users',
stateful: true,
stateId: 'grid-users',
initComponent: function() {
var me = this;
var caps = Ext.state.Manager.get('GuiCap');
var store = new Ext.data.Store({
id: "users",
model: 'pmx-users',
sorters: {
property: 'userid',
direction: 'ASC',
},
});
let reload = () => store.load();
let sm = Ext.create('Ext.selection.RowModel', {});
let remove_btn = Ext.create('Proxmox.button.StdRemoveButton', {
selModel: sm,
baseurl: '/access/users/',
dangerous: true,
enableFn: rec => caps.access['User.Modify'] && rec.data.userid !== 'root@pam',
callback: () => reload(),
});
let run_editor = function() {
var rec = sm.getSelection()[0];
if (!rec || !caps.access['User.Modify']) {
return;
}
Ext.create('PVE.dc.UserEdit', {
userid: rec.data.userid,
autoShow: true,
listeners: {
destroy: () => reload(),
},
});
};
let edit_btn = new Proxmox.button.Button({
text: gettext('Edit'),
disabled: true,
enableFn: function(rec) {
return !!caps.access['User.Modify'];
},
selModel: sm,
handler: run_editor,
});
let pwchange_btn = new Proxmox.button.Button({
text: gettext('Password'),
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].pwchange;
}
}
return false;
},
handler: function(btn, event, rec) {
Ext.create('Proxmox.window.PasswordEdit', {
userid: rec.data.userid,
autoShow: true,
listeners: {
destroy: () => reload(),
},
});
},
});
var perm_btn = new Proxmox.button.Button({
text: gettext('Permissions'),
disabled: true,
selModel: sm,
handler: function(btn, event, rec) {
Ext.create('PVE.dc.PermissionView', {
userid: rec.data.userid,
autoShow: true,
listeners: {
destroy: () => reload(),
},
});
},
});
let unlock_btn = new Proxmox.button.Button({
text: gettext('Unlock TFA'),
disabled: true,
selModel: sm,
enableFn: rec => !!(caps.access['User.Modify'] &&
(rec.data['totp-locked'] || rec.data['tfa-locked-until'])),
handler: function(btn, event, rec) {
Ext.Msg.confirm(
Ext.String.format(gettext('Unlock TFA authentication for {0}'), rec.data.userid)),
gettext("Locked 2nd factors can happen if the user's password was leaked. Are you sure you want to unlock the user?"),
function(btn_response) {
if (btn_response === 'yes') {
Proxmox.Utils.API2Request({
url: `/access/users/${rec.data.userid}/unlock-tfa`,
waitMsgTarget: me,
method: 'PUT',
failure: function(response, options) {
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
},
success: function(response, options) {
reload();
},
});
}
},
);
},
});
Ext.apply(me, {
store: store,
selModel: sm,
tbar: [
{
text: gettext('Add'),
disabled: !caps.access['User.Modify'],
handler: function() {
Ext.create('PVE.dc.UserEdit', {
autoShow: true,
listeners: {
destroy: () => reload(),
},
});
},
},
'-',
edit_btn,
remove_btn,
'-',
pwchange_btn,
'-',
perm_btn,
'-',
unlock_btn,
],
viewConfig: {
trackOver: false,
},
columns: [
{
header: gettext('User name'),
width: 200,
sortable: true,
renderer: Proxmox.Utils.render_username,
dataIndex: 'userid',
},
{
header: gettext('Realm'),
width: 100,
sortable: true,
renderer: Proxmox.Utils.render_realm,
dataIndex: 'userid',
},
{
header: gettext('Enabled'),
width: 80,
sortable: true,
renderer: Proxmox.Utils.format_boolean,
dataIndex: 'enable',
},
{
header: gettext('Expire'),
width: 80,
sortable: true,
renderer: Proxmox.Utils.format_expire,
dataIndex: 'expire',
},
{
header: gettext('Name'),
width: 150,
sortable: true,
renderer: PVE.Utils.render_full_name,
dataIndex: 'firstname',
},
{
header: 'TFA',
width: 120,
sortable: true,
renderer: function(v, metaData, record) {
let tfa_type = PVE.Parser.parseTfaType(v);
if (tfa_type === undefined) {
return Proxmox.Utils.noText;
}
if (tfa_type !== 1) {
return tfa_type;
}
let locked_until = record.data['tfa-locked-until'];
if (locked_until !== undefined) {
let now = new Date().getTime() / 1000;
if (locked_until > now) {
return gettext('Locked');
}
}
if (record.data['totp-locked']) {
return gettext('TOTP Locked');
}
return Proxmox.Utils.yesText;
},
dataIndex: 'keys',
},
{
header: gettext('Comment'),
sortable: false,
renderer: Ext.String.htmlEncode,
dataIndex: 'comment',
flex: 1,
},
],
listeners: {
activate: reload,
itemdblclick: run_editor,
},
});
me.callParent();
Proxmox.Utils.monStoreErrors(me, store);
},
});