From 96df94f71c609c45d9ed6dd338e6212b16df7ef2 Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Tue, 25 Jun 2024 09:40:22 +0300 Subject: [PATCH 1/3] Close tab on declined grant --- src/background/services/openPayments.ts | 44 +++++++++++++++++-------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/background/services/openPayments.ts b/src/background/services/openPayments.ts index 6631cd46..60e26491 100644 --- a/src/background/services/openPayments.ts +++ b/src/background/services/openPayments.ts @@ -306,7 +306,7 @@ export class OpenPaymentsService { // Q: Should this be moved to continuation polling? // https://github.com/interledger/open-payments/issues/385 - const { interactRef, hash } = await this.confirmPayment( + const { interactRef, hash } = await this.getInteractionInfo( grant.interact.redirect ) @@ -424,31 +424,49 @@ export class OpenPaymentsService { if (calculatedHash !== hash) throw new Error('Invalid interaction hash') } - private async confirmPayment(url: string): Promise { + private async closeTab(currentTab: number, tabToClose: number) { + await this.browser.tabs.update(currentTab, { active: true }) + await this.browser.tabs.remove(tabToClose) + } + + private async getInteractionInfo(url: string): Promise { const currentTab = await getCurrentActiveTab(this.browser) + // eslint-disable-next-line @typescript-eslint/no-this-alias + const self = this return await new Promise((res) => { - if (url) { - this.browser.tabs.create({ url }).then((tab) => { - if (tab.id) { - this.browser.tabs.onUpdated.addListener((tabId, changeInfo) => { + this.browser.tabs.create({ url }).then((tab) => { + if (tab.id) { + this.browser.tabs.onUpdated.addListener( + async function getInteractionRefAndHash(tabId, changeInfo) { + if (tabId !== tab.id) return try { const tabUrl = new URL(changeInfo.url || '') const interactRef = tabUrl.searchParams.get('interact_ref') const hash = tabUrl.searchParams.get('hash') + const result = tabUrl.searchParams.get('result') + + if ( + (interactRef && hash) || + result === 'grant_rejected' || + result === 'grant_invalid' + ) { + await self.closeTab(currentTab.id!, tabId) + self.browser.tabs.onUpdated.removeListener( + getInteractionRefAndHash + ) + } - if (tabId === tab.id && interactRef && hash) { - this.browser.tabs.update(currentTab.id, { active: true }) - this.browser.tabs.remove(tab.id) + if (interactRef && hash) { res({ interactRef, hash }) } } catch (e) { /* do nothing */ } - }) - } - }) - } + } + ) + } + }) }) } From bb46ec5dce3655164db840bdeea37401d7c1b0df Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Tue, 25 Jun 2024 11:05:57 +0300 Subject: [PATCH 2/3] Remove named function --- src/background/services/openPayments.ts | 55 ++++++++++++------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/src/background/services/openPayments.ts b/src/background/services/openPayments.ts index 60e26491..c4e17be3 100644 --- a/src/background/services/openPayments.ts +++ b/src/background/services/openPayments.ts @@ -15,7 +15,7 @@ import * as ed from '@noble/ed25519' import { type Request } from 'http-message-signatures' import { signMessage } from 'http-message-signatures/lib/httpbis' import { createContentDigestHeader } from 'httpbis-digest-headers' -import { Browser } from 'webextension-polyfill' +import { Browser, Tabs } from 'webextension-polyfill' import { getCurrentActiveTab, getExchangeRates, @@ -431,40 +431,37 @@ export class OpenPaymentsService { private async getInteractionInfo(url: string): Promise { const currentTab = await getCurrentActiveTab(this.browser) - // eslint-disable-next-line @typescript-eslint/no-this-alias - const self = this return await new Promise((res) => { this.browser.tabs.create({ url }).then((tab) => { if (tab.id) { - this.browser.tabs.onUpdated.addListener( - async function getInteractionRefAndHash(tabId, changeInfo) { - if (tabId !== tab.id) return - try { - const tabUrl = new URL(changeInfo.url || '') - const interactRef = tabUrl.searchParams.get('interact_ref') - const hash = tabUrl.searchParams.get('hash') - const result = tabUrl.searchParams.get('result') - - if ( - (interactRef && hash) || - result === 'grant_rejected' || - result === 'grant_invalid' - ) { - await self.closeTab(currentTab.id!, tabId) - self.browser.tabs.onUpdated.removeListener( - getInteractionRefAndHash - ) - } - - if (interactRef && hash) { - res({ interactRef, hash }) - } - } catch (e) { - /* do nothing */ + const getInteractionInfo: Parameters< + Tabs.onUpdatedEvent['addListener'] + >[0] = async (tabId, changeInfo) => { + if (tabId !== tab.id) return + try { + const tabUrl = new URL(changeInfo.url || '') + const interactRef = tabUrl.searchParams.get('interact_ref') + const hash = tabUrl.searchParams.get('hash') + const result = tabUrl.searchParams.get('result') + + if ( + (interactRef && hash) || + result === 'grant_rejected' || + result === 'grant_invalid' + ) { + await this.closeTab(currentTab.id!, tabId) + this.browser.tabs.onUpdated.removeListener(getInteractionInfo) } + + if (interactRef && hash) { + res({ interactRef, hash }) + } + } catch (e) { + /* do nothing */ } - ) + } + this.browser.tabs.onUpdated.addListener(getInteractionInfo) } }) }) From d060cc280d0dea75e0457fba4cc7f0464a231dbc Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Tue, 25 Jun 2024 11:46:26 +0300 Subject: [PATCH 3/3] Early return if tab id is not defined --- src/background/services/openPayments.ts | 52 +++++++++++++------------ 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/background/services/openPayments.ts b/src/background/services/openPayments.ts index c4e17be3..197f4bda 100644 --- a/src/background/services/openPayments.ts +++ b/src/background/services/openPayments.ts @@ -91,6 +91,8 @@ interface CreateOutgoingPaymentParams { quoteId: string } +type TabUpdateCallback = Parameters[0] + export class OpenPaymentsService { client?: AuthenticatedClient @@ -434,35 +436,35 @@ export class OpenPaymentsService { return await new Promise((res) => { this.browser.tabs.create({ url }).then((tab) => { - if (tab.id) { - const getInteractionInfo: Parameters< - Tabs.onUpdatedEvent['addListener'] - >[0] = async (tabId, changeInfo) => { - if (tabId !== tab.id) return - try { - const tabUrl = new URL(changeInfo.url || '') - const interactRef = tabUrl.searchParams.get('interact_ref') - const hash = tabUrl.searchParams.get('hash') - const result = tabUrl.searchParams.get('result') - - if ( - (interactRef && hash) || - result === 'grant_rejected' || - result === 'grant_invalid' - ) { - await this.closeTab(currentTab.id!, tabId) - this.browser.tabs.onUpdated.removeListener(getInteractionInfo) - } + if (!tab.id) return + const getInteractionInfo: TabUpdateCallback = async ( + tabId, + changeInfo + ) => { + if (tabId !== tab.id) return + try { + const tabUrl = new URL(changeInfo.url || '') + const interactRef = tabUrl.searchParams.get('interact_ref') + const hash = tabUrl.searchParams.get('hash') + const result = tabUrl.searchParams.get('result') + + if ( + (interactRef && hash) || + result === 'grant_rejected' || + result === 'grant_invalid' + ) { + await this.closeTab(currentTab.id!, tabId) + this.browser.tabs.onUpdated.removeListener(getInteractionInfo) + } - if (interactRef && hash) { - res({ interactRef, hash }) - } - } catch (e) { - /* do nothing */ + if (interactRef && hash) { + res({ interactRef, hash }) } + } catch (e) { + /* do nothing */ } - this.browser.tabs.onUpdated.addListener(getInteractionInfo) } + this.browser.tabs.onUpdated.addListener(getInteractionInfo) }) }) }