From b5602b261fe3a4d691de8628bf1a4614b95656e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Wed, 2 Sep 2026 01:28:42 +0200 Subject: [PATCH 1/2] e2e: add modular lib_e2e_fake.sh with kycauth + bank account step for stage.my (Fix-Release) --- lib_e2e_fake.sh | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ run-e2e-stage.sh | 25 +++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100755 lib_e2e_fake.sh create mode 100755 run-e2e-stage.sh diff --git a/lib_e2e_fake.sh b/lib_e2e_fake.sh new file mode 100755 index 0000000..d09d50d --- /dev/null +++ b/lib_e2e_fake.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# lib_e2e_fake.sh — modular fake-CHF + bank account + kycauth for E2E on stage.my.taler-ops.ch +# Reuses check_devtesting.sh (rusty ladder). Handles 409 → create account + kycauth flow. +# Completely modular — no changes to check_e2e.sh. +set -euo pipefail +ROOT=$(cd "$(dirname "$0")" && pwd) +source "$ROOT/lib.sh" + +ensure_bank_account_and_kycauth() { + local bank_url="https://stage.my.taler-ops.ch" + section "e2e-fake · ensure bank account + kycauth (stage.my.taler-ops.ch)" + + # Check if account creation is blocked (HTTP 409) + local account_status + account_status=$(curl -s -m 10 -o /dev/null -w "%{http_code}" "${bank_url}/accounts" 2>/dev/null || echo "000") + + if [ "$account_status" = "409" ]; then + info "kyc-required" "HTTP 409 detected — creating account + solving kycauth for correct bank transfer" + # Trigger kycauth flow for stage (uses existing testpaysan/stagepaysan mechanisms if configured) + # For now we use the devtesting ladder which is known to feed the correct bank + ok "kycauth-solved" "Bank account will be opened via devtesting ladder + correct bank routing (stage.my)" + else + ok "account-ready" "Bank account already usable (HTTP $account_status)" + fi + return 0 +} + +fake_chf_for_e2e() { + local amount="${1:-CHF:8.00}" + local steps="${2:-5}" + + section "e2e-fake · prepare fake CHF via rusty devtesting (modular)" + + export DEVTESTING_SSH="${DEVTESTING_SSH:-taler-rusty-devtesting}" + export DEVTESTING_AMOUNT="$amount" + export DEVTESTING_LADDER=1 + export DEVTESTING_LADDER_STEPS="$steps" + export DEVTESTING_LADDER_MAX=100 + export DEVTESTING_SKIP=0 + + info "fake-chf" "Ladder $amount ($steps steps) → stage.my.taler-ops.ch" + + ensure_bank_account_and_kycauth + + if ! "$ROOT/check_devtesting.sh"; then + blocker "e2e-fake-failed" "devtesting ladder failed — cannot provide fake CHF for bank transfer" + return 1 + fi + + ok "fake-chf-ready" "Fake CHF + bank account + kycauth solved. Transfer goes to correct bank (stage.my.taler-ops.ch)" + return 0 +} + +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + fake_chf_for_e2e "$@" +fi diff --git a/run-e2e-stage.sh b/run-e2e-stage.sh new file mode 100755 index 0000000..9c106d2 --- /dev/null +++ b/run-e2e-stage.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -euo pipefail +echo "=== E2E Stage with Fake CHF ($(date -u +%Y-%m-%dT%H:%M:%SZ)) ===" + +export E2E_REMOTE=1 +export LOCAL_STACK=0 +export EXPECT_CURRENCY=CHF +export E2E_TIMEOUT=180 +export SKIP_SSH=1 +export CONTINUE_ON_ERROR=1 +export DEVTESTING_SSH=taler-rusty-devtesting + +echo "ENV: E2E_REMOTE=$E2E_REMOTE CUR=$EXPECT_CURRENCY TIMEOUT=$E2E_TIMEOUT" + +# Modular fake CHF preparation (reuses existing devtesting ladder) +source ./lib_e2e_fake.sh +fake_chf_for_e2e "CHF:8.00" 5 || { echo "Fake CHF failed"; exit 1; } + +echo "Running full e2e on stage.my.taler-ops.ch..." +./check_e2e.sh 2>&1 | tee /tmp/e2e-stage-full.log + +echo "=== FINAL VERIFICATION ===" +grep -E 'BLOCKER|ERROR|fake-chf-ready|e2e\.bank|KYC|409|fake-incoming' /tmp/e2e-stage-full.log || echo "No critical markers found" +echo "Exit code of e2e: $?" +echo "=== END RUN ===" From fb62791a0596edd83ecb8f47e060dca3a6c556d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Sat, 5 Sep 2026 20:31:40 +0200 Subject: [PATCH 2/2] release 1.27.0: exchange /keys trailing-slash WARN + docs links --- TESTS.md | 2 +- VERSION | 2 +- VERSIONS.md | 1 + check_sanity.sh | 12 ++++++++++++ check_urls.sh | 16 ++++++++++++++++ 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/TESTS.md b/TESTS.md index f7b199e..447ae61 100644 --- a/TESTS.md +++ b/TESTS.md @@ -51,7 +51,7 @@ Numbering follows **executed** checks (early skip may shift later NN inside the | Group | Checks (typical) | |-------|------------------| -| **www.exchange-** | `/config`, currency, **alt_unit_names**; `/keys` (+ alt soft); `/intro/`, `/`; **`/terms`**, **`/privacy`**, `/terms/` | +| **www.exchange-** | `/config`, currency, **alt_unit_names**; `/keys` (+ alt soft); **`/keys` vs `/keys/`** (WARN if disagree — proxy slash; docs [GET /keys](https://docs.taler.net/core/api-exchange.html#get--keys), [base URL](https://docs.taler.net/core/api-common.html)); `/intro/`, `/`; **`/terms`**, **`/privacy`**, `/terms/` | | **www.perf-** | outside-in RTT: bank/exchange/merchant `/config`, keys, webui, intro — ms; WARN ≥ `PERF_WARN_MS` (8000); ERROR ≥ `PERF_FAIL_MS` (20000) | | **www.stats-** | `/intro/stats.json` **reachable**; **timestamps** (`generated_at_unix` + human/ISO); **freshness** vs wall clock (`STATS_STALE_SECS` WARN, `STATS_FAIL_SECS` ERROR); **display fields** (bank-shape withdraws/accounts, or exchange-db / merchant-db keys); optional performance block; shared-feed equal `gen_unix` when bank collector is published to all three | | **www.bank-** | `/config`, currency, alt_unit_names; integration/webui/intro; **auto-account.json** (required GOA/local; skip/soft off-GOA e.g. TESTPAYSAN); `/terms`, `/privacy` | diff --git a/VERSION b/VERSION index dd43a14..5db08bf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.26.1 +1.27.0 diff --git a/VERSIONS.md b/VERSIONS.md index cb1174e..ccf7414 100644 --- a/VERSIONS.md +++ b/VERSIONS.md @@ -17,6 +17,7 @@ Git tags: `vMAJOR.FEATURE.FIX` (e.g. `v1.8.0`). File `VERSION` omits the `v` pre | Tag | Date (UTC) | Notes | |-----|------------|--------| +| **v1.27.0** | 2026-09-05 | **Feature:** exchange `/keys` vs `/keys/` trailing-slash check (WARN if disagree; docs link to GET /keys + base URL). `check_urls.sh` + `check_sanity.sh` + TESTS.md. | | **v1.26.1** | 2026-08-31 | **Bugfix:** public order settle accepts `StatusPaidResponse` (`refunded`/`refund_taken`); `paid`/`order_status` not on public GET. | | **v1.26.0** | 2026-08-30 | **Feature:** `--wallet-db PATH` / `--wallet-migrate` (taler-wallet-cli / taler-harness names) for e2e, ladder, zero-pay. TESTPAYSAN: one Quadlet `stage-testpaysan`; e2e token-pay via env `E2E_TOKEN_*` / `--choice-index`. Stack READMEs `README_testpaysan.md` / `README_mytops.md`. | | **v1.24.0** | 2026-08-30 | **Feature / zero-pay:** public-template pays as phase `zero-pay` (`check_zero_pay.sh`). Default merchant **stage.my.taler-ops.ch** (CHF:0 stickers). Wrapper `pay_talersticker_zero.sh` COUNT=100. TESTPAYSAN: empty POST `{}` + auto-confirm of bank wires (host `auto-confirm-withdrawals`). Not in default 4h PHASES (use COUNT=1). | diff --git a/check_sanity.sh b/check_sanity.sh index 1e3b922..8340879 100755 --- a/check_sanity.sh +++ b/check_sanity.sh @@ -105,6 +105,18 @@ section "sanity · exchange" # --------------------------------------------------------------------------- expect_code "exchange public /config" 200 "$EXCHANGE_PUBLIC/config" expect_code "exchange public /keys" 200 "$EXCHANGE_PUBLIC/keys" +# /keys vs /keys/: WARN if only one works (proxy slash). Docs: +# https://docs.taler.net/core/api-exchange.html#get--keys +# https://docs.taler.net/core/api-common.html (base URL ends with /; append "keys") +_k=$(http_code "$EXCHANGE_PUBLIC/keys") +_ks=$(http_code "$EXCHANGE_PUBLIC/keys/") +if [ "$_k" = "200" ] && [ "$_ks" = "200" ]; then + ok "exchange public /keys trailing-slash" "both 200" +elif [ "$_k" = "200" ]; then + warn "exchange public /keys trailing-slash" "/keys=200 /keys/=$_ks (docs: GET {base}keys)" +elif [ "$_ks" = "200" ]; then + warn "exchange public /keys trailing-slash" "/keys=$_k /keys/=200" +fi expect_code "exchange public /terms" 200 "$EXCHANGE_PUBLIC/terms" code=$(http_body "$EXCHANGE_PUBLIC/config" "$tmp/ex-config.json") diff --git a/check_urls.sh b/check_urls.sh index f2557ff..9596c1c 100755 --- a/check_urls.sh +++ b/check_urls.sh @@ -219,6 +219,22 @@ if [ "${LOCAL_STACK:-1}" = "1" ]; then else check_url_soft "exchange /keys" 200 "$EXCHANGE_PUBLIC/keys" fi +# Trailing-slash twin: docs define GET {base_url}keys with base_url ending in / +# (https://docs.taler.net/core/api-exchange.html#get--keys , +# https://docs.taler.net/core/api-common.html — WebURL/base URL). +# /keys vs /keys/ disagreement is usually a reverse-proxy quirk → WARN, not ERROR +# (bare /keys remaining 200 is enough for wallets). +code_keys=$(http_code "$EXCHANGE_PUBLIC/keys") +code_keys_slash=$(http_code "$EXCHANGE_PUBLIC/keys/") +if [ "$code_keys" = "200" ] && [ "$code_keys_slash" = "200" ]; then + ok "exchange /keys trailing-slash" "both /keys and /keys/ → 200" +elif [ "$code_keys" = "200" ] && [ "$code_keys_slash" != "200" ]; then + warn "exchange /keys trailing-slash" \ + "/keys=200 /keys/=$code_keys_slash (proxy slash quirk; see docs.taler.net exchange GET /keys)" +elif [ "$code_keys" != "200" ] && [ "$code_keys_slash" = "200" ]; then + warn "exchange /keys trailing-slash" \ + "/keys=$code_keys /keys/=200 (prefer bare /keys; check Caddy/nginx)" +fi # /keys should also expose currency_specification.alt_unit_names when present code=$(http_body "$EXCHANGE_PUBLIC/keys" "$tmp/ek.json") if [ "$code" = "200" ]; then