docs/ops: merchant portal instance ids must be lowercase (avoid 401)

Document that mixed-case instance ids yield odd HTTP 401 in webui/API.
Lowercase MERCHANT_INSTANCE / shop paths defensively in monitoring and landings.
This commit is contained in:
Hernâni Marques 2026-07-17 22:36:54 +02:00
parent 57cf9aa2a1
commit ba48f334ea
No known key found for this signature in database
9 changed files with 44 additions and 8 deletions

View file

@ -8,3 +8,5 @@
2. Start vor Merchant-Apps → 502
3. Pasta AAAA/timeout → pin `172.17.0.1`
Live-Stack war gesund (302/402); Ursache/Fix nicht wiederholen.
- **Merchant portal:** instance ids **lowercase only** — capitals → odd **401**;
documented in taler-hacktivism + stagepaysan config READMEs; monitoring lowercases `MERCHANT_INSTANCE`.

View file

@ -10,7 +10,7 @@
(function () {
var MERCHANT_HOST = "taler.hacktivism.ch";
/* goa-shop: dedicated instance with fixed-order product templates */
var INSTANCE = "goa-shop";
var INSTANCE = String("goa-shop").toLowerCase();
var SHOP_PAYTO =
"payto://x-taler-bank/bank.hacktivism.ch/goa-shop?receiver-name=GOA%20Shop";
var SHOP_PAYTO_HTTPS = "https://bank.hacktivism.ch/webui/";

View file

@ -9,8 +9,9 @@
*/
(function () {
var MERCHANT_HOST = "taler.hacktivism.ch";
/* goa-shop: dedicated instance with fixed-order product templates */
var INSTANCE = "goa-shop";
/* goa-shop: dedicated instance with fixed-order product templates.
* Instance id must stay lowercase (portal/API: capitals odd 401s). */
var INSTANCE = String("goa-shop").toLowerCase();
var SHOP_PAYTO =
"payto://x-taler-bank/bank.hacktivism.ch/goa-shop?receiver-name=GOA%20Shop";
var SHOP_PAYTO_HTTPS = "https://bank.hacktivism.ch/webui/";

View file

@ -56,6 +56,23 @@ After conf/hosts changes: `taler-merchant-exchangekeyupdate -t` and `taler-merch
| 9010 | nginx TLS in container (podman) |
| unix sock | `taler-merchant-httpd` |
## Merchant portal (SPA `/webui/`) — instance IDs **lowercase only**
The merchant **webui** (and private API paths under `/instances/{id}/…`) must use
**only lowercase** instance ids (`a-z`, digits, hyphens).
| Do | Do not |
|----|--------|
| `goa-shop`, `goa-demo-cp4zqk`, `fermes-des-collines` | `Goa-Shop`, `GOA-DEMO`, mixed case |
**Why:** uppercase (or mixed-case) ids produce **odd HTTP 401** failures on
login / private API even when the password/token is correct. Auth looks like
“wrong secret” but the real issue is path / instance string case.
Create instances, login fields, `Authorization` targets, and `taler://pay…`
paths with the **exact lowercase** id. Display names may use capitals;
**ids must not**.
## Demo instance (2026-07-09)
Self-provisioned shop **`goa-demo-cp4zqk`**, bank account same username, payto linked, seed **GOA:5000**.

View file

@ -15,6 +15,10 @@ Created **2026-07-09** via self-provisioning (`POST /instances`, no SMS TAN).
Login: SPA → instance id + password (or bearer `secret-token:$PASSWORD`).
**Instance id must be all-lowercase** (`goa-demo-cp4zqk`). Typing capitals in
the portal login field (or calling `/instances/Goa-Demo-…/private/…`) yields
**strange 401s** even with the right password — use exact lowercase only.
## Bank account (linked)
| Field | Value |

View file

@ -30,6 +30,13 @@ Automatic import needs:
SMS backends are symlinks into `/var/taler-src/...` (not copied).
## Portal / instance IDs: **lowercase only**
Merchant SPA (`/webui/`) and `/instances/{id}/…` require **lowercase** instance
ids. Uppercase or mixed case → **weird HTTP 401** (looks like bad password).
Display names may be mixed case; **ids must be lowercase** (`goa-shop`, not
`Goa-Shop`). See `configs/taler-hacktivism/README.md`.
## Usage
```bash

View file

@ -16,7 +16,8 @@
# - restarts taler-merchant-wirewatch (once, after facade is set)
set -euo pipefail
INST="${MERCHANT_INSTANCE:-goa-demo-cp4zqk}"
# Instance id must be lowercase (portal/API: capitals → odd 401s).
INST=$(printf '%s' "${MERCHANT_INSTANCE:-goa-demo-cp4zqk}" | tr '[:upper:]' '[:lower:]')
BANK_USER="${BANK_USER:-$INST}"
MERCHANT_PW_FILE="${MERCHANT_PW_FILE:-/root/merchant-${INST}-password.txt}"
BANK_PW_FILE="${BANK_PW_FILE:-/root/bank-${BANK_USER}-password.txt}"

View file

@ -52,8 +52,8 @@ case "$STACK" in
PKG="${PKG:-net.taler.wallet.fdroid.debug}"
BANK="${BANK:-https://bank.hacktivism.ch}"
MERCHANT="${MERCHANT:-https://taler.hacktivism.ch}"
INSTANCE="${INSTANCE:-goa-shop}"
DONATE_INSTANCE="${DONATE_INSTANCE:-goa-demo-cp4zqk}"
INSTANCE=$(printf '%s' "${INSTANCE:-goa-shop}" | tr '[:upper:]' '[:lower:]')
DONATE_INSTANCE=$(printf '%s' "${DONATE_INSTANCE:-goa-demo-cp4zqk}" | tr '[:upper:]' '[:lower:]')
DONATE_TEMPLATE="${DONATE_TEMPLATE:-goa-free}"
DEFAULT_AMOUNTS=("GOA:10" "GOA:20")
DEFAULT_PAYS=("product:orbit-sticker" "product:nebula-coffee" "product:voidwave-playlist" "donate:GOA:12")
@ -63,8 +63,8 @@ case "$STACK" in
PKG="${PKG:-net.taler.wallet.fdroid.debug}"
BANK="${BANK:-https://stage.bank.lefrancpaysan.ch}"
MERCHANT="${MERCHANT:-https://stage.monnaie.lefrancpaysan.ch}"
INSTANCE="${INSTANCE:-fermes-des-collines}"
DONATE_INSTANCE="${DONATE_INSTANCE:-fermes-des-collines}"
INSTANCE=$(printf '%s' "${INSTANCE:-fermes-des-collines}" | tr '[:upper:]' '[:lower:]')
DONATE_INSTANCE=$(printf '%s' "${DONATE_INSTANCE:-fermes-des-collines}" | tr '[:upper:]' '[:lower:]')
DONATE_TEMPLATE="${DONATE_TEMPLATE:-don-panier-libre}"
DEFAULT_AMOUNTS=("TESTPAYSAN:10" "TESTPAYSAN:20")
DEFAULT_PAYS=("product:panier-legumes" "product:fromage-chevre" "product:oeufs-6")

View file

@ -14,6 +14,9 @@
# When LAN Host "koopa" is unreachable, try WAN DNAT (see ~/.ssh/config Host koopa-external).
: "${KOOPA_SSH_FALLBACKS:=koopa-external}"
: "${MERCHANT_INSTANCE:=goa-demo-cp4zqk}"
# Merchant portal /private API: instance ids must be lowercase or you get odd 401s.
# (Display names may use capitals; path segment /instances/{id}/ must not.)
MERCHANT_INSTANCE=$(printf '%s' "${MERCHANT_INSTANCE}" | tr '[:upper:]' '[:lower:]')
: "${WITHDRAW_AMT:=GOA:20}" # single-shot fallback; e2e ladder uses ATM notes
: "${PAY_AMT:=GOA:0.01}"
: "${CREDIT_AMT:=GOA:4700}" # covers ATM ladder 20+50+100+200+4200 (paivana)
@ -201,6 +204,7 @@ apply_taler_domain() {
MERCHANT_INSTANCE=fermes-des-collines
;;
esac
MERCHANT_INSTANCE=$(printf '%s' "${MERCHANT_INSTANCE}" | tr '[:upper:]' '[:lower:]')
WITHDRAW_AMT="${WITHDRAW_AMT:-TESTPAYSAN:50}"
PAY_AMT="${PAY_AMT:-TESTPAYSAN:5}"
# Cover oeufs(5)+fromage(8.5)+jus(6)+shop pick(~512) + fees