]>
git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/panel/TfaView.js
1 Ext
.define('pmx-tfa-users', {
2 extend
: 'Ext.data.Model',
7 url
: '/api2/json/access/tfa',
11 Ext
.define('pmx-tfa-entry', {
12 extend
: 'Ext.data.Model',
13 fields
: ['fullid', 'userid', 'type', 'description', 'created', 'enable'],
18 Ext
.define('Proxmox.panel.TfaView', {
19 extend
: 'Ext.grid.GridPanel',
20 alias
: 'widget.pmxTfaView',
21 mixins
: ['Proxmox.Mixin.CBind'],
23 title
: gettext('Second Factors'),
26 issuerName
: 'Proxmox',
29 cbindData: function(initialConfig
) {
32 yubicoEnabled
: me
.yubicoEnabled
,
39 autoDestroyRstore
: true,
40 model
: 'pmx-tfa-entry',
44 storeid
: 'pmx-tfa-entry',
45 model
: 'pmx-tfa-entry',
50 xclass
: 'Ext.app.ViewController',
52 init: function(view
) {
54 view
.tfaStore
= Ext
.create('Proxmox.data.UpdateStore', {
57 storeid
: 'pmx-tfa-users',
58 model
: 'pmx-tfa-users',
60 view
.tfaStore
.on('load', this.onLoad
, this);
61 view
.on('destroy', view
.tfaStore
.stopUpdate
);
62 Proxmox
.Utils
.monStoreErrors(view
, view
.tfaStore
);
65 reload: function() { this.getView().tfaStore
.load(); },
67 onLoad: function(store
, data
, success
) {
71 Ext
.Array
.each(data
, user
=> {
72 Ext
.Array
.each(user
.data
.entries
, entry
=> {
74 fullid
: `${user.id}/${entry.id}`,
77 description
: entry
.description
,
78 created
: entry
.created
,
84 let rstore
= this.getView().store
.rstore
;
85 rstore
.loadData(records
);
86 rstore
.fireEvent('load', rstore
, records
, true);
92 Ext
.create('Proxmox.window.AddTotp', {
94 issuerName
: me
.getView().issuerName
,
103 addWebauthn: function() {
106 Ext
.create('Proxmox.window.AddWebauthn', {
110 destroy
: () => me
.reload(),
115 addRecovery
: async
function() {
118 Ext
.create('Proxmox.window.AddTfaRecovery', {
121 destroy
: () => me
.reload(),
126 addYubico: function() {
129 Ext
.create('Proxmox.window.AddYubico', {
133 destroy
: () => me
.reload(),
138 editItem: function() {
140 let view
= me
.getView();
141 let selection
= view
.getSelection();
142 if (selection
.length
!== 1 || selection
[0].id
.endsWith("/recovery")) {
146 Ext
.create('Proxmox.window.TfaEdit', {
147 'tfa-id': selection
[0].data
.fullid
,
150 destroy
: () => me
.reload(),
155 renderUser
: fullid
=> fullid
.split('/')[0],
157 renderEnabled
: enabled
=> {
158 if (enabled
=== undefined) {
159 return Proxmox
.Utils
.yesText
;
161 return Proxmox
.Utils
.format_boolean(enabled
);
165 onRemoveButton: function(btn
, event
, record
) {
168 Ext
.create('Proxmox.tfa.confirmRemove', {
170 callback
: password
=> me
.removeItem(password
, record
),
175 removeItem
: async
function(password
, record
) {
178 if (password
!== null) {
179 password
= '?password=' + encodeURIComponent(password
);
185 me
.getView().mask(gettext('Please wait...'), 'x-mask-loading');
186 await Proxmox
.Async
.api2({
187 url
: `/api2/extjs/access/tfa/${record.id}${password}`,
192 Ext
.Msg
.alert(gettext('Error'), response
.result
.message
);
194 me
.getView().unmask();
204 itemdblclick
: 'editItem',
209 header
: gettext('User'),
213 renderer
: 'renderUser',
216 header
: gettext('Enabled'),
220 renderer
: 'renderEnabled',
223 header
: gettext('TFA Type'),
229 header
: gettext('Created'),
232 dataIndex
: 'created',
233 renderer
: t
=> !t
? 'N/A' : Proxmox
.Utils
.render_timestamp(t
),
236 header
: gettext('Description'),
239 dataIndex
: 'description',
240 renderer
: Ext
.String
.htmlEncode
,
247 text
: gettext('Add'),
253 text
: gettext('TOTP'),
255 iconCls
: 'fa fa-fw fa-clock-o',
259 text
: gettext('Webauthn'),
261 iconCls
: 'fa fa-fw fa-shield',
262 handler
: 'addWebauthn',
265 text
: gettext('Recovery Keys'),
267 iconCls
: 'fa fa-fw fa-file-text-o',
268 handler
: 'addRecovery',
271 text
: gettext('Yubico'),
273 iconCls
: 'fa fa-fw fa-yahoo',
274 handler
: 'addYubico',
276 hidden
: '{!yubicoEnabled}',
284 xtype
: 'proxmoxButton',
285 text
: gettext('Edit'),
287 enableFn
: rec
=> !rec
.id
.endsWith("/recovery"),
291 xtype
: 'proxmoxButton',
293 text
: gettext('Remove'),
294 getRecordName
: rec
=> rec
.data
.description
,
295 handler
: 'onRemoveButton',