summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-10-30 18:42:39 -0300
committerSebastian <sebasjm@gmail.com>2023-10-30 18:44:41 -0300
commitf1967ab0baf825cdfa767d36bb7cce78521e4e4b (patch)
tree43650091b8542dfa750a69524efa3e5ff16b7201 /packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts
parentfb4c172bb430936268bcebe34142d4206a0d422e (diff)
downloadwallet-core-f1967ab0baf825cdfa767d36bb7cce78521e4e4b.tar.gz
wallet-core-f1967ab0baf825cdfa767d36bb7cce78521e4e4b.tar.bz2
wallet-core-f1967ab0baf825cdfa767d36bb7cce78521e4e4b.zip
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.ts120
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();