From bed3f7e6d22398e8790d7654a05331ba3ee17950 Mon Sep 17 00:00:00 2001 From: Erhan Yakut Date: Mon, 8 Mar 2021 00:40:12 +0300 Subject: [PATCH 1/5] docs: update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d9991c0..ff21bbb 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,6 @@ $ yarn serve ### Run as extension -Open developer mode on your Chrome extension page then click "load unpacked" button. Select `dist/` folder +Open developer mode on your Chrome extension page then click "load unpacked" button. Select `dist/` folder. In Firefox, go to `about:debugging` url, select "This Firefox" tab then click "install temporary extension" and select `manifest.json` in your `/dist` folder From 1df9bdfe6954ae51b77fa75ad3e164afb1f7dd32 Mon Sep 17 00:00:00 2001 From: bufgix Date: Mon, 8 Mar 2021 01:27:16 +0300 Subject: [PATCH 2/5] refactor: Storage system moved to IndexedDB --- package.json | 1 + src/popup/config.js | 3 ++ src/popup/main.js | 31 ++++++++++--------- src/popup/router/auth-check.js | 6 ++-- src/popup/store/index.js | 54 ++++++++++++++++++++-------------- src/popup/views/Auth/Login.vue | 7 ++++- src/popup/views/Home/index.vue | 3 +- src/utils/storage.js | 7 +++++ yarn.lock | 19 ++++++++++++ 9 files changed, 90 insertions(+), 41 deletions(-) create mode 100644 src/utils/storage.js diff --git a/package.json b/package.json index 6b6584e..14e250e 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "axios": "^0.21.1", "core-js": "^3.6.5", "crypto-js": "^4.0.0", + "localforage": "^1.9.0", "skeleton-loader-vue": "^1.0.6", "v-tooltip": "^2.1.1", "vee-validate": "2.2.15", diff --git a/src/popup/config.js b/src/popup/config.js index c4e9c2b..5869edf 100644 --- a/src/popup/config.js +++ b/src/popup/config.js @@ -11,6 +11,9 @@ Vue.prototype.$waiters = Waiters import * as Constants from '@/utils/constants' Vue.prototype.$c = Constants +import storage from '@/utils/storage' +Vue.prototype.$storage = storage + import * as Helpers from '@/utils/helpers' Vue.prototype.$helpers = Helpers diff --git a/src/popup/main.js b/src/popup/main.js index 259c475..cf39635 100644 --- a/src/popup/main.js +++ b/src/popup/main.js @@ -6,18 +6,21 @@ import router from '@p/router' import store from '@p/store' import i18n from '@/i18n' import HTTPClient from '@/api/HTTPClient' +import Storage from '@/utils/storage' import '../styles/app.scss' - -if (localStorage.access_token) { - HTTPClient.setHeader('Authorization', `Bearer ${localStorage.access_token}`) -} - -/* eslint-disable no-new */ -new Vue({ - router, - store, - i18n, - wait: window.wait, - el: '#app', - render: h => h(App) -}) +;(async () => { + await store.dispatch('init') + const token = await Storage.getItem('access_token') + if (token) { + HTTPClient.setHeader('Authorization', `Bearer ${token}`) + } + /* eslint-disable no-new */ + new Vue({ + router, + store, + i18n, + wait: window.wait, + el: '#app', + render: h => h(App) + }) +})() diff --git a/src/popup/router/auth-check.js b/src/popup/router/auth-check.js index 948bceb..14eff95 100644 --- a/src/popup/router/auth-check.js +++ b/src/popup/router/auth-check.js @@ -1,7 +1,9 @@ -export default (to, _, next) => { +import Storage from '@/utils/storage' + +export default async (to, _, next) => { const isAuthPage = to.matched.some(record => record.meta.auth) - const access_token = localStorage.getItem('access_token') + const access_token = await Storage.getItem('access_token') if (access_token) { if (isAuthPage) { return next({ name: 'Home' }) diff --git a/src/popup/store/index.js b/src/popup/store/index.js index 211357c..fc0be28 100644 --- a/src/popup/store/index.js +++ b/src/popup/store/index.js @@ -6,6 +6,8 @@ import CryptoUtils from '@/utils/crypto' import HTTPClient from '@/api/HTTPClient' import AuthService from '@/api/services/Auth' +import Storage from '@/utils/storage' + import Logins from '@p/views/Logins/store' import CreditCards from '@/popup/views/CreditCards/store' import Emails from '@p/views/Emails/store' @@ -15,14 +17,11 @@ import Servers from '@p/views/Servers/store' export default new Vuex.Store({ state() { - CryptoUtils.encryptKey = localStorage.master_hash - CryptoUtils.transmissionKey = localStorage.transmission_key - return { - access_token: localStorage.access_token, - refresh_token: localStorage.refresh_token, - transmission_key: localStorage.transmission_key, - master_hash: localStorage.master_hash, + access_token: '', + refresh_token: '', + transmission_key: '', + master_hash: '', searchQuery: '', user: {} @@ -35,10 +34,21 @@ export default new Vuex.Store({ }, actions: { + async init({ state }) { + CryptoUtils.encryptKey = await Storage.getItem('master_hash') + CryptoUtils.transmissionKey = await Storage.getItem('transmission_key') + + state.access_token = await Storage.getItem('access_token') + state.refresh_token = await Storage.getItem('refresh_token') + state.transmission_key = await Storage.getItem('transmission_key') + state.master_hash = await Storage.getItem('master_hash') + }, + async Login({ state }, payload) { payload.master_password = CryptoUtils.sha256Encrypt(payload.master_password) const { data } = await AuthService.Login(payload) + state.access_token = data.access_token state.refresh_token = data.refresh_token state.transmission_key = data.transmission_key.substr(0, 32) @@ -47,31 +57,31 @@ export default new Vuex.Store({ CryptoUtils.transmissionKey = state.transmission_key state.user = data - localStorage.email = payload.email - localStorage.server = payload.server - localStorage.access_token = data.access_token - localStorage.refresh_token = data.refresh_token - localStorage.user = JSON.stringify(data) - - localStorage.master_hash = state.master_hash - localStorage.transmission_key = state.transmission_key + await Promise.all([ + Storage.setItem('email', payload.email), + Storage.setItem('server', payload.server), + Storage.setItem('access_token', data.access_token), + Storage.setItem('refresh_token', data.refresh_token), + Storage.setItem('user', data), + Storage.setItem('master_hash', state.master_hash), + Storage.setItem('transmission_key', state.transmission_key) + ]) HTTPClient.setHeader('Authorization', `Bearer ${state.access_token}`) }, - Logout({ state }) { + async Logout({ state }) { + const email = await Storage.getItem('email') + await Storage.clear() state.access_token = null state.refresh_token = null state.transmission_key = null state.master_hash = null state.user = null - const lsKeys = Object.keys(localStorage).filter( - key => ['email', 'server'].includes(key) === false - ) - lsKeys.forEach(key => localStorage.removeItem(key)) + await Storage.setItem('email', email) }, - loadStore({ state }) { - state.user = JSON.parse(localStorage.user) + async loadStore({ state }) { + state.user = await Storage.getItem('user') } }, mutations: { diff --git a/src/popup/views/Auth/Login.vue b/src/popup/views/Auth/Login.vue index a857ccb..6183015 100644 --- a/src/popup/views/Auth/Login.vue +++ b/src/popup/views/Auth/Login.vue @@ -63,11 +63,16 @@ export default { data() { return { LoginForm: { - email: localStorage.email || '', + email: '', master_password: '' } } }, + mounted() { + this.$storage.getItem('email').then(e => { + if (e) this.LoginForm.email = e + }) + }, methods: { ...mapActions(['Login']), async onLogin() { diff --git a/src/popup/views/Home/index.vue b/src/popup/views/Home/index.vue index dc03a85..b7abd37 100644 --- a/src/popup/views/Home/index.vue +++ b/src/popup/views/Home/index.vue @@ -59,8 +59,7 @@ export default { }, logout() { - this.Logout() - this.$router.push('Login') + this.Logout().then(() => this.$router.push('Login')) } } } diff --git a/src/utils/storage.js b/src/utils/storage.js new file mode 100644 index 0000000..869842b --- /dev/null +++ b/src/utils/storage.js @@ -0,0 +1,7 @@ +import LocalForage from 'localforage' + +export default LocalForage.createInstance({ + driver: LocalForage.INDEXEDDB, + name: 'Passwall Storage', + storeName: "login_data" +}) diff --git a/yarn.lock b/yarn.lock index ff7e5b7..64ab01c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5508,6 +5508,11 @@ ignore@^4.0.3, ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= + import-cwd@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" @@ -6715,6 +6720,13 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lie@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + integrity sha1-mkNrLMd0bKWd56QfpGmz77dr2H4= + dependencies: + immediate "~3.0.5" + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" @@ -6761,6 +6773,13 @@ loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" +localforage@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.9.0.tgz#f3e4d32a8300b362b4634cc4e066d9d00d2f09d1" + integrity sha512-rR1oyNrKulpe+VM9cYmcFn6tsHuokyVHFaCM3+osEmxaHTbEk8oQu6eGDfS6DQLWi/N67XRmB8ECG37OES368g== + dependencies: + lie "3.1.1" + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" From 506c5dc7bf4192a6d3a7610030edc4c1f6e1f5b6 Mon Sep 17 00:00:00 2001 From: bufgix Date: Mon, 8 Mar 2021 02:33:13 +0300 Subject: [PATCH 3/5] test: replace new tests --- __tests__/integration/App.test.js | 27 +++++++++++---------------- package.json | 3 ++- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/__tests__/integration/App.test.js b/__tests__/integration/App.test.js index 4b15229..e384dfe 100644 --- a/__tests__/integration/App.test.js +++ b/__tests__/integration/App.test.js @@ -17,18 +17,6 @@ const getTestId = id => { return `[data-testid='${id}']` } -const getLocalStorage = async page => { - const j = await page.evaluate(() => { - let json = {} - for (let i = 0; i < localStorage.length; i++) { - const key = localStorage.key(i) - json[key] = localStorage.getItem(key) - } - return json - }) - return j -} - describe('Popup page', () => { let page, browser const usernameField = '[data-testid="username"] > input' @@ -91,8 +79,11 @@ describe('Popup page', () => { await page.waitForSelector(usernameLabel) const labelText = await page.$eval(usernameLabel, el => el.innerText) - const localStorageData = await getLocalStorage(page) - const userObj = JSON.parse(localStorageData.user) + const userObj = await page.evaluate(async () => { + const $vm = document.querySelector('body > div').__vue__ + const storage = $vm.$storage + return storage.getItem('user') + }) await page.screenshot({ path: path.join(ssPath, 'home.png') }) expect(labelText).toEqual('Erhan Yakut') @@ -121,8 +112,12 @@ describe('Popup page', () => { await page.waitForSelector(logoutBtn) await page.$eval(logoutBtn, el => el.click()) - const localStorageData = await getLocalStorage(page) + const userObj = await page.evaluate(async () => { + const $vm = document.querySelector('body > div').__vue__ + const storage = $vm.$storage + return storage.getItem('user') + }) await page.screenshot({ path: path.join(ssPath, 'logout.png') }) - expect(localStorageData.user).not.toBeDefined() + expect(userObj).toBeNull() }) }) diff --git a/package.json b/package.json index 14e250e..28b2fcf 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "serve": "vue-cli-service build --mode development --watch", "build": "vue-cli-service build", "lint": "vue-cli-service lint", - "test": "yarn build && jest" + "test": "jest", + "test:build": "yarn build && jest" }, "jest": { "verbose": true, From 3bbe22a7012f33c3d1f93ad849d37c5bfa1a2d8d Mon Sep 17 00:00:00 2001 From: bufgix Date: Thu, 11 Mar 2021 09:38:58 +0300 Subject: [PATCH 4/5] v1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 28b2fcf..898cde4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "passwall-extension", - "version": "0.1.0", + "version": "1.0.0", "private": true, "scripts": { "serve": "vue-cli-service build --mode development --watch", From 031ac7ebb865bba46bdf99fd35deca4c497e186d Mon Sep 17 00:00:00 2001 From: bufgix Date: Thu, 11 Mar 2021 11:33:57 +0300 Subject: [PATCH 5/5] chore: remove key in manifestjson --- src/manifest.json | 1 - 1 file changed, 1 deletion(-) diff --git a/src/manifest.json b/src/manifest.json index 9deb3de..9342c5d 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -5,7 +5,6 @@ "description": "Passwall official extension", "default_locale": "en", "permissions": ["tabs", "activeTab", "", "*://*/*", "webRequest"], - "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+KCvbvNcEFoYK6Wv2YDjMDSfXEY5czwNjy8tqe9dWXcKmV64zKahzXPkaS4g7ZA5S1fHD7sWuai4g78K7xUGMvgtDTY9AYcyjmNgW1bE+ZwRPgZFXEwKHQCwXAgUDiHfhRfngSf1sgvznAZrMzNWkppJc0Pi0gR1HqyxRBxO6f2b2BDkaPszlFxTi3AQ1mT+v34ogorgT6yKnfaD9wQfIoPW4eiPNb/OPWW2I/R7P+mGGuqKLAU2KddRuPjC2plS2VEVjXPXCG4w2M6SRyFClpCeWR2F0GCmTbjRbKWoAmtCiX5OeORa39jvSh4vZBEZBYPa57RlRdxRWVxhUso2aQIDAQAB", "icons": { "16": "icons/16.png", "48": "icons/48.png",