fix https://github.com/lesspass/lesspass/issues/142pull/342/head
@@ -27,6 +27,9 @@ | |||
<span v-on:click="saveOrUpdatePassword" class="white-link" v-else> | |||
<i class="fa fa-lg fa-save fa-clickable"></i> | |||
</span> | |||
<router-link class="white-link pl-2" :to="{ name: 'configureOptions'}"> | |||
<i class="fa fa-lg fa-cog" aria-hidden="true"></i> | |||
</router-link> | |||
<router-link class="white-link pl-2" :to="{ name: 'passwords'}"> | |||
<i class="fa fa-lg fa-key" aria-hidden="true"></i> | |||
</router-link> | |||
@@ -43,6 +46,9 @@ | |||
<router-link class="white-link" :to="{ name: 'home'}">LessPass</router-link> | |||
</div> | |||
<div class="col-6 text-right"> | |||
<router-link class="white-link pl-2" :to="{ name: 'configureOptions'}"> | |||
<i class="fa fa-lg fa-cog" aria-hidden="true"></i> | |||
</router-link> | |||
<router-link class="white-link pl-1" :to="{ name: 'login'}"> | |||
<i class="fa fa-lg fa-user-secret fa-clickable" aria-hidden="true"></i> | |||
</router-link> | |||
@@ -0,0 +1,98 @@ | |||
<template> | |||
<div> | |||
<div class="form-group row no-gutters pt-3"> | |||
<div class="col col-sm-2"> | |||
<label class="custom-control custom-checkbox mr-0"> | |||
<input type="checkbox" class="custom-control-input" id="lowercase" v-model="options.lowercase"> | |||
<span class="custom-control-indicator"></span> | |||
<span class="custom-control-description">abc</span> | |||
</label> | |||
</div> | |||
<div class="col col-sm-2 text-center"> | |||
<label class="custom-control custom-checkbox mr-0"> | |||
<input type="checkbox" class="custom-control-input" id="uppercase" v-model="options.uppercase"> | |||
<span class="custom-control-indicator"></span> | |||
<span class="custom-control-description">ABC</span> | |||
</label> | |||
</div> | |||
<div class="col col-sm-2 text-center"> | |||
<label class="custom-control custom-checkbox mr-0"> | |||
<input type="checkbox" class="custom-control-input" id="numbers" v-model="options.numbers"> | |||
<span class="custom-control-indicator"></span> | |||
<span class="custom-control-description">123</span> | |||
</label> | |||
</div> | |||
<div class="col col-sm-2 text-right"> | |||
<label class="custom-control custom-checkbox mr-0"> | |||
<input type="checkbox" class="custom-control-input" id="symbols" v-model="options.symbols"> | |||
<span class="custom-control-indicator"></span> | |||
<span class="custom-control-description">%!@</span> | |||
</label> | |||
</div> | |||
</div> | |||
<div class="form-group row"> | |||
<div class="col-4"> | |||
<label for="passwordLength"> | |||
Length | |||
</label> | |||
<input id="passwordLength" class="form-control form-control-sm" type="number" | |||
v-model="options.length" min="5" max="35"> | |||
</div> | |||
<div class="col-4 text-center text-sm-left"> | |||
<label for="passwordCounter"> | |||
Counter | |||
</label> | |||
<input id="passwordCounter" class="form-control form-control-sm" type="number" | |||
v-model="options.counter" min="1"> | |||
</div> | |||
<div class="col-4 text-sm-left text-right"> | |||
<label>Version</label> | |||
<br> | |||
<div class="btn-group btn-group-sm"> | |||
<button type="button" class="btn" | |||
v-bind:class="{'btn-primary':options.version===2,'btn-secondary':options.version!==2}" | |||
v-on:click="setVersion(2)"> | |||
v2 | |||
</button> | |||
<button type="button" class="btn" | |||
v-bind:class="{'btn-warning':options.version===1,'btn-secondary':options.version!==1}" | |||
v-on:click="setVersion(1)"> | |||
v1 | |||
</button> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</template> | |||
<script type="text/ecmascript-6"> | |||
export default { | |||
name: 'options', | |||
props: { | |||
password: { | |||
type: Object, | |||
required: true | |||
} | |||
}, | |||
data() { | |||
return { | |||
options: this.password | |||
}; | |||
}, | |||
watch: { | |||
options: { | |||
handler: function (newOptions) { | |||
this.$emit('optionsUpdated', newOptions) | |||
}, | |||
deep: true | |||
} | |||
}, | |||
methods: { | |||
setVersion(value){ | |||
this.options.version = value; | |||
this.$store.dispatch('saveVersion', {version: value}); | |||
} | |||
} | |||
} | |||
</script> |
@@ -1,36 +0,0 @@ | |||
<template> | |||
<div> | |||
<label>Version</label> | |||
<br> | |||
<div class="btn-group" v-bind:class="{'btn-group-sm':small}"> | |||
<button type="button" class="btn" | |||
v-bind:class="{'btn-primary':version===2,'btn-secondary':version!==2}" v-on:click="setVersion(2)"> | |||
v2 | |||
</button> | |||
<button type="button" class="btn" | |||
v-bind:class="{'btn-warning':version===1,'btn-secondary':version!==1}" v-on:click="setVersion(1)"> | |||
v1 | |||
</button> | |||
</div> | |||
</div> | |||
</template> | |||
<script type="text/ecmascript-6"> | |||
import {mapGetters} from 'vuex'; | |||
export default { | |||
props: { | |||
small: { | |||
type: Boolean, | |||
default: true | |||
} | |||
}, | |||
computed: { | |||
...mapGetters(['version']) | |||
}, | |||
methods: { | |||
setVersion(value){ | |||
this.$store.dispatch('saveVersion', {version: value}); | |||
} | |||
} | |||
} | |||
</script> | |||
@@ -1,8 +1,9 @@ | |||
import Vue from 'vue'; | |||
import VueRouter from 'vue-router'; | |||
import PasswordGenerator from './views/PasswordGenerator.vue'; | |||
import ConfigureOptions from './views/ConfigureOptions.vue'; | |||
import Login from './views/Login.vue'; | |||
import PasswordGenerator from './views/PasswordGenerator.vue'; | |||
import PasswordReset from './views/PasswordReset.vue'; | |||
import PasswordResetConfirm from './views/PasswordResetConfirm.vue'; | |||
import Passwords from './views/Passwords.vue'; | |||
@@ -13,6 +14,7 @@ const routes = [ | |||
{path: '/', name: 'home', component: PasswordGenerator}, | |||
{path: '/login', name: 'login', component: Login}, | |||
{path: '/passwords/', name: 'passwords', component: Passwords}, | |||
{path: '/options/default/', name: 'configureOptions', component: ConfigureOptions}, | |||
{path: '/passwords/:id', name: 'password', component: PasswordGenerator}, | |||
{path: '/password/reset', name: 'passwordReset', component: PasswordReset}, | |||
{path: '/password/reset/confirm/:uid/:token', name: 'passwordResetConfirm', component: PasswordResetConfirm}, | |||
@@ -0,0 +1,51 @@ | |||
<template> | |||
<div> | |||
<h4>Default Options</h4> | |||
<small class="help-text">default options are saved locally</small> | |||
<options v-bind:password="defaultPassword" v-on:optionsUpdated="updatePassword"></options> | |||
<div class="form-group"> | |||
<button type="button" class="btn btn-primary" v-on:click="saveDefault"> | |||
<span v-if="optionsSaved"> | |||
<i class="fa fa-check" aria-hidden="true"></i> saved | |||
</span> | |||
<span v-else> | |||
save as default options | |||
</span> | |||
</button> | |||
</div> | |||
</div> | |||
</template> | |||
<script type="text/ecmascript-6"> | |||
import {mapGetters} from 'vuex'; | |||
import Options from '../components/Options.vue'; | |||
export default { | |||
name: 'configure-options-view', | |||
components: { | |||
Options | |||
}, | |||
computed: mapGetters(['defaultPassword']), | |||
data(){ | |||
return { | |||
options: null, | |||
optionsSaved: false | |||
} | |||
}, | |||
methods: { | |||
saveDefault(){ | |||
if (this.options !== null) { | |||
this.$store.dispatch('saveDefaultPassword', {password: this.options}); | |||
} | |||
this.optionsSaved = true; | |||
setTimeout(() => { | |||
this.optionsSaved = false; | |||
}, 3000); | |||
}, | |||
updatePassword(password){ | |||
console.log(password); | |||
this.options = password; | |||
} | |||
} | |||
} | |||
</script> |
@@ -64,9 +64,6 @@ | |||
</small> | |||
</div> | |||
</div> | |||
<div class="col-sm-4 col mt-3"> | |||
<version-button :small="false"></version-button> | |||
</div> | |||
</div> | |||
<div class="form-group my-0"> | |||
<router-link :to="{ name: 'passwordReset'}"> | |||
@@ -82,7 +79,6 @@ | |||
import {mapGetters} from 'vuex'; | |||
import MasterPassword from '../components/MasterPassword.vue'; | |||
import OptionsButton from '../components/OptionsButton.vue'; | |||
import VersionButton from '../components/VersionButton.vue'; | |||
const defaultErrors = { | |||
userNameAlreadyExist: false, | |||
@@ -111,8 +107,7 @@ | |||
}, | |||
components: { | |||
MasterPassword, | |||
OptionsButton, | |||
VersionButton | |||
OptionsButton | |||
}, | |||
computed: { | |||
...mapGetters(['version']) | |||
@@ -130,9 +125,9 @@ | |||
uppercase: true, | |||
numbers: true, | |||
symbols: true, | |||
length: this.version == 2 ? 16 : 12, | |||
length: 16, | |||
counter: 1, | |||
version: this.version, | |||
version: 2, | |||
}; | |||
return LessPass.generatePassword('lesspass.com', this.email, this.password, defaultPasswordProfile).then(generatedPassword => { | |||
this.password = generatedPassword; | |||
@@ -113,75 +113,17 @@ | |||
<options-button v-on:click.native="showOptions=!showOptions"></options-button> | |||
</div> | |||
</div> | |||
<div class="form-group row no-gutters pt-3" v-if="showOptions"> | |||
<div class="col col-sm-2"> | |||
<label class="custom-control custom-checkbox mr-0"> | |||
<input type="checkbox" class="custom-control-input" id="lowercase" v-model="password.lowercase"> | |||
<span class="custom-control-indicator"></span> | |||
<span class="custom-control-description">abc</span> | |||
</label> | |||
</div> | |||
<div class="col col-sm-2 text-center"> | |||
<label class="custom-control custom-checkbox mr-0"> | |||
<input type="checkbox" class="custom-control-input" id="uppercase" v-model="password.uppercase"> | |||
<span class="custom-control-indicator"></span> | |||
<span class="custom-control-description">ABC</span> | |||
</label> | |||
</div> | |||
<div class="col col-sm-2 text-center"> | |||
<label class="custom-control custom-checkbox mr-0"> | |||
<input type="checkbox" class="custom-control-input" id="numbers" v-model="password.numbers"> | |||
<span class="custom-control-indicator"></span> | |||
<span class="custom-control-description">123</span> | |||
</label> | |||
</div> | |||
<div class="col col-sm-2 text-right"> | |||
<label class="custom-control custom-checkbox mr-0"> | |||
<input type="checkbox" class="custom-control-input" id="symbols" v-model="password.symbols"> | |||
<span class="custom-control-indicator"></span> | |||
<span class="custom-control-description">%!@</span> | |||
</label> | |||
</div> | |||
</div> | |||
<div class="form-group row" v-if="showOptions"> | |||
<div class="col-4"> | |||
<label for="passwordLength"> | |||
Length | |||
</label> | |||
<input class="form-control form-control-sm" type="number" id="passwordLength" | |||
v-model="password.length" min="5" max="35"> | |||
</div> | |||
<div class="col-4 text-center text-sm-left"> | |||
<label for="passwordCounter"> | |||
Counter | |||
</label> | |||
<input class="form-control form-control-sm" type="number" id="passwordCounter" | |||
v-model="password.counter" min="1"> | |||
</div> | |||
<div class="col-4 text-sm-left text-right"> | |||
<version-button class="mr-1"></version-button> | |||
</div> | |||
</div> | |||
<options :password="password" v-on:optionsUpdated="updatePassword" v-if="showOptions"></options> | |||
<div class="form-group" v-if="showOptions"> | |||
<div class="input-group input-group-sm"> | |||
<span class="input-group-btn btn-copy" data-clipboard-target="#passwordURL" > | |||
<button class="btn btn-secondary"type="button"> | |||
<span class="input-group-btn btn-copy" data-clipboard-target="#passwordURL"> | |||
<button class="btn btn-secondary" type="button"> | |||
<i class="fa fa-share-alt" aria-hidden="true"></i> | |||
</button> | |||
</span> | |||
<input id="passwordURL" type="text" class="form-control" v-model="passwordURL"> | |||
</div> | |||
</div> | |||
<div class="form-group" v-if="showOptions"> | |||
<button type="button" class="btn btn-secondary btn-sm" v-on:click="saveDefault"> | |||
<span v-if="optionsSaved" class="text-success"> | |||
<i class="fa fa-check" aria-hidden="true"></i> saved | |||
</span> | |||
<span v-else> | |||
save as default options | |||
</span> | |||
</button> | |||
</div> | |||
<div class="form-group mt-3" v-if="showError"> | |||
<div class="alert alert-danger" role="alert"> | |||
site, login and master password fields are mandatory | |||
@@ -197,8 +139,8 @@ | |||
import {getSite, getPasswordFromUrlQuery} from '../domain/url-parser'; | |||
import RemoveAutoComplete from '../components/RemoveAutoComplete.vue'; | |||
import MasterPassword from '../components/MasterPassword.vue'; | |||
import VersionButton from '../components/VersionButton.vue'; | |||
import OptionsButton from '../components/OptionsButton.vue'; | |||
import Options from '../components/Options.vue'; | |||
function fetchPasswords(store) { | |||
return store.dispatch('getPasswords') | |||
@@ -218,7 +160,7 @@ | |||
components: { | |||
RemoveAutoComplete, | |||
MasterPassword, | |||
VersionButton, | |||
Options, | |||
OptionsButton | |||
}, | |||
computed: mapGetters(['passwords', 'password', 'passwordURL']), | |||
@@ -268,8 +210,7 @@ | |||
cleanTimeout: null, | |||
showOptions: false, | |||
showError: false, | |||
generatingPassword: false, | |||
optionsSaved: false | |||
generatingPassword: false | |||
} | |||
}, | |||
watch: { | |||
@@ -292,24 +233,6 @@ | |||
'password.login': function () { | |||
this.cleanErrors(); | |||
}, | |||
'password.uppercase': function () { | |||
this.cleanErrors(); | |||
}, | |||
'password.lowercase': function () { | |||
this.cleanErrors(); | |||
}, | |||
'password.numbers': function () { | |||
this.cleanErrors(); | |||
}, | |||
'password.symbols': function () { | |||
this.cleanErrors(); | |||
}, | |||
'password.length': function () { | |||
this.cleanErrors(); | |||
}, | |||
'password.counter': function () { | |||
this.cleanErrors(); | |||
}, | |||
'generatedPassword': function () { | |||
this.cleanFormInSeconds(30); | |||
}, | |||
@@ -370,12 +293,9 @@ | |||
window.document.getElementById('copyPasswordButton').setAttribute('data-clipboard-text', generatedPassword); | |||
}); | |||
}, | |||
saveDefault(){ | |||
this.$store.dispatch('saveDefaultPassword', {password: this.password}); | |||
this.optionsSaved = true; | |||
setTimeout(() => { | |||
this.optionsSaved = false; | |||
}, 3000); | |||
updatePassword(password){ | |||
this.cleanErrors(); | |||
this.$store.dispatch('savePassword', {password: password}); | |||
} | |||
} | |||
} | |||