fix(firefox): short session duration, closes #4030

This commit is contained in:
kyranjamie
2023-08-14 11:15:08 +02:00
committed by kyranjamie
parent 3a77bfce5b
commit 5a09c43846
6 changed files with 19 additions and 107 deletions

View File

@@ -37,7 +37,7 @@ function setWalletEncryptionPassword(args: {
password,
});
await initalizeWalletSession(encryptionKey, secretKey);
await initalizeWalletSession(encryptionKey);
const legacyAccountActivityLookup =
await checkForLegacyGaiaConfigWithKnownGeneratedAccountIndex(secretKey);
@@ -102,7 +102,7 @@ function unlockWalletAction(password: string): AppThunk {
if (!currentKey) return;
if (currentKey.type !== 'software') return;
const { secretKey, encryptionKey } = await decryptMnemonic({ password, ...currentKey });
await initalizeWalletSession(encryptionKey, secretKey);
await initalizeWalletSession(encryptionKey);
const rootKey = mnemonicToRootNode(secretKey);
if (!rootKey.publicKey) throw new Error('Could not derive root key from mnemonic');

View File

@@ -1,72 +1,32 @@
import { decrypt } from '@stacks/wallet-sdk';
import { InternalMethods } from '@shared/message-types';
import { sendMessage } from '@shared/messages';
import { whenBrowserRuntime } from '@shared/utils/get-browser-runtime';
import { logger } from '@shared/logger';
import { store } from '@app/store';
import { inMemoryKeyActions } from '@app/store/in-memory-key/in-memory-key.actions';
import { selectCurrentKey } from '@app/store/keys/key.selectors';
import { defaultKeyId } from '@app/store/keys/key.slice';
export async function initalizeWalletSession(encryptionKey: string, secretKey: string) {
return await whenBrowserRuntime({
async chromium() {
return chrome.storage.session.set({ encryptionKey });
},
async firefox() {
return sendMessage({
method: InternalMethods.ShareInMemoryKeyToBackground,
payload: { secretKey, keyId: defaultKeyId },
});
},
})();
export async function initalizeWalletSession(encryptionKey: string) {
return chrome.storage.session.set({ encryptionKey });
}
export async function clearWalletSession() {
return await whenBrowserRuntime({
async chromium() {
return chrome.storage.session.remove('encryptionKey');
},
async firefox() {
return chrome.runtime.sendMessage({ method: InternalMethods.RemoveInMemoryKeys });
},
})();
return chrome.storage.session.remove('encryptionKey');
}
export async function restoreWalletSession() {
return whenBrowserRuntime({
async chromium() {
const key = await chrome.storage.session.get(['encryptionKey']);
if (!key.encryptionKey) return false;
const key = await chrome.storage.session.get(['encryptionKey']);
try {
const currentKey = selectCurrentKey(store.getState());
if (!key.encryptionKey) return;
if (currentKey?.type === 'software') {
const secretKey = await decrypt(currentKey.encryptedSecretKey, key.encryptionKey);
store.dispatch(inMemoryKeyActions.setKeysInMemory({ default: secretKey }));
return true;
}
} catch (e) {
return false;
}
try {
const currentKey = selectCurrentKey(store.getState());
return false;
},
async firefox() {
return checkForInMemoryKeys();
},
})();
}
async function checkForInMemoryKeys() {
return new Promise(resolve =>
chrome.runtime.sendMessage({ method: InternalMethods.RequestInMemoryKeys }, resp => {
if (!resp) resolve(false);
if (Object.keys(resp).length === 0) return resolve(false);
store.dispatch(inMemoryKeyActions.setKeysInMemory(resp));
resolve(true);
})
);
if (currentKey?.type === 'software') {
const secretKey = await decrypt(currentKey.encryptedSecretKey, key.encryptionKey);
store.dispatch(inMemoryKeyActions.setKeysInMemory({ default: secretKey }));
}
} catch (e) {
logger.error('Failed to decrypt secret key');
}
}

View File

@@ -1,5 +1,4 @@
import { logger } from '@shared/logger';
import { InternalMethods } from '@shared/message-types';
import { BackgroundMessages } from '@shared/messages';
function validateMessagesAreFromExtension(sender: chrome.runtime.MessageSender) {
@@ -7,8 +6,6 @@ function validateMessagesAreFromExtension(sender: chrome.runtime.MessageSender)
return sender.url?.startsWith(chrome.runtime.getURL(''));
}
const inMemoryKeys = new Map();
function makeFormStateKey(tabId: number) {
return 'form-state-' + tabId.toString();
}
@@ -31,23 +28,5 @@ export async function internalBackgroundMessageHandler(
return;
}
logger.debug('Internal message', message);
switch (message.method) {
case InternalMethods.ShareInMemoryKeyToBackground: {
const { keyId, secretKey } = message.payload;
inMemoryKeys.set(keyId, secretKey);
sendResponse();
break;
}
case InternalMethods.RequestInMemoryKeys: {
sendResponse(Object.fromEntries(inMemoryKeys));
break;
}
case InternalMethods.RemoveInMemoryKeys: {
inMemoryKeys.clear();
sendResponse();
break;
}
}
sendResponse();
}

View File

@@ -27,9 +27,6 @@ export enum ExternalMethods {
export enum InternalMethods {
RequestDerivedStxAccounts = 'RequestDerivedStxAccounts',
ShareInMemoryKeyToBackground = 'ShareInMemoryKeyToBackground',
RequestInMemoryKeys = 'RequestInMemoryKeys',
RemoveInMemoryKeys = 'RemoveInMemoryKeys',
OriginatingTabClosed = 'OriginatingTabClosed',
}

View File

@@ -8,25 +8,12 @@ type BackgroundMessage<Msg extends ExtensionMethods, Payload = undefined> = Omit
'source'
>;
type FirefoxShareInMemoryKeyToBackground = BackgroundMessage<
InternalMethods.ShareInMemoryKeyToBackground,
{ secretKey: string; keyId: string }
>;
type FirefoxRequestInMemoryKeys = BackgroundMessage<InternalMethods.RequestInMemoryKeys>;
type FirefoxRemoveInMemoryKeys = BackgroundMessage<InternalMethods.RemoveInMemoryKeys>;
type OriginatingTabClosed = BackgroundMessage<
InternalMethods.OriginatingTabClosed,
{ tabId: number }
>;
export type BackgroundMessages =
| FirefoxShareInMemoryKeyToBackground
| FirefoxRequestInMemoryKeys
| FirefoxRemoveInMemoryKeys
| OriginatingTabClosed;
export type BackgroundMessages = OriginatingTabClosed;
export function sendMessage(message: BackgroundMessages) {
return chrome.runtime.sendMessage(message);

View File

@@ -1,11 +0,0 @@
type BrowserRuntime = 'chromium' | 'firefox';
function getBrowserRuntime(): BrowserRuntime {
return chrome.runtime.getURL('').startsWith('moz-extension://') ? 'firefox' : 'chromium';
}
type WhenBrowserRuntimeMap<T> = Record<BrowserRuntime, T>;
export function whenBrowserRuntime<T>(runtimeMap: WhenBrowserRuntimeMap<T>) {
return runtimeMap[getBrowserRuntime()];
}