Browse Source

Fix email reset password and update login mechanism

pull/544/head
Guillaume Vincent 4 years ago
parent
commit
1aa99a7577
14 changed files with 126 additions and 118 deletions
  1. +1
    -1
      packages/lesspass-pure/package.json
  2. +0
    -1
      packages/lesspass-pure/src/LessPass.vue
  3. +1
    -1
      packages/lesspass-pure/src/api/password.js
  4. +1
    -1
      packages/lesspass-pure/src/api/password.test.js
  5. +17
    -17
      packages/lesspass-pure/src/api/user.js
  6. +21
    -29
      packages/lesspass-pure/src/api/user.test.js
  7. +2
    -2
      packages/lesspass-pure/src/components/Menu.vue
  8. +6
    -13
      packages/lesspass-pure/src/store/actions.js
  9. +3
    -2
      packages/lesspass-pure/src/store/index.js
  10. +1
    -1
      packages/lesspass-pure/src/store/mutation-types.js
  11. +3
    -2
      packages/lesspass-pure/src/store/mutations.js
  12. +7
    -5
      packages/lesspass-pure/src/store/mutations.test.js
  13. +2
    -1
      packages/lesspass-pure/src/views/Login.vue
  14. +61
    -42
      packages/lesspass-pure/src/views/PasswordResetConfirm.vue

+ 1
- 1
packages/lesspass-pure/package.json View File

@@ -1,6 +1,6 @@
{
"name": "lesspass-pure",
"version": "9.1.9",
"version": "9.1.10",
"description": "LessPass web component",
"license": "GPL-3.0",
"author": "Guillaume Vincent <guillaume@oslab.fr>",


+ 0
- 1
packages/lesspass-pure/src/LessPass.vue View File

@@ -80,7 +80,6 @@ export default {
},
created() {
this.$store.dispatch("cleanMessage");
this.$store.dispatch("refreshToken");
this.$store.dispatch("resetPassword");
}
};


+ 1
- 1
packages/lesspass-pure/src/api/password.js View File

@@ -4,7 +4,7 @@ export default {
addAuthorizationHeader(config) {
return {
...config,
headers: { Authorization: `JWT ${config.token}` }
headers: { Authorization: `Bearer ${config.access_token}` }
};
},
all(config) {


+ 1
- 1
packages/lesspass-pure/src/api/password.test.js View File

@@ -4,7 +4,7 @@ import Passwords from "./password";

const mock = new MockAdapter(axios);

const config = { baseURL: "https://lesspass.com", token: "abc" };
const config = { baseURL: "https://lesspass.com", access_token: "abc" };

test("Passwords.create", () => {
const password = { login: "text@example.org" };


+ 17
- 17
packages/lesspass-pure/src/api/user.js View File

@@ -1,25 +1,25 @@
import axios from "axios";

export default {
login(user, config) {
return axios.post("/api/tokens/auth/", user, config).then(response => {
return response.data;
});
login({ email, password }, config) {
return axios.post("/api/auth/jwt/create/", { email, password }, config);
},
register(user, config) {
return axios.post("/api/auth/register/", user, config).then(response => {
return response.data;
});
register({ email, password }, config) {
return axios.post("/api/auth/users/", { email, password }, config);
},
resetPassword(email, config) {
return axios.post("/api/auth/password/reset/", email, config);
resetPassword({ email }, config) {
return axios.post("/api/auth/users/reset_password/", { email }, config);
},
confirmResetPassword(password, config) {
return axios.post("/api/auth/password/reset/confirm/", password, config);
},
requestNewToken(token, config) {
return axios.post("/api/tokens/refresh/", token, config).then(response => {
return response.data.token;
});
confirmResetPassword({ uid, token, password }, config) {
return axios.post(
"/api/auth/users/reset_password_confirm/",
{
uid,
token,
new_password: password,
re_new_password: password
},
config
);
}
};

+ 21
- 29
packages/lesspass-pure/src/api/user.test.js View File

@@ -5,40 +5,42 @@ import User from "./user";
const mock = new MockAdapter(axios);

test("login", () => {
const token = "5e0651";
const access = "12345";
const refresh = "67890"
const user = { email: "test@example.org", password: "password" };
mock
.onPost("/api/tokens/auth/", user)
.reply(201, { token });
.onPost("/api/auth/jwt/create/", user)
.reply(201, { access, refresh });
return User.login(user, {
baseURL: "https://lesspass.com"
}).then(response => {
expect(response.token).toBe(token);
expect(response.data.access).toBe(access);
expect(response.data.refresh).toBe(refresh);
});
});

test("register", () => {
const user = { email: "test@example.org", password: "password" };
mock
.onPost("/api/auth/register/", user)
.onPost("/api/auth/users/", user)
.reply(201, { email: user.email, pk: 1 });
return User.register(user, {
baseURL: "https://lesspass.com"
}).then(response => {
expect(response.email).toBe(user.email);
expect(response.data.email).toBe(user.email);
});
});

test("resetPassword", () => {
var email = "test@lesspass.com";
mock
.onPost("/api/auth/password/reset/", { email })
.onPost("/api/auth/users/reset_password/", { email })
.reply(204);
return User.resetPassword(
{ email },
{ baseURL: "https://lesspass.com" }
).then(data => {
expect(data.status).toBe(204);
).then(response => {
expect(response.status).toBe(204);
});
});

@@ -46,29 +48,19 @@ test("confirmResetPassword", () => {
var newPassword = {
uid: "MQ",
token: "5g1-2bd69bd6f6dcd73f8124",
new_password: "password1"
new_password: "password1",
re_new_password: "password1",
};
mock
.onPost("/api/auth/password/reset/confirm/", newPassword)
.onPost("/api/auth/users/reset_password_confirm/", newPassword)
.reply(204);
return User.confirmResetPassword(newPassword, {
return User.confirmResetPassword({
uid: "MQ",
token: "5g1-2bd69bd6f6dcd73f8124",
password: "password1",
}, {
baseURL: "https://lesspass.com"
}).then(data => {
expect(data.status).toBe(204);
});
});

test("refresh token", () => {
const token = "3e3231";
const newToken =
"wibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9eyJzdWIiOiIxMjM0NTY3ODkwIi";
mock
.onPost("/api/tokens/refresh/", { token })
.reply(200, { token: newToken });
return User.requestNewToken(
{ token },
{ baseURL: "https://lesspass.com" }
).then(refreshedToken => {
expect(refreshedToken).toBe(newToken);
}).then(response => {
expect(response.status).toBe(204);
});
});

+ 2
- 2
packages/lesspass-pure/src/components/Menu.vue View File

@@ -59,11 +59,11 @@
methods: {
fullReload() {
this.$store.dispatch('resetPassword');
this.$router.push({name: 'home'});
this.$router.push({name: 'home'}).catch(e => {});
},
logout() {
this.$store.dispatch('logout');
this.$router.push({name: 'home'});
this.$router.push({name: 'home'}).catch(e => {});
},
saveOrUpdatePassword() {
this.$store.dispatch('saveOrUpdatePassword');


+ 6
- 13
packages/lesspass-pure/src/store/actions.js View File

@@ -1,18 +1,8 @@
import Password from "../api/password";
import User from "../api/user";
import * as urlParser from "../services/url-parser";
import * as types from "./mutation-types";
import defaultPasswordProfile from "./defaultPassword";

export const refreshToken = ({ commit, state }) => {
const token = state.token;
if (token) {
User.requestNewToken({ token }, { baseURL: state.baseURL })
.then(newToken => commit(types.SET_TOKEN, { token: newToken }))
.catch(() => commit(types.LOGOUT));
}
};

export const saveDefaultOptions = ({ commit }, payload) => {
commit(types.SET_DEFAULT_OPTIONS, payload);
};
@@ -37,9 +27,12 @@ export const resetPassword = ({ commit }) => {
commit(types.RESET_PASSWORD);
};

export const login = ({ commit }, payload) => {
commit(types.SET_BASE_URL, payload);
commit(types.SET_TOKEN, payload);
export const setBaseURL = ({ commit }, { baseURL }) => {
commit(types.SET_BASE_URL, { baseURL });
};

export const login = ({ commit }, { access, refresh }) => {
commit(types.SET_TOKENS, { access_token: access, refresh_token: refresh });
commit(types.LOGIN);
};



+ 3
- 2
packages/lesspass-pure/src/store/index.js View File

@@ -15,7 +15,8 @@ const state = {
message: "",
defaultPassword: defaultPassword,
showOptions: false,
token: null,
access_token: null,
refresh_token: null,
baseURL: "https://lesspass.com"
};

@@ -27,7 +28,7 @@ export default new Vuex.Store({
plugins: [
createPersistedState({
key: "lesspass",
paths: ["token", "baseURL", "authenticated", "defaultPassword"]
paths: ["access_token", "refresh_token", "baseURL", "authenticated", "defaultPassword"]
})
]
});

+ 1
- 1
packages/lesspass-pure/src/store/mutation-types.js View File

@@ -5,7 +5,7 @@ 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 SET_TOKEN = "SET_TOKEN";
export const SET_TOKENS = "SET_TOKENS";
export const RESET_PASSWORD = "RESET_PASSWORD";
export const SET_SITE = "SET_SITE";
export const LOAD_PASSWORD_PROFILE = "LOAD_PASSWORD_PROFILE";


+ 3
- 2
packages/lesspass-pure/src/store/mutations.js View File

@@ -4,8 +4,9 @@ export default {
[types.LOGIN](state) {
state.authenticated = true;
},
[types.SET_TOKEN](state, { token }) {
state.token = token;
[types.SET_TOKENS](state, { refresh_token, access_token }) {
state.refresh_token = refresh_token;
state.access_token = access_token
},
[types.LOGOUT](state) {
state.authenticated = false;


+ 7
- 5
packages/lesspass-pure/src/store/mutations.test.js View File

@@ -43,12 +43,14 @@ test("LOGIN", () => {
expect(state.authenticated).toBe(true);
});

test("SET_TOKEN", () => {
const token = "123456";
const SET_TOKEN = mutations[types.SET_TOKEN];
test("SET_TOKENS", () => {
const access_token = "123456";
const refresh_token = "7890"
const SET_TOKENS = mutations[types.SET_TOKENS];
const state = { token: null };
SET_TOKEN(state, { token });
expect(state.token).toBe(token);
SET_TOKENS(state, { access_token, refresh_token });
expect(state.access_token).toBe(access_token);
expect(state.refresh_token).toBe(refresh_token);
});

test("SET_PASSWORD", () => {


+ 2
- 1
packages/lesspass-pure/src/views/Login.vue View File

@@ -107,7 +107,8 @@ export default {
const baseURL = this.baseURL;
User.login({ email: this.email, password: this.password }, { baseURL })
.then(response => {
this.$store.dispatch("login", { token: response.token, baseURL });
this.$store.dispatch("login", response.data);
this.$store.dispatch("setBaseURL", { baseURL });
this.$router.push({ name: "home" });
})
.catch(err => {


+ 61
- 42
packages/lesspass-pure/src/views/PasswordResetConfirm.vue View File

@@ -4,12 +4,14 @@
<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">
<input
id="email"
class="form-control"
name="email"
type="email"
placeholder="Email"
v-model="email"
/>
</div>
</div>
</div>
@@ -20,56 +22,73 @@
v-bind:label="$t('Master Password')"
v-bind:email="email"
v-bind:showEncryptButton="true"
v-bind:EncryptButtonText="$t('Encrypt my master password')"></master-password>
v-bind:EncryptButtonText="$t('Encrypt my master password')"
></master-password>
</div>
</div>
<div class="form-group row">
<div class="col-12">
<button id="loginButton" class="btn btn-primary">
{{$t('Reset my password')}}
{{ $t("Reset my password") }}
</button>
</div>
</div>
</form>
</template>
<script type="text/ecmascript-6">
import User from '../api/user';
import message from '../services/message';
import MasterPassword from '../components/MasterPassword.vue';
import User from '../api/user';
import message from '../services/message';
import MasterPassword from '../components/MasterPassword.vue';
import { mapState } from "vuex";

export default {
components: {
MasterPassword
},
data() {
return {
email: '',
password: ''
};
},
methods: {
resetPasswordConfirm(){
if (!this.password) {
message.error(this.$t('PasswordResetRequired', 'A password is required'));
return;
}
User
.confirmResetPassword({
export default {
components: {
MasterPassword
},
data() {
return {
email: '',
password: ''
};
},
computed: mapState([
'baseURL'
]),
methods: {
resetPasswordConfirm(){
if (!this.password) {
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.password
})
.then(() => {
message.success(this.$t('PasswordResetSuccessful', 'Your password was reset successfully.'));
})
.catch(err => {
if (err.response.status === 400) {
message.error(this.$t('ResetLinkExpired', 'This password reset link has expired.'));
} else {
message.displayGenericError();
}
});
}
password: this.password
},
{
baseURL: this.baseURL
}
)
.then(() => {
message.success(this.$t('PasswordResetSuccessful', 'Your password was reset successfully.'));
User
.login({ email: this.email, password: this.password }, { baseURL: this.baseURL })
.then(response => {
this.$store.dispatch("login", response.data);
this.$router.push({ name: "home" });
})
.catch(err => message.displayGenericError());
})
.catch(err => {
if (err.response.status === 400) {
message.error(this.$t('ResetLinkExpired', 'This password reset link has expired.'));
} else {
message.displayGenericError();
}
});
}
}
}
</script>

Loading…
Cancel
Save