From 0e43e91d847a9b2578fad7bef346d30ba818153b Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Mon, 24 May 2021 18:59:35 +0100 Subject: [PATCH] Adds update restore from backup functionality --- .../Configuration/CloudBackupRestore.vue | 33 +++++++++++-- src/utils/CloudBackup.js | 47 ++++++++++--------- 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/components/Configuration/CloudBackupRestore.vue b/src/components/Configuration/CloudBackupRestore.vue index e1ff9934..7fdfac75 100644 --- a/src/components/Configuration/CloudBackupRestore.vue +++ b/src/components/Configuration/CloudBackupRestore.vue @@ -49,7 +49,7 @@ label="Password" type="password" /> - @@ -64,7 +64,7 @@ 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, update } from '@/utils/CloudBackup'; +import { backup, update, restore } from '@/utils/CloudBackup'; import { localStorageKeys } from '@/utils/defaults'; export default { @@ -87,6 +87,14 @@ export default { IconRestore, }, methods: { + restoreBackup() { + restore(this.restoreCode, this.restorePassword) + .then((response) => { + this.restoreFromBackup(response, this.restoreCode); + }).catch((msg) => { + this.showErrorMsg(msg); + }); + }, checkPass() { const savedHash = localStorage[localStorageKeys.BACKUP_HASH] || undefined; if (!savedHash) { @@ -121,10 +129,19 @@ export default { this.showErrorMsg('Unable to process request'); }); }, + restoreFromBackup(config, backupId) { + localStorage.setItem(localStorageKeys.CONF_SECTIONS, JSON.stringify(config.sections)); + localStorage.setItem(localStorageKeys.APP_CONFIG, JSON.stringify(config.appConfig)); + localStorage.setItem(localStorageKeys.PAGE_INFO, JSON.stringify(config.pageInfo)); + if (config.appConfig.theme) { + localStorage.setItem(localStorageKeys.THEME, config.appConfig.theme); + } + this.setBackupIdLocally(backupId, this.restorePassword); + this.showSuccessMsg('Config Restored Succesfully'); + setTimeout(() => { location.reload(); }, 1500); // eslint-disable-line no-restricted-globals + }, updateUiAfterBackup(backupId, isUpdate = false) { - const hash = this.makeHash(this.backupPassword); - localStorage.setItem(localStorageKeys.BACKUP_ID, backupId); - localStorage.setItem(localStorageKeys.BACKUP_HASH, hash); + this.setBackupIdLocally(backupId, this.backupPassword); this.showSuccessMsg(`${isUpdate ? 'Update' : 'Backup'} Completed Succesfully`); this.backupPassword = ''; }, @@ -137,6 +154,12 @@ export default { makeHash(pass) { return sha256(pass).toString(); }, + setBackupIdLocally(backupId, pass) { + this.backupId = backupId; + const hash = this.makeHash(pass); + localStorage.setItem(localStorageKeys.BACKUP_ID, backupId); + localStorage.setItem(localStorageKeys.BACKUP_HASH, hash); + }, }, }; diff --git a/src/utils/CloudBackup.js b/src/utils/CloudBackup.js index b8d58d31..59d6a845 100644 --- a/src/utils/CloudBackup.js +++ b/src/utils/CloudBackup.js @@ -1,10 +1,9 @@ -/* eslint-disable */ import sha256 from 'crypto-js/sha256'; import aes from 'crypto-js/aes'; import Utf8 from 'crypto-js/enc-utf8'; import axios from 'axios'; -const ENDPOINT = 'https://dashy-sync-service.as93.net/'; +const ENDPOINT = 'https://dashy-sync-service.as93.net'; /* Stringify, encrypt and encode data for transmission */ const encryptData = (data, password) => { @@ -14,34 +13,38 @@ const encryptData = (data, password) => { }; /* Decrypt, decode and parse received data */ -const decryptData = (data, password) => { - return aes.decrypt(data, password).toString(Utf8); -}; +const decryptData = (data, password) => aes.decrypt(data, password).toString(Utf8); /* Returns a splice of the hash of the users password */ const makeSubHash = (pass) => sha256(pass).toString().slice(0, 14); /* Makes the backup */ -export const backup = (data, password) => { - return axios.post(ENDPOINT, { - userData: encryptData(data, password), - subHash: makeSubHash(password), - }); -}; +export const backup = (data, password) => axios.post(ENDPOINT, { + userData: encryptData(data, password), + subHash: makeSubHash(password), +}); /* Updates and existing backup */ -export const update = (data, password, backupId) => { - return axios.put(ENDPOINT, { - backupId, - userData: encryptData(data, password), - subHash: makeSubHash(password), - }); -}; +export const update = (data, password, backupId) => axios.put(ENDPOINT, { + backupId, + userData: encryptData(data, password), + subHash: makeSubHash(password), +}); + +const encodeGetParams = p => Object.entries(p).map(kv => kv.map(encodeURIComponent).join('=')).join('&'); /* Restores the backup */ export const restore = (backupId, password) => { - // return axios.get(ENDPOINT, { - // backupId, - // subHash: makeSubHash(password), - // }); + const params = encodeGetParams({ backupId, subHash: makeSubHash(password) }); + const url = `${ENDPOINT}/?${params}`; + return new Promise((resolve, reject) => { + axios.get(url).then((response) => { + if (!response.data || response.data.errorMsg) { + reject(response.data.errorMsg || 'Error'); + } else { + const decryptedData = decryptData(response.data.userData.userData, password); + try { resolve(JSON.parse(decryptedData)); } catch (e) { reject(e); } + } + }); + }); };