taldir

Directory service to resolve wallet mailboxes by messenger addresses
Log | Files | Refs | Submodules | README | LICENSE

commit e256cbcc73bad947729f7527bdf4bced3af376d1
parent de58e42f472aa2cdf915c17dae43c0604ed54d29
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Fri, 25 Apr 2025 23:17:39 +0200

add test data

Diffstat:
M.gitignore | 2--
Mcmd/taldir-server/main_test.go | 446++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mcmd/taldir-server/testdata/taldir-test.conf | 10++++++----
Dcmd/taldir-server/testdata/templates/validation_landing.html | 17-----------------
Acmd/taldir-server/testdata/web/templates/about.html | 30++++++++++++++++++++++++++++++
Acmd/taldir-server/testdata/web/templates/footer.html | 7+++++++
Rweb/templates/imprint.html -> cmd/taldir-server/testdata/web/templates/imprint.html | 0
Acmd/taldir-server/testdata/web/templates/landing.html | 44++++++++++++++++++++++++++++++++++++++++++++
Acmd/taldir-server/testdata/web/templates/landing_email.html | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acmd/taldir-server/testdata/web/templates/landing_phone.html | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acmd/taldir-server/testdata/web/templates/landing_test-cost.html | 0
Acmd/taldir-server/testdata/web/templates/landing_test.html | 0
Acmd/taldir-server/testdata/web/templates/lookup_result.html | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acmd/taldir-server/testdata/web/templates/nav.html | 27+++++++++++++++++++++++++++
Acmd/taldir-server/testdata/web/templates/privacy.html | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acmd/taldir-server/testdata/web/templates/terms.html | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acmd/taldir-server/testdata/web/templates/validation_landing.html | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpkg/rest/taldir.go | 40++++++++++++++++++----------------------
18 files changed, 839 insertions(+), 243 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,6 +1,4 @@ .gitignore go.sum **/validation_code -taldir-server -taldir-cli gana diff --git a/cmd/taldir-server/main_test.go b/cmd/taldir-server/main_test.go @@ -28,13 +28,14 @@ import ( "os" "strings" "testing" + "fmt" gnunetutil "gnunet/util" - "github.com/jarcoal/httpmock" "gopkg.in/ini.v1" "gorm.io/driver/sqlite" _ "taler.net/taldir/cmd/taldir-server" + "github.com/schanzen/taler-go/pkg/merchant" "taler.net/taldir/internal/util" taldir "taler.net/taldir/pkg/rest" ) @@ -45,8 +46,7 @@ var t taldir.Taldir var validRegisterRequest = []byte(` { "address": "abc@test", - "public_key": "000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946A90", - "inbox_url": "myinbox@xyz", + "target_uri": "myinbox@xyz", "duration": 53135000000000 } `) @@ -54,8 +54,7 @@ var validRegisterRequest = []byte(` var validRegisterRequestUnmodified = []byte(` { "address": "abc@test", - "public_key": "000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946A90", - "inbox_url": "myinbox@xyz", + "target_uri": "myinbox@xyz", "duration": 0 } `) @@ -74,6 +73,32 @@ var newOrderStatusUnpaidMockResponse = ` } ` +const merchantConfigResponse = `{ + "currency": "KUDOS", + "currencies": { + "KUDOS": { + "name": "Kudos (Taler Demonstrator)", + "currency": "KUDOS", + "num_fractional_input_digits": 2, + "num_fractional_normal_digits": 2, + "num_fractional_trailing_zero_digits": 2, + "alt_unit_names": { + "0": "ク" + } + } + }, + "exchanges": [ + { + "master_pub": "F80MFRG8HVH6R9CQ47KRFQSJP3T6DBJ4K1D9B703RJY3Z39TBMJ0", + "currency": "KUDOS", + "base_url": "https://exchange.demo.taler.net/" + } + ], + "implementation": "urn:net:taler:specs:taler-merchant:c-reference", + "name": "taler-merchant", + "version": "18:0:15" +}` + func TestMain(m *testing.M) { cfg, err := ini.LooseLoad("testdata/taldir-test.conf") if err != nil { @@ -81,253 +106,278 @@ func TestMain(m *testing.M) { os.Exit(1) } db := sqlite.Open("file::memory:?cache=shared") - t.Initialize(taldir.TaldirConfig{ - Ini: cfg, - Version: "testing", - Datahome: "../../", - Db: db, - }) - log.Println("hello") - code := m.Run() - t.ClearDatabase() - os.Exit(code) + merchServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/config" { + w.WriteHeader(http.StatusOK) + w.Write([]byte(merchantConfigResponse)) + return + } + if !strings.HasPrefix(r.URL.Path, "/private/orders") { + log.Printf("Expected to request '/private/orders', got: %s\n", r.URL.Path) + return + } + if r.Method == http.MethodPost { + jsonResp := fmt.Sprintf("{\"order_id\":\"%s\"}", "uniqueOrderId") + w.WriteHeader(http.StatusOK) + w.Write([]byte(jsonResp)) + } else { + if r.Header.Get("PaidIndicator") == "yes" { + jsonResp := "{\"order_status\":\"paid\"}" + w.WriteHeader(http.StatusOK) + w.Write([]byte(jsonResp)) + } else { + jsonResp := "{\"order_status\":\"unpaid\", \"taler_pay_uri\": \"somepaytouri\"}" + w.WriteHeader(http.StatusOK) + w.Write([]byte(jsonResp)) + } + } + })) + defer merchServer.Close() + merch := merchant.NewMerchant(merchServer.URL, "supersecret") + t.Initialize(taldir.TaldirConfig{ + Ini: cfg, + Version: "testing", + Datahome: "./testdata", + Db: db, + Merchant: merch, + }) + log.Println("hello") + code := m.Run() + t.ClearDatabase() + os.Exit(code) } func getHAddress(addr string) string { - h := sha512.New() - h.Write([]byte(addr)) - return gnunetutil.EncodeBinaryToString(h.Sum(nil)) + h := sha512.New() + h.Write([]byte(addr)) + return gnunetutil.EncodeBinaryToString(h.Sum(nil)) } func TestNoEntry(s *testing.T) { - t.ClearDatabase() + t.ClearDatabase() - h_addr := getHAddress("jdoe@example.com") - req, _ := http.NewRequest("GET", "/"+h_addr, nil) - response := executeRequest(req) + h_addr := getHAddress("jdoe@example.com") + req, _ := http.NewRequest("GET", "/"+h_addr, nil) + response := executeRequest(req) - if http.StatusNotFound != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusNotFound, response.Code) - } + if http.StatusNotFound != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusNotFound, response.Code) + } } func executeRequest(req *http.Request) *httptest.ResponseRecorder { - rr := httptest.NewRecorder() - t.Router.ServeHTTP(rr, req) - return rr + rr := httptest.NewRecorder() + t.Router.ServeHTTP(rr, req) + return rr } func TestRegisterRequest(s *testing.T) { - t.ClearDatabase() + t.ClearDatabase() - req, _ := http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) - response := executeRequest(req) + req, _ := http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) + response := executeRequest(req) - if http.StatusAccepted != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) - } - file, err := os.Open("validation_code") - if err != nil { - s.Errorf("No validation code file found!\n") - } - code, err := io.ReadAll(file) - if err != nil { - s.Errorf("Error reading validation code file contents!\n") - } - h_addr := getHAddress("abc@test") - trimCode := strings.Trim(string(code), " \r\n") - solution := util.GenerateSolution("000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946A90", trimCode) - solutionJSON := "{\"solution\": \"" + solution + "\"}" - req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) - response = executeRequest(req) - if http.StatusNoContent != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusNoContent, response.Code) - } + if http.StatusAccepted != response.Code { + s.Errorf("Expected response code %d. Got %d, with %s\n", http.StatusAccepted, response.Code, response.Body) + } + file, err := os.Open("validation_code") + if err != nil { + s.Errorf("No validation code file found!\n") + } + code, err := io.ReadAll(file) + if err != nil { + s.Errorf("Error reading validation code file contents!\n") + } + h_addr := getHAddress("abc@test") + trimCode := strings.Trim(string(code), " \r\n") + solution := util.GenerateSolution("myinbox@xyz", trimCode) + solutionJSON := "{\"solution\": \"" + solution + "\"}" + req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) + response = executeRequest(req) + if http.StatusNoContent != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusNoContent, response.Code) + } } func TestRegisterQRPageRequest(s *testing.T) { - t.ClearDatabase() + t.ClearDatabase() - req, _ := http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) - response := executeRequest(req) + req, _ := http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) + response := executeRequest(req) - if http.StatusAccepted != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) - } - req, _ = http.NewRequest("GET", "/register/NonSenseAddr/NonSenseCode", nil) - response = executeRequest(req) - if http.StatusNotFound != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusNotFound, response.Code) - } + if http.StatusAccepted != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) + } + req, _ = http.NewRequest("GET", "/register/NonSenseAddr/NonSenseCode", nil) + response = executeRequest(req) + if http.StatusNotFound != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusNotFound, response.Code) + } - file, err := os.Open("validation_code") - if err != nil { - s.Errorf("No validation code file found!\n") - } - code, err := io.ReadAll(file) - if err != nil { - s.Errorf("Error reading validation code file contents!\n") - } - h_addr := getHAddress("abc@test") - trimCode := strings.Trim(string(code), " \r\n") - req, _ = http.NewRequest("GET", "/register/"+h_addr+"/"+trimCode, nil) - response = executeRequest(req) - if http.StatusOK != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusOK, response.Code) - } + file, err := os.Open("validation_code") + if err != nil { + s.Errorf("No validation code file found!\n") + } + code, err := io.ReadAll(file) + if err != nil { + s.Errorf("Error reading validation code file contents!\n") + } + h_addr := getHAddress("abc@test") + trimCode := strings.Trim(string(code), " \r\n") + req, _ = http.NewRequest("GET", "/register/"+h_addr+"/"+trimCode+"?address="+"abc@test", nil) + response = executeRequest(req) + if http.StatusOK != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusOK, response.Code) + } } func TestReRegisterRequest(s *testing.T) { - t.ClearDatabase() + t.ClearDatabase() - req, _ := http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) - response := executeRequest(req) + req, _ := http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) + response := executeRequest(req) - if http.StatusAccepted != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) - } - file, err := os.Open("validation_code") - if err != nil { - s.Errorf("No validation code file found!\n") - } - code, err := io.ReadAll(file) - if err != nil { - s.Errorf("Error reading validation code file contents!\n") - } - h_addr := getHAddress("abc@test") - trimCode := strings.Trim(string(code), " \r\n") - solution := util.GenerateSolution("000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946A90", trimCode) - solutionJSON := "{\"solution\": \"" + solution + "\"}" - req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) - response = executeRequest(req) - if http.StatusNoContent != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusNoContent, response.Code) - } - req, _ = http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequestUnmodified)) - response = executeRequest(req) + if http.StatusAccepted != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) + } + file, err := os.Open("validation_code") + if err != nil { + s.Errorf("No validation code file found!\n") + } + code, err := io.ReadAll(file) + if err != nil { + s.Errorf("Error reading validation code file contents!\n") + } + h_addr := getHAddress("abc@test") + trimCode := strings.Trim(string(code), " \r\n") + solution := util.GenerateSolution("myinbox@xyz", trimCode) + solutionJSON := "{\"solution\": \"" + solution + "\"}" + req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) + response = executeRequest(req) + if http.StatusNoContent != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusNoContent, response.Code) + } + req, _ = http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequestUnmodified)) + response = executeRequest(req) - if http.StatusOK != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusOK, response.Code) - } + if http.StatusOK != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusOK, response.Code) + } } func TestReRegisterRequestTooMany(s *testing.T) { - t.ClearDatabase() + t.ClearDatabase() - req, _ := http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) - response := executeRequest(req) + req, _ := http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) + response := executeRequest(req) - if http.StatusAccepted != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) - } - req, _ = http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) - response = executeRequest(req) + if http.StatusAccepted != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) + } + req, _ = http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) + response = executeRequest(req) - if http.StatusAccepted != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) - } - req, _ = http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) - response = executeRequest(req) + if http.StatusAccepted != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) + } + req, _ = http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) + response = executeRequest(req) - if http.StatusAccepted != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) - } - req, _ = http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) - response = executeRequest(req) + if http.StatusAccepted != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) + } + req, _ = http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) + response = executeRequest(req) - if http.StatusTooManyRequests != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusTooManyRequests, response.Code) - } + if http.StatusTooManyRequests != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusTooManyRequests, response.Code) + } } func TestSolutionRequestTooMany(s *testing.T) { - t.ClearDatabase() + t.ClearDatabase() - req, _ := http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) - response := executeRequest(req) + req, _ := http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) + response := executeRequest(req) - if http.StatusAccepted != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) - } - h_addr := getHAddress("abc@test") - solution := util.GenerateSolution("000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946A90", "wrongSolution") - solutionJSON := "{\"solution\": \"" + solution + "\"}" - req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) - response = executeRequest(req) - if http.StatusForbidden != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusForbidden, response.Code) - } - req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) - response = executeRequest(req) - if http.StatusForbidden != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusForbidden, response.Code) - } - req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) - response = executeRequest(req) - if http.StatusForbidden != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusForbidden, response.Code) - } - req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) - response = executeRequest(req) - if http.StatusTooManyRequests != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusTooManyRequests, response.Code) - } + if http.StatusAccepted != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) + } + h_addr := getHAddress("abc@test") + solution := util.GenerateSolution("myinbox@xyz", "wrongSolution") + solutionJSON := "{\"solution\": \"" + solution + "\"}" + req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) + response = executeRequest(req) + if http.StatusForbidden != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusForbidden, response.Code) + } + req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) + response = executeRequest(req) + if http.StatusForbidden != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusForbidden, response.Code) + } + req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) + response = executeRequest(req) + if http.StatusForbidden != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusForbidden, response.Code) + } + req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) + response = executeRequest(req) + if http.StatusTooManyRequests != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusTooManyRequests, response.Code) + } } -func TestRegisterRequestWrongPubkey(s *testing.T) { - t.ClearDatabase() +func TestRegisterRequestWrongTargetUri(s *testing.T) { + t.ClearDatabase() - req, _ := http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) - response := executeRequest(req) + req, _ := http.NewRequest("POST", "/register/test", bytes.NewBuffer(validRegisterRequest)) + response := executeRequest(req) - if http.StatusAccepted != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) - } - file, err := os.Open("validation_code") - if err != nil { - s.Errorf("No validation code file found!\n") - } - code, err := io.ReadAll(file) - if err != nil { - s.Errorf("Error reading validation code file contents!\n") - } - h_addr := getHAddress("abc@test") - trimCode := strings.Trim(string(code), " \r\n") - solution := util.GenerateSolution("000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946AA0", trimCode) - solutionJSON := "{\"solution\": \"" + solution + "\"}" - req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) - response = executeRequest(req) - if http.StatusForbidden != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusForbidden, response.Code) - } + if http.StatusAccepted != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, response.Code) + } + file, err := os.Open("validation_code") + if err != nil { + s.Errorf("No validation code file found!\n") + } + code, err := io.ReadAll(file) + if err != nil { + s.Errorf("Error reading validation code file contents!\n") + } + h_addr := getHAddress("abc@test") + trimCode := strings.Trim(string(code), " \r\n") + solution := util.GenerateSolution("myinox@xyz", trimCode) + solutionJSON := "{\"solution\": \"" + solution + "\"}" + req, _ = http.NewRequest("POST", "/"+h_addr, bytes.NewBuffer([]byte(solutionJSON))) + response = executeRequest(req) + if http.StatusForbidden != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusForbidden, response.Code) + } } func TestUnsupportedMethod(s *testing.T) { - t.ClearDatabase() + t.ClearDatabase() - req, _ := http.NewRequest("POST", "/register/email", bytes.NewBuffer(validRegisterRequest)) - response := executeRequest(req) + req, _ := http.NewRequest("POST", "/register/email", bytes.NewBuffer(validRegisterRequest)) + response := executeRequest(req) - if http.StatusNotFound != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusNotFound, response.Code) - } + if http.StatusNotFound != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusNotFound, response.Code) + } } func TestPaymentRequiredMethod(s *testing.T) { - t.ClearDatabase() - t.MonthlyFee = "KUDOS:5" - httpmock.Activate() - defer httpmock.DeactivateAndReset() - req, _ := http.NewRequest("POST", "/register/test-cost", bytes.NewBuffer(validRegisterRequest)) - httpmock.RegisterResponder("POST", "http://merchant.taldir/instances/myInstance/private/orders", httpmock.NewStringResponder(200, newOrderMockResponse)) - httpmock.RegisterResponder("GET", "http://merchant.taldir/instances/myInstance/private/orders/testOrder1234", httpmock.NewStringResponder(200, newOrderStatusUnpaidMockResponse)) - - response := executeRequest(req) - t.MonthlyFee = "KUDOS:0" - if http.StatusPaymentRequired != response.Code { - s.Errorf("Expected response code %d. Got %d\n", http.StatusPaymentRequired, response.Code) - } + t.ClearDatabase() + t.MonthlyFee = "KUDOS:5" + req, _ := http.NewRequest("POST", "/register/test-cost", bytes.NewBuffer(validRegisterRequest)) + + response := executeRequest(req) + t.MonthlyFee = "KUDOS:0" + if http.StatusPaymentRequired != response.Code { + s.Errorf("Expected response code %d. Got %d\n", http.StatusPaymentRequired, response.Code) + } } diff --git a/cmd/taldir-server/testdata/taldir-test.conf b/cmd/taldir-server/testdata/taldir-test.conf @@ -5,7 +5,6 @@ host = "https://taldir.net" bind_to = "localhost:11000" salt = "ChangeMe" monthly_fee = KUDOS:0 -validation_landing = testdata/templates/validation_landing.html default_doc_filetype = text/markdown default_doc_lang = en-US default_tos_path = terms/ @@ -19,14 +18,17 @@ merchant_baseurl_private = http://merchant.taldir/instances/myInstance merchant_token = superSecretToken validation_expiration = 5m -[taldir-test] +[taldir-validator-test] challenge_fee = KUDOS:0 command = testdata/taldir-validate-test +type = command +enabled = true -[taldir-test-cost] +[taldir-validator-test-cost] challenge_fee = KUDOS:23 command = testdata/taldir-validate-test - +type = command +enabled = true [taldir-pq] host = "localhost" diff --git a/cmd/taldir-server/testdata/templates/validation_landing.html b/cmd/taldir-server/testdata/templates/validation_landing.html @@ -1,17 +0,0 @@ -<!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"> - <title>Validation Landing Page</title> - </head> - <body> - <div class="container"> - <h1>Scan this QR code with your Taler Wallet to complete your registration.</h1> - <a href="{{.WalletLink}}"> - <img src="{{.QRCode}}"/> - </a> - </div> - </body> -</html> diff --git a/cmd/taldir-server/testdata/web/templates/about.html b/cmd/taldir-server/testdata/web/templates/about.html @@ -0,0 +1,30 @@ +<!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"> + <link href="/css/style.css" rel="stylesheet"> + <link href="/fontawesome/css/fontawesome.css" rel="stylesheet" /> + <link href="/fontawesome/css/solid.css" rel="stylesheet" /> + <title>{{ call .tr "title" }}</title> + </head> + <body> + {{ template "nav.html" . }} + <div class="container pt-5"> + <div class="card"> + <div class="card-body"> + <h4 class="card-title">{{ call .tr "about" }}</h4> + <p class="card-text">{{ .productDisclaimer }}</p> + <div class="container p-2 center" style="text-align: center;"> + <a href="https://www.taler.net/en/"><img class="p-2" style="height:6em;" src="/images/talerlogo.svg" alt="GNUTaler"></a> + <a href="https://nlnet.nl/project/TALER-LookupService/"><img class="p-2" style="height:6em;" src="/images/nlnetbanner.svg" alt="NLNet"></a> + </div> + </div> + </div> + </div> + </div> + {{ template "footer.html" . }} + </body> +</html> diff --git a/cmd/taldir-server/testdata/web/templates/footer.html b/cmd/taldir-server/testdata/web/templates/footer.html @@ -0,0 +1,7 @@ +<footer class="fs-6 text-sm-end mt-4 me-2"> + <span><a href="https://git.taler.net/taldir.git">Browse Git Repository</a></span><br/> + <span><a href="/terms">Terms</a></span><br/> + <span><a href="/privacy">Privacy</a></span><br/> + <span><a href="/imprint">Imprint</a></span><br/> + <span>{{.version}}</span><br/> +</footer> diff --git a/web/templates/imprint.html b/cmd/taldir-server/testdata/web/templates/imprint.html diff --git a/cmd/taldir-server/testdata/web/templates/landing.html b/cmd/taldir-server/testdata/web/templates/landing.html @@ -0,0 +1,44 @@ +<!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"> + <link href="/css/style.css" rel="stylesheet"> + <link href="/fontawesome/css/fontawesome.css" rel="stylesheet" /> + <link href="/fontawesome/css/solid.css" rel="stylesheet" /> + <title>{{ call .tr "title" }}</title> + </head> + <body> + {{ template "nav.html" . }} + <div class="container pt-5"> + {{if .error}} + <div class="container pt-5"> + <div id="ebanner" class="alert alert-danger" role="alert"> + <h4 class="alert-heading">{{ call .tr "error" }}</h4> + <hr> + <p class="mb-0">{{.error}}.</p> + </div> + </div> + {{end}} + <div class="card"> + <div class="card-body"> + <h4 class="card-title">{{ .lookupOrRegisterCardTitle }}</h4> + <p class="card-text">{{ .selectAliasToLookupCardText }}</p> + {{range .validators}} + <div class="row"> + <div class="col-lg-4 mb-2 offset-lg-3 text-center d-grid gap-2"> + <a href="/landing/{{.Name}}" class="btn btn-outline-primary btn-block">{{ call $.tr .Name}}</a> + </div> + </div> + {{end}} + <hr> + <h4>{{ call .tr "registerOrModify" }}</h4> + <p class="mb-0">{{.registerCardText}}</p> + </div> + </div> + </div> + {{ template "footer.html" . }} + </body> +</html> diff --git a/cmd/taldir-server/testdata/web/templates/landing_email.html b/cmd/taldir-server/testdata/web/templates/landing_email.html @@ -0,0 +1,60 @@ +<!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"> + <link href="/css/style.css" rel="stylesheet"> + <link href="/fontawesome/css/fontawesome.css" rel="stylesheet" /> + <link href="/fontawesome/css/solid.css" rel="stylesheet" /> + <title>{{ call .tr "title" }}</title> + </head> + <body> + {{ template "nav.html" . }} + <div class="container pt-5"> + {{if .error}} + <div class="container pt-5"> + <div id="ebanner" class="alert alert-danger" role="alert"> + <h4 class="alert-heading">{{ call .tr "error" }}</h4> + <hr> + <p class="mb-0">{{.error}}</p> + </div> + </div> + {{end}} + <div class="row"> + <div class="col-2"> + <ul class="timeline"> + <li class="inprogress">{{ call .tr "lookup" }}</li> + <li>{{ call .tr "registerOrModify" }}</li> + <li>{{ call .tr "confirm" }}</li> + </ul> + </div> + <div class="col-8"> + <div class="card"> + <div class="card-body"> + <h4 class="cart-title">{{ call .tr "lookupEmail" }}</h4> + <hr> + <p class="card-text">{{ call .tr "lookupEmailDescription" }}</p> + </div> + <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="form-floating"> + <input type="email" name="address" id="floatingInput" class="form-control" placeholder="jdoe@example.com" aria-label="Default" aria-describedby="inputGroup-sizing-default" data-sb-validations="required,email"> + <label for="floatingInput">{{ call .tr "email" }}</label> + </div> + <div class="invalid-feedback text-white" data-sb-feedback="emailAddressBelow:required">Email Address is required.</div> + <div class="invalid-feedback text-white" data-sb-feedback="emailAddressBelow:email">Email Address is not valid.</div> + <input class="input-group-text btn btn-outline-primary" type="submit" value="{{ call .tr "lookup" }}"> + </div> + </div> + </div> + </form> + </div> + </div> + </div> + {{ template "footer.html" . }} + </body> +</html> diff --git a/cmd/taldir-server/testdata/web/templates/landing_phone.html b/cmd/taldir-server/testdata/web/templates/landing_phone.html @@ -0,0 +1,58 @@ +<!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"> + <link href="/css/style.css" rel="stylesheet"> + <link href="/fontawesome/css/fontawesome.css" rel="stylesheet" /> + <link href="/fontawesome/css/solid.css" rel="stylesheet" /> + <title>{{ call .tr "title" }}</title> + </head> + <body> + {{ template "nav.html" . }} + <div class="container pt-5"> + {{if .error}} + <div class="container pt-5"> + <div id="ebanner" class="alert alert-danger" role="alert"> + <h4 class="alert-heading">{{ call .tr "error" }}</h4> + <hr> + <p class="mb-0">{{.error}}.</p> + </div> + </div> + {{end}} + <div class="row"> + <div class="col-2"> + <ul class="timeline"> + <li class="inprogress">{{ call .tr "lookup" }}</li> + <li>{{ call .tr "registerOrModify" }}</li> + <li>{{ call .tr "confirm" }}</li> + </ul> + </div> + <div class="col-8"> + <div class="card"> + <div class="card-body"> + <h4 class="card-title">{{ call .tr "lookupPhoneNr" }}</h4> + <p class="card-text">{{ call .tr "lookupPhoneDescription" }}</p> + </div> + <form method="get" action="/lookup/phone"> + <div class="row"> + <div class="col-lg-6 offset-lg-3 text-center"> + <div class="input-group mb-3"> + <span class="input-group-text" id="inputGroup-sizing-default">+</span> + <div class="form-floating"> + <input type="text" name="address" id="phoneInput" class="form-control" aria-label="Default" placeholder="49123456789" aria-describedby="inputGroup-sizing-default"> + <label for="phoneInput">{{ call .tr "phone" }}</label> + </div> + <input class="input-group-text btn btn-outline-primary" type="submit" value="{{ call .tr "lookup" }}"> + </div> + </div> + </div> + </form> + </div> + </div> + </div> + {{ template "footer.html" . }} + </body> +</html> diff --git a/cmd/taldir-server/testdata/web/templates/landing_test-cost.html b/cmd/taldir-server/testdata/web/templates/landing_test-cost.html diff --git a/cmd/taldir-server/testdata/web/templates/landing_test.html b/cmd/taldir-server/testdata/web/templates/landing_test.html diff --git a/cmd/taldir-server/testdata/web/templates/lookup_result.html b/cmd/taldir-server/testdata/web/templates/lookup_result.html @@ -0,0 +1,123 @@ +<!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"> + <link href="/css/style.css" rel="stylesheet"> + <link href="/fontawesome/css/fontawesome.css" rel="stylesheet" /> + <link href="/fontawesome/css/solid.css" rel="stylesheet" /> + <title>{{ call .tr "title" }}</title> + </head> + <body> + {{ template "nav.html" . }} + <div class="container"> + <div id="ebanner" class="container" hidden> + <div class="alert alert-danger" role="alert"> + <h4 class="alert-heading">{{ call .tr "error" }}</h4> + <hr> + <p class="mb-0" id="ebanner-text">{{.error}}.</p> + </div> + </div> + <div id="sbanner" class="container" hidden> + <div class="alert alert-success" role="alert"> + <h4 class="alert-heading">{{ call .tr "validationInitiated" }}</h4> + <hr> + {{ call .tr "pleaseCompleteValidation" }} + </div> + </div> + <div class="container pt-5"> + <div class="row"> + <div class="col-2"> + <ul class="timeline"> + <li class="done">{{ call .tr "lookup" }}</li> + <li class="inprogress">{{ call .tr "registerOrModify" }}</li> + <li>{{ call .tr "confirm" }}</li> + </ul> + </div> + <div class="col-8"> + <div class="card"> + {{if .available}} + <div class="card-body"> + <h4 class="card-title">{{ call .tr "available" }}</h4> + <hr> + <p class="card-text">{{ call .tr "notYetLinked" .address}}</p> + </div> + <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-8 offset-lg-2 text-center"> + <div class="input-group mb-3"> + <!--<span class="input-group-text" id="inputGroup-sizing-default">{{.address}}: </span>--> + <input id="uriInput" name="target_uri" type="text" class="form-control" placeholder="{{ call .tr "paymentSystemAddressExample" }}" aria-label="Default" aria-describedby="inputGroup-sizing-default"> + <input class="input-group-text btn btn-outline-primary" type="submit" value="{{ call .tr "linkIt" }}"> + </div> + </div> + </div> + </form> + {{else}} + <div class="card-body" role="alert"> + <h4 class="card-title">{{ call .tr "lookupResultFound" }}</h4> + <hr> + <p class="card-text">{{ call .tr "isLinked" .address }}</p> + </div> + <form id="regform"> + <input id="methodInput" type="hidden" name="method" value="{{.method}}"> + <input id="addrInput" type="hidden" name="address" value="{{.address}}"> + <input id="uriInput" type="hidden" name="target_uri" value=""> + <div class="row"> + <div class="col-lg-6 offset-lg-3 text-center"> + <div class="input-group mb-3"> + <!--<span class="input-group-text" id="inputGroup-sizing-default">{{.address}}: </span>--> + <input disabled="disabled" type="text" class="form-control" aria-label="Default" aria-describedby="inputGroup-sizing-default" value="{{.result}}"> + <input class="input-group-text btn btn-outline-danger" type="submit" value="{{ call .tr "deleteIt" }}"> + </div> + </div> + </div> + </form> + {{end}} + </div> + </div> + </div> + </div> + {{ template "footer.html" . }} + </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"); + var addr = data.get("address"); + 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. + var ebanner = document.getElementById('ebanner'); + var sbanner = document.getElementById('sbanner'); + if (xhr.status == 202) { + sbanner.hidden = false; + ebanner.hidden = true; + } else { + var jsonResponse = JSON.parse(xhr.responseText); + document.getElementById('ebanner-text').innerHTML = jsonResponse.hint; + sbanner.hidden = true; + ebanner.hidden = false; + // window.location.href = "/?error=Registration failed"; + } + } + } + + //Dont submit the form. + return false; + } + </script> +</html> diff --git a/cmd/taldir-server/testdata/web/templates/nav.html b/cmd/taldir-server/testdata/web/templates/nav.html @@ -0,0 +1,27 @@ +<!-- As a heading --> +<nav class="navbar navbar-expand-lg bg-body-tertiary"> + <div class="container-fluid"> + <a class="navbar-brand" href="#"><img src="/images/talerlogo.svg" alt="TalDir" style="height:3em;"></a> + <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + <div class="collapse navbar-collapse" id="navbarSupportedContent"> + <ul class="navbar-nav me-auto mb-2 mb-lg-0"> + <li class="nav-item"> + <a class="nav-link active" aria-current="page" href="/">TalDir Home</a> + </li> + <li class="nav-item"> + <a class="nav-link" href="/about">{{ call .tr "about" }}</a> + </li> + </ul> + </div> + <div>{{ call .tr "title" }}</div> + </div> +</nav> +<div class="alert alert-warning" role="alert"> + <!--<h4 class="alert-heading">{{ call .tr "demoService" }}</h4> + <hr>--> + <p class="mb-0"> + {{ .productDisclaimerShort }} + </p> +</div> diff --git a/cmd/taldir-server/testdata/web/templates/privacy.html b/cmd/taldir-server/testdata/web/templates/privacy.html @@ -0,0 +1,59 @@ +<!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"> + <link href="/fontawesome/css/fontawesome.css" rel="stylesheet" /> + <link href="/fontawesome/css/solid.css" rel="stylesheet" /> + <title>{{ call .tr "title" }}</title> + </head> + <body> + {{ template "nav.html" . }} + <div class="card"> + <p>The <strong>TalDir Alias Registration and Lookup</strong> application is designed to allow users to securely store and retrieve bank + account information, accessible via email address and mobile phone number, to facilitate seamless banking + operations.</p> + + <p>This Privacy Policy outlines how we handle the data collected during the use of the service, in compliance with + applicable data protection regulations and legal requirements.</p> + + <h2>1. Types of Data Collected</h2> + <p>In the course of using the service, we collect the following data:</p> + <ul> + <li>A hash of the email or phone number provided by users.</li> + <li>The payment system address.</li> + </ul> + + <h2>2. Purpose of Data Collection</h2> + <p>The collected data is used solely to enable the storage and retrieval of bank account information in a secure and + efficient manner. No data is used for marketing or unsolicited communication purposes.</p> + + <h2>3. Access and Modification of Data</h2> + <p>Users retain full control over their personal data. They can update their information by completing the + registration process again or delete it by selecting the appropriate option during registration.</p> + + <h2>4. Data Sharing</h2> + <p>We do not share personal data with third parties unless required by law.</p> + + <h2>5. Data Storage and Security</h2> + <p>The collected data is stored on secure servers that comply with current data protection regulations. Technical + and organizational measures are in place to protect the data from unauthorized access, loss, or misuse.</p> + + <h2>6. Rights of the Data Subjects</h2> + <p>Users have full control over their personal data. They can access, update, or delete their data themselves + through the registration process.</p> + + <h2>7. Contact</h2> + <p>If you have any questions regarding the collection, processing, or use of your personal data, or if you wish to + exercise your rights as a data subject, please contact us at <a href="mailto:legal@gnunet.org">legal@gnunet.org</a>.</p> + + <h2>8. Scope and Changes</h2> + <p>This Privacy Policy applies to the use of the service and may be updated periodically to reflect + legal requirements or changes in the project. Any changes will be reflected on this page and will not be + announced separately.</p> + + </div> + </body> +</html> diff --git a/cmd/taldir-server/testdata/web/templates/terms.html b/cmd/taldir-server/testdata/web/templates/terms.html @@ -0,0 +1,59 @@ +<!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"> + <link href="/fontawesome/css/fontawesome.css" rel="stylesheet" /> + <link href="/fontawesome/css/solid.css" rel="stylesheet" /> + <title>{{ call .tr "title" }}</title> + </head> + <body> + {{ template "nav.html" . }} + <div class="card"> + <p> + The <strong>TalDir Alias Registration and Lookup</strong> service is designed to allow users to securely store and retrieve bank + account information, accessible via email address and mobile phone number, to facilitate seamless banking + operations. + </p> + + <h2>1. General Use</h2> + <p> + TalDir is a public service intended for use by anyone. Users shall only register information about + themselves and must not register information pertaining to other individuals. + </p> + + <h2>2. Data Protection</h2> + <p> + The protection of your data is our top priority. The application strictly adheres to applicable data protection + laws and regulations. For more information, please consult our <a href="privacy.html">Privacy Policy</a>. + </p> + + <h2>3. User Responsibilities</h2> + <p> + Users are responsible for using the application according to the provided guidelines and ensuring that all + input data is accurate and truthful. + </p> + + <h2>4. Disclaimer and Availability</h2> + <p> + The project team assumes no liability for damages resulting from improper use of the application. The application + is provided in its current state, and no guarantee is given for complete error-free operation. + </p> + <div class="alert alert-warning"> + <p><strong>Important Note on Availability:</strong> We strive to keep the application available as much as + possible. However, due to technical maintenance, system updates, or unforeseen issues, occasional downtimes + or maintenance periods may occur.</p> + </div> + + <h2>5. Changes to the Terms of Use</h2> + <p>The project team reserves the right to change these Terms of Use at any time. + Any changes will be reflected on this page and will not be announced separately.</p> + + <h2>6. Contact</h2> + <p>If you have any questions regarding these Terms of Use or the use of the ECB Lookup application, please contact + us at <a href="mailto:legal@gnunet.org">legal@gnunet.org</a>.</p> + </div> + </body> +</html> diff --git a/cmd/taldir-server/testdata/web/templates/validation_landing.html b/cmd/taldir-server/testdata/web/templates/validation_landing.html @@ -0,0 +1,100 @@ +<!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"> + <link href="/css/style.css" rel="stylesheet"> + <link href="/fontawesome/css/fontawesome.css" rel="stylesheet" /> + <link href="/fontawesome/css/solid.css" rel="stylesheet" /> + <title>{{ call .tr "title" }}</title> + </head> + <body> + {{ template "nav.html" . }} + {{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}} + <div class="container"> + <div id="sbanner" class="alert alert-success" role="alert" hidden> + <h4 class="alert-heading">Registration successful!</h4> + <hr> + You may now <a href="/">go back to the front page</a>. + </div> + </div> + {{if .WalletLink}} + <div class="qr"> + <h1>Scan this QR code with your Taler Wallet to complete your registration.</h1> + <a href="{{.WalletLink}}"> + <img class="taldir-qr" src="{{.QRCode}}"/> + </a> + </div> + {{else}} + <div class="container pt-5"> + <div class="row"> + <div class="col-2"> + <ul class="timeline"> + <li class="done">{{ call .tr "lookup" }}</li> + <li class="done">{{ call .tr "registerOrModify" }}</li> + <li id="confirmitem" class="inprogress">{{ call .tr "confirm" }}</li> + </ul> + </div> + <div class="col-8"> + <div id="regcontainer" class="card"> + <div class="card-body"> + <h4 class="card-title">{{ call .tr "confirmation" }}</h4> + <p class="card-text">{{ .confirmDeletionOrRegistration }}</p> + <div class="row mt-2"> + <div class="col-lg-6 offset-lg-3 text-center"> + <form id="regform"> + <input id="haddrInput" name="haddr" type="hidden" value="{{.haddress}}"> + <input id="solutionInput" name="solution" type="hidden" value="{{.solution}}"> + <input id="confirmbutton" class="btn btn-outline-primary" type="submit" value="{{ call .tr "confirm" }}"> + </form> + </div> + </div> + </div> + </div> + </div> + </div> + {{end}} + {{ template "footer.html" . }} + </body> + <script> + var form = document.getElementById('regform'); + form.onsubmit = function(event){ + var xhr = new XMLHttpRequest(); + var data = new FormData(form); + var haddr = data.get("haddr"); + data.delete("haddr"); + xhr.open('POST','/' + haddr) + xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); + var json = JSON.stringify(Object.fromEntries(data)); + xhr.send(json); + + xhr.onreadystatechange = function() { + if (xhr.readyState == XMLHttpRequest.DONE) { + if (xhr.status == 204) { + var sbanner = document.getElementById('sbanner'); + var confirmitem = document.getElementById('confirmitem'); + var confirmbutton = document.getElementById('confirmbutton'); + sbanner.hidden = false; + confirmitem.classList.add("done"); + confirmbutton.disabled = true; + } else { + window.location.href = "?error=Registration failed"; + } + } + } + + //Dont submit the form. + return false; + } + </script> +</html> diff --git a/pkg/rest/taldir.go b/pkg/rest/taldir.go @@ -673,7 +673,6 @@ func (t *Taldir) validationPage(w http.ResponseWriter, r *http.Request) { var png []byte var validation Validation - log.Println("Validation Page") err := t.Db.First(&validation, "h_address = ?", vars["h_address"]).Error w.Header().Set("Content-Type", "text/html; charset=utf-8") if err != nil { @@ -715,7 +714,7 @@ func (t *Taldir) validationPage(w http.ResponseWriter, r *http.Request) { } encodedPng := base64.StdEncoding.EncodeToString(png) - fullData := map[string]interface{}{ + fullData := map[string]any{ "version": t.Cfg.Version, "QRCode": template.URL("data:image/png;base64," + encodedPng), "WalletLink": template.URL(walletLink), @@ -730,7 +729,7 @@ func (t *Taldir) validationPage(w http.ResponseWriter, r *http.Request) { } else { confirmDeletionOrRegistration = t.I18n.GetLocale(r).GetMessage("confirmReg", address, validation.TargetUri) } - fullData := map[string]interface{}{ + fullData := map[string]any{ "version": t.Cfg.Version, "error": r.URL.Query().Get("error"), "target_uri": template.URL(validation.TargetUri), @@ -862,7 +861,6 @@ func (t *Taldir) methodLookupResultPage(w http.ResponseWriter, r *http.Request) if err != nil { fmt.Println(err) } - return } func (t *Taldir) methodLandingPage(w http.ResponseWriter, r *http.Request) { @@ -875,7 +873,7 @@ func (t *Taldir) methodLandingPage(w http.ResponseWriter, r *http.Request) { w.WriteHeader(404) return } - fullData := map[string]interface{}{ + fullData := map[string]any{ "version": t.Cfg.Version, "error": r.URL.Query().Get("error"), "productDisclaimerShort": template.HTML(t.I18n.GetLocale(r).GetMessage("productDisclaimerShort")), @@ -885,7 +883,6 @@ func (t *Taldir) methodLandingPage(w http.ResponseWriter, r *http.Request) { if err != nil { fmt.Println(err) } - return } func (t *Taldir) setupHandlers() { @@ -933,6 +930,7 @@ func (t *Taldir) getFileName(relativeFileName string, datahome string) string { if errors.Is(err, os.ErrNotExist) { _, err := os.Stat(datahome + "/" + relativeFileName) if errors.Is(err, os.ErrNotExist) { + log.Printf("Tried fallback not found %s\n",datahome + "/" + relativeFileName) return "" } return datahome + "/" + relativeFileName @@ -990,7 +988,7 @@ func (t *Taldir) Initialize(cfg TaldirConfig) { t.SolutionAttemptsMax = cfg.Ini.Section("taldir").Key("solution_attempt_max").MustInt(3) validationTTLStr := cfg.Ini.Section("taldir").Key("validation_timeframe").MustString("5m") - t.ValidPMSRegex = cfg.Ini.Section("taldir").Key("valid_payment_system_address_regex").MustString("[A-Z]+") + t.ValidPMSRegex = cfg.Ini.Section("taldir").Key("valid_payment_system_address_regex").MustString(".*") t.ValidationTimeframe, err = time.ParseDuration(validationTTLStr) if err != nil { log.Fatal(err) @@ -1072,20 +1070,18 @@ func (t *Taldir) Initialize(cfg TaldirConfig) { t.Salt = cfg.Ini.Section("taldir").Key("salt").MustString("ChangeMe") } t.Host = cfg.Ini.Section("taldir").Key("base_url").MustString("http://localhost") - //merchURL := t.Cfg.Section("taldir").Key("merchant_base_url").MustString("http://merchant.taldir/") - //merchToken := t.Cfg.Section("taldir").Key("merchant_token").MustString("secretAccessToken") - //t.Merchant = merchant.NewMerchant(merchURL, merchToken) - //merchConfig, err := t.Merchant.GetConfig() - //if nil != err { - // log.Fatal("Failed to get merchant config") - // os.Exit(1) - //} - //registrationCost, _ := talerutil.ParseAmount(t.MonthlyFee) - //currencySpec, currencySupported := merchConfig.Currencies[registrationCost.Currency] - //for !currencySupported { - // log.Fatalf("Currency `%s' not supported by merchant!\n", registrationCost.Currency) - // os.Exit(1) - //} - //t.CurrencySpec = currencySpec + t.Merchant = cfg.Merchant + registrationCost, _ := talerutil.ParseAmount(t.MonthlyFee) + merchConfig, err := t.Merchant.GetConfig() + if err != nil { + log.Fatal(err) + os.Exit(1) + } + currencySpec, currencySupported := merchConfig.Currencies[registrationCost.Currency] + for !currencySupported { + log.Fatalf("Currency `%s' not supported by merchant!\n", registrationCost.Currency) + os.Exit(1) + } + t.CurrencySpec = currencySpec t.setupHandlers() }