Selaa lähdekoodia

Redesign encrypt master password feature

* remove checkbox and replace with a button
 * remove inner-addon to clean the interface
 * add encrypt master password feature in reset password page

fix https://github.com/lesspass/lesspass/issues/227
fix https://github.com/lesspass/lesspass/issues/110
pull/342/head
Guillaume Vincent 7 vuotta sitten
vanhempi
commit
ef7feb46b0
6 muutettua tiedostoa jossa 138 lisäystä ja 141 poistoa
  1. +48
    -0
      src/components/EncryptMasterPassword.vue
  2. +20
    -3
      src/components/MasterPassword.vue
  3. +17
    -55
      src/views/Login.vue
  4. +21
    -54
      src/views/PasswordGenerator.vue
  5. +6
    -9
      src/views/PasswordReset.vue
  6. +26
    -20
      src/views/PasswordResetConfirm.vue

+ 48
- 0
src/components/EncryptMasterPassword.vue Näytä tiedosto

@@ -0,0 +1,48 @@
<template>
<div id="encryptMasterPassword">
<master-password
v-model="password"
showEncryptMasterPassword="true"
v-on:input="$emit('input', password)"
v-on:encryptMasterPassword="encryptMasterPassword"></master-password>
</div>
</template>
<script type="text/ecmascript-6">
import LessPass from 'lesspass';
import MasterPassword from './MasterPassword.vue';
import message from '../services/message';

export default {
components: {
MasterPassword
},
props: ['value', 'email'],
data(){
return {
password: this.value
}
},
methods: {
encryptMasterPassword(){
if (!this.email) {
message.error(this.$t('EmailRequired', 'An email is required'));
return;
}
const defaultPasswordProfile = {
lowercase: true,
uppercase: true,
numbers: true,
symbols: true,
length: 16,
counter: 1,
version: 2,
};
return LessPass
.generatePassword('lesspass.com', this.email, this.password, defaultPasswordProfile)
.then(generatedPassword => {
this.password = generatedPassword;
});
}
}
}
</script>

+ 20
- 3
src/components/MasterPassword.vue Näytä tiedosto

@@ -1,7 +1,15 @@
<template>
<div id="masterPassword" class="inner-addon left-addon input-group">
<div id="masterPassword" class="input-group">
<span class="input-group-btn" v-if="showEncryptMasterPassword">
<button type="button"
tabindex="-1"
class="btn btn-secondary hint--right hint--medium"
v-on:click="encryptMasterPassword()"
v-bind:data-hint="$t('EncryptMasterPassword', 'Click me to encrypt this password before sending it to lesspass.com')">
<i class="fa fa-shield"></i>
</button>
</span>
<label for="password" class="sr-only">{{ $t('Master Password') }}</label>
<i class="fa fa-lock"></i>
<input id="password"
name="password"
ref="password"
@@ -26,7 +34,13 @@
components: {
Fingerprint
},
props: ['value', 'keyupEnter'],
props: {
value: '',
keyupEnter: '',
showEncryptMasterPassword: {
'default': false
}
},
data(){
return {
fingerprint: '',
@@ -62,6 +76,9 @@
if (typeof this.keyupEnter !== 'undefined' && this.password) {
this.keyupEnter()
}
},
encryptMasterPassword(){
this.$emit('encryptMasterPassword')
}
}
}


+ 17
- 55
src/views/Login.vue Näytä tiedosto

@@ -10,39 +10,25 @@
<template>
<form v-on:submit.prevent="signIn">
<div class="form-group">
<div class="inner-addon left-addon">
<i class="fa fa-globe"></i>
<input id="baseURL"
class="form-control"
type="text"
placeholder="https://lesspass.com"
v-model="baseURL">
</div>
<input id="baseURL"
class="form-control"
type="text"
v-bind:placeholder="$t('LessPass Database Url')"
v-model="baseURL">
</div>
<div class="form-group row">
<div class="col-12">
<div class="inner-addon left-addon">
<i class="fa fa-user"></i>
<input id="email"
class="form-control"
name="username"
type="email"
v-bind:placeholder="$t('Email')"
required
v-model="email">
</div>
<input id="email"
class="form-control"
name="username"
type="email"
v-bind:placeholder="$t('Email')"
required
v-model="email">
</div>
</div>
<div class="form-group mb-2">
<master-password v-model="password"></master-password>
<label class="custom-control custom-checkbox hint--top hint--medium mb-0"
v-bind:data-hint="$t('EncryptMasterPassword', 'Click me to encrypt this password before sending it to lesspass.com')">
<input type="checkbox" class="custom-control-input" v-model="transformMasterPassword">
<span class="custom-control-indicator"></span>
<span class="custom-control-description text-muted">
{{$t('Encrypt my master password')}}
</span>
</label>
<div class="form-group">
<encrypt-master-password v-model="password" v-bind:email="email"></encrypt-master-password>
</div>
<div class="form-group row no-gutters mb-0">
<div class="col">
@@ -65,10 +51,9 @@
</form>
</template>
<script type="text/ecmascript-6">
import LessPass from 'lesspass';
import User from '../api/user';
import {mapGetters} from 'vuex';
import MasterPassword from '../components/MasterPassword.vue';
import EncryptMasterPassword from '../components/EncryptMasterPassword.vue';
import message from '../services/message';

export default {
@@ -76,38 +61,15 @@
return {
email: '',
password: '',
baseURL: 'https://lesspass.com',
transformMasterPassword: false,
baseURL: 'https://lesspass.com'
};
},
components: {
MasterPassword
EncryptMasterPassword
},
computed: {
...mapGetters(['version'])
},
watch: {
password: function() {
this.transformMasterPassword = false;
},
transformMasterPassword: function(transformPassword) {
if (!transformPassword) {
return;
}
const defaultPasswordProfile = {
lowercase: true,
uppercase: true,
numbers: true,
symbols: true,
length: 16,
counter: 1,
version: 2,
};
return LessPass.generatePassword('lesspass.com', this.email, this.password, defaultPasswordProfile).then(generatedPassword => {
this.password = generatedPassword;
});
}
},
methods: {
formIsValid(){
if (!this.email || !this.password || !this.baseURL) {


+ 21
- 54
src/views/PasswordGenerator.vue Näytä tiedosto

@@ -3,33 +3,6 @@
font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, sans-serif;
}

.inner-addon i {
position: absolute;
padding: 10px;
pointer-events: none;
z-index: 10;
}

.inner-addon {
position: relative;
}

.left-addon i {
left: 0;
}

.right-addon i {
right: 0;
}

.left-addon input {
padding-left: 30px;
}

.right-addon input {
padding-right: 30px;
}

div.awesomplete {
display: block;
}
@@ -41,36 +14,30 @@
<template>
<form id="password-generator">
<div class="form-group">
<div class="inner-addon left-addon">
<label for="site" class="sr-only">{{ $t('Site') }}</label>
<i class="fa fa-globe"></i>
<input id="site"
name="site"
type="text"
ref="site"
class="form-control awesomplete"
autocorrect="off"
autocapitalize="none"
v-bind:placeholder="$t('Site')"
v-model="password.site">
</div>
<label for="site" class="sr-only">{{ $t('Site') }}</label>
<input id="site"
name="site"
type="text"
ref="site"
class="form-control awesomplete"
autocorrect="off"
autocapitalize="none"
v-bind:placeholder="$t('Site')"
v-model="password.site">
</div>
<remove-auto-complete></remove-auto-complete>
<div class="form-group">
<div class="inner-addon left-addon">
<label for="login" class="sr-only">{{ $t('Login') }}</label>
<i class="fa fa-user"></i>
<input id="login"
name="login"
type="text"
ref="login"
class="form-control"
autocomplete="off"
autocorrect="off"
autocapitalize="none"
v-bind:placeholder="$t('Login')"
v-model="password.login">
</div>
<label for="login" class="sr-only">{{ $t('Login') }}</label>
<input id="login"
name="login"
type="text"
ref="login"
class="form-control"
autocomplete="off"
autocorrect="off"
autocapitalize="none"
v-bind:placeholder="$t('Login')"
v-model="password.login">
</div>
<div class="form-group">
<master-password ref="masterPassword" v-model="masterPassword"


+ 6
- 9
src/views/PasswordReset.vue Näytä tiedosto

@@ -2,15 +2,12 @@
<form v-on:submit.prevent="resetPassword">
<div class="form-group row">
<div class="col-12">
<div class="inner-addon left-addon">
<i class="fa fa-user"></i>
<input id="email"
class="form-control"
name="email"
type="email"
placeholder="Email"
v-model="email">
</div>
<input id="email"
class="form-control"
name="email"
type="email"
placeholder="Email"
v-model="email">
</div>
</div>
<div class="form-group row">


+ 26
- 20
src/views/PasswordResetConfirm.vue Näytä tiedosto

@@ -2,16 +2,17 @@
<form v-on:submit.prevent="resetPasswordConfirm">
<div class="form-group row">
<div class="col-12">
<div class="inner-addon left-addon">
<i class="fa fa-lock"></i>
<input id="new-password"
class="form-control"
name="new-password"
type="password"
autocomplete="new-password"
v-bind:placeholder="$t('New Password')"
v-model="new_password">
</div>
<input id="email"
class="form-control"
name="email"
type="email"
placeholder="Email"
v-model="email">
</div>
</div>
<div class="form-group row">
<div class="col-12">
<encrypt-master-password v-model="newPassword" v-bind:email="email"></encrypt-master-password>
</div>
</div>
<div class="form-group row">
@@ -28,39 +29,44 @@
import User from '../api/user';
import {mapActions, mapGetters} from 'vuex';
import message from '../services/message';
import EncryptMasterPassword from '../components/EncryptMasterPassword.vue';

export default {
computed: {
...mapGetters(['version'])
},
components: {
EncryptMasterPassword
},
data() {
return {
new_password: ''
email: '',
newPassword: ''
};
},
methods: {
resetPasswordConfirm(){
if (!this.new_password) {
message.success($t('PasswordResetRequired', 'A password is required'));
if (!this.newPassword) {
message.error(this.$t('PasswordResetRequired', 'A password is required'));
return;
}
User
.confirmResetPassword({
uid: this.$route.params.uid,
token: this.$route.params.token,
new_password: this.new_password
newPassword: this.newPassword
})
.then(() => {
message.success($t('PasswordResetSuccessful', 'Your password was reset successfully.'));
message.success(this.$t('PasswordResetSuccessful', 'Your password was reset successfully.'));
})
.catch(err => {
if (err.response.status === 400) {
message.error($t('ResetLinkExpired', 'This password reset link has expired.'));
message.error(this.$t('ResetLinkExpired', 'This password reset link has expired.'));
} else {
message.displayGenericError();
}
});
}
},
computed: {
...mapGetters(['version'])
},
}
}
</script>

Ladataan…
Peruuta
Tallenna