Browse Source

Fix Web extension 2.5.0 profile update issues

* Load loadBestPasswordProfile when not connected
 * Dont load previous password profile is last used < 1 minute
 * Load default password profile if site different
 * Keep existing password profile if no site

Fixes: https://github.com/lesspass/lesspass/issues/265
pull/342/head
Guillaume Vincent 7 years ago
parent
commit
5e8f900994
6 changed files with 25 additions and 134 deletions
  1. +7
    -13
      src/store/actions.js
  2. +0
    -1
      src/store/index.js
  3. +0
    -1
      src/store/mutation-types.js
  4. +2
    -6
      src/store/mutations.js
  5. +8
    -6
      src/views/PasswordGenerator.vue
  6. +8
    -107
      test/unit/store.mutations.js

+ 7
- 13
src/store/actions.js View File

@@ -16,16 +16,9 @@ export const saveDefaultOptions = ({ commit }, payload) => {
commit(types.SET_DEFAULT_OPTIONS, payload);
};

export const passwordGenerated = ({ commit }) => {
commit(types.PASSWORD_GENERATED);
};

export const loadBestPasswordProfile = ({ commit }) => {
urlParser.getSite().then(site => {
if (site) {
commit(types.SET_SITE, { site });
commit(types.LOAD_PASSWORD_PROFILE, { site });
}
commit(types.LOAD_PASSWORD_PROFILE, { site });
});
};

@@ -64,12 +57,13 @@ export const logout = ({ commit }) => {

export const getPasswords = ({ commit, state }) => {
if (state.authenticated) {
Password.all(state)
.then(response => {
commit(types.SET_PASSWORDS, { passwords: response.data.results });
})
.then(() => loadBestPasswordProfile({ commit }));
return Password.all(state).then(response => {
const passwords = response.data.results;
commit(types.SET_PASSWORDS, { passwords });
return passwords;
});
}
return Promise.resolve([]);
};

export const saveOrUpdatePassword = ({ commit, state }) => {


+ 0
- 1
src/store/index.js View File

@@ -13,7 +13,6 @@ const state = {
password: defaultPassword,
passwords: [],
defaultPassword: defaultPassword,
lastUse: null,
showOptions: false,
token: null,
baseURL: "https://lesspass.com"


+ 0
- 1
src/store/mutation-types.js View File

@@ -1,6 +1,5 @@
export const LOGOUT = "LOGOUT";
export const LOGIN = "LOGIN";
export const PASSWORD_GENERATED = "PASSWORD_GENERATED";
export const SET_BASE_URL = "SET_BASE_URL";
export const SET_DEFAULT_OPTIONS = "SET_DEFAULT_OPTIONS";
export const SET_MESSAGE = "SET_MESSAGE";


+ 2
- 6
src/store/mutations.js View File

@@ -16,9 +16,6 @@ export default {
[types.SET_PASSWORD](state, { password }) {
state.password = { ...password };
},
[types.PASSWORD_GENERATED](state) {
state.lastUse = new Date().getTime();
},
[types.SET_DEFAULT_OPTIONS](state, { options }) {
state.defaultPassword = Object.assign({}, state.defaultPassword, options);
},
@@ -45,9 +42,8 @@ export default {
state.password.site = site;
},
[types.LOAD_PASSWORD_PROFILE](state, { site }) {
const oneMinuteAgo = new Date().getTime() - 60 * 1000;
const siteDontMatch = !(site && site.endsWith(state.password.site));
if (state.lastUse < oneMinuteAgo || siteDontMatch) {
const siteDontMatch = site && !site.endsWith(state.password.site);
if (siteDontMatch) {
state.password = { ...state.defaultPassword };
}
const passwords = state.passwords || [];


+ 8
- 6
src/views/PasswordGenerator.vue View File

@@ -45,7 +45,7 @@
</div>
<div class="form-group">
<master-password ref="masterPassword" v-model="masterPassword"
:keyupEnter="generatePassword"
v-on:keyupEnter="generatePassword"
v-bind:label="$t('Master Password')"></master-password>
</div>
<div class="form-group"
@@ -111,7 +111,6 @@
<options :options.sync="password" v-if="showOptions || !isDefaultProfile"></options>
</form>
</template>

<script type="text/ecmascript-6">
import LessPass from 'lesspass';
import {mapGetters, mapState} from 'vuex';
@@ -135,9 +134,13 @@
...mapGetters(['passwordURL', 'isDefaultProfile'])
},
beforeMount() {
this.$store.dispatch('getPasswords');
this.$store.dispatch('getSite');
this.$store.dispatch('getPasswordFromUrlQuery', {query: this.$route.query});
this.$store
.dispatch('getPasswords')
.then(() => {
this.$store.dispatch('loadBestPasswordProfile');
this.$store.dispatch('getSite');
this.$store.dispatch('getPasswordFromUrlQuery', {query: this.$route.query});
});
},
mounted() {
setTimeout(() => {
@@ -228,7 +231,6 @@
};
return LessPass.generatePassword(site, login, masterPassword, passwordProfile).then(passwordGenerated => {
this.passwordGenerated = passwordGenerated;
this.$store.dispatch('passwordGenerated');
});
},
focusBestInputField() {


+ 8
- 107
test/unit/store.mutations.js View File

@@ -50,28 +50,6 @@ test("SET_PASSWORD", t => {
t.true(state.password.uppercase);
});

test("SET_PASSWORD dont change lastUse date", t => {
const SET_PASSWORD = mutations[types.SET_PASSWORD];
const now = 1485989236000;
const time = new Date(now);
timekeeper.freeze(time);
const state = { lastUse: null, password: null };
SET_PASSWORD(state, { password: {} });
t.true(state.lastUse === null);
timekeeper.reset();
});

test("PASSWORD_GENERATED change lastUse date", t => {
const PASSWORD_GENERATED = mutations[types.PASSWORD_GENERATED];
const now = 1485989236000;
const time = new Date(now);
timekeeper.freeze(time);
const state = { lastUse: null };
PASSWORD_GENERATED(state);
t.is(now, state.lastUse);
timekeeper.reset();
});

test("SET_PASSWORD immutable", t => {
const SET_PASSWORD = mutations[types.SET_PASSWORD];
const state = {};
@@ -238,98 +216,19 @@ test("LOAD_PASSWORD_PROFILE", t => {
t.deepEqual(state.password, state.passwords[1]);
});

test("LOAD_PASSWORD_PROFILE 30 seconds after last use", t => {
const now = 1485989236000;
const time = new Date(now);
timekeeper.freeze(time);
const thirtySecondBefore = now - 30 * 1000;
const state = {
lastUse: thirtySecondBefore,
password: {
site: "example.org",
login: "test@example.org",
length: 30
},
defaultPassword: {
login: "",
length: 16
}
};
const LOAD_PASSWORD_PROFILE = mutations[types.LOAD_PASSWORD_PROFILE];
LOAD_PASSWORD_PROFILE(state, { site: "example.org" });
t.is(state.password.login, "test@example.org");
t.is(state.password.length, 30);
timekeeper.reset();
});

test("LOAD_PASSWORD_PROFILE 30 seconds after last use on different site #242", t => {
const now = 1485989236000;
const time = new Date(now);
timekeeper.freeze(time);
const thirtySecondBefore = now - 30 * 1000;
test("LOAD_PASSWORD_PROFILE on different site", t => {
const state = {
lastUse: thirtySecondBefore,
password: {
site: "example.org",
login: "test@example.org",
length: 30
login: "test@example.org"
},
defaultPassword: {
login: "",
length: 16
login: ""
}
};
const LOAD_PASSWORD_PROFILE = mutations[types.LOAD_PASSWORD_PROFILE];
LOAD_PASSWORD_PROFILE(state, { site: "lesspass.com" });
t.is(state.password.login, "");
t.is(state.password.length, 16);
timekeeper.reset();
});

test("LOAD_PASSWORD_PROFILE more than 1 minute after last use", t => {
const now = 1485989236000;
const time = new Date(now);
timekeeper.freeze(time);
const oneMinuteAndOneSecond = now - 61 * 1000;
const state = {
lastUse: oneMinuteAndOneSecond,
password: {
site: "example.org",
login: "test@example.org",
length: 30
},
defaultPassword: {
login: "",
length: 16
}
};
const LOAD_PASSWORD_PROFILE = mutations[types.LOAD_PASSWORD_PROFILE];
LOAD_PASSWORD_PROFILE(state, { site: "example.org" });
t.is(state.password.login, "");
t.is(state.password.length, 16);
timekeeper.reset();
});

test("LOAD_PASSWORD_PROFILE empty login", t => {
const state = {
lastUse: null,
password: {
site: "",
login: "",
version: 1
},
passwords: [],
defaultPassword: {
site: "",
login: "",
version: 2
}
};
const LOAD_PASSWORD_PROFILE = mutations[types.LOAD_PASSWORD_PROFILE];
LOAD_PASSWORD_PROFILE(state, { site: "example.org" });
t.is(state.password.login, "");
t.is(state.password.version, 2);
timekeeper.reset();
});

test("LOAD_PASSWORD_PROFILE with passwords", t => {
@@ -348,7 +247,7 @@ test("LOAD_PASSWORD_PROFILE with passwords", t => {
t.is(state.password.site, "www.google.com");
});

test("LOAD_PASSWORD_PROFILE with no site reset default", t => {
test("LOAD_PASSWORD_PROFILE with no site keep password profile", t => {
const state = {
password: {
site: "example.org",
@@ -363,8 +262,10 @@ test("LOAD_PASSWORD_PROFILE with no site reset default", t => {
};
const LOAD_PASSWORD_PROFILE = mutations[types.LOAD_PASSWORD_PROFILE];
LOAD_PASSWORD_PROFILE(state, { site: "" });
t.is(state.password.login, "");
t.is(state.password.length, 16);
t.is(state.password.site, "example.org");
t.is(state.password.login, "contact@example.org");
t.is(state.password.length, 8);
t.is(state.password.version, 1);
});

test("LOAD_PASSWORD_PROFILE no passwords", t => {


Loading…
Cancel
Save