diff options
author | Sebastian <sebasjm@gmail.com> | 2023-10-30 18:42:39 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-10-30 18:44:41 -0300 |
commit | f1967ab0baf825cdfa767d36bb7cce78521e4e4b (patch) | |
tree | 43650091b8542dfa750a69524efa3e5ff16b7201 /packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts | |
parent | fb4c172bb430936268bcebe34142d4206a0d422e (diff) | |
download | wallet-core-f1967ab0baf825cdfa767d36bb7cce78521e4e4b.tar.xz |
testing auto open feature
Diffstat (limited to 'packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts')
-rw-r--r-- | packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts | 120 |
1 files changed, 84 insertions, 36 deletions
diff --git a/packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts b/packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts index 8ea071fb6..10b1f521b 100644 --- a/packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts +++ b/packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts @@ -46,54 +46,86 @@ const suffixIsNotXMLorPDF = const rootElementIsHTML = document.documentElement.nodeName && document.documentElement.nodeName.toLowerCase() === "html"; -const pageAcceptsTalerSupport = document.head.querySelector( - "meta[name=taler-support]", -); + +/** + * Listen to any HTML Element and react to it. + * - <meta name="taler-suport" /> will inject taler-support-lib + * - <meta name="taler-uri" /> will redirect to call to action + */ +function listenToHeaderMutation() { + new MutationObserver(async function (mutations) { + const autoOpen = await callBackground("isAutoOpenEnabled", undefined) + mutations.forEach((mut) => { + if (mut.type === "childList") { + mut.addedNodes.forEach((added) => { + if (added instanceof HTMLHeadElement) { + injectTalerSupportScript(added) + } else if (added instanceof HTMLMetaElement) { + const name = added.getAttribute("name") + if (!name) return; + if (autoOpen && name === "taler-uri") { + redirectToTalerActionHandler(added) + } + } + }); + } + }); + }).observe(document, { + childList: true, + subtree: true, + attributes: false, + }) +} + +function validateTalerUri(uri: string): boolean { + return ( + !!uri && (uri.startsWith("taler://") || uri.startsWith("taler+http://")) + ); +} + +function convertURIToWebExtensionPath(uri: string) { + const url = new URL( + chrome.runtime.getURL(`static/wallet.html#/taler-uri/${encodeURIComponent(uri)}`), + ); + return url.href; +} + // safe check, if one of this is true then taler handler is not useful // or not expected const shouldNotInject = !documentDocTypeIsHTML || !suffixIsNotXMLorPDF || - // !pageAcceptsTalerSupport || FIXME: removing this before release for testing !rootElementIsHTML; + const logger = { - debug: (...msg: any[]) => {}, + debug: (...msg: any[]) => { }, info: (...msg: any[]) => console.log(`${new Date().toISOString()} TALER`, ...msg), error: (...msg: any[]) => console.error(`${new Date().toISOString()} TALER`, ...msg), }; -async function start() { - if (shouldNotInject) { - return; - } - const debugEnabled = - pageAcceptsTalerSupport?.getAttribute("debug") === "true"; - if (debugEnabled) { - logger.debug = logger.info; - } - createBridgeWithExtension(); - logger.debug("bridged created"); +// logger.debug = logger.info - const shouldInject = await callBackground("isInjectionEnabled", undefined); +/** + */ +function redirectToTalerActionHandler(element: HTMLMetaElement) { + const uri = element.getAttribute("content"); + if (!uri) return; - if (shouldInject) { - injectTalerSupportScript(debugEnabled); - logger.debug("injection completed"); - } else { - logger.debug("injection is not enabled"); + if (!validateTalerUri(uri)) { + logger.error(`taler:// URI is invalid: ${uri}`); + return; } + + location.href = convertURIToWebExtensionPath(uri) } -/** - * Create a <script /> element that load the support in the page context. - * The interaction support script will create the API to send message - * that will be received by this loader and be redirected to the extension - * using the bridge. - */ -function injectTalerSupportScript(debugEnabled: boolean) { - const container = document.head || document.documentElement; +function injectTalerSupportScript(head: HTMLHeadElement) { + const meta = head.querySelector("meta[name=taler-support]") + + const debugEnabled = meta?.getAttribute("debug") === "true"; + const scriptTag = document.createElement("script"); scriptTag.setAttribute("async", "false"); @@ -105,12 +137,17 @@ function injectTalerSupportScript(debugEnabled: boolean) { url.searchParams.set("debug", "true"); } scriptTag.src = url.href; - try { - container.insertBefore(scriptTag, container.children[0]); - } catch (e) { - logger.info("inserting link handler failed!"); - logger.error(e); - } + + callBackground("isInjectionEnabled", undefined).then(shouldInject => { + if (!shouldInject) return; + + try { + head.insertBefore(scriptTag, head.children.length ? head.children[0] : null); + } catch (e) { + logger.info("inserting link handler failed!"); + logger.error(e); + } + }); } /** @@ -146,6 +183,10 @@ export interface ExtensionOperations { request: void; response: boolean; }; + isAutoOpenEnabled: { + request: void; + response: boolean; + }; } export type MessageFromExtension<Op extends keyof ExtensionOperations> = { @@ -201,4 +242,11 @@ async function sendMessageToBackground<Op extends keyof ExtensionOperations>( }); } +function start() { + if (shouldNotInject) return; + listenToHeaderMutation(); + createBridgeWithExtension(); + logger.debug("bridged created"); +} + start(); |