]> git.proxmox.com Git - pmg-gui.git/blob - js/UserView.js
mail proxy: transports: consitent add/edit/remove button
[pmg-gui.git] / js / UserView.js
1 Ext.define('pmg-users', {
2 extend: 'Ext.data.Model',
3 fields: [
4 'userid', 'firstname', 'lastname', 'email', 'comment',
5 'role', 'keys', 'realm', 'totp-lock',
6 { type: 'boolean', name: 'enable' },
7 { type: 'date', dateFormat: 'timestamp', name: 'expire' },
8 ],
9 proxy: {
10 type: 'proxmox',
11 url: "/api2/json/access/users",
12 },
13 idProperty: 'userid',
14 });
15
16 Ext.define('PMG.UserView', {
17 extend: 'Ext.grid.GridPanel',
18 alias: 'widget.pmgUserView',
19
20 store: {
21 autoLoad: true,
22 model: 'pmg-users',
23 sorters: [
24 {
25 property: 'realm',
26 direction: 'ASC',
27 },
28 {
29 property: 'userid',
30 direction: 'ASC',
31 },
32 ],
33 },
34
35 controller: {
36
37 xclass: 'Ext.app.ViewController',
38
39 init: function(view) {
40 Proxmox.Utils.monStoreErrors(view, view.store);
41 },
42
43 renderUsername: function(userid) {
44 return Ext.htmlEncode(userid.match(/^(.+)(@[^@]+)$/)[1]);
45 },
46
47 renderFullName: function(firstname, metaData, record) {
48 var first = firstname || '';
49 var last = record.data.lastname || '';
50 return Ext.htmlEncode(first + " " + last);
51 },
52
53 onAdd: function() {
54 var view = this.getView();
55
56 var win = Ext.create('PMG.UserEdit', {});
57 win.on('destroy', function() { view.reload(); });
58 win.show();
59 },
60
61 onEdit: function() {
62 var view = this.getView();
63
64 var rec = view.selModel.getSelection()[0];
65
66 var win = Ext.create('PMG.UserEdit', {
67 userid: rec.data.userid,
68 });
69 win.on('destroy', function() { view.reload(); });
70 win.show();
71 },
72
73 onPassword: function(btn, event, rec) {
74 var view = this.getView();
75
76 var win = Ext.create('Proxmox.window.PasswordEdit', {
77 userid: rec.data.userid,
78 });
79 win.on('destroy', function() { view.reload(); });
80 win.show();
81 },
82
83 onAfterRemove: function(btn, res) {
84 var view = this.getView();
85 view.reload();
86 },
87
88 onUnlockTfa: function(btn, event, rec) {
89 let me = this;
90 let view = me.getView();
91 Ext.Msg.confirm(
92 Ext.String.format(gettext('Unlock TFA authentication for {0}'), rec.data.userid),
93 gettext("Locked 2nd factors can happen if the user's password was leaked. Are you sure you want to unlock the user?"),
94 function(btn_response) {
95 if (btn_response === 'yes') {
96 Proxmox.Utils.API2Request({
97 url: `/access/users/${rec.data.userid}/unlock-tfa`,
98 waitMsgTarget: view,
99 method: 'PUT',
100 failure: function(response, options) {
101 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
102 },
103 success: function(response, options) {
104 view.reload();
105 },
106 });
107 }
108 },
109 );
110 },
111 },
112
113 listeners: {
114 scope: 'controller',
115 itemdblclick: 'onEdit',
116 },
117
118 tbar: [
119 {
120 text: gettext('Add'),
121 reference: 'addBtn',
122 handler: 'onAdd',
123 },
124 {
125 xtype: 'proxmoxButton',
126 text: gettext('Edit'),
127 disabled: true,
128 handler: 'onEdit',
129 },
130 {
131 xtype: 'proxmoxStdRemoveButton',
132 baseurl: '/access/users',
133 reference: 'removeBtn',
134 callback: 'onAfterRemove',
135 waitMsgTarget: true,
136 },
137 {
138 xtype: 'proxmoxButton',
139 text: gettext('Password'),
140 disabled: true,
141 handler: 'onPassword',
142 },
143 '-',
144 {
145 xtype: 'proxmoxButton',
146 text: gettext('Unlock TFA'),
147 handler: 'onUnlockTfa',
148 disabled: true,
149 enableFn: ({ data }) =>
150 data['totp-locked'] || (data['tfa-locked-until'] > (new Date().getTime() / 1000)),
151 },
152 ],
153
154 columns: [
155 {
156 header: gettext('User name'),
157 width: 200,
158 sortable: true,
159 renderer: 'renderUsername',
160 dataIndex: 'userid',
161 },
162 {
163 header: gettext('Realm'),
164 width: 100,
165 sortable: true,
166 dataIndex: 'realm',
167 },
168 {
169 header: gettext('Role'),
170 width: 150,
171 sortable: true,
172 renderer: PMG.Utils.format_user_role,
173 dataIndex: 'role',
174 },
175 {
176 header: gettext('Enabled'),
177 width: 80,
178 sortable: true,
179 renderer: Proxmox.Utils.format_boolean,
180 dataIndex: 'enable',
181 },
182 {
183 header: gettext('Expire'),
184 width: 80,
185 sortable: true,
186 renderer: Proxmox.Utils.format_expire,
187 dataIndex: 'expire',
188 },
189 {
190 header: gettext('Name'),
191 width: 150,
192 sortable: true,
193 renderer: 'renderFullName',
194 dataIndex: 'firstname',
195 },
196 {
197 header: gettext('TFA Lock'),
198 width: 120,
199 sortable: true,
200 dataIndex: 'totp-locked',
201 renderer: function(v, metaData, record) {
202 let locked_until = record.data['tfa-locked-until'];
203 if (locked_until !== undefined) {
204 let now = new Date().getTime() / 1000;
205 if (locked_until > now) {
206 return gettext('Locked');
207 }
208 }
209
210 if (record.data['totp-locked']) {
211 return gettext('TOTP Locked');
212 }
213
214 return Proxmox.Utils.noText;
215 },
216 },
217 {
218 header: gettext('Comment'),
219 sortable: false,
220 renderer: Ext.String.htmlEncode,
221 dataIndex: 'comment',
222 flex: 1,
223 },
224 ],
225
226 reload: function() {
227 var me = this;
228
229 me.store.load();
230 },
231 });