diff --git a/src/services/url-parser.js b/src/services/url-parser.js index 28cf020..768676b 100644 --- a/src/services/url-parser.js +++ b/src/services/url-parser.js @@ -1,22 +1,18 @@ 'use strict'; -export function getDomainName(urlStr) { - if (typeof urlStr === 'undefined') { +export function getSite(url) { + if (typeof url === 'undefined') { return ''; } - var matchesDomainName = urlStr.match(/^(?:https?\:\/\/)([^\/?#]+)(?:[\/?#]|$)/i); + var matchesDomainName = url.match(/^(?:https?\:\/\/)([^\/?#]+)(?:[\/?#]|$)/i); return matchesDomainName && matchesDomainName[1]; } -export function getSite() { +export function getUrl() { return new Promise(resolve => { if (typeof chrome !== 'undefined' && typeof chrome.tabs !== 'undefined' && typeof chrome.tabs.query !== 'undefined') { chrome.tabs.query({active: true, currentWindow: true}, tabs => { - const url = tabs[0].url; - resolve({ - site: getDomainName(url), - url: url - }); + resolve(tabs[0].url); }); } else { resolve(''); diff --git a/src/store/actions.js b/src/store/actions.js index a779e88..b9622fa 100644 --- a/src/store/actions.js +++ b/src/store/actions.js @@ -1,6 +1,6 @@ import Password from '../api/password'; import User from '../api/user'; - +import * as urlParser from '../services/url-parser'; import * as types from './mutation-types' export const loadPasswordFirstTime = ({commit}) => { @@ -16,10 +16,6 @@ export const refreshToken = ({commit, state}) => { } }; -export const loadPasswordForSite = ({commit}, payload) => { - commit(types.LOAD_PASSWORD_FOR_SITE, payload); -}; - export const saveDefaultOptions = ({commit}, payload) => { commit(types.SET_DEFAULT_OPTIONS, payload); }; @@ -28,6 +24,23 @@ export const passwordGenerated = ({commit}) => { commit(types.PASSWORD_GENERATED); }; +export const getSite = ({commit}) => { + urlParser.getUrl().then(url => { + const site = urlParser.getSite(url); + if (site) { + commit(types.LOAD_PASSWORD_WITH_SITE, {site}); + commit(types.SET_SITE, {site}); + } + }); +}; + +export const getPasswordFromUrlQuery = ({commit}, {query}) => { + if (Object.keys(query).length >= 9) { + const password = urlParser.getPasswordFromUrlQuery(query); + commit(types.SET_PASSWORD, {password}); + } +}; + export const savePassword = ({commit}, payload) => { commit(types.SET_PASSWORD, payload); }; diff --git a/src/store/mutation-types.js b/src/store/mutation-types.js index d4a8bd5..bfae7a3 100644 --- a/src/store/mutation-types.js +++ b/src/store/mutation-types.js @@ -1,14 +1,15 @@ export const LOGOUT = 'LOGOUT'; export const LOGIN = 'LOGIN'; -export const SET_TOKEN = 'SET_TOKEN'; export const PASSWORD_GENERATED = 'PASSWORD_GENERATED'; -export const SET_PASSWORD = 'SET_PASSWORD'; +export const SET_BASE_URL = 'SET_BASE_URL'; export const SET_DEFAULT_OPTIONS = 'SET_DEFAULT_OPTIONS'; +export const SET_MESSAGE = 'SET_MESSAGE'; +export const SET_PASSWORD = 'SET_PASSWORD'; export const SET_PASSWORDS = 'SET_PASSWORDS'; -export const DELETE_PASSWORD = 'DELETE_PASSWORD'; -export const SET_BASE_URL = 'SET_BASE_URL'; +export const SET_SITE = 'SET_SITE'; +export const SET_TOKEN = 'SET_TOKEN'; export const SET_VERSION = 'SET_VERSION'; export const LOAD_PASSWORD_FIRST_TIME = 'LOAD_PASSWORD_FIRST_TIME'; -export const LOAD_PASSWORD_FOR_SITE = 'LOAD_PASSWORD_FOR_SITE'; -export const SET_MESSAGE = 'SET_MESSAGE'; +export const LOAD_PASSWORD_WITH_SITE = 'LOAD_PASSWORD_WITH_SITE'; +export const DELETE_PASSWORD = 'DELETE_PASSWORD'; export const CLEAN_MESSAGE = 'CLEAN_MESSAGE'; diff --git a/src/store/mutations.js b/src/store/mutations.js index b9f18c0..b4b014d 100644 --- a/src/store/mutations.js +++ b/src/store/mutations.js @@ -36,6 +36,11 @@ export default { [types.SET_BASE_URL](state, {baseURL}){ state.baseURL = baseURL; }, + [types.SET_SITE](state, {site}){ + if (!state.password.site) { + state.password.site = site; + } + }, [types.SET_VERSION](state, {version}){ const length = version === 1 ? 12 : 16; state.password.version = version; @@ -47,18 +52,13 @@ export default { state.password = {...state.defaultPassword}; } }, - [types.LOAD_PASSWORD_FOR_SITE](state, {site, url}){ - state.password.site = site; + [types.LOAD_PASSWORD_WITH_SITE](state, {site}){ const passwords = state.passwords; for (let i = 0; i < state.passwords.length; i++) { const password = passwords[i]; if (password.site.endsWith(site)) { state.password = {...password}; } - if (typeof url !== 'undefined' && url.includes(password.site)) { - state.password = {...password}; - break; - } } }, [types.SET_MESSAGE](state, {message}){ diff --git a/src/views/PasswordGenerator.vue b/src/views/PasswordGenerator.vue index c1088e6..b2c0368 100644 --- a/src/views/PasswordGenerator.vue +++ b/src/views/PasswordGenerator.vue @@ -134,7 +134,6 @@ import LessPass from 'lesspass'; import {mapGetters} from 'vuex'; import Clipboard from 'clipboard'; - import {getSite, getPasswordFromUrlQuery} from '../services/url-parser'; import RemoveAutoComplete from '../components/RemoveAutoComplete.vue'; import MasterPassword from '../components/MasterPassword.vue'; import Options from '../components/Options.vue'; @@ -151,18 +150,9 @@ }, computed: mapGetters(['passwords', 'password', 'passwordURL']), beforeMount () { - const query = this.$route.query; - if (Object.keys(query).length >= 9) { - this.$store.dispatch('savePassword', {password: getPasswordFromUrlQuery(query)}); - } - this.$store.dispatch('getPasswords'); - - getSite().then(site => { - if (site) { - this.$store.dispatch('loadPasswordForSite', site); - } - }); + this.$store.dispatch('getSite'); + this.$store.dispatch('getPasswordFromUrlQuery', {query:this.$route.query}); const clipboard = new Clipboard('.btn-copy'); clipboard.on('success', event => { diff --git a/test/store.mutations.js b/test/store.mutations.js index c44a69f..1cf7e80 100644 --- a/test/store.mutations.js +++ b/test/store.mutations.js @@ -234,7 +234,7 @@ test('LOAD_PASSWORD_FIRST_TIME last use null', t => { timekeeper.reset(); }); -test('LOAD_PASSWORD_FOR_SITE', t => { +test('LOAD_PASSWORD_WITH_SITE', t => { const state = { password: { site: '' @@ -244,26 +244,25 @@ test('LOAD_PASSWORD_FOR_SITE', t => { {id: '2', site: 'www.google.com'} ] }; - const LOAD_PASSWORD_FOR_SITE = mutations[types.LOAD_PASSWORD_FOR_SITE]; - LOAD_PASSWORD_FOR_SITE(state, {site: 'www.google.com'}); + const LOAD_PASSWORD_WITH_SITE = mutations[types.LOAD_PASSWORD_WITH_SITE]; + LOAD_PASSWORD_WITH_SITE(state, {site: 'www.google.com'}); t.is(state.password.id, '2'); t.is(state.password.site, 'www.google.com'); }); -test('LOAD_PASSWORD_FOR_SITE no passwords', t => { +test('LOAD_PASSWORD_WITH_SITE no passwords', t => { const state = { password: { site: '' }, passwords: [] }; - const LOAD_PASSWORD_FOR_SITE = mutations[types.LOAD_PASSWORD_FOR_SITE]; - LOAD_PASSWORD_FOR_SITE(state, {site: 'account.google.com'}); - t.false('id' in state.password); - t.is(state.password.site, 'account.google.com'); + const LOAD_PASSWORD_WITH_SITE = mutations[types.LOAD_PASSWORD_WITH_SITE]; + LOAD_PASSWORD_WITH_SITE(state, {site: 'account.google.com'}); + t.is(state.password.site, ''); }); -test('LOAD_PASSWORD_FOR_SITE multiple accounts matching criteria', t => { +test('LOAD_PASSWORD_WITH_SITE multiple accounts matching criteria', t => { const state = { password: { site: '' @@ -274,8 +273,8 @@ test('LOAD_PASSWORD_FOR_SITE multiple accounts matching criteria', t => { {id: '3', site: 'account.google.com'}, ] }; - const LOAD_PASSWORD_FOR_SITE = mutations[types.LOAD_PASSWORD_FOR_SITE]; - LOAD_PASSWORD_FOR_SITE(state, {site: 'www.google.com', url: 'https://www.google.com'}); + const LOAD_PASSWORD_WITH_SITE = mutations[types.LOAD_PASSWORD_WITH_SITE]; + LOAD_PASSWORD_WITH_SITE(state, {site: 'www.google.com'}); t.is(state.password.id, '2'); t.is(state.password.site, 'www.google.com'); }); @@ -295,3 +294,17 @@ test('CLEAN_MESSAGE', t => { t.is(state.message.text, ''); t.is(state.message.status, 'success'); }); + +test('SET_SITE', t => { + const SET_SITE = mutations[types.SET_SITE]; + const state = {password: {site: ''}}; + SET_SITE(state, {site: 'example.org'}); + t.is(state.password.site, 'example.org'); +}); + +test('SET_SITE already exists', t => { + const SET_SITE = mutations[types.SET_SITE]; + const state = {password: {site: 'lesspass.com'}}; + SET_SITE(state, {site: 'example.org'}); + t.is(state.password.site, 'lesspass.com'); +}); diff --git a/test/url-parser.js b/test/url-parser.js index bc660b8..10c7c94 100644 --- a/test/url-parser.js +++ b/test/url-parser.js @@ -1,32 +1,30 @@ import test from 'ava'; import * as urlParser from '../src/services/url-parser'; -test('urlParser.getDomainName', t => { - t.is('lesspass.com', urlParser.getDomainName('https://lesspass.com/#!/')); - t.is('lesspass.com', urlParser.getDomainName('https://lesspass.com/api/')); - t.is('api.lesspass.com', urlParser.getDomainName('https://api.lesspass.com/')); - t.is('lesspass.com', urlParser.getDomainName('http://lesspass.com')); - t.is('stackoverflow.com', urlParser.getDomainName('http://stackoverflow.com/questions/3689423/google-chrome-plugin-how-to-get-domain-from-url-tab-url')); - t.is('v4-alpha.getbootstrap.com', urlParser.getDomainName('http://v4-alpha.getbootstrap.com/components/buttons/')); - t.is('accounts.google.com', urlParser.getDomainName('https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=https://mail.google.com/mail/&ss=1&scc=1<mpl=default<mplcache=2&emr=1&osid=1#identifier')); - t.is('www.netflix.com', urlParser.getDomainName('https://www.netflix.com/browse')); - t.is('www.bbc.co.uk', urlParser.getDomainName('https://www.bbc.co.uk')); - t.is('192.168.1.1:10443', urlParser.getDomainName('https://192.168.1.1:10443/webapp/')); - t.is('', urlParser.getDomainName(undefined)); +test('getDomainName', t => { + t.is('lesspass.com', urlParser.getSite('https://lesspass.com/#!/')); + t.is('lesspass.com', urlParser.getSite('https://lesspass.com/api/')); + t.is('api.lesspass.com', urlParser.getSite('https://api.lesspass.com/')); + t.is('lesspass.com', urlParser.getSite('http://lesspass.com')); + t.is('stackoverflow.com', urlParser.getSite('http://stackoverflow.com/questions/3689423/google-chrome-plugin-how-to-get-domain-from-url-tab-url')); + t.is('v4-alpha.getbootstrap.com', urlParser.getSite('http://v4-alpha.getbootstrap.com/components/buttons/')); + t.is('accounts.google.com', urlParser.getSite('https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=https://mail.google.com/mail/&ss=1&scc=1<mpl=default<mplcache=2&emr=1&osid=1#identifier')); + t.is('www.netflix.com', urlParser.getSite('https://www.netflix.com/browse')); + t.is('www.bbc.co.uk', urlParser.getSite('https://www.bbc.co.uk')); + t.is('192.168.1.1:10443', urlParser.getSite('https://192.168.1.1:10443/webapp/')); + t.is('', urlParser.getSite(undefined)); }); -test('get current tab', t => { - const url = 'https://example.org'; +test('getUrl', t => { global.chrome = { tabs: { query(a, callback){ - callback([{url}]) + callback([{url: 'https://example.org'}]) } } }; - return urlParser.getSite().then(response => { - t.is(response.url, url); - t.is(response.site, 'example.org') + return urlParser.getUrl().then(url => { + t.is(url, 'https://example.org'); }); });