@@ -1,6 +1,6 @@ | |||
{ | |||
"name": "lesspass-pure", | |||
"version": "9.5.6", | |||
"version": "10.0.0", | |||
"description": "LessPass web component", | |||
"license": "GPL-3.0", | |||
"author": "Guillaume Vincent <guillaume@oslab.fr>", | |||
@@ -57,6 +57,7 @@ | |||
"balloon-css": "^1.0.3", | |||
"bootstrap": "^4.6.0", | |||
"core-js": "^3.9.1", | |||
"file-saver": "^2.0.5", | |||
"font-awesome": "^4.7.0", | |||
"jwt-decode": "^3.1.2", | |||
"lesspass": "9.2.0", | |||
@@ -44,6 +44,14 @@ | |||
</span> | |||
<router-link | |||
class="menu-link pl-3" | |||
:to="{ name: 'export' }" | |||
v-if="isAuthenticated" | |||
:title="$t('Export your passwords')" | |||
> | |||
<i class="fa fa-lg fa-download text-success"></i> | |||
</router-link> | |||
<router-link | |||
class="menu-link pl-3" | |||
:to="{ name: 'passwords' }" | |||
v-if="isAuthenticated" | |||
:title="$t('Saved passwords')" | |||
@@ -1,6 +1,7 @@ | |||
import Vue from "vue"; | |||
import VueRouter from "vue-router"; | |||
import ExportYourPasswords from "./views/ExportYourPasswords.vue"; | |||
import Login from "./views/Login.vue"; | |||
import Register from "./views/Register.vue"; | |||
import MyAccount from "./views/MyAccount.vue"; | |||
@@ -20,6 +21,7 @@ const routes = [ | |||
{ path: "/myaccount", name: "myaccount", component: MyAccount }, | |||
{ path: "/whatsnew", name: "whatsnew", component: WhatsNewPage }, | |||
{ path: "/settings", name: "settings", component: SettingsPage }, | |||
{ path: "/export", name: "export", component: ExportYourPasswords }, | |||
{ path: "/passwords/", name: "passwords", component: Passwords }, | |||
{ path: "/password/reset", name: "passwordReset", component: PasswordReset }, | |||
{ | |||
@@ -0,0 +1,81 @@ | |||
<template> | |||
<form v-on:submit.prevent="exportPasswords"> | |||
<div class="mb-3"> | |||
<h5>{{ $t("Export your passwords") }}</h5> | |||
</div> | |||
<div class="form-group"> | |||
<master-password | |||
v-model="masterPassword" | |||
v-bind:label="$t('Master Password')" | |||
></master-password> | |||
</div> | |||
<div class="form-group"> | |||
<button id="signInButton" class="btn btn-primary btn-block"> | |||
{{ $t("Export") }} | |||
</button> | |||
</div> | |||
<div class="form-group"> | |||
<p class="text-danger"> | |||
Be careful your passwords will be in clear text. Don't leave this file | |||
lying around for too long. Import it in your new password manager and | |||
delete it. | |||
</p> | |||
<p> | |||
The export is a csv file with the following header | |||
"name,url,username,password". It's similar to the Google Chrome export. | |||
</p> | |||
</div> | |||
</form> | |||
</template> | |||
<script> | |||
import LessPass from "lesspass"; | |||
import MasterPassword from "../components/MasterPassword.vue"; | |||
import message from "../services/message"; | |||
import { mapState } from "vuex"; | |||
import { saveAs } from "file-saver"; | |||
export default { | |||
data() { | |||
return { | |||
masterPassword: "", | |||
}; | |||
}, | |||
components: { | |||
MasterPassword, | |||
}, | |||
beforeMount() { | |||
this.$store.dispatch("getPasswords"); | |||
}, | |||
computed: mapState(["passwords"]), | |||
methods: { | |||
formIsValid() { | |||
if (!this.masterPassword) { | |||
message.error( | |||
this.$t("MasterPasswordRequired", "Your master password is required") | |||
); | |||
return false; | |||
} | |||
return true; | |||
}, | |||
exportPasswords: async function () { | |||
if (this.formIsValid()) { | |||
let content = "name,url,username,password\n"; | |||
for (let i = 0; i < this.passwords.length; i++) { | |||
const passwordProfile = this.passwords[i]; | |||
passwordProfile["digits"] = passwordProfile["numbers"]; | |||
console.log(JSON.stringify(passwordProfile, null, 2)); | |||
console.log(this.masterPassword); | |||
const generatedPassword = await LessPass.generatePassword( | |||
passwordProfile, | |||
this.masterPassword | |||
); | |||
content += `${passwordProfile.site},https://${passwordProfile.site},${passwordProfile.login},${generatedPassword}\n`; | |||
} | |||
var blob = new Blob([content], { type: "text/csv;charset=utf-8" }); | |||
saveAs(blob, "LessPass passwords.csv"); | |||
message.success("Your passwords has been exported successfully."); | |||
} | |||
}, | |||
}, | |||
}; | |||
</script> |
@@ -39,15 +39,14 @@ | |||
{{ $t("Sign In") }} | |||
</button> | |||
</div> | |||
<div class="form-group mb-0"> | |||
<button | |||
id="login__no-account-btn" | |||
type="button" | |||
class="btn btn-outline-dark btn-block" | |||
v-on:click="$router.push({ name: 'register' })" | |||
> | |||
{{ $t("NewToLessPass", "New to LessPass? Join now") }} | |||
</button> | |||
<div class="form-group text-danger"> | |||
LessPass Database server will be turned off on March 1th, 2023. | |||
<a | |||
href="https://blog.lesspass.com/2022-12-29/decommissioning-lesspass-database" | |||
target="_blank" | |||
rel="noopener noreferrer" | |||
>See announcement</a | |||
>. Sign in to export your passwords. | |||
</div> | |||
</form> | |||
</template> | |||
@@ -62,12 +61,12 @@ export default { | |||
data() { | |||
return { | |||
email: "", | |||
password: "" | |||
password: "", | |||
}; | |||
}, | |||
computed: mapState(["settings"]), | |||
components: { | |||
MasterPassword | |||
MasterPassword, | |||
}, | |||
methods: { | |||
formIsValid() { | |||
@@ -81,16 +80,16 @@ export default { | |||
}, | |||
signIn() { | |||
if (this.formIsValid()) { | |||
encryptPassword(this.email, this.password).then(encryptedPassword => { | |||
encryptPassword(this.email, this.password).then((encryptedPassword) => { | |||
const password = this.settings.encryptMasterPassword | |||
? encryptedPassword | |||
: this.password; | |||
User.login({ email: this.email, password }) | |||
.then(response => { | |||
.then((response) => { | |||
this.$store.dispatch("login", response.data); | |||
this.$router.push({ name: "home" }); | |||
}) | |||
.catch(err => { | |||
.catch((err) => { | |||
if (err.response && err.response.status === 401) { | |||
message.error( | |||
this.$t( | |||
@@ -104,7 +103,7 @@ export default { | |||
}); | |||
}); | |||
} | |||
} | |||
} | |||
}, | |||
}, | |||
}; | |||
</script> |
@@ -7,30 +7,37 @@ | |||
<p> | |||
{{ | |||
$t( | |||
"New20210331", | |||
"I took over the development on LessPass, to fix bugs and improve the interface. I simplified the login page to correct the problem with the login url for the self-hosted version. The master password is encrypted by default before being sent to the server side. It is always possible to uncheck this option but only for connections." | |||
"New20221231", | |||
"LessPass Database server will be turned off on March 1th, 2023. The static version of LessPass, the web extension and the mobile versions remain in place." | |||
) | |||
}} | |||
<router-link class="" :to="{ name: 'export' }" v-if="isAuthenticated"> | |||
Export your passwords | |||
</router-link> | |||
</p> | |||
<p>Guillaume</p> | |||
<a href="https://github.com/lesspass/lesspass/blob/master/CONTRIBUTING.md"> | |||
{{ | |||
$t( | |||
"WantToHelp", | |||
"Do you want to help me? Please feel free to contribute to LessPass" | |||
) | |||
}} | |||
<a | |||
href="https://blog.lesspass.com/2022-12-29/decommissioning-lesspass-database" | |||
> | |||
{{ $t("ReadMoreAboutDecommissioning", "See announcement") }} | |||
</a> | |||
<p v-if="isGuest"> | |||
If you want to export your password, please | |||
<router-link class="" :to="{ name: 'login' }"> sign in </router-link> | |||
</p> | |||
</div> | |||
</template> | |||
<script> | |||
import { version } from "../../package.json"; | |||
import { mapGetters } from "vuex"; | |||
export default { | |||
data() { | |||
return { | |||
version | |||
version, | |||
}; | |||
} | |||
}, | |||
computed: { | |||
...mapGetters(["isAuthenticated", "isGuest"]), | |||
}, | |||
}; | |||
</script> |
@@ -6931,6 +6931,11 @@ file-loader@^4.2.0: | |||
loader-utils "^1.2.3" | |||
schema-utils "^2.5.0" | |||
file-saver@^2.0.5: | |||
version "2.0.5" | |||
resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-2.0.5.tgz#d61cfe2ce059f414d899e9dd6d4107ee25670c38" | |||
integrity sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA== | |||
file-type@^3.1.0, file-type@^3.8.0: | |||
version "3.9.0" | |||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" | |||
@@ -10429,6 +10434,30 @@ left-pad@^1.3.0: | |||
resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" | |||
integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== | |||
lesspass-pure@^9.5.2, lesspass-pure@^9.5.6: | |||
version "9.5.6" | |||
resolved "https://registry.yarnpkg.com/lesspass-pure/-/lesspass-pure-9.5.6.tgz#e092ec551597c3775b39bba05d8d70158c12d411" | |||
integrity sha512-419u5JDap2jf0445IoCg6W1ZCcwOqbzcLJO0XrbDqvKwoxvjQsdHjEL5VtdlZAYS45g9E4Q81mcSL77XBkoQWQ== | |||
dependencies: | |||
"@oslab/atob" "^0.1.0" | |||
"@oslab/btoa" "^0.1.0" | |||
awesomplete "^1.1.5" | |||
axios "^0.21.1" | |||
balloon-css "^1.0.3" | |||
bootstrap "^4.6.0" | |||
core-js "^3.9.1" | |||
font-awesome "^4.7.0" | |||
jwt-decode "^3.1.2" | |||
lesspass "9.2.0" | |||
lodash "^4.17.21" | |||
vue "^2.6.12" | |||
vue-polyglot "^2.0.1" | |||
vue-router "^3.5.1" | |||
vuejs-paginate "^2.1.0" | |||
vuex "^3.6.2" | |||
vuex-persistedstate "^3.2.0" | |||
vuex-router-sync "^5.0.0" | |||
leven@^3.1.0: | |||
version "3.1.0" | |||
resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" | |||