Kaynağa Gözat

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 1 yıl önce
ebeveyn
işleme
c92c0e3d99
8 değiştirilmiş dosya ile 254 ekleme ve 73 silme
  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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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);
}
);


Yükleniyor…
İptal
Kaydet