ソースを参照

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年前
コミット
c92c0e3d99
8個のファイルの変更254行の追加73行の削除
  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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

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


読み込み中…
キャンセル
保存