summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-11-17 10:12:25 -0300
committerSebastian <sebasjm@gmail.com>2023-11-17 10:12:37 -0300
commitc797d551d9716924120d6ce6f270793c7bb5a4f9 (patch)
tree6627cf7f6c63b9d8ff798fd7bc7e6f5d8eef693f /packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts
parentcb2059d73e9b94d7b4179680017b962d12fcf790 (diff)
downloadwallet-core-c797d551d9716924120d6ce6f270793c7bb5a4f9.tar.gz
wallet-core-c797d551d9716924120d6ce6f270793c7bb5a4f9.tar.bz2
wallet-core-c797d551d9716924120d6ce6f270793c7bb5a4f9.zip
still finding places when the taler support is not handled, fixing firefox with manifest v2
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.ts228
1 files changed, 133 insertions, 95 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 69f508670..d1b1dc374 100644
--- a/packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts
+++ b/packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts
@@ -47,43 +47,7 @@ const rootElementIsHTML =
document.documentElement.nodeName &&
document.documentElement.nodeName.toLowerCase() === "html";
-/**
- * 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) {
- try {
- 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)
- }
- }
- });
- }
- });
- } catch (e) {
- //disconnected
- if (e instanceof TalerError) {
- logger.debug(e)
- }
- }
- }).observe(document, {
- childList: true,
- subtree: true,
- attributes: false,
- })
-}
function validateTalerUri(uri: string): boolean {
return (
@@ -118,6 +82,9 @@ const logger = {
/**
*/
function redirectToTalerActionHandler(element: HTMLMetaElement) {
+ const name = element.getAttribute("name")
+ if (!name) return;
+ if (name !== "taler-uri") return;
const uri = element.getAttribute("content");
if (!uri) return;
@@ -146,49 +113,14 @@ function injectTalerSupportScript(head: HTMLHeadElement) {
}
scriptTag.src = url.href;
- 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);
- }
- });
+ try {
+ head.insertBefore(scriptTag, head.children.length ? head.children[0] : null);
+ } catch (e) {
+ logger.info("inserting link handler failed!");
+ logger.error(e);
+ }
}
-/**
- * Create a bridge connection between the page and the extension.
- *
- * Useful for API calls and replies. Not yet supported.
- */
-function createBridgeWithExtension() {
- const port = chrome.runtime.connect();
-
- window.addEventListener(
- "message",
- (event) => {
- // logger.debug("message received", event.data);
- if (event.source !== window) {
- return;
- }
- if (event.origin !== window.origin) {
- return;
- }
-
- if (event.data.type && event.data.type === "FROM_PAGE") {
- logger.debug("Content script received: " + event.data.text);
- port.postMessage(event.data.text);
- }
- },
- false,
- );
- port.onDisconnect.addListener(function () {
- // clean up when content script gets disconnected
- })
-
-}
export interface ExtensionOperations {
isInjectionEnabled: {
@@ -248,27 +180,133 @@ async function sendMessageToBackground<Op extends keyof ExtensionOperations>(
timedout = true;
reject(TalerError.fromDetail(TalerErrorCode.GENERIC_TIMEOUT, {}))
}, 20 * 1000); //five seconds
- chrome.runtime.sendMessage(messageWithId, (backgroundResponse) => {
- if (timedout) {
- return false; //already rejected
- }
- clearTimeout(timerId);
- if (chrome.runtime.lastError) {
- reject(chrome.runtime.lastError.message);
- } else {
- resolve(backgroundResponse);
- }
- // return true to keep the channel open
- return true;
- });
+ try {
+ chrome.runtime.sendMessage(messageWithId, (backgroundResponse) => {
+ if (timedout) {
+ return false; //already rejected
+ }
+ clearTimeout(timerId);
+ if (chrome.runtime.lastError) {
+ reject(chrome.runtime.lastError.message);
+ } else {
+ resolve(backgroundResponse);
+ }
+ // return true to keep the channel open
+ return true;
+ });
+ } catch (e) {
+ console.log(e)
+ }
});
}
-function start() {
+function start(
+ onTalerMetaTagFound: (listener:(el: HTMLMetaElement)=>void) => void,
+ onHeadReady: (listener:(el: HTMLHeadElement)=>void) => void
+) {
+ // do not run everywhere, this is just expected to run on html
+ // sites
if (shouldNotInject) return;
- listenToHeaderMutation();
- createBridgeWithExtension();
- logger.debug("bridged created");
+
+ const isAutoOpenEnabled_promise = callBackground("isAutoOpenEnabled", undefined)
+ const isInjectionEnabled_promise = callBackground("isInjectionEnabled", undefined)
+
+ onTalerMetaTagFound(async (el)=> {
+ const enabled = await isAutoOpenEnabled_promise;
+ if (!enabled) return;
+ redirectToTalerActionHandler(el)
+ })
+
+ onHeadReady(async (el) => {
+ const enabled = await isInjectionEnabled_promise;
+ if (!enabled) return;
+ injectTalerSupportScript(el)
+ })
+
+}
+
+/**
+ * Tries to find taler meta tag ASAP and report
+ * @param notify
+ * @returns
+ */
+function onTalerMetaTag(notify: (el: HTMLMetaElement) => void) {
+ if (document.head) {
+ const element = document.head.querySelector("meta[name=taler-uri]")
+ if (!element) return;
+ if (!(element instanceof HTMLMetaElement)) return;
+ const name = element.getAttribute("name")
+ if (!name) return;
+ if (name !== "taler-uri") return;
+ const uri = element.getAttribute("content");
+ if (!uri) return;
+
+ notify(element)
+ return;
+ }
+ const obs = new MutationObserver(async function (mutations) {
+ try {
+ mutations.forEach((mut) => {
+ if (mut.type === "childList") {
+ mut.addedNodes.forEach((added) => {
+ if (added instanceof HTMLMetaElement) {
+ const name = added.getAttribute("name")
+ if (!name) return;
+ if (name !== "taler-uri") return;
+ const uri = added.getAttribute("content");
+ if (!uri) return;
+ notify(added)
+ obs.disconnect()
+ }
+ });
+ }
+ });
+ } catch (e) {
+ console.error(e)
+ }
+ })
+
+ obs.observe(document, {
+ childList: true,
+ subtree: true,
+ attributes: false,
+ })
+
+}
+
+/**
+ * Tries to find HEAD tag ASAP and report
+ * @param notify
+ * @returns
+ */
+function onHeaderReady(notify: (el: HTMLHeadElement) => void) {
+ if (document.head) {
+ notify(document.head)
+ return;
+ }
+ const obs = new MutationObserver(async function (mutations) {
+ try {
+ mutations.forEach((mut) => {
+ if (mut.type === "childList") {
+ mut.addedNodes.forEach((added) => {
+ if (added instanceof HTMLHeadElement) {
+
+ notify(added)
+ obs.disconnect()
+ }
+ });
+ }
+ });
+ } catch (e) {
+ console.error(e)
+ }
+ })
+
+ obs.observe(document, {
+ childList: true,
+ subtree: true,
+ attributes: false,
+ })
}
-start();
+start(onTalerMetaTag, onHeaderReady);