gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-taldir] branch master updated: better registration UI design


From: gnunet
Subject: [taler-taldir] branch master updated: better registration UI design
Date: Thu, 09 Jan 2025 23:27:36 +0100

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository taldir.

The following commit(s) were added to refs/heads/master by this push:
     new 9becafd  better registration UI design
9becafd is described below

commit 9becafda5f91fdda6cdd40e3111fa897e62b6bff
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Thu Jan 9 23:27:32 2025 +0100

    better registration UI design
---
 pkg/rest/taldir.go                                 | 124 +++++++++++++++++++--
 static/css/bootstrap.min.css                       |  11 +-
 web/templates/landing.html                         |  65 ++---------
 web/templates/landing_email.html                   |  41 +++++++
 web/templates/landing_phone.html                   |  41 +++++++
 web/templates/{landing.html => lookup_result.html} |  34 +++---
 6 files changed, 232 insertions(+), 84 deletions(-)

diff --git a/pkg/rest/taldir.go b/pkg/rest/taldir.go
index 2b063e7..4132489 100644
--- a/pkg/rest/taldir.go
+++ b/pkg/rest/taldir.go
@@ -64,12 +64,15 @@ type Taldir struct {
        Cfg *ini.File
 
        // Map of supported validators as defined in the configuration
-       Validators map[string]bool
+       Validators map[string]Validator
 
        // landing page
        ValidationTpl *template.Template
 
-       // registration page
+       // lookup result/registration page
+       LookupResultPageTpl *template.Template
+
+       // landing page
        LandingPageTpl *template.Template
 
        // The address salt
@@ -103,6 +106,25 @@ type Taldir struct {
        CurrencySpec talerutil.CurrencySpecification
 }
 
+type Validator struct {
+
+       // Amount of payment required
+       Name string
+
+       // Amount of payment required
+       ChallengeFee string
+
+       // Does this validator require payment
+       PaymentRequired bool
+
+       // The command to call for validation
+       Command string
+
+       // registration/lookup page
+       LandingPageTpl *template.Template
+
+}
+
 // VersionResponse is the JSON response of the /config enpoint
 type VersionResponse struct {
        // libtool-style representation of the Merchant protocol version, see
@@ -378,7 +400,8 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r 
*http.Request) {
        var validation validation
        var entry entry
        // Check if this validation method is supported or not.
-       if !t.Validators[vars["method"]] {
+       _, ok := t.Validators[vars["method"]]
+       if !ok {
                errDetail.Code = gana.TALDIR_METHOD_NOT_SUPPORTED
                errDetail.Hint = "Unsupported method"
                errDetail.Detail = "Given method: " + vars["method"]
@@ -634,6 +657,7 @@ func (t *Taldir) landingPage(w http.ResponseWriter, r 
*http.Request) {
        w.Header().Set("Content-Type", "text/html; charset=utf-8")
 
        fullData := map[string]interface{}{
+               "validators": t.Validators,
                "error": r.URL.Query().Get("error"),
        }
        err := t.LandingPageTpl.Execute(w, fullData)
@@ -643,6 +667,62 @@ func (t *Taldir) landingPage(w http.ResponseWriter, r 
*http.Request) {
        return
 }
 
+func (t *Taldir) methodLookupResultPage(w http.ResponseWriter, r 
*http.Request) {
+       var entry entry
+       vars := mux.Vars(r)
+       w.Header().Set("Content-Type", "text/html; charset=utf-8")
+
+       // Check if this validation method is supported or not.
+       val, ok := t.Validators[vars["method"]]
+       if !ok {
+               w.WriteHeader(404)
+               return
+       }
+
+       hAddressBin := sha512.Sum512([]byte(r.URL.Query().Get("address")))
+       hAddress := gnunetutil.EncodeBinaryToString(hAddressBin[:])
+       hsAddress := saltHAddress(hAddress, t.Salt)
+       found := false
+       var err = t.Db.First(&entry, "hs_address = ?", hsAddress).Error
+       if err != nil {
+               log.Printf("`%s` not found.\n", hAddress)
+       } else {
+               found = true
+       }
+       fullData := map[string]interface{}{
+               "available": !found,
+               "method": val.Name,
+               "address": r.URL.Query().Get("address"),
+               "result": entry.TargetUri,
+               "error": r.URL.Query().Get("error"),
+       }
+       err = t.LookupResultPageTpl.Execute(w, fullData)
+       if err != nil {
+               fmt.Println(err)
+       }
+       return
+}
+
+func (t *Taldir) methodLandingPage(w http.ResponseWriter, r *http.Request) {
+       vars := mux.Vars(r)
+       w.Header().Set("Content-Type", "text/html; charset=utf-8")
+
+       // Check if this validation method is supported or not.
+       val, ok := t.Validators[vars["method"]]
+       if !ok {
+               w.WriteHeader(404)
+               return
+       }
+       fullData := map[string]interface{}{
+               "error": r.URL.Query().Get("error"),
+       }
+       err := val.LandingPageTpl.Execute(w, fullData)
+       if err != nil {
+               fmt.Println(err)
+       }
+       return
+}
+
 func (t *Taldir) setupHandlers() {
        t.Router = mux.NewRouter().StrictSlash(true)
 
@@ -659,6 +739,8 @@ func (t *Taldir) setupHandlers() {
        /* Registration API */
        t.Router.HandleFunc("/", t.landingPage).Methods("GET")
        t.Router.HandleFunc("/{h_address}", t.getSingleEntry).Methods("GET")
+       t.Router.HandleFunc("/lookup/{method}", 
t.methodLookupResultPage).Methods("GET")
+       t.Router.HandleFunc("/landing/{method}", 
t.methodLandingPage).Methods("GET")
        t.Router.HandleFunc("/register/{method}", 
t.registerRequest).Methods("POST")
        t.Router.HandleFunc("/register/{h_address}/{challenge}", 
t.validationPage).Methods("GET")
        t.Router.HandleFunc("/{h_address}", t.validationRequest).Methods("POST")
@@ -678,9 +760,29 @@ func (t *Taldir) Initialize(cfgfile string) {
        }
 
        t.BaseUrl = 
t.Cfg.Section("taldir").Key("base_url").MustString("http://localhost:11000";)
-       t.Validators = make(map[string]bool)
-       for _, a := range 
strings.Split(t.Cfg.Section("taldir").Key("validators").String(), " ") {
-               t.Validators[a] = true
+       t.Validators = make(map[string]Validator)
+       for _, sec := range t.Cfg.Sections() {
+               if !strings.HasPrefix(sec.Name(), "taldir-validator-") {
+                       continue
+               }
+               if !sec.HasKey("enabled") {
+                       log.Printf("`enabled` key in section `[%s]` not found, 
disabling validator.\n", sec.Name())
+                       continue
+               }
+               vname := strings.TrimPrefix(sec.Name(), "taldir-validator-")
+               vlandingPageTplFile := 
sec.Key("registration_page").MustString("web/templates/landing_" + vname + 
".html")
+               vlandingPageTpl, err := template.ParseFiles(vlandingPageTplFile)
+               if err != nil {
+                       log.Printf("`%s` template not found, disabling 
validator `%s`.\n", vlandingPageTplFile, vname)
+                       continue
+               }
+               t.Validators[vname] = Validator{
+                       Name: vname,
+                       LandingPageTpl: vlandingPageTpl,
+                       ChallengeFee: 
sec.Key("challenge_fee").MustString("KUDOS:0"),
+                       PaymentRequired: sec.Key("enabled").MustBool(false),
+                       Command: sec.Key("enabled").MustString(""),
+               }
        }
        t.ChallengeBytes = 
t.Cfg.Section("taldir").Key("challenge_bytes").MustInt(16)
        t.ValidationInitiationMax = 
t.Cfg.Section("taldir").Key("validation_initiation_max").MustInt64(3)
@@ -741,8 +843,14 @@ func (t *Taldir) Initialize(cfgfile string) {
                log.Fatal(err)
                os.Exit(1)
        }
-       registrationTplFile := 
t.Cfg.Section("taldir").Key("landing_page").MustString("web/templates/landing.html")
-       t.LandingPageTpl, err = template.ParseFiles(registrationTplFile)
+       landingTplFile := 
t.Cfg.Section("taldir").Key("landing_page").MustString("web/templates/landing.html")
+       t.LandingPageTpl, err = template.ParseFiles(landingTplFile)
+       if err != nil {
+               log.Fatal(err)
+               os.Exit(1)
+       }
+       lookupResultTplFile := 
t.Cfg.Section("taldir").Key("lookup_result_page").MustString("web/templates/lookup_result.html")
+       t.LookupResultPageTpl, err = template.ParseFiles(lookupResultTplFile)
        if err != nil {
                log.Fatal(err)
                os.Exit(1)
diff --git a/static/css/bootstrap.min.css b/static/css/bootstrap.min.css
index f5910ac..6561b6f 100644
--- a/static/css/bootstrap.min.css
+++ b/static/css/bootstrap.min.css
@@ -1,6 +1,7 @@
-@charset "UTF-8";/*!
- * Bootstrap  v5.3.2 (https://getbootstrap.com/)
- * Copyright 2011-2023 The Bootstrap Authors
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
- 
*/:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--
 [...]
+/*!
+ * Bootstrap v4.0.0 (https://getbootstrap.com)
+ * Copyright 2011-2018 The Bootstrap Authors
+ * Copyright 2011-2018 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ 
*/:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-s
 [...]
 /*# sourceMappingURL=bootstrap.min.css.map */
\ No newline at end of file
diff --git a/web/templates/landing.html b/web/templates/landing.html
index 6e5eebb..1a0631f 100644
--- a/web/templates/landing.html
+++ b/web/templates/landing.html
@@ -19,66 +19,15 @@
           </div>
         </div>
         {{end}}
-        <div class="container pt-5">
-          <div id="sbanner"  class="alert alert-success" role="alert" hidden>
-            <h4 class="alert-heading">Registration initiated!</h4>
-            <hr>
-            Please complete your registration according to the instructions 
sent to you.
+        <h2>Select what type of address you want to look up or register:</h2>
+        <hr>
+        {{range .validators}}
+        <div class="row">
+          <div class="col-lg-6 mb-2 offset-lg-3 text-center">
+            <a href="/landing/{{.Name}}" class="btn btn-primary 
btn-block">{{.Name}}</a>
           </div>
         </div>
-        <form id="regform">
-          <input id="methodInput" type="hidden" name="method" value="clidummy">
-          <div class="row">
-            <div class="col-lg-6 offset-lg-3 text-center">
-              <div class="form-floating mb-3">
-                <input id="addrInput" name="address" class="form-control 
text-center" placeholder="" maxlength="63" type="text" 
aria-describedby="reg-suffix" required autofocus>
-                <label for="addrInput">Your address (e.g. john@doe.com)</label>
-              </div>
-            </div>
-          </div>
-          <div class="row">
-            <div class="col-lg-6 offset-lg-3 text-center">
-              <div class="form-floating mb-3">
-                <input id="uriInput" name="target_uri" class="form-control 
text-center" placeholder="" maxlength="63" type="text" 
aria-describedby="reg-suffix" required autofocus>
-                <label for="uriInput">Your target URI</label>
-              </div>
-            </div>
-          </div>
-          <div class="row">
-            <div class="col-lg-6 offset-lg-3 text-center">
-              <input class="btn btn-primary" type="submit" value="Initiate 
registration!">
-            </div>
-          </div>
-        </form>
+        {{end}}
       </div>
     </body>
-    <script>
-      var form = document.getElementById('regform');
-      form.onsubmit = function(event){
-        var xhr = new XMLHttpRequest();
-        var data = new FormData(form);
-        var method = data.get("method");
-        data.delete("method");
-        xhr.open('POST','/register/' + method) // FIXME method
-        xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
-        var json = JSON.stringify(Object.fromEntries(data));
-        json["duration"] = 1000000000
-        xhr.send(json);
-
-        xhr.onreadystatechange = function() {
-          if (xhr.readyState == XMLHttpRequest.DONE) {
-            form.reset(); //reset form after AJAX success.
-            if (xhr.status == 202) {
-              var sbanner = document.getElementById('sbanner');
-              sbanner.hidden = false;
-            } else {
-              window.location.href = "?error=Registration failed";
-            }
-          }
-        }
-
-        //Dont submit the form.
-        return false;
-      }
-    </script>
 </html>
diff --git a/web/templates/landing_email.html b/web/templates/landing_email.html
new file mode 100644
index 0000000..521ffa8
--- /dev/null
+++ b/web/templates/landing_email.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html lang="en">
+    <head>
+        <!-- Required meta tags -->
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1, 
shrink-to-fit=no">
+        <link href="/css/bootstrap.min.css" rel="stylesheet">
+        <title>TalDir Alias Registration and Lookup</title>
+    </head>
+    <body>
+      <div class="container pt-5">
+        <h1 class="text-center mb-5">TalDir Alias Registration and Lookup</h1>
+        {{if .error}}
+        <div class="container pt-5">
+          <div id="ebanner" class="alert alert-danger" role="alert">
+            <h4 class="alert-heading">An error occured!</h4>
+            <hr>
+            <p class="mb-0">{{.error}}.</p>
+          </div>
+        </div>
+        {{end}}
+        <form method="get" action="/lookup/email">
+          <div class="row">
+            <div class="col-lg-6 offset-lg-3 text-center">
+              <div class="input-group mb-3">
+                <div class="input-group-prepend">
+                  <span class="input-group-text" 
id="inputGroup-sizing-default">Email</span>
+                </div>
+                <input type="text" name="address" class="form-control" 
aria-label="Default" aria-describedby="inputGroup-sizing-default">
+              </div>
+            </div>
+          </div>
+          <div class="row">
+            <div class="col-lg-6 offset-lg-3 text-center">
+              <input class="btn btn-primary" type="submit" value="Lookup">
+            </div>
+          </div>
+        </form>
+      </div>
+    </body>
+</html>
diff --git a/web/templates/landing_phone.html b/web/templates/landing_phone.html
new file mode 100644
index 0000000..a4b5f47
--- /dev/null
+++ b/web/templates/landing_phone.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html lang="en">
+    <head>
+        <!-- Required meta tags -->
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1, 
shrink-to-fit=no">
+        <link href="/css/bootstrap.min.css" rel="stylesheet">
+        <title>TalDir Alias Registration and Lookup</title>
+    </head>
+    <body>
+      <div class="container pt-5">
+        <h1 class="text-center mb-5">TalDir Alias Registration and Lookup</h1>
+        {{if .error}}
+        <div class="container pt-5">
+          <div id="ebanner" class="alert alert-danger" role="alert">
+            <h4 class="alert-heading">An error occured!</h4>
+            <hr>
+            <p class="mb-0">{{.error}}.</p>
+          </div>
+        </div>
+        {{end}}
+        <form method="get" action="/lookup/email">
+          <div class="row">
+            <div class="col-lg-6 offset-lg-3 text-center">
+              <div class="input-group mb-3">
+                <div class="input-group-prepend">
+                  <span class="input-group-text" 
id="inputGroup-sizing-default">Phone</span>
+                </div>
+                <input type="text" name="address" class="form-control" 
aria-label="Default" aria-describedby="inputGroup-sizing-default">
+              </div>
+            </div>
+          </div>
+          <div class="row">
+            <div class="col-lg-6 offset-lg-3 text-center">
+              <input class="btn btn-primary" type="submit" value="Lookup">
+            </div>
+          </div>
+        </form>
+      </div>
+    </body>
+</html>
diff --git a/web/templates/landing.html b/web/templates/lookup_result.html
similarity index 74%
copy from web/templates/landing.html
copy to web/templates/lookup_result.html
index 6e5eebb..95aac36 100644
--- a/web/templates/landing.html
+++ b/web/templates/lookup_result.html
@@ -26,30 +26,37 @@
             Please complete your registration according to the instructions 
sent to you.
           </div>
         </div>
-        <form id="regform">
-          <input id="methodInput" type="hidden" name="method" value="clidummy">
-          <div class="row">
-            <div class="col-lg-6 offset-lg-3 text-center">
-              <div class="form-floating mb-3">
-                <input id="addrInput" name="address" class="form-control 
text-center" placeholder="" maxlength="63" type="text" 
aria-describedby="reg-suffix" required autofocus>
-                <label for="addrInput">Your address (e.g. john@doe.com)</label>
-              </div>
-            </div>
+        {{if .available}}
+        <div class="container pt-5">
+          <div id="ebanner" class="alert alert-info" role="alert">
+            <h4 class="alert-heading">Availiable!</h4>
+            <hr>
+            <p class="mb-0">`{{.address}}` is not yet registered.</p>
           </div>
+        </div>
+        <hr>
+        <form id="regform">
+          <input id="methodInput" type="hidden" name="method" 
value="{{.method}}">
+          <input id="addrInput" type="hidden" name="address" 
value="{{.address}}">
           <div class="row">
             <div class="col-lg-6 offset-lg-3 text-center">
-              <div class="form-floating mb-3">
-                <input id="uriInput" name="target_uri" class="form-control 
text-center" placeholder="" maxlength="63" type="text" 
aria-describedby="reg-suffix" required autofocus>
-                <label for="uriInput">Your target URI</label>
+              <div class="input-group mb-3">
+                <div class="input-group-prepend">
+                  <span class="input-group-text" 
id="inputGroup-sizing-default">Target URI</span>
+                </div>
+                <input id="uriInput" type="text" class="form-control" 
aria-label="Default" aria-describedby="inputGroup-sizing-default">
               </div>
             </div>
           </div>
           <div class="row">
             <div class="col-lg-6 offset-lg-3 text-center">
-              <input class="btn btn-primary" type="submit" value="Initiate 
registration!">
+              <input class="btn btn-primary" type="submit" value="Register">
             </div>
           </div>
         </form>
+        {{else}}
+        Lookup result: {{.result}}
+        {{end}}
       </div>
     </body>
     <script>
@@ -58,6 +65,7 @@
         var xhr = new XMLHttpRequest();
         var data = new FormData(form);
         var method = data.get("method");
+        var addr = data.get("address");
         data.delete("method");
         xhr.open('POST','/register/' + method) // FIXME method
         xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]