From 196ba7aba9d55c488c044c18b7e8db153ed632a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Fri, 17 Jul 2026 01:07:22 +0200 Subject: [PATCH] bank: strip :443 from taler://withdraw URIs for wallet apps. libeufin includes default HTTPS port; demo/auto-account APIs, refresh scripts, and landing JS now normalize hosts without :443. ensure-taler-apps also starts merchant ui-unlock after reboot. --- configs/bank-landing/index.html | 6 +++-- scripts/taler-bank/demo-withdraw-api.py | 27 ++++++++++++++++++--- scripts/taler-bank/make-demo-withdraw-qr.sh | 15 +++++++----- scripts/taler-bank/refresh-demo-withdraw.sh | 2 ++ scripts/taler-shared/ensure-taler-apps.sh | 17 +++++++++++++ 5 files changed, 56 insertions(+), 11 deletions(-) diff --git a/configs/bank-landing/index.html b/configs/bank-landing/index.html index 5dfebb3..f172304 100644 --- a/configs/bank-landing/index.html +++ b/configs/bank-landing/index.html @@ -1597,8 +1597,10 @@ tw run-until-done && tw balance } function setDemoWithdraw(uri, amount) { - /* Keep host:port (…:443) — required for taler-integration withdraw */ - uri = String(uri || "").trim(); + /* Strip default :443 — libeufin adds it; wallets prefer host without port */ + uri = String(uri || "") + .trim() + .replace(/(taler:\/\/withdraw\/[^/:]+):443(?=\/|$)/g, "$1"); var open = document.getElementById("open-withdraw-demo"); var meta = document.getElementById("withdraw-demo-meta"); if (open) { diff --git a/scripts/taler-bank/demo-withdraw-api.py b/scripts/taler-bank/demo-withdraw-api.py index b0ff9bb..d8a21de 100755 --- a/scripts/taler-bank/demo-withdraw-api.py +++ b/scripts/taler-bank/demo-withdraw-api.py @@ -42,6 +42,27 @@ def public_webui_url() -> str: return f"{BANK_PUBLIC}/webui/" +def normalize_taler_withdraw_uri(uri: str) -> str: + """Strip default :443/:80 from taler://withdraw host (wallet base-URL fix). + + libeufin builds authority from https BASE_URL and includes port 443; Android / + iOS wallets then fail host parsing or TLS. Path and id stay unchanged. + """ + if not uri: + return uri + # taler://withdraw/bank.example:443/taler-integration/UUID + uri = re.sub( + r"(taler://withdraw/)([^/?#]+):443(?=/|$)", + r"\1\2", + uri, + ) + uri = re.sub( + r"(taler://withdraw/)([^/?#]+):80(?=/|$)", + r"\1\2", + uri, + ) + return uri + def load_pass() -> str: p = os.environ.get("BANK_PASS", "").strip() if p: @@ -104,9 +125,9 @@ def mint_withdraw() -> dict: raise RuntimeError(f"no taler_withdraw_uri: {wd}") if not wid: wid = uri.rstrip("/").split("/")[-1] - # Keep host:port from libeufin (e.g. bank.hacktivism.ch:443). Stripping :443 - # breaks taler-integration withdraw links / main landing QR on HTTPS banks. - uri = str(uri).strip() + # libeufin emits taler://withdraw/host:443/... from https BASE_URL; mobile + # wallets and many desktop builds reject/mis-parse default port :443. + uri = normalize_taler_withdraw_uri(str(uri).strip()) LANDING.mkdir(parents=True, exist_ok=True) (LANDING / "withdraw.uri").write_text(uri + "\n") (LANDING / "withdraw.amount").write_text(AMOUNT + "\n") diff --git a/scripts/taler-bank/make-demo-withdraw-qr.sh b/scripts/taler-bank/make-demo-withdraw-qr.sh index f7d96f0..935882e 100755 --- a/scripts/taler-bank/make-demo-withdraw-qr.sh +++ b/scripts/taler-bank/make-demo-withdraw-qr.sh @@ -50,13 +50,16 @@ curl -sS -m 15 \ "${BANK}/accounts/${USER}/withdrawals" >"$WORKDIR/wd.out" URI=$(python3 - "$WORKDIR/wd.out" <<'PY' -import json,sys -d=json.load(open(sys.argv[1])) -print(d.get("taler_withdraw_uri") or "") -if not d.get("taler_withdraw_uri"): - sys.stderr.write(open(sys.argv[1]).read()+"\n") +import json, re, sys +d = json.load(open(sys.argv[1])) +uri = d.get("taler_withdraw_uri") or "" +if not uri: + sys.stderr.write(open(sys.argv[1]).read() + "\n") sys.exit(1) -print(d.get("withdrawal_id",""), file=sys.stderr) +# strip default HTTPS port for wallet apps +uri = re.sub(r"(taler://withdraw/[^/:]+):443(?=/|$)", r"\1", uri) +print(uri) +print(d.get("withdrawal_id", ""), file=sys.stderr) PY ) diff --git a/scripts/taler-bank/refresh-demo-withdraw.sh b/scripts/taler-bank/refresh-demo-withdraw.sh index 7e23454..901c368 100755 --- a/scripts/taler-bank/refresh-demo-withdraw.sh +++ b/scripts/taler-bank/refresh-demo-withdraw.sh @@ -38,6 +38,8 @@ URI=$(printf '%s' "$WD" | sed -n 's/.*"taler_withdraw_uri"[[:space:]]*:[[:space: WID=$(printf '%s' "$WD" | sed -n 's/.*"withdrawal_id"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p') [ -n "$URI" ] || { echo "no URI from: $WD" >&2; exit 1; } [ -n "$WID" ] || WID=$(basename "$URI") +# libeufin emits host:443 — strip default HTTPS port for wallet apps +URI=$(printf '%s' "$URI" | sed -E 's|(taler://withdraw/[^/:]+):443(/)|\1\2|; s|(taler://withdraw/[^/:]+):443$|\1|') mkdir -p "$LANDING_DIR" printf '%s\n' "$URI" >"$LANDING_DIR/withdraw.uri" diff --git a/scripts/taler-shared/ensure-taler-apps.sh b/scripts/taler-shared/ensure-taler-apps.sh index ed59020..a569410 100644 --- a/scripts/taler-shared/ensure-taler-apps.sh +++ b/scripts/taler-shared/ensure-taler-apps.sh @@ -46,10 +46,26 @@ ctr_has_proc() { podman exec "$ctr" bash -lc "ps -eo args= | grep -F -- '$pattern' | grep -v grep" >/dev/null 2>&1 } +ensure_merchant_loopback_helper() { + # Optional helper (loopback helper) — loopback :19097 + if podman exec "$MER_CTR" bash -lc "ss -tln 2>/dev/null | grep -q ':19097'" 2>/dev/null; then + log "merchant: loopback :19097 already listening" + return 0 + fi + if ! podman exec "$MER_CTR" test -f /usr/local/bin/ui-unlock-api.py 2>/dev/null; then + log "merchant: WARN helper missing" + return 0 + fi + log "merchant: start loopback helper :19097…" + podman exec -u root -d "$MER_CTR" python3 /usr/local/bin/ui-unlock-api.py \ + || log "WARN: loopback helper start failed" +} + ensure_merchant() { wait_running "$MER_CTR" if ctr_has_proc "$MER_CTR" 'taler-merchant-httpd'; then log "merchant: httpd already up" + ensure_merchant_loopback_helper return 0 fi log "merchant: start base (postgres/nginx)…" @@ -58,6 +74,7 @@ ensure_merchant() { log "merchant: start_merchant.sh…" podman exec -u root "$MER_CTR" \ runuser -u taler-merchant-httpd -- /usr/local/bin/start_merchant.sh + ensure_merchant_loopback_helper log "merchant: done" }