diff --git a/src/app/utils/permission.ts b/src/app/utils/permission.ts index c40dd5a..36004ee 100644 --- a/src/app/utils/permission.ts +++ b/src/app/utils/permission.ts @@ -1,7 +1,7 @@ import { getWalletData } from '../../background/wallet'; -import { METHOD_EXTRA_PERMISSIONS, PUBLIC_METHODS } from '../../constants'; +import { METHOD_EXTRA_PERMISSIONS, PERMISSION_PUBLIC_METHODS } from '../../constants'; import { PermissionType, RequestType, Sender, SendResponse } from '../../types'; -import { normalizeOrigin } from './utils'; +import { normalizeOrigin, raceTimeout } from './utils'; export async function getPermissions(origin: string, address: string): Promise { const stored = await chrome.storage.local.get('permissions'); @@ -21,7 +21,7 @@ export async function permissionMiddleware( ): Promise { const isFromExtensionFrontend = sender.url && sender.url.includes(chrome.runtime.getURL('/')); - if (PUBLIC_METHODS.includes(request.method) || isFromExtensionFrontend) return true; + if (PERMISSION_PUBLIC_METHODS.includes(request.method) || isFromExtensionFrontend) return true; if (!sender.origin && !sender.url) { sendResponse({ error: 'Unknown origin' }); @@ -30,8 +30,23 @@ export async function permissionMiddleware( const origin = normalizeOrigin(sender.origin || new URL(sender.url!).origin); - const wallet = await getWalletData(); - const { address } = wallet; + let address; + + try { + const wallet = await raceTimeout(getWalletData()); + + if (wallet?.address) { + address = wallet.address; + } + } catch { + sendResponse({ error: 'Wallet is offline!' }); + return false; + } + + if (!address) { + sendResponse({ error: 'Wallet is offline!' }); + return false; + } const perms = await getPermissions(origin, address); diff --git a/src/app/utils/preprocessRequest.ts b/src/app/utils/preprocessRequest.ts new file mode 100644 index 0000000..08f5a55 --- /dev/null +++ b/src/app/utils/preprocessRequest.ts @@ -0,0 +1,22 @@ +import { getUserData } from '../../background/background'; +import { RequestType, Sender, SendResponse } from '../../types'; +import { permissionMiddleware } from './permission'; + +async function preprocessRequest( + request: RequestType, + sender: Sender, + sendResponse: SendResponse, +): Promise { + const userData = await getUserData(); + if (!userData.password) { + sendResponse({ error: 'Wallet is locked!' }); + return false; + } + + const allowed = await permissionMiddleware(request, sender, sendResponse); + if (!allowed) return false; + + return true; +} + +export default preprocessRequest; diff --git a/src/app/utils/utils.ts b/src/app/utils/utils.ts index b9692ae..d5dab0e 100644 --- a/src/app/utils/utils.ts +++ b/src/app/utils/utils.ts @@ -91,3 +91,10 @@ export function normalizeOrigin(origin: string) { return origin; } } + +export function raceTimeout(promise: Promise, ms = 2500): Promise { + return Promise.race([ + promise, + new Promise((_, reject) => setTimeout(() => reject(new Error('TIMEOUT')), ms)), + ]); +} diff --git a/src/background/background.ts b/src/background/background.ts index 2a80419..ffa0e85 100644 --- a/src/background/background.ts +++ b/src/background/background.ts @@ -1,5 +1,5 @@ import JSONbig from 'json-bigint'; -import { SELF_ONLY_REQUESTS, ZANO_ASSET_ID } from '../constants'; +import { SELF_ONLY_REQUESTS, SYSTEM_PUBLIC_METHODS, ZANO_ASSET_ID } from '../constants'; import { AccessRequestType, BurnAssetDataType, @@ -31,7 +31,8 @@ import { getAliasByAddress, } from './wallet'; import { normalizeOrigin, truncateToDecimals } from '../app/utils/utils'; -import { getPermissions, hasPermission, permissionMiddleware } from '../app/utils/permission'; +import { getPermissions, hasPermission } from '../app/utils/permission'; +import preprocessRequest from '../app/utils/preprocessRequest'; const POPUP_HEIGHT = 630; const POPUP_WIDTH = 370; @@ -213,7 +214,7 @@ async function setUserData(state: UserData): Promise { }); } -async function getUserData(): Promise { +export async function getUserData(): Promise { return new Promise((resolve) => { chrome.storage.local.get('userData', (result) => { resolve(result.userData || defaultUserData); @@ -274,9 +275,10 @@ const accessReqs: AccessRequestType[] = []; const accessReqFinalizers: Record void> = {}; async function processRequest(request: RequestType, sender: Sender, sendResponse: SendResponse) { - const allowed = await permissionMiddleware(request, sender, sendResponse); // check permission access - - if (!allowed) return; + if (!SYSTEM_PUBLIC_METHODS.includes(request.method)) { + const ok = await preprocessRequest(request, sender, sendResponse); + if (!ok) return; + } const isFromExtensionFrontend = sender.url && sender.url.includes(chrome.runtime.getURL('/')); diff --git a/src/constants/index.ts b/src/constants/index.ts index b80944f..8a99acd 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -39,4 +39,6 @@ export const METHOD_EXTRA_PERMISSIONS: Record = { GET_WALLET_BALANCE: ['balance'], }; -export const PUBLIC_METHODS = ['REQUEST_ACCESS']; +export const PERMISSION_PUBLIC_METHODS = ['REQUEST_ACCESS']; + +export const SYSTEM_PUBLIC_METHODS = ['PING_WALLET', 'SET_PASSWORD', 'GET_PASSWORD'];