From 8d9aaeedbcc06e34f15e4149b16638050a4cfa18 Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Tue, 27 Aug 2024 16:02:24 +0300 Subject: [PATCH 1/3] Validate that the amount is not greater than the balance --- internal/handlers/ussd/menuhandler.go | 66 ++++++++++++++++++--------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index 897fff6..df83592 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "strconv" + "strings" "git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/lang" @@ -505,36 +506,57 @@ func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (res } func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) { - res := resource.Result{} - amount := string(input) + res := resource.Result{} + amountStr := string(input) - accountData, err := h.accountFileHandler.ReadAccountData() - if err != nil { - return res, err - } + accountData, err := h.accountFileHandler.ReadAccountData() + if err != nil { + return res, err + } - if amount != "0" { - // mimic invalid amount - if amount == "00" { - res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_AMOUNT) - res.Content = amount + balanceStr, err := server.CheckBalance(accountData["PublicKey"]) + if err != nil { + return res, err + } + res.Content = balanceStr - return res, nil - } + // Parse the balance + balanceParts := strings.Split(balanceStr, " ") + if len(balanceParts) != 2 { + return res, fmt.Errorf("unexpected balance format: %s", balanceStr) + } + balanceValue, err := strconv.ParseFloat(balanceParts[0], 64) + if err != nil { + return res, fmt.Errorf("failed to parse balance: %v", err) + } - res.Content = amount + // Parse the input amount + if amountStr != "0" { + inputAmount, err := strconv.ParseFloat(amountStr, 64) + if err != nil { + res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_AMOUNT) + res.Content = amountStr + return res, nil + } - accountData["Amount"] = amount + if inputAmount > balanceValue { + res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_AMOUNT) + res.Content = amountStr + return res, nil + } - err = h.accountFileHandler.WriteAccountData(accountData) - if err != nil { - return res, err - } + res.Content = amountStr + accountData["Amount"] = amountStr - return res, nil - } + err = h.accountFileHandler.WriteAccountData(accountData) + if err != nil { + return res, err + } - return res, nil + return res, nil + } + + return res, nil } func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) { From 2b10f6023f0efb91852d03568b6f4ced95a9835c Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Tue, 27 Aug 2024 16:10:43 +0300 Subject: [PATCH 2/3] Use the balance as the max_amount --- internal/handlers/ussd/menuhandler.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index df83592..de2e383 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -499,8 +499,17 @@ func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) { res := resource.Result{} - // mimic a max amount - res.Content = "10.00" + accountData, err := h.accountFileHandler.ReadAccountData() + if err != nil { + return res, err + } + + balance, err := server.CheckBalance(accountData["PublicKey"]) + if err != nil { + return res, nil + } + + res.Content = balance return res, nil } From 633d56b0adb6b283435f5995d30174219d3c74f1 Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Tue, 27 Aug 2024 16:16:15 +0300 Subject: [PATCH 3/3] Allow users to include 'CELO' in the amount --- internal/handlers/ussd/menuhandler.go | 100 +++++++++++++------------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index de2e383..53c5fe8 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "regexp" "strconv" "strings" @@ -389,11 +390,11 @@ func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (res res := resource.Result{} date := string(input) _, err := strconv.Atoi(date) - if err != nil { - // If conversion fails, input is not numeric - res.FlagSet = append(res.FlagSet, models.USERFLAG_INCORRECTDATEFORMAT) - return res, nil - } + if err != nil { + // If conversion fails, input is not numeric + res.FlagSet = append(res.FlagSet, models.USERFLAG_INCORRECTDATEFORMAT) + return res, nil + } if len(date) == 4 { res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTDATEFORMAT) @@ -515,59 +516,62 @@ func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (res } func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) { - res := resource.Result{} - amountStr := string(input) + res := resource.Result{} + amountStr := string(input) - accountData, err := h.accountFileHandler.ReadAccountData() - if err != nil { - return res, err - } + accountData, err := h.accountFileHandler.ReadAccountData() + if err != nil { + return res, err + } - balanceStr, err := server.CheckBalance(accountData["PublicKey"]) - if err != nil { - return res, err - } - res.Content = balanceStr + balanceStr, err := server.CheckBalance(accountData["PublicKey"]) + if err != nil { + return res, err + } + res.Content = balanceStr - // Parse the balance - balanceParts := strings.Split(balanceStr, " ") - if len(balanceParts) != 2 { - return res, fmt.Errorf("unexpected balance format: %s", balanceStr) - } - balanceValue, err := strconv.ParseFloat(balanceParts[0], 64) - if err != nil { - return res, fmt.Errorf("failed to parse balance: %v", err) - } + // Parse the balance + balanceParts := strings.Split(balanceStr, " ") + if len(balanceParts) != 2 { + return res, fmt.Errorf("unexpected balance format: %s", balanceStr) + } + balanceValue, err := strconv.ParseFloat(balanceParts[0], 64) + if err != nil { + return res, fmt.Errorf("failed to parse balance: %v", err) + } - // Parse the input amount - if amountStr != "0" { - inputAmount, err := strconv.ParseFloat(amountStr, 64) - if err != nil { - res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_AMOUNT) - res.Content = amountStr - return res, nil - } + // Extract numeric part from input + re := regexp.MustCompile(`^(\d+(\.\d+)?)\s*(?:CELO)?$`) + matches := re.FindStringSubmatch(strings.TrimSpace(amountStr)) + if len(matches) < 2 { + res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_AMOUNT) + res.Content = amountStr + return res, nil + } - if inputAmount > balanceValue { - res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_AMOUNT) - res.Content = amountStr - return res, nil - } + inputAmount, err := strconv.ParseFloat(matches[1], 64) + if err != nil { + res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_AMOUNT) + res.Content = amountStr + return res, nil + } - res.Content = amountStr - accountData["Amount"] = amountStr + if inputAmount > balanceValue { + res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_AMOUNT) + res.Content = amountStr + return res, nil + } - err = h.accountFileHandler.WriteAccountData(accountData) - if err != nil { - return res, err - } + res.Content = fmt.Sprintf("%.3f", inputAmount) // Format to 3 decimal places + accountData["Amount"] = res.Content - return res, nil - } + err = h.accountFileHandler.WriteAccountData(accountData) + if err != nil { + return res, err + } - return res, nil + return res, nil } - func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) { res := resource.Result{}