[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-taldir] branch master updated: better registration UI design,
gnunet <=