From 53941adaa1af8dd7fe0ca9da3299b16eb8a918a6 Mon Sep 17 00:00:00 2001 From: Zhe Li Date: Sun, 14 Apr 2024 16:08:58 +0800 Subject: [PATCH] refactor user settings --- package-lock.json | 66 ++----- package.json | 2 +- src/background.ts | 44 ++--- src/components/Popup/DrivePage.vue | 31 ++-- src/components/Popup/DropboxPage.vue | 29 ++-- src/components/Popup/MenuPage.vue | 7 +- src/components/Popup/OneDrivePage.vue | 34 ++-- src/components/Popup/PreferencesPage.vue | 6 +- src/models/backup.ts | 190 ++++++++++---------- src/models/otp.ts | 10 +- src/models/settings.ts | 210 +++++++++++++++++++++++ src/models/storage.ts | 70 ++++---- src/popup.ts | 85 ++++----- src/store/Accounts.ts | 38 ++-- src/store/Advisor.ts | 54 +++--- src/store/Backup.ts | 24 ++- src/store/Menu.ts | 54 +++--- src/store/Permissions.ts | 26 ++- src/syncTime.ts | 10 +- 19 files changed, 542 insertions(+), 448 deletions(-) create mode 100644 src/models/settings.ts diff --git a/package-lock.json b/package-lock.json index 706b3461d..cf918248b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,10 +21,9 @@ "vuex": "^3.4.0" }, "devDependencies": { - "@jsdevtools/coverage-istanbul-loader": "^3.0.5", "@types/argon2-browser": "^1.18.1", "@types/chai": "^4.2.14", - "@types/chrome": "^0.0.210", + "@types/chrome": "^0.0.266", "@types/crypto-js": "^4.1.1", "@types/mocha": "^10.0.6", "@types/sinon": "^17.0.2", @@ -575,19 +574,6 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, - "node_modules/@jsdevtools/coverage-istanbul-loader": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jsdevtools/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.5.tgz", - "integrity": "sha512-EUCPEkaRPvmHjWAAZkWMT7JDzpw7FKB00WTISaiXsbNOd5hCHg77XLA8sLYLFDo1zepYLo2w7GstN8YBqRXZfA==", - "dev": true, - "dependencies": { - "convert-source-map": "^1.7.0", - "istanbul-lib-instrument": "^4.0.3", - "loader-utils": "^2.0.0", - "merge-source-map": "^1.1.0", - "schema-utils": "^2.7.0" - } - }, "node_modules/@puppeteer/browsers": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.9.0.tgz", @@ -764,9 +750,9 @@ "dev": true }, "node_modules/@types/chrome": { - "version": "0.0.210", - "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.210.tgz", - "integrity": "sha512-VSjQu1k6a/rAfuqR1Gi/oxHZj4+t6+LG+GobNI3ZWI6DQ+fmphNSF6TrLHG6BYK2bXc9Gb4c1uXFKRRVLaGl5Q==", + "version": "0.0.266", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.266.tgz", + "integrity": "sha512-QSQWJTL7NjZElvq/6/E5C1+pHgEP8UAJzwoz7M4vSJ7AECt6NNehJ+tU6snnvuTqZOBjFCivvitYo5+8tNPmhg==", "dev": true, "dependencies": { "@types/filesystem": "*", @@ -4264,9 +4250,9 @@ } }, "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", "dev": true }, "node_modules/is-arguments": { @@ -5388,9 +5374,9 @@ } }, "node_modules/minipass": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz", - "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, "engines": { "node": ">=8" @@ -7256,24 +7242,6 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, - "node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -7587,9 +7555,9 @@ } }, "node_modules/socks/node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", "dev": true }, "node_modules/source-map": { @@ -7992,14 +7960,14 @@ } }, "node_modules/tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dev": true, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" diff --git a/package.json b/package.json index 179d34a17..27ae459a2 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "devDependencies": { "@types/argon2-browser": "^1.18.1", "@types/chai": "^4.2.14", - "@types/chrome": "^0.0.210", + "@types/chrome": "^0.0.266", "@types/crypto-js": "^4.1.1", "@types/mocha": "^10.0.6", "@types/sinon": "^17.0.2", diff --git a/src/background.ts b/src/background.ts index e44802009..dc3cb1ed0 100644 --- a/src/background.ts +++ b/src/background.ts @@ -8,15 +8,12 @@ import { CodeState } from "./models/otp"; import { getOTPAuthPerLineFromOPTAuthMigration } from "./models/migration"; import { isChrome, isFirefox } from "./browser"; +import { UserSettings } from "./models/settings"; let contentTab: chrome.tabs.Tab | undefined; -let LocalStorage: { - [key: string]: any; -}; chrome.runtime.onMessage.addListener(async (message, sender) => { - LocalStorage = - (await chrome.storage.local.get("LocalStorage")).LocalStorage || {}; + await UserSettings.updateItems(); if (message.action === "getCapture") { if (!sender.tab) { @@ -273,8 +270,8 @@ function getBackupToken(service: string) { if (!value) { return false; } - LocalStorage.driveToken = value; - chrome.storage.local.set({ LocalStorage }); + UserSettings.items.driveToken = value; + UserSettings.commitItems(); chrome.runtime.sendMessage({ action: "drivetoken", value }); return true; } @@ -308,10 +305,7 @@ function getBackupToken(service: string) { authUrl = `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=${ getCredentials().onedrive.client_id }&response_type=code&redirect_uri=${redirUrl}&scope=https%3A%2F%2Fgraph.microsoft.com%2FFiles.ReadWrite${ - LocalStorage.oneDriveBusiness !== "true" && - LocalStorage.oneDriveBusiness !== true - ? ".AppFolder" - : "" + UserSettings.items.oneDriveBusiness !== true ? ".AppFolder" : "" }%20https%3A%2F%2Fgraph.microsoft.com%2FUser.Read%20offline_access&response_mode=query&prompt=consent`; } chrome.identity.launchWebAuthFlow( @@ -345,8 +339,8 @@ function getBackupToken(service: string) { const value = kvMatches[2]; if (key === "access_token") { if (service === "dropbox") { - LocalStorage.dropboxToken = value; - chrome.storage.local.set({ LocalStorage }); + UserSettings.items.dropboxToken = value; + UserSettings.commitItems(); uploadBackup("dropbox"); return; } @@ -379,9 +373,9 @@ function getBackupToken(service: string) { if (res.error) { console.error(res.error_description); } else { - LocalStorage.driveToken = res.access_token; - LocalStorage.driveRefreshToken = res.refresh_token; - chrome.storage.local.set({ LocalStorage }); + UserSettings.items.driveToken = res.access_token; + UserSettings.items.driveRefreshToken = res.refresh_token; + UserSettings.commitItems(); success = true; } } catch (error) { @@ -412,9 +406,9 @@ function getBackupToken(service: string) { if (res.error) { console.error(res.error_description); } else { - LocalStorage.oneDriveToken = res.access_token; - LocalStorage.oneDriveRefreshToken = res.refresh_token; - chrome.storage.local.set({ LocalStorage }); + UserSettings.items.oneDriveToken = res.access_token; + UserSettings.items.oneDriveRefreshToken = res.refresh_token; + UserSettings.commitItems(); success = true; } } catch (error) { @@ -558,27 +552,21 @@ async function setAutolock() { return; } - if (Number(LocalStorage.autolock) > 0) { + if (Number(UserSettings.items.autolock) > 0) { chrome.alarms.create("autolock", { - delayInMinutes: Number(LocalStorage.autolock), + delayInMinutes: Number(UserSettings.items.autolock), }); } } async function updateContextMenu() { - LocalStorage = - (await chrome.storage.local.get("LocalStorage")).LocalStorage || {}; - chrome.permissions.contains( { permissions: ["contextMenus"], }, (result) => { if (result) { - if ( - LocalStorage.enableContextMenu === "true" || - LocalStorage.enableContextMenu === true - ) { + if (UserSettings.items.enableContextMenu === true) { chrome.contextMenus.removeAll(); chrome.contextMenus.create({ id: "otpContextMenu", diff --git a/src/components/Popup/DrivePage.vue b/src/components/Popup/DrivePage.vue index 2ec6fa3ab..bdbe2d88e 100644 --- a/src/components/Popup/DrivePage.vue +++ b/src/components/Popup/DrivePage.vue @@ -36,6 +36,7 @@ import Vue from "vue"; import { isChrome } from "../../browser"; import { Drive } from "../../models/backup"; +import { UserSettings } from "../../models/settings"; const service = "drive"; @@ -43,13 +44,10 @@ export default Vue.extend({ data: function () { return { email: this.i18n.loading, - LocalStorage: {} as { [key: string]: any }, }; }, created() { - chrome.storage.local.get("LocalStorage").then((res) => { - this.LocalStorage = res.LocalStorage || {}; - }); + UserSettings.updateItems(); }, computed: { encryption: function () { @@ -57,17 +55,17 @@ export default Vue.extend({ }, isEncrypted: { get(): boolean { - if (this.LocalStorage[`${service}Encrypted`] === null) { + if (UserSettings.items[`${service}Encrypted`] === null) { this.$store.commit("backup/setEnc", { service, value: true }); - this.LocalStorage[`${service}Encrypted`] = true; - chrome.storage.local.set({ LocalStorage: this.LocalStorage }); + UserSettings.items[`${service}Encrypted`] = true; + UserSettings.commitItems(); return true; } return this.$store.state.backup.driveEncrypted; }, set(newValue: string) { - this.LocalStorage.driveEncrypted = newValue; - chrome.storage.local.set({ LocalStorage: this.LocalStorage }); + UserSettings.items.driveEncrypted = newValue === "true"; + UserSettings.commitItems(); this.$store.commit("backup/setEnc", { service, value: newValue }); }, }, @@ -85,13 +83,13 @@ export default Vue.extend({ xhr.open( "POST", "https://accounts.google.com/o/oauth2/revoke?token=" + - this.LocalStorage.driveToken + UserSettings.items.driveToken ); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { if (isChrome) { chrome.identity.removeCachedAuthToken( - { token: this.LocalStorage.driveToken }, + { token: UserSettings.items.driveToken as string }, () => { resolve(true); } @@ -104,8 +102,7 @@ export default Vue.extend({ }; xhr.send(); }); - this.LocalStorage.driveToken = undefined; - chrome.storage.local.set({ LocalStorage: this.LocalStorage }); + UserSettings.removeItem("driveToken"); this.$store.commit("backup/setToken", { service, value: false }); this.$store.commit("style/hideInfo"); }, @@ -116,16 +113,12 @@ export default Vue.extend({ ); if (response === true) { this.$store.commit("notification/alert", this.i18n.updateSuccess); - } else if ( - this.LocalStorage.driveRevoked === "true" || - this.LocalStorage.driveRevoked === true - ) { + } else if (UserSettings.items.driveRevoked === true) { this.$store.commit( "notification/alert", chrome.i18n.getMessage("token_revoked", ["Google Drive"]) ); - this.LocalStorage.driveRevoked = undefined; - chrome.storage.local.set({ LocalStorage: this.LocalStorage }); + UserSettings.removeItem("driveRevoked"); this.$store.commit("backup/setToken", { service, value: false }); } else { this.$store.commit("notification/alert", this.i18n.updateFailure); diff --git a/src/components/Popup/DropboxPage.vue b/src/components/Popup/DropboxPage.vue index 243790c9d..8c3046d58 100644 --- a/src/components/Popup/DropboxPage.vue +++ b/src/components/Popup/DropboxPage.vue @@ -35,6 +35,7 @@