]>
Commit | Line | Data |
---|---|---|
488be4c2 DC |
1 | Ext.define('PVE.node.ACMEAccountCreate', { |
2 | extend: 'Proxmox.window.Edit', | |
fc40915c | 3 | mixins: ['Proxmox.Mixin.CBind'], |
488be4c2 | 4 | |
04a8058e | 5 | width: 450, |
488be4c2 DC |
6 | title: gettext('Register Account'), |
7 | isCreate: true, | |
8 | method: 'POST', | |
9 | submitText: gettext('Register'), | |
10 | url: '/cluster/acme/account', | |
11 | showTaskViewer: true, | |
fc40915c | 12 | defaultExists: false, |
488be4c2 DC |
13 | |
14 | items: [ | |
c0afd5cc DC |
15 | { |
16 | xtype: 'proxmoxtextfield', | |
e023535e | 17 | fieldLabel: gettext('Account Name'), |
c0afd5cc | 18 | name: 'name', |
fc40915c DC |
19 | cbind: { |
20 | emptyText: (get) => get('defaultExists') ? '' : 'default', | |
21 | allowBlank: (get) => !get('defaultExists'), | |
22 | }, | |
c0afd5cc | 23 | }, |
04a8058e DC |
24 | { |
25 | xtype: 'textfield', | |
26 | name: 'contact', | |
27 | vtype: 'email', | |
28 | allowBlank: false, | |
f6710aac | 29 | fieldLabel: gettext('E-Mail'), |
04a8058e | 30 | }, |
488be4c2 DC |
31 | { |
32 | xtype: 'proxmoxComboGrid', | |
33 | name: 'directory', | |
34 | allowBlank: false, | |
35 | valueField: 'url', | |
36 | displayField: 'name', | |
37 | fieldLabel: gettext('ACME Directory'), | |
38 | store: { | |
39 | autoLoad: true, | |
40 | fields: ['name', 'url'], | |
41 | idProperty: ['name'], | |
42 | proxy: { | |
43 | type: 'proxmox', | |
f6710aac | 44 | url: '/api2/json/cluster/acme/directories', |
488be4c2 DC |
45 | }, |
46 | sorters: { | |
47 | property: 'name', | |
392e3cf1 | 48 | direction: 'ASC', |
f6710aac | 49 | }, |
488be4c2 DC |
50 | }, |
51 | listConfig: { | |
52 | columns: [ | |
53 | { | |
54 | header: gettext('Name'), | |
55 | dataIndex: 'name', | |
f6710aac | 56 | flex: 1, |
488be4c2 DC |
57 | }, |
58 | { | |
59 | header: gettext('URL'), | |
60 | dataIndex: 'url', | |
f6710aac TL |
61 | flex: 1, |
62 | }, | |
63 | ], | |
488be4c2 DC |
64 | }, |
65 | listeners: { | |
66 | change: function(combogrid, value) { | |
67 | var me = this; | |
68 | if (!value) { | |
69 | return; | |
70 | } | |
71 | ||
72 | var disp = me.up('window').down('#tos_url_display'); | |
73 | var field = me.up('window').down('#tos_url'); | |
74 | var checkbox = me.up('window').down('#tos_checkbox'); | |
75 | ||
76 | disp.setValue(gettext('Loading')); | |
77 | field.setValue(undefined); | |
78 | checkbox.setValue(undefined); | |
1d5c5ba1 | 79 | checkbox.setHidden(true); |
488be4c2 DC |
80 | |
81 | Proxmox.Utils.API2Request({ | |
7fb70c3b | 82 | url: '/cluster/acme/meta', |
488be4c2 DC |
83 | method: 'GET', |
84 | params: { | |
f6710aac | 85 | directory: value, |
488be4c2 DC |
86 | }, |
87 | success: function(response, opt) { | |
7fb70c3b FG |
88 | if (response.result.data.termsOfService) { |
89 | field.setValue(response.result.data.termsOfService); | |
90 | disp.setValue(response.result.data.termsOfService); | |
91 | checkbox.setHidden(false); | |
92 | } else { | |
93 | disp.setValue(undefined); | |
94 | } | |
488be4c2 DC |
95 | }, |
96 | failure: function(response, opt) { | |
97 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
f6710aac | 98 | }, |
488be4c2 | 99 | }); |
f6710aac TL |
100 | }, |
101 | }, | |
488be4c2 DC |
102 | }, |
103 | { | |
104 | xtype: 'displayfield', | |
105 | itemId: 'tos_url_display', | |
488be4c2 | 106 | renderer: PVE.Utils.render_optional_url, |
f6710aac | 107 | name: 'tos_url_display', |
488be4c2 DC |
108 | }, |
109 | { | |
110 | xtype: 'hidden', | |
111 | itemId: 'tos_url', | |
f6710aac | 112 | name: 'tos_url', |
488be4c2 DC |
113 | }, |
114 | { | |
115 | xtype: 'proxmoxcheckbox', | |
116 | itemId: 'tos_checkbox', | |
04a8058e | 117 | boxLabel: gettext('Accept TOS'), |
488be4c2 DC |
118 | submitValue: false, |
119 | validateValue: function(value) { | |
120 | if (value && this.checked) { | |
121 | return true; | |
122 | } | |
123 | return false; | |
f6710aac | 124 | }, |
488be4c2 | 125 | }, |
f6710aac | 126 | ], |
488be4c2 DC |
127 | |
128 | }); | |
129 | ||
130 | Ext.define('PVE.node.ACMEAccountView', { | |
131 | extend: 'Proxmox.window.Edit', | |
132 | ||
133 | width: 600, | |
134 | fieldDefaults: { | |
f6710aac | 135 | labelWidth: 140, |
488be4c2 DC |
136 | }, |
137 | ||
138 | title: gettext('Account'), | |
139 | ||
140 | items: [ | |
141 | { | |
142 | xtype: 'displayfield', | |
143 | fieldLabel: gettext('E-Mail'), | |
f6710aac | 144 | name: 'email', |
488be4c2 DC |
145 | }, |
146 | { | |
147 | xtype: 'displayfield', | |
148 | fieldLabel: gettext('Created'), | |
f6710aac | 149 | name: 'createdAt', |
488be4c2 DC |
150 | }, |
151 | { | |
152 | xtype: 'displayfield', | |
153 | fieldLabel: gettext('Status'), | |
f6710aac | 154 | name: 'status', |
488be4c2 DC |
155 | }, |
156 | { | |
157 | xtype: 'displayfield', | |
158 | fieldLabel: gettext('Directory'), | |
159 | renderer: PVE.Utils.render_optional_url, | |
f6710aac | 160 | name: 'directory', |
488be4c2 DC |
161 | }, |
162 | { | |
163 | xtype: 'displayfield', | |
164 | fieldLabel: gettext('Terms of Services'), | |
165 | renderer: PVE.Utils.render_optional_url, | |
f6710aac TL |
166 | name: 'tos', |
167 | }, | |
488be4c2 DC |
168 | ], |
169 | ||
170 | initComponent: function() { | |
171 | var me = this; | |
172 | ||
173 | if (!me.accountname) { | |
174 | throw "no account name defined"; | |
175 | } | |
176 | ||
177 | me.url = '/cluster/acme/account/' + me.accountname; | |
178 | ||
179 | me.callParent(); | |
180 | ||
181 | // hide OK/Reset button, because we just want to show data | |
182 | me.down('toolbar[dock=bottom]').setVisible(false); | |
183 | ||
184 | me.load({ | |
185 | success: function(response) { | |
186 | var data = response.result.data; | |
187 | data.email = data.account.contact[0]; | |
188 | data.createdAt = data.account.createdAt; | |
189 | data.status = data.account.status; | |
190 | me.setValues(data); | |
f6710aac | 191 | }, |
488be4c2 | 192 | }); |
f6710aac | 193 | }, |
488be4c2 DC |
194 | }); |
195 | ||
8e49a93f DC |
196 | Ext.define('PVE.node.ACMEDomainEdit', { |
197 | extend: 'Proxmox.window.Edit', | |
198 | alias: 'widget.pveACMEDomainEdit', | |
199 | ||
200 | subject: gettext('Domain'), | |
201 | isCreate: false, | |
3c6b4c80 | 202 | width: 450, |
eff602d8 | 203 | onlineHelp: 'sysadmin_certificate_management', |
8e49a93f DC |
204 | |
205 | items: [ | |
206 | { | |
207 | xtype: 'inputpanel', | |
208 | onGetValues: function(values) { | |
209 | let me = this; | |
210 | let win = me.up('pveACMEDomainEdit'); | |
211 | let nodeconfig = win.nodeconfig; | |
212 | let olddomain = win.domain || {}; | |
213 | ||
214 | let params = { | |
215 | digest: nodeconfig.digest, | |
216 | }; | |
217 | ||
218 | let configkey = olddomain.configkey; | |
6ac64c3a | 219 | let acmeObj = PVE.Parser.parseACME(nodeconfig.acme); |
8e49a93f DC |
220 | |
221 | if (values.type === 'dns') { | |
222 | if (!olddomain.configkey || olddomain.configkey === 'acme') { | |
223 | // look for first free slot | |
224 | for (let i = 0; i < PVE.Utils.acmedomain_count; i++) { | |
225 | if (nodeconfig[`acmedomain${i}`] === undefined) { | |
226 | configkey = `acmedomain${i}`; | |
227 | break; | |
228 | } | |
229 | } | |
230 | if (olddomain.domain) { | |
231 | // we have to remove the domain from the acme domainlist | |
232 | PVE.Utils.remove_domain_from_acme(acmeObj, olddomain.domain); | |
233 | params.acme = PVE.Parser.printACME(acmeObj); | |
234 | } | |
235 | } | |
236 | ||
237 | delete values.type; | |
238 | params[configkey] = PVE.Parser.printPropertyString(values, 'domain'); | |
239 | } else { | |
240 | if (olddomain.configkey && olddomain.configkey !== 'acme') { | |
241 | // delete the old dns entry | |
242 | params.delete = [olddomain.configkey]; | |
243 | } | |
244 | ||
245 | // add new, remove old and make entries unique | |
246 | PVE.Utils.add_domain_to_acme(acmeObj, values.domain); | |
247 | PVE.Utils.remove_domain_from_acme(acmeObj, olddomain.domain); | |
248 | params.acme = PVE.Parser.printACME(acmeObj); | |
249 | } | |
250 | ||
251 | return params; | |
252 | }, | |
253 | items: [ | |
254 | { | |
255 | xtype: 'proxmoxKVComboBox', | |
256 | name: 'type', | |
3c6b4c80 | 257 | fieldLabel: gettext('Challenge Type'), |
8e49a93f | 258 | allowBlank: false, |
3c6b4c80 | 259 | value: 'standalone', |
8e49a93f | 260 | comboItems: [ |
9c164224 | 261 | ['standalone', 'HTTP'], |
8e49a93f DC |
262 | ['dns', 'DNS'], |
263 | ], | |
264 | validator: function(value) { | |
265 | let me = this; | |
266 | let win = me.up('pveACMEDomainEdit'); | |
267 | let oldconfigkey = win.domain ? win.domain.configkey : undefined; | |
268 | let val = me.getValue(); | |
269 | if (val === 'dns' && (!oldconfigkey || oldconfigkey === 'acme')) { | |
270 | // we have to check if there is a 'acmedomain' slot left | |
271 | let found = false; | |
272 | for (let i = 0; i < PVE.Utils.acmedomain_count; i++) { | |
273 | if (!win.nodeconfig[`acmedomain${i}`]) { | |
274 | found = true; | |
275 | } | |
276 | } | |
277 | if (!found) { | |
278 | return gettext('Only 5 Domains with type DNS can be configured'); | |
279 | } | |
280 | } | |
281 | ||
282 | return true; | |
283 | }, | |
284 | listeners: { | |
285 | change: function(cb, value) { | |
286 | let me = this; | |
287 | let view = me.up('pveACMEDomainEdit'); | |
a94b71fb TL |
288 | let pluginField = view.down('field[name=plugin]'); |
289 | pluginField.setDisabled(value !== 'dns'); | |
290 | pluginField.setHidden(value !== 'dns'); | |
8e49a93f DC |
291 | }, |
292 | }, | |
293 | }, | |
294 | { | |
295 | xtype: 'hidden', | |
296 | name: 'alias', | |
297 | }, | |
8e49a93f DC |
298 | { |
299 | xtype: 'pveACMEPluginSelector', | |
300 | name: 'plugin', | |
301 | disabled: true, | |
a94b71fb | 302 | hidden: true, |
8e49a93f DC |
303 | allowBlank: false, |
304 | }, | |
a94b71fb TL |
305 | { |
306 | xtype: 'proxmoxtextfield', | |
307 | name: 'domain', | |
308 | allowBlank: false, | |
309 | vtype: 'DnsName', | |
310 | value: '', | |
311 | fieldLabel: gettext('Domain'), | |
312 | }, | |
8e49a93f DC |
313 | ], |
314 | }, | |
315 | ], | |
316 | ||
317 | initComponent: function() { | |
318 | let me = this; | |
319 | ||
320 | if (!me.nodename) { | |
321 | throw 'no nodename given'; | |
322 | } | |
323 | ||
324 | if (!me.nodeconfig) { | |
325 | throw 'no nodeconfig given'; | |
326 | } | |
327 | ||
328 | me.isCreate = !me.domain; | |
8b779b4a TL |
329 | if (me.isCreate) { |
330 | me.domain = `${me.nodename}.`; // TODO: FQDN of node | |
331 | } | |
8e49a93f DC |
332 | |
333 | me.url = `/api2/extjs/nodes/${me.nodename}/config`; | |
334 | ||
335 | me.callParent(); | |
336 | ||
337 | if (!me.isCreate) { | |
338 | me.setValues(me.domain); | |
8b779b4a TL |
339 | } else { |
340 | me.setValues({ domain: me.domain }); | |
8e49a93f DC |
341 | } |
342 | }, | |
343 | }); | |
344 | ||
fd254233 DC |
345 | Ext.define('pve-acme-domains', { |
346 | extend: 'Ext.data.Model', | |
347 | fields: ['domain', 'type', 'alias', 'plugin', 'configkey'], | |
348 | idProperty: 'domain', | |
349 | }); | |
350 | ||
488be4c2 | 351 | Ext.define('PVE.node.ACME', { |
fd254233 DC |
352 | extend: 'Ext.grid.Panel', |
353 | alias: 'widget.pveACMEView', | |
488be4c2 DC |
354 | |
355 | margin: '10 0 0 0', | |
356 | title: 'ACME', | |
357 | ||
e666f688 DC |
358 | emptyText: gettext('No Domains configured'), |
359 | ||
fd254233 DC |
360 | viewModel: { |
361 | data: { | |
1580b605 | 362 | domaincount: 0, |
3071cc5b DC |
363 | account: undefined, // the account we display |
364 | configaccount: undefined, // the account set in the config | |
fd254233 | 365 | accountEditable: false, |
a8b6a80a | 366 | accountsAvailable: false, |
fd254233 DC |
367 | }, |
368 | ||
369 | formulas: { | |
1580b605 | 370 | canOrder: (get) => !!get('account') && get('domaincount') > 0, |
80bd3209 | 371 | editBtnIcon: (get) => 'fa black fa-' + (get('accountEditable') ? 'check' : 'pencil'), |
8fc2d938 | 372 | editBtnText: (get) => get('accountEditable') ? gettext('Apply') : gettext('Edit'), |
a8b6a80a TL |
373 | accountTextHidden: (get) => get('accountEditable') || !get('accountsAvailable'), |
374 | accountValueHidden: (get) => !get('accountEditable') || !get('accountsAvailable'), | |
fd254233 DC |
375 | }, |
376 | }, | |
377 | ||
378 | controller: { | |
379 | xclass: 'Ext.app.ViewController', | |
380 | ||
a8b6a80a | 381 | init: function(view) { |
a8b6a80a TL |
382 | let accountSelector = this.lookup('accountselector'); |
383 | accountSelector.store.on('load', this.onAccountsLoad, this); | |
384 | }, | |
385 | ||
386 | onAccountsLoad: function(store, records, success) { | |
80bd3209 DC |
387 | let me = this; |
388 | let vm = me.getViewModel(); | |
3071cc5b | 389 | let configaccount = vm.get('configaccount'); |
a8b6a80a | 390 | vm.set('accountsAvailable', records.length > 0); |
80bd3209 DC |
391 | if (me.autoChangeAccount && records.length > 0) { |
392 | me.changeAccount(records[0].data.name, () => { | |
31c9edc8 | 393 | vm.set('accountEditable', false); |
80bd3209 | 394 | me.reload(); |
31c9edc8 TL |
395 | }); |
396 | me.autoChangeAccount = false; | |
3071cc5b DC |
397 | } else if (configaccount) { |
398 | if (store.findExact('name', configaccount) !== -1) { | |
399 | vm.set('account', configaccount); | |
400 | } else { | |
401 | vm.set('account', null); | |
402 | } | |
31c9edc8 | 403 | } |
a8b6a80a TL |
404 | }, |
405 | ||
fd254233 DC |
406 | addDomain: function() { |
407 | let me = this; | |
408 | let view = me.getView(); | |
409 | ||
410 | Ext.create('PVE.node.ACMEDomainEdit', { | |
411 | nodename: view.nodename, | |
412 | nodeconfig: view.nodeconfig, | |
413 | apiCallDone: function() { | |
414 | me.reload(); | |
415 | }, | |
416 | }).show(); | |
417 | }, | |
418 | ||
419 | editDomain: function() { | |
420 | let me = this; | |
421 | let view = me.getView(); | |
422 | ||
423 | let selection = view.getSelection(); | |
424 | if (selection.length < 1) return; | |
425 | ||
426 | Ext.create('PVE.node.ACMEDomainEdit', { | |
427 | nodename: view.nodename, | |
428 | nodeconfig: view.nodeconfig, | |
429 | domain: selection[0].data, | |
430 | apiCallDone: function() { | |
431 | me.reload(); | |
432 | }, | |
433 | }).show(); | |
434 | }, | |
435 | ||
436 | removeDomain: function() { | |
437 | let me = this; | |
438 | let view = me.getView(); | |
439 | let selection = view.getSelection(); | |
440 | if (selection.length < 1) return; | |
441 | ||
442 | let rec = selection[0].data; | |
443 | let params = {}; | |
444 | if (rec.configkey !== 'acme') { | |
445 | params.delete = rec.configkey; | |
446 | } else { | |
447 | let acme = PVE.Parser.parseACME(view.nodeconfig.acme); | |
448 | PVE.Utils.remove_domain_from_acme(acme, rec.domain); | |
449 | params.acme = PVE.Parser.printACME(acme); | |
450 | } | |
451 | ||
452 | Proxmox.Utils.API2Request({ | |
453 | method: 'PUT', | |
454 | url: `/nodes/${view.nodename}/config`, | |
455 | params, | |
456 | success: function(response, opt) { | |
457 | me.reload(); | |
458 | }, | |
459 | failure: function(response, opt) { | |
460 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
461 | }, | |
462 | }); | |
463 | }, | |
464 | ||
465 | toggleEditAccount: function() { | |
466 | let me = this; | |
467 | let vm = me.getViewModel(); | |
468 | let editable = vm.get('accountEditable'); | |
469 | if (editable) { | |
470 | me.changeAccount(vm.get('account'), function() { | |
471 | vm.set('accountEditable', false); | |
472 | me.reload(); | |
473 | }); | |
474 | } else { | |
475 | vm.set('accountEditable', true); | |
476 | } | |
477 | }, | |
478 | ||
479 | changeAccount: function(account, callback) { | |
480 | let me = this; | |
481 | let view = me.getView(); | |
482 | let params = {}; | |
483 | ||
484 | let acme = PVE.Parser.parseACME(view.nodeconfig.acme); | |
485 | acme.account = account; | |
486 | params.acme = PVE.Parser.printACME(acme); | |
487 | ||
488 | Proxmox.Utils.API2Request({ | |
489 | method: 'PUT', | |
490 | waitMsgTarget: view, | |
491 | url: `/nodes/${view.nodename}/config`, | |
492 | params, | |
493 | success: function(response, opt) { | |
494 | if (Ext.isFunction(callback)) { | |
495 | callback(); | |
496 | } | |
497 | }, | |
498 | failure: function(response, opt) { | |
499 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
500 | }, | |
501 | }); | |
502 | }, | |
503 | ||
504 | order: function() { | |
505 | let me = this; | |
506 | let view = me.getView(); | |
507 | ||
508 | Proxmox.Utils.API2Request({ | |
509 | method: 'POST', | |
510 | params: { | |
511 | force: 1, | |
512 | }, | |
513 | url: `/nodes/${view.nodename}/certificates/acme/certificate`, | |
514 | success: function(response, opt) { | |
515 | Ext.create('Proxmox.window.TaskViewer', { | |
516 | upid: response.result.data, | |
517 | taskDone: function(success) { | |
518 | me.orderFinished(success); | |
519 | }, | |
520 | }).show(); | |
521 | }, | |
522 | failure: function(response, opt) { | |
523 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
524 | }, | |
525 | }); | |
526 | }, | |
527 | ||
528 | orderFinished: function(success) { | |
529 | if (!success) return; | |
72cfb3d4 FS |
530 | // reload only if the Web UI is open on the same node that the cert was ordered for |
531 | if (this.getView().nodename !== Proxmox.NodeName) { | |
532 | return; | |
533 | } | |
fd254233 DC |
534 | var txt = gettext('pveproxy will be restarted with new certificates, please reload the GUI!'); |
535 | Ext.getBody().mask(txt, ['pve-static-mask']); | |
536 | // reload after 10 seconds automatically | |
537 | Ext.defer(function() { | |
538 | window.location.reload(true); | |
539 | }, 10000); | |
540 | }, | |
541 | ||
542 | reload: function() { | |
543 | let me = this; | |
544 | let view = me.getView(); | |
545 | view.rstore.load(); | |
546 | }, | |
547 | ||
31c9edc8 TL |
548 | addAccount: function() { |
549 | let me = this; | |
550 | Ext.create('PVE.node.ACMEAccountCreate', { | |
551 | autoShow: true, | |
552 | taskDone: function() { | |
553 | me.reload(); | |
554 | let accountSelector = me.lookup('accountselector'); | |
555 | me.autoChangeAccount = true; | |
556 | accountSelector.store.load(); | |
557 | }, | |
558 | }); | |
fd254233 DC |
559 | }, |
560 | }, | |
561 | ||
488be4c2 DC |
562 | tbar: [ |
563 | { | |
fd254233 DC |
564 | xtype: 'proxmoxButton', |
565 | text: gettext('Add'), | |
566 | handler: 'addDomain', | |
567 | selModel: false, | |
568 | }, | |
569 | { | |
570 | xtype: 'proxmoxButton', | |
571 | text: gettext('Edit'), | |
572 | disabled: true, | |
573 | handler: 'editDomain', | |
574 | }, | |
575 | { | |
576 | xtype: 'proxmoxStdRemoveButton', | |
577 | handler: 'removeDomain', | |
488be4c2 | 578 | }, |
fd254233 | 579 | '-', |
488be4c2 DC |
580 | { |
581 | xtype: 'button', | |
fd254233 | 582 | reference: 'order', |
a8b6a80a | 583 | text: gettext('Order Certificates Now'), |
31c9edc8 | 584 | bind: { |
1580b605 | 585 | disabled: '{!canOrder}', |
31c9edc8 | 586 | }, |
fd254233 DC |
587 | handler: 'order', |
588 | }, | |
589 | '-', | |
590 | { | |
591 | xtype: 'displayfield', | |
a8b6a80a TL |
592 | value: gettext('Using Account') + ':', |
593 | bind: { | |
594 | hidden: '{!accountsAvailable}', | |
595 | }, | |
fd254233 DC |
596 | }, |
597 | { | |
598 | xtype: 'displayfield', | |
599 | reference: 'accounttext', | |
3071cc5b | 600 | renderer: (val) => val || Proxmox.Utils.NoneText, |
fd254233 DC |
601 | bind: { |
602 | value: '{account}', | |
a8b6a80a | 603 | hidden: '{accountTextHidden}', |
fd254233 DC |
604 | }, |
605 | }, | |
606 | { | |
607 | xtype: 'pveACMEAccountSelector', | |
608 | hidden: true, | |
609 | reference: 'accountselector', | |
610 | bind: { | |
611 | value: '{account}', | |
a8b6a80a | 612 | hidden: '{accountValueHidden}', |
fd254233 | 613 | }, |
488be4c2 DC |
614 | }, |
615 | { | |
616 | xtype: 'button', | |
fd254233 | 617 | iconCls: 'fa black fa-pencil', |
fd254233 | 618 | bind: { |
a8b6a80a | 619 | iconCls: '{editBtnIcon}', |
8fc2d938 | 620 | text: '{editBtnText}', |
a8b6a80a | 621 | hidden: '{!accountsAvailable}', |
fd254233 DC |
622 | }, |
623 | handler: 'toggleEditAccount', | |
488be4c2 | 624 | }, |
a8b6a80a TL |
625 | { |
626 | xtype: 'displayfield', | |
627 | value: gettext('No Account available.'), | |
628 | bind: { | |
629 | hidden: '{accountsAvailable}', | |
630 | }, | |
631 | }, | |
488be4c2 DC |
632 | { |
633 | xtype: 'button', | |
fd254233 DC |
634 | hidden: true, |
635 | reference: 'accountlink', | |
31c9edc8 | 636 | text: gettext('Add ACME Account'), |
a8b6a80a TL |
637 | bind: { |
638 | hidden: '{accountsAvailable}', | |
639 | }, | |
31c9edc8 | 640 | handler: 'addAccount', |
80bd3209 | 641 | }, |
488be4c2 DC |
642 | ], |
643 | ||
fd254233 DC |
644 | updateStore: function(store, records, success) { |
645 | let me = this; | |
646 | let data = []; | |
647 | let rec; | |
648 | if (success && records.length > 0) { | |
649 | rec = records[0]; | |
650 | } else { | |
651 | rec = { | |
80bd3209 | 652 | data: {}, |
fd254233 | 653 | }; |
488be4c2 | 654 | } |
488be4c2 | 655 | |
fd254233 | 656 | me.nodeconfig = rec.data; // save nodeconfig for updates |
488be4c2 | 657 | |
fd254233 | 658 | let account = 'default'; |
488be4c2 | 659 | |
fd254233 DC |
660 | if (rec.data.acme) { |
661 | let obj = PVE.Parser.parseACME(rec.data.acme); | |
662 | (obj.domains || []).forEach(domain => { | |
663 | if (domain === '') return; | |
664 | let record = { | |
665 | domain, | |
666 | type: 'standalone', | |
667 | configkey: 'acme', | |
668 | }; | |
669 | data.push(record); | |
670 | }); | |
488be4c2 | 671 | |
fd254233 DC |
672 | if (obj.account) { |
673 | account = obj.account; | |
674 | } | |
675 | } | |
488be4c2 | 676 | |
fd254233 DC |
677 | let vm = me.getViewModel(); |
678 | let oldaccount = vm.get('account'); | |
679 | ||
680 | // account changed, and we do not edit currently, load again to verify | |
681 | if (oldaccount !== account && !vm.get('accountEditable')) { | |
3071cc5b DC |
682 | vm.set('configaccount', account); |
683 | me.lookup('accountselector').store.load(); | |
fd254233 | 684 | } |
488be4c2 | 685 | |
fd254233 DC |
686 | for (let i = 0; i < PVE.Utils.acmedomain_count; i++) { |
687 | let acmedomain = rec.data[`acmedomain${i}`]; | |
688 | if (!acmedomain) continue; | |
488be4c2 | 689 | |
fd254233 DC |
690 | let record = PVE.Parser.parsePropertyString(acmedomain, 'domain'); |
691 | record.type = 'dns'; | |
692 | record.configkey = `acmedomain${i}`; | |
693 | data.push(record); | |
694 | } | |
695 | ||
1580b605 | 696 | vm.set('domaincount', data.length); |
fd254233 | 697 | me.store.loadData(data, false); |
488be4c2 DC |
698 | }, |
699 | ||
700 | listeners: { | |
fd254233 | 701 | itemdblclick: 'editDomain', |
488be4c2 DC |
702 | }, |
703 | ||
fd254233 DC |
704 | columns: [ |
705 | { | |
706 | dataIndex: 'domain', | |
3c6b4c80 | 707 | flex: 5, |
fd254233 DC |
708 | text: gettext('Domain'), |
709 | }, | |
710 | { | |
711 | dataIndex: 'type', | |
3c6b4c80 | 712 | flex: 1, |
fd254233 DC |
713 | text: gettext('Type'), |
714 | }, | |
715 | { | |
716 | dataIndex: 'plugin', | |
3c6b4c80 | 717 | flex: 1, |
fd254233 DC |
718 | text: gettext('Plugin'), |
719 | }, | |
720 | ], | |
488be4c2 DC |
721 | |
722 | initComponent: function() { | |
723 | var me = this; | |
724 | ||
725 | if (!me.nodename) { | |
726 | throw "no nodename given"; | |
727 | } | |
728 | ||
fd254233 | 729 | me.rstore = Ext.create('Proxmox.data.UpdateStore', { |
1b90cfc6 | 730 | interval: 10 * 1000, |
fd254233 DC |
731 | autoStart: true, |
732 | storeid: `pve-node-domains-${me.nodename}`, | |
733 | proxy: { | |
734 | type: 'proxmox', | |
735 | url: `/api2/json/nodes/${me.nodename}/config`, | |
736 | }, | |
737 | }); | |
738 | ||
739 | me.store = Ext.create('Ext.data.Store', { | |
740 | model: 'pve-acme-domains', | |
741 | sorters: 'domain', | |
742 | }); | |
488be4c2 DC |
743 | |
744 | me.callParent(); | |
fd254233 DC |
745 | me.mon(me.rstore, 'load', 'updateStore', me); |
746 | Proxmox.Utils.monStoreErrors(me, me.rstore); | |
1f249769 | 747 | me.on('destroy', me.rstore.stopUpdate, me.rstore); |
fd254233 | 748 | }, |
488be4c2 | 749 | }); |