commit 3280fbf5eefa2145f81a3971d8a958ccbbe33acb
parent 04a6c997c2961437f1fe24d6c45b240b362f76f3
Author: Vlada Svirsh <svirv1@bfh.ch>
Date: Tue, 16 Sep 2025 16:05:49 +0200
fixed #10356
Diffstat:
2 files changed, 121 insertions(+), 0 deletions(-)
diff --git a/design-documents/069-exchange-base-url-completion.rst b/design-documents/069-exchange-base-url-completion.rst
@@ -0,0 +1,120 @@
+DD 69: Exchange Base URL Completion
+###################################
+
+Summary
+=======
+
+Define the request, which turns user-provided input (like ``exchange.example.com`` or just ``example.com``) into a canonical,
+validated **HTTPS** exchange base URL. Validation requires that ``GET <base>/keys`` returns a valid
+`ExchangeKeysResponse <https://docs.taler.net/core/api-exchange.html#get--keys>`__ object.
+
+Motivation
+==========
+
+Users may provide incomplete or ambiguous input when configuring an exchange. For example, they may type just
+``example.com`` instead of the full ``https://exchange.example.com/``.
+The system must normalize, complete, and validate such inputs to ensure that only valid exchanges are accepted.
+This improves robustness and user experience while preventing misconfiguration.
+
+Requirements
+============
+
+* Accepts a single string from the user (host or URL).
+* Supports inputs like ``exchange.example.com``, ``example.com``,
+ or ``https://exchange.example.com/``.
+* Always enforces HTTPS.
+* Base URL must end with a single ``/`` and omit ports.
+* Must validate by requesting ``GET <base>/keys`` and checking for a valid
+ `ExchangeKeysResponse <https://docs.taler.net/core/api-exchange.html#get--keys>`__ object.
+* Must support a local list of trusted exchanges for resolution of ambiguous
+ inputs or typos (70% Levenshtein similarity).
+
+Proposed Solution
+=================
+
+Process:
+
+1. **Clean up locally**
+
+ * Trim spaces and lowercase scheme/host.
+ * Default scheme to ``https://`` if missing.
+ * Reject non-HTTPS schemes.
+ * Remove explicit port and strip query/fragment.
+ * Ensure a trailing slash.
+
+2. **Candidate base URLs**
+
+ * If input host starts with ``exchange.``, use directly.
+ * If input is a bare domain, construct
+ ``https://exchange.<domain>/`` as a second candidate.
+
+3. **Network check (keys)**
+
+ * For each candidate, perform ``GET <base>/keys``.
+ * Follow HTTPS redirects within limits.
+ * Accept if the final response is a valid
+ `ExchangeKeysResponse <https://docs.taler.net/core/api-exchange.html#get--keys>`__.
+ * Otherwise, treat as protocol failure.
+
+4. **List of trusted exchanges**
+
+ * Check the input against a local list of trusted exchanges.
+ * Match by exact part match of hostname and fuzzy match (≥70% Levenshtein).
+ * Return ``bad-protocol`` and if trusted entry(ies) is(are) found, return it(them) back in object(``sugestions: array``).
+
+Outcome values
+--------------
+
+* **ok** — Keys validated; return canonical base.
+* **bad-syntax** — Input invalid (e.g., non-HTTPS scheme).
+* **bad-network** — Network failure (DNS/connect/TLS/timeout).
+* **bad-protocol** — Response received but not a valid exchange.
+
+Canonicalization of output
+--------------------------
+
+* Always return in the form ``https://<lowercased-host>/``.
+* No ports, queries, or fragments.
+
+Examples
+--------
+
+* ``exchange.example.com`` -> **ok**, returns ``https://exchange.example.com/``.
+* ``example.com`` -> try ``https://example.com/keys`` first.
+ If not valid, then try ``https://exchange.example.com/keys``.
+ If that works → **ok**, returns ``https://exchange.example.com/``.
+* ``https://exchange.example.com/`` with ``/keys`` returning something other
+ than a valid ``ExchangeKeysResponse`` object -> **bad-protocol**.
+* ``http://exchange.example.com`` -> **bad-syntax** (HTTPS required).
+* ``example.com`` where ``/keys`` redirects to
+ ``https://api.example.com/keys`` and returns valid data -> **ok**, returns
+ ``https://api.example.com/``.
+* DNS failure -> **bad-network**.
+
+
+Definition of Done
+==================
+
+* Request implemented and documented.
+* Unit tests cover:
+ - valid inputs,
+ - redirects,
+ - trusted exchange fallback,
+ - failure cases (syntax, network, protocol).
+* Feature is enabled by default once tests pass.
+
+Alternatives
+============
+
+Drawbacks
+=========
+
+* Requires maintaining a local list of trusted exchanges and fuzzy matching.
+* Adds network overhead (``GET /keys`` probes).
+* Possible user confusion if multiple trusted exchanges are suggested
+ as fuzzy matches.
+
+Discussion / Q&A
+================
+
+(To be filled in with results from discussions on mailing lists / personal communication.)
diff --git a/design-documents/index.rst b/design-documents/index.rst
@@ -80,4 +80,5 @@ Design documents that start with "XX" are considered deprecated.
066-wallet-color-scheme
067-merchant-self-provisioning
068-tokens-roadmap
+ 069-exchange-base-url-completion
999-template