From ee20e0ccdf5b52bf9b793cd0741d5b0b69f7fd19 Mon Sep 17 00:00:00 2001 From: Kavin <20838718+FireMasterK@users.noreply.github.com> Date: Mon, 20 Feb 2023 15:43:25 +0000 Subject: [PATCH] Add support to sync preferences. --- src/App.vue | 54 ++++++++++++++++++++++++++++++ src/components/FooterComponent.vue | 8 ----- src/components/PreferencesPage.vue | 50 +++++++++++++++++++++++++++ src/utils/store.js | 3 ++ 4 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 src/utils/store.js diff --git a/src/App.vue b/src/App.vue index 49004ade..823eaa0e 100644 --- a/src/App.vue +++ b/src/App.vue @@ -19,6 +19,10 @@ import FooterComponent from "./components/FooterComponent.vue"; const darkModePreference = window.matchMedia("(prefers-color-scheme: dark)"); +import { generateKey, encodeArrayToBase64, decodeBase64ToArray, decryptAESGCM } from "./utils/encryptionUtils"; +import { decompressGzip } from "./utils/compressionUtils"; +import { state } from "./utils/store"; + export default { components: { NavBar, @@ -39,6 +43,7 @@ export default { this.fetchJson(this.authApiUrl() + "/config") .then(config => { this.config = config; + state.config = config; }) .then(() => { this.onConfigLoaded(); @@ -120,6 +125,55 @@ export default { const root = document.querySelector(":root"); this.theme == "dark" ? root.classList.add("dark") : root.classList.remove("dark"); }, + async onConfigLoaded() { + if (this.config.s3Enabled && this.authenticated) { + if (this.getPreferenceBoolean("syncPreferences", false, false)) { + var e2e2_b64_key = this.getPreferenceString("e2ee_key", null, false); + if (!e2e2_b64_key) { + const key = new Uint8Array(await generateKey()); + const encoded = encodeArrayToBase64(key); + this.setPreference("e2ee_key", encoded); + e2e2_b64_key = encoded; + } + + const statResult = await this.fetchJson( + this.authApiUrl() + "/storage/stat", + { + file: "pipedpref", + }, + { + headers: { + Authorization: this.getAuthToken(), + }, + }, + ); + + if (statResult.status === "exists") { + const data = await fetch(this.authApiUrl() + "/storage/get?file=pipedpref", { + method: "GET", + headers: { + Authorization: this.getAuthToken(), + }, + }).then(resp => resp.arrayBuffer()); + + const cryptoKey = decodeBase64ToArray(e2e2_b64_key).buffer; + + const decrypted = await decryptAESGCM(data, cryptoKey); + + const decompressed = await decompressGzip(new Uint8Array(decrypted)); + + const localStorageJson = JSON.parse(decompressed); + + // import into localStorage + for (var key in localStorageJson) { + if (Object.prototype.hasOwnProperty.call(localStorageJson, key)) { + localStorage[key] = localStorageJson[key]; + } + } + } + } + } + }, }, }; diff --git a/src/components/FooterComponent.vue b/src/components/FooterComponent.vue index c267b440..f0441678 100644 --- a/src/components/FooterComponent.vue +++ b/src/components/FooterComponent.vue @@ -29,15 +29,12 @@