Adds backup functionality
This commit is contained in:
@@ -14,21 +14,30 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="section backup-section">
|
||||
<h3>Backup</h3>
|
||||
<h3 v-if="backupId">Update Backup</h3>
|
||||
<h3 v-else>Make a Backup</h3>
|
||||
<Input
|
||||
v-model="backupPassword"
|
||||
name="backup-password"
|
||||
label="Choose a Password"
|
||||
:label="backupId ? 'Enter your Password' : 'Choose a Password'"
|
||||
layout="vertical"
|
||||
type="password"
|
||||
/>
|
||||
<Button>
|
||||
<template v-slot:text>Backup</template>
|
||||
<Button :click="checkPass">
|
||||
<template v-slot:text>{{backupId ? 'Update Backup' : 'Backup'}}</template>
|
||||
<template v-slot:icon><IconBackup /></template>
|
||||
</Button>
|
||||
<div class="results-view" v-if="backupId">
|
||||
<span class="backup-id-label">Your Backup ID: </span>
|
||||
<pre class="backup-id-value">{{ backupId }}</pre>
|
||||
<span class="backup-id-note">
|
||||
This is used to restore from backups later.
|
||||
So keep it, along with your password somewhere safe.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section restore-section">
|
||||
<h3>Restore</h3>
|
||||
<h3>Restore a Backup</h3>
|
||||
<Input
|
||||
v-model="restoreCode"
|
||||
name="restore-code"
|
||||
@@ -50,10 +59,13 @@
|
||||
|
||||
<script>
|
||||
|
||||
import sha256 from 'crypto-js/sha256';
|
||||
import Button from '@/components/FormElements/Button';
|
||||
import Input from '@/components/FormElements/Input';
|
||||
import IconBackup from '@/assets/interface-icons/config-backup.svg';
|
||||
import IconRestore from '@/assets/interface-icons/config-restore.svg';
|
||||
import { backup } from '@/utils/CloudBackup';
|
||||
import { localStorageKeys } from '@/utils/defaults';
|
||||
|
||||
export default {
|
||||
name: 'CloudBackupRestore',
|
||||
@@ -65,6 +77,7 @@ export default {
|
||||
backupPassword: '',
|
||||
restorePassword: '',
|
||||
restoreCode: '',
|
||||
backupId: localStorage[localStorageKeys.BACKUP_ID] || '',
|
||||
};
|
||||
},
|
||||
components: {
|
||||
@@ -73,6 +86,44 @@ export default {
|
||||
IconBackup,
|
||||
IconRestore,
|
||||
},
|
||||
methods: {
|
||||
checkPass() {
|
||||
const savedHash = localStorage[localStorageKeys.BACKUP_HASH] || undefined;
|
||||
if (!savedHash || savedHash === this.makeHash(this.backupPassword)) {
|
||||
this.makeBackup();
|
||||
} else {
|
||||
this.showErrorMsg('Incorrect password. Please enter the password you used last time.');
|
||||
}
|
||||
},
|
||||
makeBackup() {
|
||||
backup(this.config, this.backupPassword)
|
||||
.then((response) => {
|
||||
if (!response.data || response.data.errorMsg || !response.data.backupId) {
|
||||
this.showErrorMsg(response.data.errorMsg || 'Error');
|
||||
} else { // All clear, no error
|
||||
this.updateAfterBackup(response.data.backupId);
|
||||
}
|
||||
}).catch(() => {
|
||||
this.showErrorMsg('Unable to process request');
|
||||
});
|
||||
},
|
||||
updateAfterBackup(backupId) {
|
||||
const hash = this.makeHash(this.backupPassword);
|
||||
localStorage.setItem(localStorageKeys.BACKUP_ID, backupId);
|
||||
localStorage.setItem(localStorageKeys.BACKUP_HASH, hash);
|
||||
this.showSuccessMsg('Backup Completed Succesfully');
|
||||
this.backupPassword = '';
|
||||
},
|
||||
showErrorMsg(errorMsg) {
|
||||
this.$toasted.show(errorMsg, { className: 'toast-error' });
|
||||
},
|
||||
showSuccessMsg(msg) {
|
||||
this.$toasted.show(msg, { className: 'toast-success' });
|
||||
},
|
||||
makeHash(pass) {
|
||||
return sha256(pass).toString();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -112,8 +163,29 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
div.results-view {
|
||||
width: 16rem;
|
||||
margin: 0.5rem auto;
|
||||
padding: 0.5rem 0.75rem;
|
||||
box-sizing: border-box;
|
||||
border: 1px dashed var(--config-settings-color);
|
||||
border-radius: var(--curve-factor);
|
||||
text-align: left;
|
||||
.backup-id-label, .backup-id-value {
|
||||
display: inline;
|
||||
font-size: 1rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
.backup-id-note {
|
||||
font-size: 0.8rem;
|
||||
display: block;
|
||||
opacity: 0.8;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Overide form element colors, so that config menu can be themed by user */
|
||||
input, button {
|
||||
input, button, {
|
||||
color: var(--config-settings-color);
|
||||
border: 1px solid var(--config-settings-color);
|
||||
background: none;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<button>
|
||||
<button @click="click()">
|
||||
<slot name="text"></slot>
|
||||
<slot name="icon"></slot>
|
||||
</button>
|
||||
@@ -11,6 +11,7 @@ export default {
|
||||
name: 'Button',
|
||||
props: {
|
||||
text: String,
|
||||
click: Function,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</modal>
|
||||
|
||||
<!-- Modal for cloud backup and restore options -->
|
||||
<modal :name="modalNames.CLOUD_BACKUP" :resizable="true" width="60%" height="60%"
|
||||
<modal :name="modalNames.CLOUD_BACKUP" :resizable="true" width="65%" height="60%"
|
||||
@closed="$emit('modalChanged', false)">
|
||||
<CloudBackupRestore :config="combineConfig()" />
|
||||
</modal>
|
||||
|
||||
Reference in New Issue
Block a user