Ver a proveniência

Make clients compatible with the old API

old servers uses numbers instead of digits in the API.
This patch intercept API requests to make it compatible with new and old servers.
pull/763/head
Guillaume Vincent há 1 ano
ascendente
cometimento
c92c0e3d99
8 ficheiros alterados com 254 adições e 73 eliminações
  1. +46
    -9
      mobile/src/password/profilesActions.js
  2. +26
    -0
      mobile/src/password/profilesActions.test.js
  3. +6
    -17
      mobile/src/password/profilesReducer.js
  4. +0
    -17
      mobile/src/password/profilesReducer.test.js
  5. +1
    -1
      packages/lesspass-pure/package.json
  6. +41
    -5
      packages/lesspass-pure/src/api/password.js
  7. +6
    -4
      packages/lesspass-pure/src/services/encryption.js
  8. +128
    -20
      packages/lesspass-pure/tests/unit/api/password.spec.js

+ 46
- 9
mobile/src/password/profilesActions.js Ver ficheiro

@@ -22,6 +22,17 @@ function removePasswordProfile(profile) {
};
}

function replaceNumbersWithDigitsInProfile(profile) {
if ("numbers" in profile) {
const { numbers, ...profileWithoutNumbers } = profile;
return {
...profileWithoutNumbers,
digits: numbers,
};
}
return profile;
}

export function getPasswordProfiles() {
return (dispatch, getState) => {
const { settings, auth } = getState();
@@ -30,21 +41,39 @@ export function getPasswordProfiles() {
headers: { Authorization: `Bearer ${auth.accessToken}` },
})
.then((response) => {
dispatch(setPasswordProfiles(response.data.results));
const profiles = response.data.results.map(
replaceNumbersWithDigitsInProfile
);
dispatch(setPasswordProfiles(profiles));
return response;
});
};
}

export function addNumbersFieldInProfile(profile) {
return {
...profile,
numbers: profile.digits,
};
}

export function savePasswordProfile(profile) {
return (dispatch, getState) => {
const { settings, auth } = getState();
return axios
.post(`${settings.baseURL}/passwords/`, profile, {
headers: { Authorization: `Bearer ${auth.accessToken}` },
})
.post(
`${settings.baseURL}/passwords/`,
addNumbersFieldInProfile(profile),
{
headers: { Authorization: `Bearer ${auth.accessToken}` },
}
)
.then((response) => {
dispatch(addPasswordProfile({ ...response.data }));
dispatch(
addPasswordProfile(
replaceNumbersWithDigitsInProfile({ ...response.data })
)
);
return response;
})
.catch(() =>
@@ -61,11 +90,19 @@ export function updatePasswordProfile(profile) {
return (dispatch, getState) => {
const { settings, auth } = getState();
return axios
.put(`${settings.baseURL}/passwords/${profile.id}/`, profile, {
headers: { Authorization: `Bearer ${auth.accessToken}` },
})
.put(
`${settings.baseURL}/passwords/${profile.id}/`,
addNumbersFieldInProfile(profile),
{
headers: { Authorization: `Bearer ${auth.accessToken}` },
}
)
.then((response) => {
dispatch(addPasswordProfile({ ...response.data }));
dispatch(
addPasswordProfile(
replaceNumbersWithDigitsInProfile({ ...response.data })
)
);
return response;
})
.catch(() =>


+ 26
- 0
mobile/src/password/profilesActions.test.js Ver ficheiro

@@ -0,0 +1,26 @@
import {
replaceNumbersWithDigitsInProfile,
addNumbersFieldInProfile,
} from "./profilesActions";

it("replaceNumbersWithDigitsInProfile numbers become digits", () => {
expect(
replaceNumbersWithDigitsInProfile({ id: "p2", numbers: false })
).toEqual({ id: "p2", digits: false });
expect(
replaceNumbersWithDigitsInProfile([{ id: "p1", numbers: true }])
).toEqual({ id: "p1", digits: true });
});

it("addNumbersFieldInProfile add numbers with digits", () => {
expect(addNumbersFieldInProfile({ id: "p1", digits: true })).toEqual({
id: "p1",
digits: true,
numbers: true,
});
expect(addNumbersFieldInProfile({ id: "p2", digits: false })).toEqual({
id: "p2",
digits: false,
numbers: false,
});
});

+ 6
- 17
mobile/src/password/profilesReducer.js Ver ficheiro

@@ -3,23 +3,12 @@ const initialState = {};
export default function reduce(state = initialState, action) {
switch (action.type) {
case "SET_PASSWORD_PROFILES":
return action.profiles
.map((profile) => {
if ("numbers" in profile) {
const { numbers, ...profileWithoutNumbers } = profile;
return {
...profileWithoutNumbers,
digits: numbers,
};
}
return profile;
})
.reduce((acc, p) => {
acc[p.id] = {
...p,
};
return acc;
}, {});
return action.profiles.reduce((acc, profile) => {
acc[profile.id] = {
...profile,
};
return acc;
}, {});
case "ADD_PASSWORD_PROFILE":
return {
...state,


+ 0
- 17
mobile/src/password/profilesReducer.test.js Ver ficheiro

@@ -18,23 +18,6 @@ describe("profiles reducer", () => {
p2: { id: "p2" },
});
});
it("SET_PASSWORD_PROFILES numbers become digits", () => {
expect(
reducer(
{},
{
type: "SET_PASSWORD_PROFILES",
profiles: [
{ id: "p1", numbers: true },
{ id: "p2", numbers: false },
],
}
)
).toEqual({
p1: { id: "p1", digits: true },
p2: { id: "p2", digits: false },
});
});
it("REMOVE_PASSWORD_PROFILE", () => {
expect(
reducer(


+ 1
- 1
packages/lesspass-pure/package.json Ver ficheiro

@@ -11,7 +11,7 @@
"i18n:translate": "node src/i18n/translate.js",
"prettier": "prettier --write 'src/**/*'",
"test": "yarn test:unit && yarn test:e2e",
"test:watch": "jest --watch",
"test:watch": "vue-cli-service test:unit --watch",
"test:unit": "vue-cli-service test:unit",
"test:e2e": "vue-cli-service test:e2e --headless",
"lint": "vue-cli-service lint"


+ 41
- 5
packages/lesspass-pure/src/api/password.js Ver ficheiro

@@ -1,19 +1,55 @@
import http from "./http";

function addNumbersFieldInProfile(profile) {
return {
...profile,
numbers: profile.digits,
};
}

function replaceNumbersWithDigitsInProfile(profile) {
if ("numbers" in profile) {
const { numbers, ...profileWithoutNumbers } = profile;
return {
...profileWithoutNumbers,
digits: numbers,
};
}
return profile;
}

export default {
all() {
return http.get("/passwords/");
return http.get("/passwords/").then((response) => {
response.data.results = response.data.results.map(
replaceNumbersWithDigitsInProfile
);
return response;
});
},
create(resource) {
return http.post("/passwords/", resource);
return http
.post("/passwords/", addNumbersFieldInProfile(resource))
.then((response) => {
response.data = replaceNumbersWithDigitsInProfile(response.data);
return response;
});
},
read(resource) {
return http.get(`/passwords/${resource.id}/`);
return http.get(`/passwords/${resource.id}/`).then((response) => {
response.data = replaceNumbersWithDigitsInProfile(response.data);
return response;
});
},
update(resource) {
return http.put(`/passwords/${resource.id}/`, resource);
return http
.put(`/passwords/${resource.id}/`, addNumbersFieldInProfile(resource))
.then((response) => {
response.data = replaceNumbersWithDigitsInProfile(response.data);
return response;
});
},
delete(resource) {
return http.delete(`/passwords/${resource.id}/`);
}
},
};

+ 6
- 4
packages/lesspass-pure/src/services/encryption.js Ver ficheiro

@@ -3,9 +3,11 @@ import defaultPasswordProfile from "../store/defaultPassword";

export function encryptPassword(email, password) {
return LessPass.generatePassword(
"lesspass.com",
email,
password,
defaultPasswordProfile
{
...defaultPasswordProfile,
site: "lesspass.com",
login: email,
},
password
);
}

+ 128
- 20
packages/lesspass-pure/tests/unit/api/password.spec.js Ver ficheiro

@@ -4,51 +4,159 @@ import Passwords from "@/api/password";

const mock = new MockAdapter(axios);

test("Passwords.create", () => {
const password = { login: "text@example.org" };
test("Passwords.create on old server replace numbers field after creation", () => {
mock
.onPost("https://api.lesspass.com/passwords/", password)
.reply(201, { ...password, id: "1" });
return Passwords.create(password).then(response => {
const passwordCreated = response.data;
expect(passwordCreated.id).toBe("1");
expect(passwordCreated.login).toBe(password.login);
.onPost("https://api.lesspass.com/passwords/", {
login: "text@example.org",
digits: false,
numbers: false,
})
.reply(201, { id: "p1", login: "text@example.org", numbers: false });
const password = { login: "text@example.org", digits: false };
return Passwords.create(password).then((response) => {
expect(response.status).toBe(201);
expect(response.data).toEqual({
id: "p1",
login: "text@example.org",
digits: false,
});
});
});

test("Passwords.all", () => {
mock.onGet("https://api.lesspass.com/passwords/").reply(200, {});
return Passwords.all().then(response => {
test("Passwords.create on new server keeps digits", () => {
mock
.onPost("https://api.lesspass.com/passwords/", {
login: "text@example.org",
digits: false,
numbers: false,
})
.reply(201, { id: "p1", login: "text@example.org", digits: false });
const password = { login: "text@example.org", digits: false };
return Passwords.create(password).then((response) => {
expect(response.status).toBe(201);
expect(response.data).toEqual({
id: "p1",
login: "text@example.org",
digits: false,
});
});
});

test("Passwords.all on old server transform numbers into digits", () => {
mock.onGet("https://api.lesspass.com/passwords/").reply(200, {
results: [{ id: "p1", numbers: false }],
});
return Passwords.all().then((response) => {
expect(response.status).toBe(200);
expect(response.data).toEqual({
results: [{ id: "p1", digits: false }],
});
});
});

test("Passwords.all on new server keeps digits", () => {
mock.onGet("https://api.lesspass.com/passwords/").reply(200, {
results: [{ id: "p2", digits: false }],
});
return Passwords.all().then((response) => {
expect(response.status).toBe(200);
expect(response.data).toEqual({
results: [{ id: "p2", digits: false }],
});
});
});

test("Passwords.get", () => {
test("Passwords.get on old server replace numbers with digits", () => {
mock
.onGet(
"https://api.lesspass.com/passwords/c8e4f983-8ffe-b705-4064-d3b7aa4a4782/"
)
.reply(200, {});
.reply(200, { id: "p1", numbers: false });
return Passwords.read({ id: "c8e4f983-8ffe-b705-4064-d3b7aa4a4782" }).then(
response => {
(response) => {
expect(response.status).toBe(200);
expect(response.data).toEqual({ id: "p1", digits: false });
}
);
});

test("Passwords.update", () => {
test("Passwords.get on new server keeps digits", () => {
mock
.onGet(
"https://api.lesspass.com/passwords/c8e4f983-8ffe-b705-4064-d3b7aa4a4782/"
)
.reply(200, { id: "p1", digits: false });
return Passwords.read({ id: "c8e4f983-8ffe-b705-4064-d3b7aa4a4782" }).then(
(response) => {
expect(response.status).toBe(200);
expect(response.data).toEqual({ id: "p1", digits: false });
}
);
});

test("Passwords.update on old server replace numbers field after update", () => {
mock
.onPut(
"https://api.lesspass.com/passwords/c8e4f983-4064-8ffe-b705-d3b7aa4a4782/",
{
id: "c8e4f983-4064-8ffe-b705-d3b7aa4a4782",
login: "test@example.org",
digits: true,
numbers: true,
}
)
.reply(200, {
id: "c8e4f983-4064-8ffe-b705-d3b7aa4a4782",
login: "test@example.org",
numbers: true,
});

const password = {
id: "c8e4f983-4064-8ffe-b705-d3b7aa4a4782",
login: "test@example.org"
login: "test@example.org",
digits: true,
};

return Passwords.update(password).then((response) => {
expect(response.status).toBe(200);
expect(response.data).toEqual({
id: "c8e4f983-4064-8ffe-b705-d3b7aa4a4782",
login: "test@example.org",
digits: true,
});
});
});

test("Passwords.update on new keeps digits", () => {
mock
.onPut(
"https://api.lesspass.com/passwords/c8e4f983-4064-8ffe-b705-d3b7aa4a4782/",
password
{
id: "c8e4f983-4064-8ffe-b705-d3b7aa4a4782",
login: "test@example.org",
digits: true,
numbers: true,
}
)
.reply(200, {});
return Passwords.update(password).then(response => {
.reply(200, {
id: "c8e4f983-4064-8ffe-b705-d3b7aa4a4782",
login: "test@example.org",
digits: true,
});

const password = {
id: "c8e4f983-4064-8ffe-b705-d3b7aa4a4782",
login: "test@example.org",
digits: true,
};

return Passwords.update(password).then((response) => {
expect(response.status).toBe(200);
expect(response.data).toEqual({
id: "c8e4f983-4064-8ffe-b705-d3b7aa4a4782",
login: "test@example.org",
digits: true,
});
});
});

@@ -59,7 +167,7 @@ test("Passwords.delete", () => {
)
.reply(204);
return Passwords.delete({ id: "c8e4f983-8ffe-4064-b705-d3b7aa4a4782" }).then(
response => {
(response) => {
expect(response.status).toBe(204);
}
);


Carregando…
Cancelar
Guardar