]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/dc/UserView.js
ui: user view: add 'Unlock TFA' button
[pve-manager.git] / www / manager6 / dc / UserView.js
CommitLineData
ee7a4dad
DM
1Ext.define('PVE.dc.UserView', {
2 extend: 'Ext.grid.GridPanel',
3
4 alias: ['widget.pveUserView'],
5
ba93a9c6
DC
6 onlineHelp: 'pveum_users',
7
3ac2a964
DC
8 stateful: true,
9 stateId: 'grid-users',
10
8058410f 11 initComponent: function() {
ee7a4dad
DM
12 var me = this;
13
14 var caps = Ext.state.Manager.get('GuiCap');
15
16 var store = new Ext.data.Store({
17 id: "users",
69c33cff 18 model: 'pmx-users',
2a4971d8
TL
19 sorters: {
20 property: 'userid',
392e3cf1 21 direction: 'ASC',
f6710aac 22 },
ee7a4dad 23 });
42d48022 24 let reload = () => store.load();
ee7a4dad 25
42d48022 26 let sm = Ext.create('Ext.selection.RowModel', {});
ee7a4dad 27
42d48022 28 let remove_btn = Ext.create('Proxmox.button.StdRemoveButton', {
ee7a4dad 29 selModel: sm,
3b1ca3ff 30 baseurl: '/access/users/',
42a8a0b4 31 dangerous: true,
42d48022
TL
32 enableFn: rec => caps.access['User.Modify'] && rec.data.userid !== 'root@pam',
33 callback: () => reload(),
34 });
35 let run_editor = function() {
ee7a4dad
DM
36 var rec = sm.getSelection()[0];
37 if (!rec || !caps.access['User.Modify']) {
38 return;
39 }
42d48022
TL
40 Ext.create('PVE.dc.UserEdit', {
41 userid: rec.data.userid,
42 autoShow: true,
43 listeners: {
44 destroy: () => reload(),
45 },
46 });
ee7a4dad 47 };
42d48022 48 let edit_btn = new Proxmox.button.Button({
ee7a4dad
DM
49 text: gettext('Edit'),
50 disabled: true,
51 enableFn: function(rec) {
52 return !!caps.access['User.Modify'];
53 },
54 selModel: sm,
f6710aac 55 handler: run_editor,
ee7a4dad 56 });
42d48022 57 let pwchange_btn = new Proxmox.button.Button({
ee7a4dad
DM
58 text: gettext('Password'),
59 disabled: true,
60 selModel: sm,
60265958 61 enableFn: function(record) {
c0e3df11
TL
62 let type = record.data['realm-type'];
63 if (type) {
60265958
DC
64 if (PVE.Utils.authSchema[type]) {
65 return !!PVE.Utils.authSchema[type].pwchange;
66 }
67 }
68 return false;
69 },
ee7a4dad 70 handler: function(btn, event, rec) {
42d48022
TL
71 Ext.create('Proxmox.window.PasswordEdit', {
72 userid: rec.data.userid,
73 autoShow: true,
74 listeners: {
75 destroy: () => reload(),
76 },
ee7a4dad 77 });
f6710aac 78 },
ee7a4dad 79 });
24d2ed8c 80
98d48570
FG
81 var perm_btn = new Proxmox.button.Button({
82 text: gettext('Permissions'),
42d48022 83 disabled: true,
98d48570
FG
84 selModel: sm,
85 handler: function(btn, event, rec) {
42d48022
TL
86 Ext.create('PVE.dc.PermissionView', {
87 userid: rec.data.userid,
88 autoShow: true,
89 listeners: {
90 destroy: () => reload(),
91 },
98d48570 92 });
f6710aac 93 },
98d48570
FG
94 });
95
59706074
WB
96 let unlock_btn = new Proxmox.button.Button({
97 text: gettext('Unlock TFA'),
98 disabled: true,
99 selModel: sm,
100 enableFn: rec => !!(caps.access['User.Modify'] &&
101 (rec.data['totp-locked'] || rec.data['tfa-locked-until'])),
102 handler: function(btn, event, rec) {
103 Ext.Msg.confirm(
104 gettext(Ext.String.format('Unlock TFA authentication for {0}', rec.data.userid)),
105 gettext("Locked 2nd factors can happen if the user's password was leaked. Are you sure you want to unlock the user?"),
106 function(btn_response) {
107 if (btn_response === 'yes') {
108 Proxmox.Utils.API2Request({
109 url: `/access/users/${rec.data.userid}/unlock-tfa`,
110 waitMsgTarget: me,
111 method: 'PUT',
112 failure: function(response, options) {
113 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
114 },
115 success: function(response, options) {
116 reload();
117 },
118 });
119 }
120 },
121 );
122 },
123 });
124
ee7a4dad
DM
125 Ext.apply(me, {
126 store: store,
127 selModel: sm,
42d48022
TL
128 tbar: [
129 {
130 text: gettext('Add'),
131 disabled: !caps.access['User.Modify'],
132 handler: function() {
133 Ext.create('PVE.dc.UserEdit', {
134 autoShow: true,
135 listeners: {
136 destroy: () => reload(),
137 },
138 });
139 },
140 },
141 '-',
142 edit_btn,
143 remove_btn,
144 '-',
145 pwchange_btn,
42d48022
TL
146 '-',
147 perm_btn,
59706074
WB
148 '-',
149 unlock_btn,
42d48022 150 ],
ee7a4dad 151 viewConfig: {
f6710aac 152 trackOver: false,
ee7a4dad
DM
153 },
154 columns: [
155 {
156 header: gettext('User name'),
157 width: 200,
158 sortable: true,
b8dcc6d3 159 renderer: Proxmox.Utils.render_username,
f6710aac 160 dataIndex: 'userid',
ee7a4dad
DM
161 },
162 {
163 header: gettext('Realm'),
164 width: 100,
165 sortable: true,
b8dcc6d3 166 renderer: Proxmox.Utils.render_realm,
f6710aac 167 dataIndex: 'userid',
ee7a4dad
DM
168 },
169 {
170 header: gettext('Enabled'),
171 width: 80,
172 sortable: true,
e7ade592 173 renderer: Proxmox.Utils.format_boolean,
f6710aac 174 dataIndex: 'enable',
ee7a4dad
DM
175 },
176 {
177 header: gettext('Expire'),
178 width: 80,
179 sortable: true,
2a4971d8 180 renderer: Proxmox.Utils.format_expire,
f6710aac 181 dataIndex: 'expire',
ee7a4dad
DM
182 },
183 {
184 header: gettext('Name'),
185 width: 150,
186 sortable: true,
6ad4be69 187 renderer: PVE.Utils.render_full_name,
f6710aac 188 dataIndex: 'firstname',
ee7a4dad 189 },
bf0754fd
TL
190 {
191 header: 'TFA',
2387c194 192 width: 120,
bf0754fd 193 sortable: true,
2387c194 194 renderer: function(v, metaData, record) {
42d48022 195 let tfa_type = PVE.Parser.parseTfaType(v);
da898810
WB
196 if (tfa_type === undefined) {
197 return Proxmox.Utils.noText;
2387c194
WB
198 }
199
200 if (tfa_type !== 1) {
da898810
WB
201 return tfa_type;
202 }
2387c194
WB
203
204 let locked_until = record.data['tfa-locked-until'];
205 if (locked_until !== undefined) {
206 let now = new Date().getTime() / 1000;
207 if (locked_until > now) {
208 return gettext('Locked');
209 }
210 }
211
212 if (record.data['totp-locked']) {
213 return gettext('TOTP Locked');
214 }
215
216 return Proxmox.Utils.yesText;
bf0754fd 217 },
f6710aac 218 dataIndex: 'keys',
bf0754fd 219 },
ee7a4dad 220 {
ee7a4dad
DM
221 header: gettext('Comment'),
222 sortable: false,
2eb0767b 223 renderer: Ext.String.htmlEncode,
ee7a4dad 224 dataIndex: 'comment',
f6710aac
TL
225 flex: 1,
226 },
ee7a4dad
DM
227 ],
228 listeners: {
c0b3df6e 229 activate: reload,
f6710aac
TL
230 itemdblclick: run_editor,
231 },
ee7a4dad
DM
232 });
233
234 me.callParent();
f3c90a1d
DC
235
236 Proxmox.Utils.monStoreErrors(me, store);
f6710aac 237 },
ee7a4dad 238});