diff --git a/configs/taler-ops-ng/README.md b/configs/taler-ops-ng/README.md new file mode 100644 index 0000000..dc1d6a9 --- /dev/null +++ b/configs/taler-ops-ng/README.md @@ -0,0 +1,121 @@ +# Taler Operations WWW — design previews (koopa) + +Experimental **static** previews for a redesign of [taler-ops.ch](https://taler-ops.ch/). +Content is inspired by **`taler-ops-www`** (`git.taler.net/taler-ops-www`). + +## Source branches (`taler-ops-www`) + +| Branch | Meaning | +|--------|---------| +| **`stable`** | **Stable website** (classic production-oriented tree) | +| **`master`** | Ongoing development | + +This preview stack **does not build** `taler-ops-www` (Jinja/Parcel). +If the upstream tree is old, incomplete, or fails to build — **we do not build it**. +- **ng1 / ng2**: hand-crafted static HTML in this repo +- **ng3**: optional **HTTP mirror** of live classic site (or a tiny fallback page) + +## Ports (9090+) + +| Host | Variant | Port | Container | +|------|---------|------|-----------| +| `tops.ng1.hacktivism.ch` | Taler DD 90 branding (Montserrat, `#0042B3`) | **9090** | `koopa-tops-ng1` | +| `tops.ng2.hacktivism.ch` | DD 90 + step/amount sliders | **9091** | `koopa-tops-ng2` | +| `tops.ng3.hacktivism.ch` | Classic / stable-era look | **9092** | `koopa-tops-ng3` | + +## FINMA + +ng1 and ng2 keep a **sticky, always-visible** FINMA disclaimer (not supervised by FINMA; escrow not deposit-insured; segregated account). +ng3 uses the classic site wording when mirrored, or the same disclaimer on the fallback page. + +## Deploy on koopa + +Copy this tree to the host, then run the script (rootless podman as `hernani`): + +```bash +# from your laptop (example) +scp -r configs/taler-ops-ng hernani@koopa:~/koopa-tops + +# on koopa +cd ~/koopa-tops +chmod +x bin/up.sh +./bin/up.sh # start :9090 :9091 :9092 +./bin/up.sh status +./bin/up.sh --refresh-classic # re-mirror live taler-ops.ch → ng3 (no build) +./bin/up.sh down +``` + +Smoke without Caddy: + +```bash +curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9090/ +curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9091/ +curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9092/ +``` + +## Caddy (host) + +Snippet: `deploy/Caddyfile.snippet` + +```caddy +# 9090 tops ng1 | 9091 tops ng2 | 9092 tops ng3 + +tops.ng1.hacktivism.ch { + header Alt-Svc "clear" + reverse_proxy 127.0.0.1:9090 { + header_up Host {host} + header_up X-Forwarded-For {remote_host} + header_up X-Forwarded-Proto {scheme} + } +} + +tops.ng2.hacktivism.ch { + header Alt-Svc "clear" + reverse_proxy 127.0.0.1:9091 { + header_up Host {host} + header_up X-Forwarded-For {remote_host} + header_up X-Forwarded-Proto {scheme} + } +} + +tops.ng3.hacktivism.ch { + header Alt-Svc "clear" + reverse_proxy 127.0.0.1:9092 { + header_up Host {host} + header_up X-Forwarded-For {remote_host} + header_up X-Forwarded-Proto {scheme} + } +} +``` + +Also add the three hostnames to the existing HTTP→HTTPS redirect site list, then: + +```bash +sudo caddy validate --config /etc/caddy/Caddyfile +sudo systemctl reload caddy +``` + +DNS: `tops.ng1`, `tops.ng2`, `tops.ng3` under `hacktivism.ch` → koopa (same as other public vhosts). + +## Layout + +``` +configs/taler-ops-ng/ + README.md ← this file + bin/up.sh ← run on koopa + deploy/compose.yml ← podman compose + deploy/Caddyfile.snippet + ng1/index.html ← design preview + ng1/CHANGES/index.html ← /CHANGES + ng2/… · ng3/… ← same; ng3 also mirror/fallback +``` + +## /CHANGES + +Each preview serves a short change log at **`/CHANGES/`** (ng1, ng2, ng3). + +## Design notes + +- **ng1**: GNU Taler branding per [DD 90](https://docs.taler.net/design-documents/090-branding.html) / [DD 66](https://docs.taler.net/design-documents/066-wallet-color-scheme.html) (Montserrat, primary `#0042B3`, official logo). +- **ng2**: same DD 90 tokens as ng1; step carousel + amount range slider + topic tabs. +- **ng3**: classic production look via mirror; no Parcel/Jinja build pipeline. diff --git a/configs/taler-ops-ng/bin/up.sh b/configs/taler-ops-ng/bin/up.sh new file mode 100755 index 0000000..dd0fc0e --- /dev/null +++ b/configs/taler-ops-ng/bin/up.sh @@ -0,0 +1,190 @@ +#!/usr/bin/env bash +# Install / refresh Taler Operations design previews on koopa. +# Ports: 9090 (ng1), 9091 (ng2), 9092 (ng3 classic). +# +# Run ON koopa as hernani (rootless podman): +# ~/koopa-tops/bin/up.sh +# ~/koopa-tops/bin/up.sh --refresh-classic # re-mirror taler-ops.ch into ng3 +# ~/koopa-tops/bin/up.sh --down +# +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +cd "$ROOT" + +COMPOSE=(podman compose -f deploy/compose.yml) +# older podman-compose fallback +if ! podman compose version >/dev/null 2>&1; then + if command -v podman-compose >/dev/null 2>&1; then + COMPOSE=(podman-compose -f deploy/compose.yml) + fi +fi + +log() { printf '[tops] %s\n' "$*"; } + +ensure_dirs() { + mkdir -p ng1 ng2 ng3 + if [ ! -f ng1/index.html ]; then + log "ERROR: ng1/index.html missing — copy configs/taler-ops-ng from koopa-admin-log first" + exit 1 + fi + if [ ! -f ng2/index.html ]; then + log "ERROR: ng2/index.html missing" + exit 1 + fi + # nginx container user must read bind mounts + chmod -R a+rX ng1 ng2 ng3 2>/dev/null || true +} + +# Classic / stable-era site: HTTP mirror of production only. +# Do NOT build taler-ops-www (Jinja/Parcel) — if upstream is old/broken, we skip builds. +# Branch note: git.taler.net/taler-ops-www **stable** = stable website source; master = dev. +mirror_classic() { + log "mirroring classic site → ng3/ (from https://taler-ops.ch/) — no source build" + log "taler-ops-www: branch 'stable' = stable site; we never run make/parcel here" + local tmp + tmp=$(mktemp -d) + # shellcheck disable=SC2064 + trap "rm -rf '$tmp'" RETURN + + if command -v wget >/dev/null 2>&1; then + wget -q -r -np -nH --cut-dirs=0 -E -p -k \ + --directory-prefix="$tmp" \ + --domains=taler-ops.ch \ + --timeout=20 --tries=2 \ + https://taler-ops.ch/en/index.html \ + https://taler-ops.ch/de/index.html \ + https://taler-ops.ch/fr/index.html \ + 2>/dev/null || true + # flatten: prefer mirrored en as index if present + if [ -d "$tmp" ]; then + rm -rf ng3/* + # wget often creates host dir + if [ -d "$tmp/taler-ops.ch" ]; then + cp -a "$tmp/taler-ops.ch/." ng3/ 2>/dev/null || true + else + cp -a "$tmp/." ng3/ 2>/dev/null || true + fi + fi + fi + + # Fallback / ensure something serves if mirror thin + if [ ! -f ng3/index.html ] && [ ! -f ng3/en/index.html ]; then + log "mirror incomplete — writing ng3 fallback index (points at live + FINMA text)" + cat >ng3/index.html <<'HTML' + + + + + + Taler Operations · classic (ng3) + + + + +

Classic site (ng3)

+

+ This preview is meant to serve the stable / classic Taler Operations website. + Source: taler-ops-www branch stable; production: + https://taler-ops.ch/ +

+

Mirror failed on this host — open production for the full classic UI, or re-run + ./bin/up.sh --refresh-classic with network + wget.

+

→ Open live classic EN

+ + +HTML + elif [ -f ng3/en/index.html ] && [ ! -f ng3/index.html ]; then + # convenience root redirect + cat >ng3/index.html <<'HTML' + + + +Redirect +

English

+HTML + fi + # keep /CHANGES even after mirror wipe + if [ -f deploy/CHANGES-ng3.html ]; then + mkdir -p ng3/CHANGES + cp -f deploy/CHANGES-ng3.html ng3/CHANGES/index.html + elif [ -f ng3/CHANGES/index.html ]; then + : + else + mkdir -p ng3/CHANGES + # minimal fallback if repo copy missing + printf '%s\n' 'CHANGES ng3

CHANGES ng3

Classic mirror. FINMA disclaimer on main site. Branch stable = stable website. Port 9092.

Home

' >ng3/CHANGES/index.html + fi + chmod -R a+rX ng3 2>/dev/null || true + log "ng3 ready ($(du -sh ng3 | awk '{print $1}'))" +} + +cmd_up() { + ensure_dirs + if [ ! -f ng3/index.html ] && [ ! -f ng3/en/index.html ]; then + mirror_classic + fi + log "pulling nginx image…" + podman pull docker.io/library/nginx:1.27-alpine + log "starting containers on :9090 :9091 :9092 …" + "${COMPOSE[@]}" up -d --force-recreate + sleep 1 + cmd_status + cat <<'EOF' + +=== Caddy (on host) === +Add vhosts from deploy/Caddyfile.snippet then: + sudo caddy validate --config /etc/caddy/Caddyfile + sudo systemctl reload caddy # or however you reload + +DNS: tops.ng1/ng2/ng3.hacktivism.ch → this host + +Local smoke (no Caddy): + curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9090/ + curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9091/ + curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9092/ +EOF +} + +cmd_down() { + log "stopping…" + "${COMPOSE[@]}" down || true +} + +cmd_status() { + podman ps --filter name=koopa-tops --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' || true + for p in 9090 9091 9092; do + code=$(curl -sS -m 3 -o /dev/null -w '%{http_code}' "http://127.0.0.1:${p}/" 2>/dev/null || echo fail) + log "port $p → HTTP $code" + done +} + +cmd_refresh_classic() { + mirror_classic + "${COMPOSE[@]}" up -d --force-recreate tops-ng3 + cmd_status +} + +case "${1:-up}" in + up|start) cmd_up ;; + down|stop) cmd_down ;; + status|ps) cmd_status ;; + --refresh-classic|refresh-classic) cmd_refresh_classic ;; + -h|--help) + sed -n '2,12p' "$0" | sed 's/^# \?//' + ;; + *) + log "unknown arg: $1 (try up|down|status|--refresh-classic)" + exit 2 + ;; +esac diff --git a/configs/taler-ops-ng/deploy/CHANGES-ng3.html b/configs/taler-ops-ng/deploy/CHANGES-ng3.html new file mode 100644 index 0000000..b1c4dbf --- /dev/null +++ b/configs/taler-ops-ng/deploy/CHANGES-ng3.html @@ -0,0 +1,39 @@ + + + + + + Notiz · tops.ng3 + + + + +

← Start · tops.ng3 · Port 9092

+

Diese Seite

+ +

Inhalt

+ + +

Auslieferung (aktuell)

+ + + diff --git a/configs/taler-ops-ng/deploy/Caddyfile.snippet b/configs/taler-ops-ng/deploy/Caddyfile.snippet new file mode 100644 index 0000000..c3fc268 --- /dev/null +++ b/configs/taler-ops-ng/deploy/Caddyfile.snippet @@ -0,0 +1,36 @@ +# Paste into host Caddyfile (/etc/caddy/Caddyfile) and reload Caddy. +# Ports: 9090 ng1 | 9091 ng2 | 9092 ng3 +# DNS: tops.ng{1,2,3}.hacktivism.ch → koopa (same as other *.hacktivism.ch) + +# --- comment at top of Caddyfile port map --- +# 9090 tops ng1 | 9091 tops ng2 | 9092 tops ng3 + +tops.ng1.hacktivism.ch { + header Alt-Svc "clear" + reverse_proxy 127.0.0.1:9090 { + header_up Host {host} + header_up X-Forwarded-For {remote_host} + header_up X-Forwarded-Proto {scheme} + } +} + +tops.ng2.hacktivism.ch { + header Alt-Svc "clear" + reverse_proxy 127.0.0.1:9091 { + header_up Host {host} + header_up X-Forwarded-For {remote_host} + header_up X-Forwarded-Proto {scheme} + } +} + +tops.ng3.hacktivism.ch { + header Alt-Svc "clear" + reverse_proxy 127.0.0.1:9092 { + header_up Host {host} + header_up X-Forwarded-For {remote_host} + header_up X-Forwarded-Proto {scheme} + } +} + +# Also add these hosts to the existing HTTP→HTTPS redirect block, e.g.: +# http://..., http://tops.ng1.hacktivism.ch, http://tops.ng2.hacktivism.ch, http://tops.ng3.hacktivism.ch { diff --git a/configs/taler-ops-ng/deploy/compose.yml b/configs/taler-ops-ng/deploy/compose.yml new file mode 100644 index 0000000..a1b37f6 --- /dev/null +++ b/configs/taler-ops-ng/deploy/compose.yml @@ -0,0 +1,63 @@ +# Taler Operations design previews — host ports 9090+ +# tops.ng1 → 9090 | tops.ng2 → 9091 | tops.ng3 → 9092 +# +# Usage (on koopa): +# cd ~/koopa-tops && ./bin/up.sh + +services: + tops-ng1: + image: docker.io/library/nginx:1.27-alpine + container_name: koopa-tops-ng1 + restart: unless-stopped + ports: + - "9090:80" + volumes: + - ../ng1:/usr/share/nginx/html:ro + labels: + org.hacktivism.service: tops-ng1 + org.hacktivism.host_port: "9090" + org.hacktivism.site: tops.ng1.hacktivism.ch + org.hacktivism.managed_by: koopa-admin + healthcheck: + test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1/"] + interval: 30s + timeout: 5s + retries: 3 + + tops-ng2: + image: docker.io/library/nginx:1.27-alpine + container_name: koopa-tops-ng2 + restart: unless-stopped + ports: + - "9091:80" + volumes: + - ../ng2:/usr/share/nginx/html:ro + labels: + org.hacktivism.service: tops-ng2 + org.hacktivism.host_port: "9091" + org.hacktivism.site: tops.ng2.hacktivism.ch + org.hacktivism.managed_by: koopa-admin + healthcheck: + test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1/"] + interval: 30s + timeout: 5s + retries: 3 + + tops-ng3: + image: docker.io/library/nginx:1.27-alpine + container_name: koopa-tops-ng3 + restart: unless-stopped + ports: + - "9092:80" + volumes: + - ../ng3:/usr/share/nginx/html:ro + labels: + org.hacktivism.service: tops-ng3 + org.hacktivism.host_port: "9092" + org.hacktivism.site: tops.ng3.hacktivism.ch + org.hacktivism.managed_by: koopa-admin + healthcheck: + test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1/"] + interval: 30s + timeout: 5s + retries: 3 diff --git a/configs/taler-ops-ng/ng1/CHANGES/index.html b/configs/taler-ops-ng/ng1/CHANGES/index.html new file mode 100644 index 0000000..13a73a6 --- /dev/null +++ b/configs/taler-ops-ng/ng1/CHANGES/index.html @@ -0,0 +1,42 @@ + + + + + + Notiz · tops.ng1 + + + + +

← Start · tops.ng1 · Port 9090

+

Diese Seite

+ +

Inhalt & Branding

+ + +

Auslieferung (aktuell)

+ + + diff --git a/configs/taler-ops-ng/ng1/assets/montserrat-latin.woff2 b/configs/taler-ops-ng/ng1/assets/montserrat-latin.woff2 new file mode 100644 index 0000000..5379c12 Binary files /dev/null and b/configs/taler-ops-ng/ng1/assets/montserrat-latin.woff2 differ diff --git a/configs/taler-ops-ng/ng1/assets/taler-full-white-text.svg b/configs/taler-ops-ng/ng1/assets/taler-full-white-text.svg new file mode 100644 index 0000000..2f1f1e4 --- /dev/null +++ b/configs/taler-ops-ng/ng1/assets/taler-full-white-text.svg @@ -0,0 +1,88 @@ + + + + + + + image/svg+xml + + + + + + + + \ No newline at end of file diff --git a/configs/taler-ops-ng/ng1/assets/taler-full.svg b/configs/taler-ops-ng/ng1/assets/taler-full.svg new file mode 100644 index 0000000..fc0d37f --- /dev/null +++ b/configs/taler-ops-ng/ng1/assets/taler-full.svg @@ -0,0 +1,88 @@ + + + + + + + image/svg+xml + + + + + + + + \ No newline at end of file diff --git a/configs/taler-ops-ng/ng1/index.html b/configs/taler-ops-ng/ng1/index.html new file mode 100644 index 0000000..3c8e392 --- /dev/null +++ b/configs/taler-ops-ng/ng1/index.html @@ -0,0 +1,264 @@ + + + + + + Taler Operations AG · digital cash for Switzerland + + + + + + + + + + +
+ + GNU Taler + + +
+ +
+
+ Switzerland · eCHF · privacy +

Taler — a digital payment system as private as cash

+

+ The Taler Wallet is your digital purse. Withdraw electronic cash from your Swiss bank account, + then pay with QR code or NFC — standard bank transfer times apply. +

+ +
+
+ + + +
+
+

Prerequisites

+
+
    +
  • Swiss bank account with an IBAN starting with CH
  • +
  • Mobile phone number with +41 to receive P2P payments
  • +
+
+
+ +
+

3 steps to get started

+
+
+ 1 +
+

Install the wallet

+

Android, iOS, or browser extension from the official wallet portal.

+ +
+
+
+ 2 +
+

Withdraw digital cash

+

Tap “Withdraw CHF”, enter an amount, confirm the bank transfer. Processing follows Swiss bank transfer times.

+
+
+
+ 3 +
+

Pay

+

Scan a merchant QR code or use NFC — confirm once. Only spend what you withdrew.

+
+
+
+
+ +
+

Merchants & map

+

+ Pay in person where eCHF with Taler is accepted. + Full merchant map and onboarding: + taler-ops.ch map · + become a merchant. +

+
+ +
+

FAQ

+
+ Is this supervised by FINMA? +

No. Taler Operations AG is not supervised by FINMA. Escrow is in a segregated bank account and is not covered by deposit insurance. See the sticky notice above.

+
+
+ How is this like a regular wallet? +

You can only spend money you previously withdrew. No credit; the exchange does not learn what you bought.

+
+
+ Where is production? +

Live service: taler-ops.ch.

+
+
+
+ + + + diff --git a/configs/taler-ops-ng/ng2/CHANGES/index.html b/configs/taler-ops-ng/ng2/CHANGES/index.html new file mode 100644 index 0000000..a2db094 --- /dev/null +++ b/configs/taler-ops-ng/ng2/CHANGES/index.html @@ -0,0 +1,40 @@ + + + + + + Notiz · tops.ng2 + + + + +

← Start · tops.ng2 · Port 9091

+

Diese Seite

+ +

Inhalt & UI

+ + +

Auslieferung (aktuell)

+ + + diff --git a/configs/taler-ops-ng/ng2/assets/montserrat-latin.woff2 b/configs/taler-ops-ng/ng2/assets/montserrat-latin.woff2 new file mode 100644 index 0000000..5379c12 Binary files /dev/null and b/configs/taler-ops-ng/ng2/assets/montserrat-latin.woff2 differ diff --git a/configs/taler-ops-ng/ng2/assets/taler-full.svg b/configs/taler-ops-ng/ng2/assets/taler-full.svg new file mode 100644 index 0000000..fc0d37f --- /dev/null +++ b/configs/taler-ops-ng/ng2/assets/taler-full.svg @@ -0,0 +1,88 @@ + + + + + + + image/svg+xml + + + + + + + + \ No newline at end of file diff --git a/configs/taler-ops-ng/ng2/index.html b/configs/taler-ops-ng/ng2/index.html new file mode 100644 index 0000000..5086b80 --- /dev/null +++ b/configs/taler-ops-ng/ng2/index.html @@ -0,0 +1,485 @@ + + + + + + Taler Operations AG · digital cash for Switzerland + + + + + + + + + + +
+ + GNU Taler + + +
+ +
+
+

Digital cash as private as cash

+

+ Withdraw eCHF into the Taler wallet from your Swiss bank account, then pay with QR or NFC. +

+ Get the wallet + Slide through steps +
+
+ +
+
+

3 steps

+
+
+ How it works + 1 / 3 +
+
+
+
+ 1 +

Install the wallet

+

Android, iOS, or browser extension from the official wallet portal.

+ +
+
+ 2 +

Withdraw digital cash

+

Tap “Withdraw CHF”, enter an amount, confirm the bank transfer. Processing follows Swiss bank transfer times.

+
+
+ 3 +

Pay

+

Scan a merchant QR code or use NFC — confirm once. Only spend what you withdrew.

+
+
+
+
+ +
+ +
+
+
+ +
+

Withdraw amount

+
+
+ Example only — not a live withdrawal +
50 CHF
+
+ + +
+ Slide to pick a sample amount. In the real wallet you confirm a bank transfer for that sum; processing follows normal Swiss transfer times. +
+
+ +
+
    +
  • Swiss bank account with an IBAN starting with CH
  • +
  • Mobile phone number with +41 to receive P2P payments
  • +
+
+
+ +
+

More

+
+ + + +
+
+

For users

+

Withdraw eCHF, keep private purchases, pay in person where Taler is accepted.

+ User guide +
+ + +
+ +
+

FAQ

+
+ Is this supervised by FINMA? +

No. Taler Operations AG is not supervised by FINMA. Escrow is in a segregated bank account and is not covered by deposit insurance. See the sticky notice above.

+
+
+ How is this like a regular wallet? +

You can only spend money you previously withdrew. No credit; the exchange does not learn what you bought.

+
+
+ Where is production? +

Live service: taler-ops.ch.

+
+
+
+ + + + + + diff --git a/configs/taler-ops-ng/ng3/CHANGES/index.html b/configs/taler-ops-ng/ng3/CHANGES/index.html new file mode 100644 index 0000000..b1c4dbf --- /dev/null +++ b/configs/taler-ops-ng/ng3/CHANGES/index.html @@ -0,0 +1,39 @@ + + + + + + Notiz · tops.ng3 + + + + +

← Start · tops.ng3 · Port 9092

+

Diese Seite

+ +

Inhalt

+ + +

Auslieferung (aktuell)

+ + + diff --git a/configs/taler-ops-ng/ng3/README.md b/configs/taler-ops-ng/ng3/README.md new file mode 100644 index 0000000..c1bbbe2 --- /dev/null +++ b/configs/taler-ops-ng/ng3/README.md @@ -0,0 +1,10 @@ +# ng3 — classic / stable-era site + +- **Intent:** serve the **old/classic** Taler Operations website. +- **Source of truth:** `taler-ops-www` branch **`stable`** (stable website). + `master` is development — not used for this preview. +- **On koopa:** `bin/up.sh` fills this directory via **wget mirror** of + `https://taler-ops.ch/` (no Jinja/Parcel build). +- If the mirror fails, `up.sh` writes a small fallback page with FINMA text. + +Do not commit large mirror dumps into git unless intentional.