/*global QRCode*/
Ext.define('Proxmox.form.PBSEncryptionCheckbox', {
extend: 'Ext.form.field.Checkbox',
xtype: 'pbsEncryptionCheckbox',
inputValue: true,
viewModel: {
data: {
value: null,
originalValue: null,
},
formulas: {
blabel: (get) => {
let v = get('value');
let original = get('originalValue');
if (!get('isCreate') && original) {
if (!v) {
return gettext('Warning: Existing encryption key will be deleted!');
}
return gettext('Active');
} else {
return gettext('Auto-generate a client encryption key, saved privately on cluster filesystem');
}
},
},
},
bind: {
value: '{value}',
boxLabel: '{blabel}',
},
resetOriginalValue: function() {
let me = this;
let vm = me.getViewModel();
vm.set('originalValue', me.value);
me.callParent(arguments);
},
getSubmitData: function() {
let me = this;
let val = me.getSubmitValue();
if (!me.isCreate) {
if (val === null) {
return { 'delete': 'encryption-key' };
} else if (val && !!val !== !!me.originalValue) {
return { 'encryption-key': 'autogen' };
}
} else if (val) {
return { 'encryption-key': 'autogen' };
}
return null;
},
initComponent: function() {
let me = this;
me.callParent();
let vm = me.getViewModel();
vm.set('isCreate', me.isCreate);
},
});
Ext.define('PVE.Storage.PBSKeyShow', {
extend: 'Ext.window.Window',
alias: ['widget.pveKeyShow'],
mixins: ['Proxmox.Mixin.CBind'],
width: 600,
modal: true,
resizable: false,
title: gettext('Important: Save your Encryption Key'),
// avoid that esc closes this by mistake, force user to more manual action
onEsc: Ext.emptyFn,
closable: false,
items: [
{
xtype: 'form',
layout: {
type: 'vbox',
align: 'stretch',
},
bodyPadding: 10,
border: false,
defaults: {
anchor: '100%',
border: false,
padding: '10 0 0 0',
},
items: [
{
xtype: 'textfield',
fieldLabel: gettext('Key'),
labelWidth: 30,
inputId: 'encryption-key-value',
cbind: {
value: '{key}',
},
editable: false,
},
{
xtype: 'component',
html: gettext('Keep your master key safe, but easily accessible for disaster recovery.')
+ '
' + gettext('We recommend the following safe-keeping strategy:'),
},
{
xtyp: 'container',
layout: 'hbox',
items: [
{
xtype: 'component',
html: '1. ' + gettext('Save the key in your password manager.'),
flex: 1,
},
{
xtype: 'button',
text: gettext('Copy Key'),
iconCls: 'fa fa-clipboard x-btn-icon-el-default-toolbar-small',
cls: 'x-btn-default-toolbar-small proxmox-inline-button',
width: 110,
handler: function(b) {
document.getElementById('encryption-key-value').select();
document.execCommand("copy");
},
},
],
},
{
xtype: 'container',
layout: 'hbox',
items: [
{
xtype: 'component',
html: '2. ' + gettext('Download the key to a USB (pen) drive, placed in secure vault.'),
flex: 1,
},
{
xtype: 'button',
text: gettext('Download'),
iconCls: 'fa fa-download x-btn-icon-el-default-toolbar-small',
cls: 'x-btn-default-toolbar-small proxmox-inline-button',
width: 110,
handler: function(b) {
let win = this.up('window');
let pveID = PVE.ClusterName || window.location.hostname;
let name = `pve-${pveID}-storage-${win.sid}.enc`;
let hiddenElement = document.createElement('a');
hiddenElement.href = 'data:attachment/text,' + encodeURI(win.key);
hiddenElement.target = '_blank';
hiddenElement.download = name;
hiddenElement.click();
},
},
],
},
{
xtype: 'container',
layout: 'hbox',
items: [
{
xtype: 'component',
html: '3. ' + gettext('Print as paperkey, laminated and placed in secure vault.'),
flex: 1,
},
{
xtype: 'button',
text: gettext('Print Key'),
iconCls: 'fa fa-print x-btn-icon-el-default-toolbar-small',
cls: 'x-btn-default-toolbar-small proxmox-inline-button',
width: 110,
handler: function(b) {
let win = this.up('window');
win.paperkey(win.key);
},
},
],
},
],
},
{
xtype: 'component',
border: false,
padding: '10 10 10 10',
userCls: 'pmx-hint',
html: gettext('Please save the encryption key - loosing it will render any backup created with it unuseable'),
},
],
buttons: [
{
text: gettext('Close'),
handler: function(b) {
let win = this.up('window');
win.close();
},
},
],
paperkey: function(key) {
let me = this;
const qrwidth = 500;
let qrdiv = document.createElement('div');
let qrcode = new QRCode(qrdiv, {
width: qrwidth,
height: qrwidth,
correctLevel: QRCode.CorrectLevel.H,
});
qrcode.makeCode(key);
let printFrame = document.createElement("iframe");
Object.assign(printFrame.style, {
position: "fixed",
right: "0",
bottom: "0",
width: "0",
height: "0",
border: "0",
});
const prettifiedKey = JSON.stringify(JSON.parse(key), null, 2);
const keyQrBase64 = qrdiv.children[0].toDataURL("image/png");
const html = `
-----BEGIN PROXMOX BACKUP KEY----- ${prettifiedKey} -----END PROXMOX BACKUP KEY-----