Skip to content

Commit

Permalink
Use chrome.storage.local instead of localStorage
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibautBremand committed Aug 5, 2023
1 parent 3575e00 commit 433eb0d
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 54 deletions.
10 changes: 9 additions & 1 deletion packages/extension/src/components/pages/Login/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ import { Logo } from '../../atoms/Logo';

export const Login: FC = () => {
const [passwordError, setPasswordError] = useState('');
const [rememberSession, setRememberSession] = useState(loadRememberSessionState());
const [rememberSession, setRememberSession] = useState(false);
const navigate = useNavigate();
const { search } = useLocation();
const { signIn, wallets, selectedWallet } = useWallet();
Expand Down Expand Up @@ -109,6 +109,14 @@ export const Login: FC = () => {
}
}, [navigate, navigateToPath, search, selectedWallet, wallets]);

useEffect(() => {
const loadRememberSession = async () => {
const loadedState = await loadRememberSessionState();
setRememberSession(loadedState);
};
loadRememberSession();
}, []);

const handleUnlock = useCallback(() => {
const passwordValue = passwordRef.current?.value;
if (passwordValue && signIn(passwordValue, rememberSession)) {
Expand Down
2 changes: 1 addition & 1 deletion packages/extension/src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export * from './apiErrors';
export * from './colors';
export * from './links';
export * from './localStorage';
export * from './storage';
export * from './navigation';
export * from './parameters';
export * from './routes';
Expand Down
File renamed without changes.
3 changes: 2 additions & 1 deletion packages/extension/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export * from './link';
export * from './network';
export * from './numbersToSeed';
export * from './parseFromString';
export * from './storage';
export * from './storageChrome';
export * from './storageLocal';
export * from './transaction';
export * from './truncateAddress';
export * from './truncateWalletName';
Expand Down
83 changes: 42 additions & 41 deletions packages/extension/src/utils/login.test.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,63 @@
// Mock the chrome storage object and its methods
import { STORAGE_REMEMBER_SESSION } from '../constants';
import { loadRememberSessionState, saveRememberSessionState } from './login';

// Mock the localStorage object and its methods
const localStorageMock = {
getItem: jest.fn(),
setItem: jest.fn(),
clear: jest.fn(),
removeItem: jest.fn(),
length: 0,
key: jest.fn()
const chrome = {
storage: {
local: {
get: jest.fn(),
set: jest.fn()
}
}
};

beforeEach(() => {
jest.spyOn(window, 'localStorage', 'get').mockImplementation(() => localStorageMock);
});

afterEach(() => {
// Reset the mock after each test
localStorageMock.getItem.mockReset();
localStorageMock.setItem.mockReset();
});
// Make sure the chrome object is available globally
global.chrome = chrome as any;

describe('saveRememberSessionState', () => {
test('should save the remember session state to local storage', () => {
const state = true;
saveRememberSessionState(state);
expect(localStorage.setItem).toHaveBeenCalledWith(
STORAGE_REMEMBER_SESSION,
JSON.stringify(state)
);
beforeEach(() => {
// Clear all instances and calls to constructor and all methods:
chrome.storage.local.set.mockClear();
});

test('should throw an error if saving to local storage fails', () => {
const error = new Error('Error saving to local storage');
localStorage.setItem = jest.fn(() => {
throw error;
test('should save the remember session state to chrome storage', async () => {
const state = true;
saveRememberSessionState(state);
expect(chrome.storage.local.set).toHaveBeenCalledWith({
[STORAGE_REMEMBER_SESSION]: JSON.stringify(state)
});
expect(() => saveRememberSessionState(true)).toThrowError(error);
});
});

describe('loadRememberSessionState', () => {
test('should load the remember session state from local storage', () => {
beforeEach(() => {
// Clear all instances and calls to constructor and all methods:
chrome.storage.local.get.mockClear();
});

test('should load the remember session state from chrome storage', async () => {
const state = true;
localStorage.getItem = jest.fn(() => JSON.stringify(state));
expect(loadRememberSessionState()).toEqual(state);
chrome.storage.local.get.mockResolvedValue({
[STORAGE_REMEMBER_SESSION]: JSON.stringify(state)
});

const loadedState = await loadRememberSessionState();
expect(loadedState).toEqual(state);
});

test('should return false if no state is found in local storage', () => {
localStorage.getItem = jest.fn(() => null);
expect(loadRememberSessionState()).toEqual(false);
test('should return false if no state is found in chrome storage', async () => {
chrome.storage.local.get.mockResolvedValue({});

const loadedState = await loadRememberSessionState();
expect(loadedState).toEqual(false);
});

test('should return false if an error occurs while loading the state', () => {
const error = new Error('Error loading state from local storage');
localStorageMock.getItem = jest.fn(() => {
throw error;
});
expect(loadRememberSessionState()).toEqual(false);
test('should return false if an error occurs while loading the state', async () => {
chrome.storage.local.get.mockRejectedValue(
new Error('Error loading state from chrome storage')
);

const loadedState = await loadRememberSessionState();
expect(loadedState).toEqual(false);
});
});
9 changes: 5 additions & 4 deletions packages/extension/src/utils/login.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { STORAGE_REMEMBER_SESSION } from '../constants';
import { loadFromChromeStorage, saveInChromeStorage } from './storageChrome';

export const saveRememberSessionState = (checked: boolean) => {
localStorage.setItem(STORAGE_REMEMBER_SESSION, JSON.stringify(checked));
saveInChromeStorage(STORAGE_REMEMBER_SESSION, JSON.stringify(checked));
};

export const loadRememberSessionState = (): boolean => {
export const loadRememberSessionState = async (): Promise<boolean> => {
try {
const storedState = localStorage.getItem(STORAGE_REMEMBER_SESSION);
return storedState ? JSON.parse(storedState) === true : false;
const storedState = await loadFromChromeStorage(STORAGE_REMEMBER_SESSION);
return storedState ? JSON.parse(storedState[STORAGE_REMEMBER_SESSION]) === true : false;
} catch (e) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/extension/src/utils/network.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NETWORK, Network } from '@gemwallet/constants';
import { NetworkData } from '@gemwallet/constants/src/network/network.types';

import { STORAGE_CUSTOM_NETWORKS, STORAGE_NETWORK } from '../constants/localStorage';
import { STORAGE_CUSTOM_NETWORKS, STORAGE_NETWORK } from '../constants/storage';

import { loadData, removeData, saveData } from '.';

Expand Down
23 changes: 23 additions & 0 deletions packages/extension/src/utils/storageChrome.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Manages the storage in Chrome storage
*/

export const saveInChromeStorage = (key: string, value: string) => {
try {
chrome.storage.local.set({ [key]: value });
} catch (e) {
throw e;
}
};

export const loadFromChromeStorage = (key: string) => {
try {
return chrome.storage.local.get(key);
} catch (e) {
throw e;
}
};

export const generateKey = () => {
return (Date.now() + Math.random()).toString();
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Manages localStorage data
*/

export const saveData = (key: string, value: string) => {
try {
localStorage.setItem(key, value);
Expand Down
2 changes: 1 addition & 1 deletion packages/extension/src/utils/trustedApps.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { STORAGE_TRUSTED_APPS } from '../constants';
import { loadData } from './storage';
import { loadData } from './storageLocal';
import {
checkPermissions,
loadTrustedApps,
Expand Down
4 changes: 2 additions & 2 deletions packages/extension/src/utils/trustedApps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { STORAGE_TRUSTED_APPS } from '../constants/localStorage';
import { loadData, removeData, saveData } from './storage';
import { STORAGE_TRUSTED_APPS } from '../constants/storage';
import { loadData, removeData, saveData } from './storageLocal';

export enum Permission {
Address = 'address',
Expand Down
4 changes: 2 additions & 2 deletions packages/extension/src/utils/wallet.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { STORAGE_SELECTED_WALLET, STORAGE_WALLETS } from '../constants/localStorage';
import { STORAGE_SELECTED_WALLET, STORAGE_WALLETS } from '../constants/storage';
import { Wallet } from '../types';
import { decrypt, encrypt } from './crypto';
import { loadData, removeData, saveData } from './storage';
import { loadData, removeData, saveData } from './storageLocal';

export interface WalletToSave extends Omit<Wallet, 'name'> {
name?: string;
Expand Down

0 comments on commit 433eb0d

Please sign in to comment.