diff --git a/src/background/bgPopupHandler.ts b/src/background/bgPopupHandler.ts index 2f2b20524..cbf343191 100644 --- a/src/background/bgPopupHandler.ts +++ b/src/background/bgPopupHandler.ts @@ -1,9 +1,11 @@ import { v4 as uuid } from 'uuid'; import type { Dictionary, + IAppData, IPopupProps, PopupType, } from '@/types'; +import { UNKNOWN_SOURCE, UNKNOWN_APP_DETAILS } from '@/constants/common'; interface IPopupConfigNoActions { id: string; @@ -38,8 +40,16 @@ export const openPopup = async ( popupProps: Partial = {}, ) => { const id = uuid(); - const { href, protocol, host } = (typeof aepp === 'object') ? getAeppUrl(aepp) : new URL(aepp); - const { name = host } = (typeof aepp === 'object') ? aepp : {} as any; + + let app: IAppData; + + if (typeof aepp === 'object') { + app = getAeppUrl(aepp); + } else if (aepp === UNKNOWN_SOURCE) { + app = UNKNOWN_APP_DETAILS; + } else { + app = new URL(aepp); + } const tabs = await browser.tabs.query({ active: true }); @@ -47,14 +57,14 @@ export const openPopup = async ( const tabUrl = new URL(tabURL as string); if ( tabUrl.searchParams.get('type') === POPUP_TYPE_CONNECT - && decodeURIComponent(tabUrl.searchParams.get('url') || '') === href + && decodeURIComponent(tabUrl.searchParams.get('url') || '') === app.href ) { browser.tabs.remove(tabId as number); } }); const extUrl = browser.runtime.getURL('./index.html'); - const popupUrl = `${extUrl}?id=${id}&type=${popupType}&url=${encodeURIComponent(href)}`; + const popupUrl = `${extUrl}?id=${id}&type=${popupType}&url=${encodeURIComponent(app.href!)}`; const isMacOsExtension = IS_EXTENSION && browser.runtime.getPlatformInfo().then(({ os }) => os === 'mac'); const popupWindow = await browser.windows.create({ @@ -73,10 +83,10 @@ export const openPopup = async ( props: { ...popupProps, app: { - url: href, - name, - protocol, - host, + url: app.href, + name: app.name || app.host, + protocol: app.protocol, + host: app.host, }, }, }; diff --git a/src/composables/deepLinkApi.ts b/src/composables/deepLinkApi.ts index a426f9d5c..565dc8ed0 100644 --- a/src/composables/deepLinkApi.ts +++ b/src/composables/deepLinkApi.ts @@ -7,12 +7,15 @@ import { checkIfSuperheroCallbackUrl } from '@/utils'; import { IS_IOS, IS_MOBILE_APP, MODAL_TRANSFER_SEND } from '@/constants'; import { useModals } from '@/composables/modals'; -export function useDeepLinkApi() { - const router = useIonRouter(); +let isDeepLinkUsed = false; + +export function useDeepLinkApi(doNotInitializeRouter?: boolean) { + // `useIonRouter` breaks if it is not run in `IonPage` context + const router = doNotInitializeRouter ? null : useIonRouter(); const route = useRoute(); const callbackOrigin = ref( - route.query['x-success'] + route?.query['x-success'] ? (new URL(decodeURIComponent(route.query['x-success'] as string))) : null, ); @@ -37,14 +40,14 @@ export function useDeepLinkApi() { ) { const callbackUrlTemplate = route.query[isSuccess ? 'x-success' : 'x-cancel']; if (!callbackUrlTemplate) { - router.replace({ name: ROUTE_ACCOUNT }); + router?.replace({ name: ROUTE_ACCOUNT }); return; } const callbackUrl = Object.entries(templateParams).reduce( (url, [key, value]) => url.replace(new RegExp(`{${key}}`, 'g'), encodeURIComponent(value)), decodeURIComponent(String(route.query[isSuccess ? 'x-success' : 'x-cancel'])), ) as string; - router.replace({ name: ROUTE_ACCOUNT }); + router?.replace({ name: ROUTE_ACCOUNT }); if (IS_MOBILE_APP && !IS_IOS) { window.open(callbackUrl, '_system'); } else { @@ -52,9 +55,15 @@ export function useDeepLinkApi() { } } + function setIsDeepLinkUsed(value: boolean) { + isDeepLinkUsed = value; + } + return { checkIfOpenTransferSendModal, callbackOrigin, openCallbackOrGoHome, + setIsDeepLinkUsed, + isDeepLinkUsed, }; } diff --git a/src/composables/permissions.ts b/src/composables/permissions.ts index db581051e..76641cb9c 100644 --- a/src/composables/permissions.ts +++ b/src/composables/permissions.ts @@ -23,6 +23,7 @@ import { POPUP_TYPE_SIGN, STORAGE_KEYS, PROTOCOLS, + UNKNOWN_SOURCE, } from '@/constants'; import { getCleanModalOptions } from '@/utils'; import { aettosToAe, isTxOfASupportedType } from '@/protocols/aeternity/helpers'; @@ -197,8 +198,8 @@ export function usePermissions() { popup = POPUP_TYPE_RAW_SIGN; } await ( - (IS_OFFSCREEN_TAB && app?.url) - ? openPopup(popup, app.url, props) + (IS_OFFSCREEN_TAB) + ? openPopup(popup, app?.url || UNKNOWN_SOURCE, props) : openModal(modal, props) ); return true; diff --git a/src/constants/common.ts b/src/constants/common.ts index 964ceaa56..127163846 100644 --- a/src/constants/common.ts +++ b/src/constants/common.ts @@ -1,4 +1,4 @@ -import type { ICurrency, IPermission } from '@/types'; +import type { ICurrency, IAppData, IPermission } from '@/types'; import { IS_MOBILE_APP } from './environment'; export const APP_NAME = 'Superhero Wallet'; @@ -375,6 +375,16 @@ export const POPUP_TYPES = [ export const POPUP_CONNECT_ADDRESS_PERMISSION = 'address'; export const POPUP_CONNECT_TRANSACTIONS_PERMISSION = 'transactions'; +export const UNKNOWN_SOURCE = 'Unknown source'; +export const UNKNOWN_URL = 'Unknown url'; +export const UNKNOWN_APP_DETAILS: IAppData = { + url: UNKNOWN_URL, + href: UNKNOWN_URL, + protocol: '', + host: '', + name: UNKNOWN_SOURCE, +}; + export const POPUP_ACTIONS = { getProps: 'getProps', resolve: 'resolve', diff --git a/src/icons/warning-outline.svg b/src/icons/warning-outline.svg new file mode 100644 index 000000000..11982e71f --- /dev/null +++ b/src/icons/warning-outline.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/popup/components/DetailsItem.vue b/src/popup/components/DetailsItem.vue index f32935ae9..d9046d764 100644 --- a/src/popup/components/DetailsItem.vue +++ b/src/popup/components/DetailsItem.vue @@ -4,6 +4,7 @@ :class="{ expandable, expanded, + warning, }" > diff --git a/src/popup/components/Modals/ConfirmRawSign.vue b/src/popup/components/Modals/ConfirmRawSign.vue index 08de427fe..4940e10be 100644 --- a/src/popup/components/Modals/ConfirmRawSign.vue +++ b/src/popup/components/Modals/ConfirmRawSign.vue @@ -6,9 +6,19 @@ data-cy="popup-aex2" > + +
popupProps.value?.txBase64?.toString() || ''); + const isUnknownDapp = computed(() => ( + !popupProps.value?.app || popupProps.value.app.name === UNKNOWN_SOURCE + )); async function confirm() { if (RUNNING_IN_POPUP && activeAccount?.type === 'airgap') { @@ -124,6 +138,7 @@ export default defineComponent({ cancel, activeAccount, dataAsString, + isUnknownDapp, sender, }; }, diff --git a/src/popup/components/Modals/ConfirmTransactionSign.vue b/src/popup/components/Modals/ConfirmTransactionSign.vue index 5eca10075..7fd480755 100644 --- a/src/popup/components/Modals/ConfirmTransactionSign.vue +++ b/src/popup/components/Modals/ConfirmTransactionSign.vue @@ -13,7 +13,13 @@