From 9980e78918c77985af3978100003c8828ec1182f Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Mon, 27 Apr 2020 22:55:24 +0200 Subject: [PATCH] use react native keystore instead of expo secure store --- __mocks__/react-native-keychain/index.js | 7 ++++ __tests__/managers/ConnectionManager.test.js | 42 +------------------- package.json | 2 +- src/managers/ConnectionManager.js | 24 +++++------ 4 files changed, 22 insertions(+), 53 deletions(-) create mode 100644 __mocks__/react-native-keychain/index.js diff --git a/__mocks__/react-native-keychain/index.js b/__mocks__/react-native-keychain/index.js new file mode 100644 index 0000000..3d30acb --- /dev/null +++ b/__mocks__/react-native-keychain/index.js @@ -0,0 +1,7 @@ +const keychainMock = { + SECURITY_LEVEL_ANY: "MOCK_SECURITY_LEVEL_ANY", + SECURITY_LEVEL_SECURE_SOFTWARE: "MOCK_SECURITY_LEVEL_SECURE_SOFTWARE", + SECURITY_LEVEL_SECURE_HARDWARE: "MOCK_SECURITY_LEVEL_SECURE_HARDWARE", +} + +export default keychainMock; \ No newline at end of file diff --git a/__tests__/managers/ConnectionManager.test.js b/__tests__/managers/ConnectionManager.test.js index 2a9a996..e307fd5 100644 --- a/__tests__/managers/ConnectionManager.test.js +++ b/__tests__/managers/ConnectionManager.test.js @@ -1,7 +1,8 @@ +jest.mock('react-native-keychain'); + import React from 'react'; import ConnectionManager from "../../src/managers/ConnectionManager"; import {ERROR_TYPE} from "../../src/utils/WebData"; -import * as SecureStore from 'expo-secure-store'; let fetch = require('isomorphic-fetch'); // fetch is not implemented in nodeJS but in react-native @@ -25,45 +26,6 @@ test('isLoggedIn no', () => { return expect(c.isLoggedIn()).toBe(false); }); -test('recoverLogin error crypto', () => { - jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => { - return Promise.reject(); - }); - return expect(c.recoverLogin()).rejects.toBe(false); -}); - -test('recoverLogin success crypto', () => { - jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => { - return Promise.resolve('token1'); - }); - return expect(c.recoverLogin()).resolves.toBe('token1'); -}); - -test('saveLogin success', () => { - jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => { - return Promise.resolve(); - }); - return expect(c.saveLogin('email', 'token2')).resolves.toBeTruthy(); -}); - -test('saveLogin error', () => { - jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => { - return Promise.reject(); - }); - return expect(c.saveLogin('email', 'token3')).rejects.toBeFalsy(); -}); - -test('recoverLogin error crypto with saved token', () => { - jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => { - return Promise.reject(); - }); - return expect(c.recoverLogin()).resolves.toBe('token2'); -}); - -test('recoverLogin success saved', () => { - return expect(c.recoverLogin()).resolves.toBe('token2'); -}); - test("isConnectionResponseValid", () => { let json = { error: 0, diff --git a/package.json b/package.json index 916508e..d59e6c3 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,6 @@ "expo": "^37.0.0", "expo-barcode-scanner": "~8.1.0", "expo-camera": "latest", - "expo-secure-store": "~8.1.0", "i18n-js": "^3.3.0", "react": "~16.9.0", "react-dom": "16.9.0", @@ -40,6 +39,7 @@ "react-native-collapsible": "^1.5.2", "react-native-gesture-handler": "~1.6.0", "react-native-image-modal": "^1.0.6", + "react-native-keychain": "^6.0.0", "react-native-linear-gradient": "^2.5.6", "react-native-localize": "^1.4.0", "react-native-modalize": "^1.3.6", diff --git a/src/managers/ConnectionManager.js b/src/managers/ConnectionManager.js index 9ff1675..ead57d7 100644 --- a/src/managers/ConnectionManager.js +++ b/src/managers/ConnectionManager.js @@ -1,6 +1,6 @@ // @flow -import * as SecureStore from 'expo-secure-store'; +import * as Keychain from 'react-native-keychain'; import {apiRequest, ERROR_TYPE, isResponseValid} from "../utils/WebData"; /** @@ -14,7 +14,7 @@ import {apiRequest, ERROR_TYPE, isResponseValid} from "../utils/WebData"; * 500 : SERVER_ERROR -> pb coté serveur */ - +const SERVER_NAME = "amicale-insat.fr"; const AUTH_PATH = "password"; export default class ConnectionManager { @@ -60,16 +60,16 @@ export default class ConnectionManager { if (this.getToken() !== null) resolve(this.getToken()); else { - SecureStore.getItemAsync('token') - .then((token) => { - this.#token = token; - if (token !== null) { + Keychain.getInternetCredentials(SERVER_NAME) + .then((data) => { + if (data) { + this.#token = data.password; this.onLoginStateChange(true); - resolve(token); + resolve(this.#token); } else reject(false); }) - .catch(error => { + .catch(() => { reject(false); }); } @@ -82,14 +82,14 @@ export default class ConnectionManager { async saveLogin(email: string, token: string) { return new Promise((resolve, reject) => { - SecureStore.setItemAsync('token', token) + Keychain.setInternetCredentials(SERVER_NAME, 'token', token) .then(() => { this.#token = token; this.#email = email; this.onLoginStateChange(true); resolve(true); }) - .catch(error => { + .catch(() => { reject(false); }); }); @@ -97,13 +97,13 @@ export default class ConnectionManager { async disconnect() { return new Promise((resolve, reject) => { - SecureStore.deleteItemAsync('token') + Keychain.resetInternetCredentials(SERVER_NAME) .then(() => { this.#token = null; this.onLoginStateChange(false); resolve(true); }) - .catch((error) => { + .catch(() => { reject(false); }); });