From 67b78da1a70a07159570b65e0f9b130cec90ae70 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 27 Oct 2023 12:24:52 -0300 Subject: response header WIP --- .../taler-wallet-webextension/src/platform/api.ts | 2 +- .../src/platform/chrome.ts | 166 +++++++++++++-------- 2 files changed, 102 insertions(+), 66 deletions(-) (limited to 'packages/taler-wallet-webextension/src/platform') diff --git a/packages/taler-wallet-webextension/src/platform/api.ts b/packages/taler-wallet-webextension/src/platform/api.ts index 56d668a97..820711ea9 100644 --- a/packages/taler-wallet-webextension/src/platform/api.ts +++ b/packages/taler-wallet-webextension/src/platform/api.ts @@ -211,7 +211,7 @@ export interface BackgroundPlatformAPI { * Backend API */ registerTalerHeaderListener( - onHeader: (tabId: number, url: string) => void, + // onHeader: (tabId: number, url: string) => void, ): void; containsTalerHeaderListener(): boolean; diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts b/packages/taler-wallet-webextension/src/platform/chrome.ts index 3151bd6ab..fa9ad0522 100644 --- a/packages/taler-wallet-webextension/src/platform/chrome.ts +++ b/packages/taler-wallet-webextension/src/platform/chrome.ts @@ -290,7 +290,7 @@ async function sendMessageToBackground< let timedout = false; const timerId = setTimeout(() => { timedout = true; - reject(TalerError.fromDetail(TalerErrorCode.GENERIC_TIMEOUT, {}) ); + reject(TalerError.fromDetail(TalerErrorCode.GENERIC_TIMEOUT, {})); }, 20 * 1000); chrome.runtime.sendMessage(messageWithId, (backgroundResponse) => { if (timedout) { @@ -451,26 +451,26 @@ function setAlertedIcon(): void { interface OffscreenCanvasRenderingContext2D extends CanvasState, - CanvasTransform, - CanvasCompositing, - CanvasImageSmoothing, - CanvasFillStrokeStyles, - CanvasShadowStyles, - CanvasFilters, - CanvasRect, - CanvasDrawPath, - CanvasUserInterface, - CanvasText, - CanvasDrawImage, - CanvasImageData, - CanvasPathDrawingStyles, - CanvasTextDrawingStyles, - CanvasPath { + CanvasTransform, + CanvasCompositing, + CanvasImageSmoothing, + CanvasFillStrokeStyles, + CanvasShadowStyles, + CanvasFilters, + CanvasRect, + CanvasDrawPath, + CanvasUserInterface, + CanvasText, + CanvasDrawImage, + CanvasImageData, + CanvasPathDrawingStyles, + CanvasTextDrawingStyles, + CanvasPath { readonly canvas: OffscreenCanvas; } declare const OffscreenCanvasRenderingContext2D: { prototype: OffscreenCanvasRenderingContext2D; - new (): OffscreenCanvasRenderingContext2D; + new(): OffscreenCanvasRenderingContext2D; }; interface OffscreenCanvas extends EventTarget { @@ -483,7 +483,7 @@ interface OffscreenCanvas extends EventTarget { } declare const OffscreenCanvas: { prototype: OffscreenCanvas; - new (width: number, height: number): OffscreenCanvas; + new(width: number, height: number): OffscreenCanvas; }; function createCanvas(size: number): OffscreenCanvas { @@ -723,51 +723,69 @@ function containsTalerHeaderListener(): boolean { currentHeaderListener !== undefined || currentTabListener !== undefined ); } -function registerTalerHeaderListener( - callback: (tabId: number, url: string) => void, -): void { - logger.info("setting up header listener"); - function headerListener( - details: chrome.webRequest.WebResponseHeadersDetails, - ): void { - if (chrome.runtime.lastError) { - logger.error(JSON.stringify(chrome.runtime.lastError)); - return; - } - if ( - details.statusCode === 402 || - details.statusCode === 202 || - details.statusCode === 200 - ) { - const values = (details.responseHeaders || []) - .filter((h) => h.name.toLowerCase() === "taler") - .map((h) => h.value) - .filter((value): value is string => !!value); - if (values.length > 0) { - logger.info( - `Found a Taler URI in a response header for the request ${details.url} from tab ${details.tabId}`, - ); - callback(details.tabId, values[0]); - } +function headerListener( + details: chrome.webRequest.WebResponseHeadersDetails, +): void { + if (chrome.runtime.lastError) { + logger.error(JSON.stringify(chrome.runtime.lastError)); + return; + } + console.log("HEADER", details.statusCode, details.url, details.responseHeaders) + if ( + details.statusCode === 402 || + details.statusCode === 202 || + details.statusCode === 200 + ) { + const values = (details.responseHeaders || []) + .filter((h) => h.name.toLowerCase() === "taler") + .map((h) => h.value) + .filter((value): value is string => !!value); + if (values.length > 0) { + logger.info( + `Found a Taler URI in a response header for the request ${details.url} from tab ${details.tabId}`, + ); + redirectTabToWalletPage(details.tabId, values[0]); } + } + return; +} +function parseTalerUriAndRedirect(tabId: number, maybeTalerUri: string): void { + const talerUri = maybeTalerUri.startsWith("ext+") + ? maybeTalerUri.substring(4) + : maybeTalerUri; + const uri = parseTalerUri(talerUri); + if (!uri) { + logger.warn( + `Response with HTTP 402 the Taler header but could not classify ${talerUri}`, + ); return; } + return redirectTabToWalletPage( + tabId, + `/taler-uri/${encodeURIComponent(talerUri)}`, + ); +} - async function tabListener( - tabId: number, - info: chrome.tabs.TabChangeInfo, - ): Promise { - if (tabId < 0) return; - const tabLocationHasBeenUpdated = info.status === "complete"; - const tabTitleHasBeenUpdated = info.title !== undefined; - if (tabLocationHasBeenUpdated || tabTitleHasBeenUpdated) { - const uri = await findTalerUriInTab(tabId); - if (!uri) return; - logger.info(`Found a Taler URI in the tab ${tabId}`); - callback(tabId, uri); - } +async function tabListener( + tabId: number, + info: chrome.tabs.TabChangeInfo, +): Promise { + if (tabId < 0) return; + const tabLocationHasBeenUpdated = info.status === "complete"; + const tabTitleHasBeenUpdated = info.title !== undefined; + if (tabLocationHasBeenUpdated || tabTitleHasBeenUpdated) { + const uri = await findTalerUriInTab(tabId); + if (!uri) return; + logger.info(`Found a Taler URI in the tab ${tabId}`); + parseTalerUriAndRedirect(tabId, uri); } +} + +function registerTalerHeaderListener( + // callback: (tabId: number, url: string) => void, +): void { + logger.info("setting up header listener"); const prevHeaderListener = currentHeaderListener; const prevTabListener = currentTabListener; @@ -780,24 +798,40 @@ function registerTalerHeaderListener( prevHeaderListener && chrome?.webRequest?.onHeadersReceived?.hasListener(prevHeaderListener) ) { + console.log("removming on header listener") chrome.webRequest.onHeadersReceived.removeListener(prevHeaderListener); - } + chrome.webRequest.onCompleted.removeListener(prevHeaderListener); + chrome.webRequest.onResponseStarted.removeListener(prevHeaderListener); + chrome.webRequest.onErrorOccurred.removeListener(prevHeaderListener); + } if ( prevTabListener && chrome?.tabs?.onUpdated?.hasListener(prevTabListener) ) { + console.log("removming on tab listener") chrome.tabs.onUpdated.removeListener(prevTabListener); } //if the result was positive, add the headerListener if (result) { - const headersEvent: - | chrome.webRequest.WebResponseHeadersEvent - | undefined = chrome?.webRequest?.onHeadersReceived; - if (headersEvent) { - headersEvent.addListener(headerListener, { urls: [""] }, [ - "responseHeaders", - ]); + console.log("headers on, disabled:", chrome?.webRequest?.onHeadersReceived === undefined) + if (chrome?.webRequest) { + chrome.webRequest.onHeadersReceived.addListener(headerListener, + { urls: [""] }, + ["responseHeaders", "extraHeaders"] + ); + chrome.webRequest.onCompleted.addListener(headerListener, + { urls: [""] }, + ["responseHeaders", "extraHeaders"] + ); + chrome.webRequest.onResponseStarted.addListener(headerListener, + { urls: [""] }, + ["responseHeaders", "extraHeaders"] + ); + chrome.webRequest.onErrorOccurred.addListener(headerListener, + { urls: [""] }, + ["extraHeaders"] + ); currentHeaderListener = headerListener; } @@ -807,6 +841,8 @@ function registerTalerHeaderListener( tabsEvent.addListener(tabListener); currentTabListener = tabListener; } + } else { + console.log("headers off") } //notify the browser about this change, this operation is expensive -- cgit v1.2.3