forked from grassrootseconomics/visedriver
		
	Compare commits
	
		
			29 Commits
		
	
	
		
			master
			...
			menu-optio
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bb28112f47 | |||
| 5b5352f569 | |||
| e3e8bfe85c | |||
| 10c917b6da | |||
| 7c7150b103 | |||
| 99fcb9706e | |||
| 67062a41ad | |||
| 123fdec009 | |||
| 20694d956b | |||
| 10abad9e59 | |||
| ca366ee2bc | |||
| c7f0ddec9b | |||
| 2fe4ada5d3 | |||
| b0342936e1 | |||
| 63d060afe2 | |||
| 92d212f891 | |||
| b25288db2c | |||
| 5aed7c647f | |||
| 8765077177 | |||
| 4a6e4ebe55 | |||
| 525eee93d4 | |||
| 0c3ef357df | |||
| c2d2bd250a | |||
| cb2254664d | |||
| f010d097ed | |||
| c5fcb79e9e | |||
| cb77e44cbd | |||
| 4d7c584394 | |||
| 5ff06e8626 | 
@ -71,6 +71,9 @@ func getHandler(appFlags *asm.FlagParser, rs *resource.DbResource, pe *persist.P
 | 
				
			|||||||
	rs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob)
 | 
						rs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob)
 | 
				
			||||||
	rs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit)
 | 
						rs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit)
 | 
				
			||||||
	rs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction)
 | 
						rs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction)
 | 
				
			||||||
 | 
						rs.AddLocalFunc("quit_with_help", ussdHandlers.QuitWithHelp)
 | 
				
			||||||
 | 
						rs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin)
 | 
				
			||||||
 | 
						rs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ussdHandlers, nil
 | 
						return ussdHandlers, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										3
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								go.mod
									
									
									
									
									
								
							@ -5,9 +5,12 @@ go 1.22.6
 | 
				
			|||||||
require (
 | 
					require (
 | 
				
			||||||
	git.defalsify.org/vise.git v0.1.0-rc.3.0.20240911162138-1f2af8672dc7
 | 
						git.defalsify.org/vise.git v0.1.0-rc.3.0.20240911162138-1f2af8672dc7
 | 
				
			||||||
	github.com/alecthomas/assert/v2 v2.2.2
 | 
						github.com/alecthomas/assert/v2 v2.2.2
 | 
				
			||||||
 | 
						github.com/peteole/testdata-loader v0.3.0
 | 
				
			||||||
	gopkg.in/leonelquinteros/gotext.v1 v1.3.1
 | 
						gopkg.in/leonelquinteros/gotext.v1 v1.3.1
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require gopkg.in/dnaeon/go-vcr.v4 v4.0.1 // indirect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/alecthomas/participle/v2 v2.0.0 // indirect
 | 
						github.com/alecthomas/participle/v2 v2.0.0 // indirect
 | 
				
			||||||
	github.com/alecthomas/repr v0.2.0 // indirect
 | 
						github.com/alecthomas/repr v0.2.0 // indirect
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							@ -30,6 +30,8 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
 | 
				
			|||||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
 | 
					github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
 | 
				
			||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 | 
					gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 | 
				
			||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
					gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
				
			||||||
 | 
					gopkg.in/dnaeon/go-vcr.v4 v4.0.1 h1:dIFuOqqDZIJ9BTcK+DXmElzypQ6PV9fBQZSIwY+J1yM=
 | 
				
			||||||
 | 
					gopkg.in/dnaeon/go-vcr.v4 v4.0.1/go.mod h1:65yxh9goQVrudqofKtHA4JNFWd6XZRkWfKN4YpMx7KI=
 | 
				
			||||||
gopkg.in/leonelquinteros/gotext.v1 v1.3.1 h1:8d9/fdTG0kn/B7NNGV1BsEyvektXFAbkMsTZS2sFSCc=
 | 
					gopkg.in/leonelquinteros/gotext.v1 v1.3.1 h1:8d9/fdTG0kn/B7NNGV1BsEyvektXFAbkMsTZS2sFSCc=
 | 
				
			||||||
gopkg.in/leonelquinteros/gotext.v1 v1.3.1/go.mod h1:X1WlGDeAFIYsW6GjgMm4VwUwZ2XjI7Zan2InxSUQWrU=
 | 
					gopkg.in/leonelquinteros/gotext.v1 v1.3.1/go.mod h1:X1WlGDeAFIYsW6GjgMm4VwUwZ2XjI7Zan2InxSUQWrU=
 | 
				
			||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 | 
					gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 | 
				
			||||||
 | 
				
			|||||||
@ -16,10 +16,9 @@ type AccountServiceInterface interface {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AccountService struct {
 | 
					type AccountService struct {
 | 
				
			||||||
 | 
						Client *http.Client
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// CheckAccountStatus retrieves the status of an account transaction based on the provided tracking ID.
 | 
					// CheckAccountStatus retrieves the status of an account transaction based on the provided tracking ID.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Parameters:
 | 
					// Parameters:
 | 
				
			||||||
@ -27,14 +26,12 @@ type AccountService struct {
 | 
				
			|||||||
//     CreateAccount or a similar function that returns an AccountResponse. The `trackingId` field in the
 | 
					//     CreateAccount or a similar function that returns an AccountResponse. The `trackingId` field in the
 | 
				
			||||||
//     AccountResponse struct can be used here to check the account status during a transaction.
 | 
					//     AccountResponse struct can be used here to check the account status during a transaction.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Returns:
 | 
					// Returns:
 | 
				
			||||||
//   - string: The status of the transaction as a string. If there is an error during the request or processing, this will be an empty string.
 | 
					//   - string: The status of the transaction as a string. If there is an error during the request or processing, this will be an empty string.
 | 
				
			||||||
//   - error: An error if any occurred during the HTTP request, reading the response, or unmarshalling the JSON data.
 | 
					//   - error: An error if any occurred during the HTTP request, reading the response, or unmarshalling the JSON data.
 | 
				
			||||||
//     If no error occurs, this will be nil.
 | 
					//     If no error occurs, this will be nil.
 | 
				
			||||||
//
 | 
					 | 
				
			||||||
func (as *AccountService) CheckAccountStatus(trackingId string) (string, error) {
 | 
					func (as *AccountService) CheckAccountStatus(trackingId string) (string, error) {
 | 
				
			||||||
	resp, err := http.Get(config.TrackStatusURL + trackingId)
 | 
						resp, err := as.Client.Get(config.TrackStatusURL + trackingId)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", err
 | 
							return "", err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -50,18 +47,15 @@ func (as *AccountService) CheckAccountStatus(trackingId string) (string, error)
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", err
 | 
							return "", err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	status := trackResp.Result.Transaction.Status
 | 
						status := trackResp.Result.Transaction.Status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return status, nil
 | 
						return status, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
// CheckBalance retrieves the balance for a given public key from the custodial balance API endpoint.
 | 
					// CheckBalance retrieves the balance for a given public key from the custodial balance API endpoint.
 | 
				
			||||||
// Parameters:
 | 
					// Parameters:
 | 
				
			||||||
//   - publicKey: The public key associated with the account whose balance needs to be checked.
 | 
					//   - publicKey: The public key associated with the account whose balance needs to be checked.
 | 
				
			||||||
func (as *AccountService) CheckBalance(publicKey string) (string, error) {
 | 
					func (as *AccountService) CheckBalance(publicKey string) (string, error) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
	resp, err := http.Get(config.BalanceURL + publicKey)
 | 
						resp, err := http.Get(config.BalanceURL + publicKey)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "0.0", err
 | 
							return "0.0", err
 | 
				
			||||||
@ -83,15 +77,14 @@ func (as *AccountService) CheckBalance(publicKey string) (string, error) {
 | 
				
			|||||||
	return balance, nil
 | 
						return balance, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CreateAccount creates a new account in the custodial system.
 | 
				
			||||||
//CreateAccount creates a new account in the custodial system.
 | 
					 | 
				
			||||||
// Returns:
 | 
					// Returns:
 | 
				
			||||||
//   - *models.AccountResponse: A pointer to an AccountResponse struct containing the details of the created account.
 | 
					//   - *models.AccountResponse: A pointer to an AccountResponse struct containing the details of the created account.
 | 
				
			||||||
//     If there is an error during the request or processing, this will be nil.
 | 
					//     If there is an error during the request or processing, this will be nil.
 | 
				
			||||||
//   - error: An error if any occurred during the HTTP request, reading the response, or unmarshalling the JSON data.
 | 
					//   - error: An error if any occurred during the HTTP request, reading the response, or unmarshalling the JSON data.
 | 
				
			||||||
//     If no error occurs, this will be nil.
 | 
					//     If no error occurs, this will be nil.
 | 
				
			||||||
func (as *AccountService) CreateAccount() (*models.AccountResponse, error) {
 | 
					func (as *AccountService) CreateAccount() (*models.AccountResponse, error) {
 | 
				
			||||||
	resp, err := http.Post(config.CreateAccountURL, "application/json", nil)
 | 
						resp, err := as.Client.Post(config.CreateAccountURL, "application/json", nil)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -107,6 +100,5 @@ func (as *AccountService) CreateAccount() (*models.AccountResponse, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &accountResp, nil
 | 
						return &accountResp, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
@ -73,10 +74,13 @@ func NewHandlers(appFlags *asm.FlagParser, userdataStore db.Db) (*Handlers, erro
 | 
				
			|||||||
	userDb := &utils.UserDataStore{
 | 
						userDb := &utils.UserDataStore{
 | 
				
			||||||
		Db: userdataStore,
 | 
							Db: userdataStore,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						client := &http.Client{}
 | 
				
			||||||
	h := &Handlers{
 | 
						h := &Handlers{
 | 
				
			||||||
		userdataStore:      userDb,
 | 
							userdataStore: userDb,
 | 
				
			||||||
		flagManager:        appFlags,
 | 
							flagManager:   appFlags,
 | 
				
			||||||
		accountService:     &server.AccountService{},
 | 
							accountService: &server.AccountService{
 | 
				
			||||||
 | 
								Client: client,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return h, nil
 | 
						return h, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -188,6 +192,48 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
 | 
				
			|||||||
	return res, nil
 | 
						return res, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handlers) SaveTemporaryPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | 
				
			||||||
 | 
						var res resource.Result
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sessionId, ok := ctx.Value("SessionId").(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return res, fmt.Errorf("missing session")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						accountPIN := string(input)
 | 
				
			||||||
 | 
						// Validate that the PIN is a 4-digit number
 | 
				
			||||||
 | 
						if !isValidPIN(accountPIN) {
 | 
				
			||||||
 | 
							res.FlagSet = append(res.FlagSet, flag_incorrect_pin)
 | 
				
			||||||
 | 
							return res, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						store := h.userdataStore
 | 
				
			||||||
 | 
						err = store.WriteEntry(ctx, sessionId, utils.DATA_TEMPORARY_PIN, []byte(accountPIN))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return res, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return res, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handlers) ConfirmPinChange(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | 
				
			||||||
 | 
						var res resource.Result
 | 
				
			||||||
 | 
						sessionId, ok := ctx.Value("SessionId").(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return res, fmt.Errorf("missing session")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						store := h.userdataStore
 | 
				
			||||||
 | 
						temporaryPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_TEMPORARY_PIN)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return res, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err = store.WriteEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN, []byte(temporaryPin))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return res, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return res, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SavePin persists the user's PIN choice into the filesystem
 | 
					// SavePin persists the user's PIN choice into the filesystem
 | 
				
			||||||
func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | 
					func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | 
				
			||||||
	var res resource.Result
 | 
						var res resource.Result
 | 
				
			||||||
@ -256,15 +302,19 @@ func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (res
 | 
				
			|||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return res, fmt.Errorf("missing session")
 | 
							return res, fmt.Errorf("missing session")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	//AccountPin, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
 | 
					 | 
				
			||||||
	store := h.userdataStore
 | 
						store := h.userdataStore
 | 
				
			||||||
	AccountPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN)
 | 
						AccountPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return res, err
 | 
							return res, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						TemporaryPIn, err := store.ReadEntry(ctx, sessionId, utils.DATA_TEMPORARY_PIN)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if !db.IsNotFound(err) {
 | 
				
			||||||
 | 
								return res, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if bytes.Equal(input, AccountPin) {
 | 
						if bytes.Equal(input, AccountPin) || bytes.Equal(input, TemporaryPIn) {
 | 
				
			||||||
		res.FlagSet = []uint32{flag_valid_pin}
 | 
							res.FlagSet = []uint32{flag_valid_pin}
 | 
				
			||||||
		res.FlagReset = []uint32{flag_pin_mismatch}
 | 
							res.FlagReset = []uint32{flag_pin_mismatch}
 | 
				
			||||||
		res.FlagSet = append(res.FlagSet, flag_pin_set)
 | 
							res.FlagSet = append(res.FlagSet, flag_pin_set)
 | 
				
			||||||
@ -481,22 +531,19 @@ func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (res
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return res, err
 | 
							return res, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if len(input) == 4 {
 | 
				
			||||||
	if err == nil {
 | 
							if bytes.Equal(input, AccountPin) {
 | 
				
			||||||
		if len(input) == 4 {
 | 
								if h.st.MatchFlag(flag_account_authorized, false) {
 | 
				
			||||||
			if bytes.Equal(input, AccountPin) {
 | 
									res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
 | 
				
			||||||
				if h.st.MatchFlag(flag_account_authorized, false) {
 | 
									res.FlagSet = append(res.FlagSet, flag_allow_update, flag_account_authorized)
 | 
				
			||||||
					res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
 | 
					 | 
				
			||||||
					res.FlagSet = append(res.FlagSet, flag_allow_update, flag_account_authorized)
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					res.FlagSet = append(res.FlagSet, flag_allow_update)
 | 
					 | 
				
			||||||
					res.FlagReset = append(res.FlagReset, flag_account_authorized)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				res.FlagSet = append(res.FlagSet, flag_incorrect_pin)
 | 
									res.FlagSet = append(res.FlagSet, flag_allow_update)
 | 
				
			||||||
				res.FlagReset = append(res.FlagReset, flag_account_authorized)
 | 
									res.FlagReset = append(res.FlagReset, flag_account_authorized)
 | 
				
			||||||
				return res, nil
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								res.FlagSet = append(res.FlagSet, flag_incorrect_pin)
 | 
				
			||||||
 | 
								res.FlagReset = append(res.FlagReset, flag_account_authorized)
 | 
				
			||||||
 | 
								return res, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return res, nil
 | 
							return res, nil
 | 
				
			||||||
@ -543,7 +590,6 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return res, nil
 | 
							return res, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if status == "SUCCESS" {
 | 
						if status == "SUCCESS" {
 | 
				
			||||||
		res.FlagSet = append(res.FlagSet, flag_account_success)
 | 
							res.FlagSet = append(res.FlagSet, flag_account_success)
 | 
				
			||||||
		res.FlagReset = append(res.FlagReset, flag_account_pending)
 | 
							res.FlagReset = append(res.FlagReset, flag_account_pending)
 | 
				
			||||||
@ -569,6 +615,21 @@ func (h *Handlers) Quit(ctx context.Context, sym string, input []byte) (resource
 | 
				
			|||||||
	return res, nil
 | 
						return res, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// QuitWithHelp displays helpline information then exits the menu
 | 
				
			||||||
 | 
					func (h *Handlers) QuitWithHelp(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | 
				
			||||||
 | 
						var res resource.Result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						code := codeFromCtx(ctx)
 | 
				
			||||||
 | 
						l := gotext.NewLocale(translationDir, code)
 | 
				
			||||||
 | 
						l.AddDomain("default")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.Content = l.Get("For more help,please call: 0757628885")
 | 
				
			||||||
 | 
						res.FlagReset = append(res.FlagReset, flag_account_authorized)
 | 
				
			||||||
 | 
						return res, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// VerifyYob verifies the length of the given input
 | 
					// VerifyYob verifies the length of the given input
 | 
				
			||||||
func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | 
					func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 | 
				
			||||||
	var res resource.Result
 | 
						var res resource.Result
 | 
				
			||||||
@ -748,7 +809,8 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
 | 
						flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
 | 
						store := h.userdataStore
 | 
				
			||||||
 | 
						publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	amountStr := string(input)
 | 
						amountStr := string(input)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -757,6 +819,7 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return res, err
 | 
							return res, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res.Content = balanceStr
 | 
						res.Content = balanceStr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Parse the balance
 | 
						// Parse the balance
 | 
				
			||||||
@ -764,6 +827,7 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 | 
				
			|||||||
	if len(balanceParts) != 2 {
 | 
						if len(balanceParts) != 2 {
 | 
				
			||||||
		return res, fmt.Errorf("unexpected balance format: %s", balanceStr)
 | 
							return res, fmt.Errorf("unexpected balance format: %s", balanceStr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	balanceValue, err := strconv.ParseFloat(balanceParts[0], 64)
 | 
						balanceValue, err := strconv.ParseFloat(balanceParts[0], 64)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return res, fmt.Errorf("failed to parse balance: %v", err)
 | 
							return res, fmt.Errorf("failed to parse balance: %v", err)
 | 
				
			||||||
@ -773,6 +837,7 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 | 
				
			|||||||
	re := regexp.MustCompile(`^(\d+(\.\d+)?)\s*(?:CELO)?$`)
 | 
						re := regexp.MustCompile(`^(\d+(\.\d+)?)\s*(?:CELO)?$`)
 | 
				
			||||||
	matches := re.FindStringSubmatch(strings.TrimSpace(amountStr))
 | 
						matches := re.FindStringSubmatch(strings.TrimSpace(amountStr))
 | 
				
			||||||
	if len(matches) < 2 {
 | 
						if len(matches) < 2 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		res.FlagSet = append(res.FlagSet, flag_invalid_amount)
 | 
							res.FlagSet = append(res.FlagSet, flag_invalid_amount)
 | 
				
			||||||
		res.Content = amountStr
 | 
							res.Content = amountStr
 | 
				
			||||||
		return res, nil
 | 
							return res, nil
 | 
				
			||||||
@ -780,6 +845,7 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	inputAmount, err := strconv.ParseFloat(matches[1], 64)
 | 
						inputAmount, err := strconv.ParseFloat(matches[1], 64)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		res.FlagSet = append(res.FlagSet, flag_invalid_amount)
 | 
							res.FlagSet = append(res.FlagSet, flag_invalid_amount)
 | 
				
			||||||
		res.Content = amountStr
 | 
							res.Content = amountStr
 | 
				
			||||||
		return res, nil
 | 
							return res, nil
 | 
				
			||||||
@ -792,7 +858,7 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res.Content = fmt.Sprintf("%.3f", inputAmount) // Format to 3 decimal places
 | 
						res.Content = fmt.Sprintf("%.3f", inputAmount) // Format to 3 decimal places
 | 
				
			||||||
	store := h.userdataStore
 | 
						store = h.userdataStore
 | 
				
			||||||
	err = store.WriteEntry(ctx, sessionId, utils.DATA_AMOUNT, []byte(amountStr))
 | 
						err = store.WriteEntry(ctx, sessionId, utils.DATA_AMOUNT, []byte(amountStr))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return res, err
 | 
							return res, err
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,10 +1,7 @@
 | 
				
			|||||||
package utils
 | 
					package utils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"encoding/binary"
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"git.defalsify.org/vise.git/db"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type DataTyp uint16
 | 
					type DataTyp uint16
 | 
				
			||||||
@ -25,6 +22,7 @@ const (
 | 
				
			|||||||
	DATA_OFFERINGS
 | 
						DATA_OFFERINGS
 | 
				
			||||||
	DATA_RECIPIENT
 | 
						DATA_RECIPIENT
 | 
				
			||||||
	DATA_AMOUNT
 | 
						DATA_AMOUNT
 | 
				
			||||||
 | 
						DATA_TEMPORARY_PIN
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func typToBytes(typ DataTyp) []byte {
 | 
					func typToBytes(typ DataTyp) []byte {
 | 
				
			||||||
@ -37,21 +35,3 @@ func PackKey(typ DataTyp, data []byte) []byte {
 | 
				
			|||||||
	v := typToBytes(typ)
 | 
						v := typToBytes(typ)
 | 
				
			||||||
	return append(v, data...)
 | 
						return append(v, data...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func ReadEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp) ([]byte, error) {
 | 
					 | 
				
			||||||
	store.SetPrefix(db.DATATYPE_USERDATA)
 | 
					 | 
				
			||||||
	store.SetSession(sessionId)
 | 
					 | 
				
			||||||
	k := PackKey(typ, []byte(sessionId))
 | 
					 | 
				
			||||||
	b, err := store.Get(ctx, k)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func WriteEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp, value []byte) error {
 | 
					 | 
				
			||||||
	store.SetPrefix(db.DATATYPE_USERDATA)
 | 
					 | 
				
			||||||
	store.SetSession(sessionId)
 | 
					 | 
				
			||||||
	k := PackKey(typ, []byte(sessionId))
 | 
					 | 
				
			||||||
	return store.Put(ctx, k, value)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								services/registration/confirm_pin_change
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								services/registration/confirm_pin_change
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					Confirm your new PIN:
 | 
				
			||||||
							
								
								
									
										7
									
								
								services/registration/confirm_pin_change.vis
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								services/registration/confirm_pin_change.vis
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					LOAD verify_pin 0
 | 
				
			||||||
 | 
					MOUT back 0
 | 
				
			||||||
 | 
					HALT
 | 
				
			||||||
 | 
					RELOAD verify_pin
 | 
				
			||||||
 | 
					CATCH  create_pin_mismatch flag_pin_mismatch 1
 | 
				
			||||||
 | 
					MOVE pin_reset_success
 | 
				
			||||||
 | 
					INCMP _ 0
 | 
				
			||||||
							
								
								
									
										2
									
								
								services/registration/help.vis
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								services/registration/help.vis
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					LOAD quit_with_help 0
 | 
				
			||||||
 | 
					HALT
 | 
				
			||||||
							
								
								
									
										1
									
								
								services/registration/invalid_pin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								services/registration/invalid_pin
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					The PIN you entered is invalid.The PIN must be different from your current PIN.For help call +254757628885
 | 
				
			||||||
							
								
								
									
										4
									
								
								services/registration/invalid_pin.vis
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								services/registration/invalid_pin.vis
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					MOUT back 0
 | 
				
			||||||
 | 
					HALT
 | 
				
			||||||
 | 
					INCMP _ 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -6,3 +6,6 @@ msgstr "Ombi lako limetumwa. %s atapokea %s kutoka kwa %s."
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
msgid "Thank you for using Sarafu. Goodbye!"
 | 
					msgid "Thank you for using Sarafu. Goodbye!"
 | 
				
			||||||
msgstr "Asante kwa kutumia huduma ya Sarafu. Kwaheri!"
 | 
					msgstr "Asante kwa kutumia huduma ya Sarafu. Kwaheri!"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "For more help,please call: 0757628885"
 | 
				
			||||||
 | 
					msgstr "Kwa usaidizi zaidi,piga: 0757628885"
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,6 @@ HALT
 | 
				
			|||||||
INCMP send 1
 | 
					INCMP send 1
 | 
				
			||||||
INCMP quit 2
 | 
					INCMP quit 2
 | 
				
			||||||
INCMP my_account 3
 | 
					INCMP my_account 3
 | 
				
			||||||
INCMP quit 4
 | 
					INCMP help 4
 | 
				
			||||||
INCMP quit 9
 | 
					INCMP quit 9
 | 
				
			||||||
INCMP . *
 | 
					INCMP . *
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								services/registration/new_pin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								services/registration/new_pin
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					Enter a new four number pin
 | 
				
			||||||
							
								
								
									
										7
									
								
								services/registration/new_pin.vis
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								services/registration/new_pin.vis
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					LOAD save_temporary_pin 0
 | 
				
			||||||
 | 
					MOUT back 0
 | 
				
			||||||
 | 
					HALT
 | 
				
			||||||
 | 
					RELOAD save_temporary_pin
 | 
				
			||||||
 | 
					CATCH invalid_pin flag_incorrect_pin 1
 | 
				
			||||||
 | 
					INCMP _ 0
 | 
				
			||||||
 | 
					MOVE confirm_pin_change 
 | 
				
			||||||
							
								
								
									
										1
									
								
								services/registration/old_pin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								services/registration/old_pin
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					Enter your old PIN
 | 
				
			||||||
							
								
								
									
										9
									
								
								services/registration/old_pin.vis
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								services/registration/old_pin.vis
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					LOAD authorize_account 6
 | 
				
			||||||
 | 
					MOUT back 0
 | 
				
			||||||
 | 
					HALT
 | 
				
			||||||
 | 
					RELOAD authorize_account
 | 
				
			||||||
 | 
					CATCH incorrect_pin flag_incorrect_pin 1
 | 
				
			||||||
 | 
					MOVE new_pin
 | 
				
			||||||
 | 
					INCMP _ 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -4,3 +4,4 @@ MOUT guard_pin 3
 | 
				
			|||||||
MOUT back 0
 | 
					MOUT back 0
 | 
				
			||||||
HALT
 | 
					HALT
 | 
				
			||||||
INCMP _ 0
 | 
					INCMP _ 0
 | 
				
			||||||
 | 
					INCMP old_pin  1
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								services/registration/pin_reset_success
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								services/registration/pin_reset_success
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					Your PIN change request has been successful
 | 
				
			||||||
							
								
								
									
										6
									
								
								services/registration/pin_reset_success.vis
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								services/registration/pin_reset_success.vis
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					LOAD confirm_pin_change 0
 | 
				
			||||||
 | 
					MOUT back 0
 | 
				
			||||||
 | 
					MOUT quit 9
 | 
				
			||||||
 | 
					HALT
 | 
				
			||||||
 | 
					INCMP _ 0
 | 
				
			||||||
 | 
					INCMP quit 9
 | 
				
			||||||
@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					LOAD authorize_account 6
 | 
				
			||||||
MAP validate_amount
 | 
					MAP validate_amount
 | 
				
			||||||
RELOAD get_recipient
 | 
					RELOAD get_recipient
 | 
				
			||||||
MAP get_recipient
 | 
					MAP get_recipient
 | 
				
			||||||
@ -6,9 +7,9 @@ MAP get_sender
 | 
				
			|||||||
MOUT back 0
 | 
					MOUT back 0
 | 
				
			||||||
MOUT quit 9
 | 
					MOUT quit 9
 | 
				
			||||||
HALT
 | 
					HALT
 | 
				
			||||||
LOAD authorize_account 6
 | 
					 | 
				
			||||||
RELOAD authorize_account
 | 
					RELOAD authorize_account
 | 
				
			||||||
CATCH incorrect_pin flag_incorrect_pin 1
 | 
					CATCH incorrect_pin flag_incorrect_pin 1
 | 
				
			||||||
 | 
					CATCH transaction_initiated flag_account_authorized 1
 | 
				
			||||||
INCMP _ 0
 | 
					INCMP _ 0
 | 
				
			||||||
INCMP quit 9
 | 
					INCMP quit 9
 | 
				
			||||||
INCMP transaction_initiated *
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user