updated the file structure to have external functions on a different package
This commit is contained in:
		
							parent
							
								
									68dc77d5eb
								
							
						
					
					
						commit
						1a997e8b26
					
				
							
								
								
									
										820
									
								
								cmd/main.go
									
									
									
									
									
								
							
							
						
						
									
										820
									
								
								cmd/main.go
									
									
									
									
									
								
							| @ -1,774 +1,21 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"path" | ||||
| 	"regexp" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"git.defalsify.org/vise.git/cache" | ||||
| 	"git.defalsify.org/vise.git/engine" | ||||
| 	"git.defalsify.org/vise.git/lang" | ||||
| 	"git.defalsify.org/vise.git/persist" | ||||
| 	"git.defalsify.org/vise.git/resource" | ||||
| 	"git.defalsify.org/vise.git/state" | ||||
| 	"git.grassecon.net/urdt/ussd/internal/models" | ||||
| 	"git.grassecon.net/urdt/ussd/internal/server/handlers" | ||||
| 	"git.grassecon.net/urdt/ussd/internal/utils" | ||||
| 	"git.grassecon.net/urdt/ussd/internal/handlers/ussd" | ||||
| ) | ||||
| 
 | ||||
| type fsData struct { | ||||
| 	path string | ||||
| 	st   *state.State | ||||
| } | ||||
| 
 | ||||
| func codeFromCtx(ctx context.Context) string { | ||||
| 	var code string | ||||
| 	engine.Logg.DebugCtxf(ctx, "in msg", "ctx", ctx, "val", code) | ||||
| 	if ctx.Value("Language") != nil { | ||||
| 		lang := ctx.Value("Language").(lang.Language) | ||||
| 		code = lang.Code | ||||
| 	} | ||||
| 	return code | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) save_firstname(cxt context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if len(input) > 0 { | ||||
| 		name := string(input) | ||||
| 		accountData["FirstName"] = name | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) save_familyname(cxt context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if len(input) > 0 { | ||||
| 		//Save name
 | ||||
| 		secondname := string(input) | ||||
| 		accountData["FamilyName"] = secondname | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| func (fsd *fsData) save_yob(cxt context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if len(input) > 0 { | ||||
| 		yob := string(input) | ||||
| 		accountData["YOB"] = yob | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) save_location(cxt context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if len(input) > 0 { | ||||
| 		location := string(input) | ||||
| 		accountData["Location"] = location | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) save_gender(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if len(input) > 0 { | ||||
| 		gender := string(input) | ||||
| 
 | ||||
| 		switch gender { | ||||
| 		case "1": | ||||
| 			gender = "Male" | ||||
| 		case "2": | ||||
| 			gender = "Female" | ||||
| 		case "3": | ||||
| 			gender = "Other" | ||||
| 		} | ||||
| 		accountData["Gender"] = gender | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) save_offerings(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if len(input) > 0 { | ||||
| 		offerings := string(input) | ||||
| 		accountData["Offerings"] = offerings | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) set_language(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	inputStr := string(input) | ||||
| 	res := resource.Result{} | ||||
| 	switch inputStr { | ||||
| 	case "0": | ||||
| 		res.FlagSet = []uint32{state.FLAG_LANG} | ||||
| 		res.Content = "eng" | ||||
| 	case "1": | ||||
| 		res.FlagSet = []uint32{state.FLAG_LANG} | ||||
| 		res.Content = "swa" | ||||
| 	default: | ||||
| 	} | ||||
| 
 | ||||
| 	res.FlagSet = append(res.FlagSet, models.USERFLAG_LANGUAGE_SET) | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) create_account(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 	f, err := os.OpenFile(fp, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	f.Close() | ||||
| 	accountResp, err := handlers.CreateAccount() | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Failed to create account:", err) | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	accountData := map[string]string{ | ||||
| 		"TrackingId":  accountResp.Result.TrackingId, | ||||
| 		"PublicKey":   accountResp.Result.PublicKey, | ||||
| 		"CustodialId": accountResp.Result.CustodialId.String(), | ||||
| 		"Status":      "PENDING", | ||||
| 	} | ||||
| 
 | ||||
| 	jsonData, err := json.Marshal(accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	err = os.WriteFile(fp, jsonData, 0644) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_CREATED) | ||||
| 	return res, err | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) reset_unlock_for_update(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_UNLOCKFORUPDATE) | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) reset_account_unlocked(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_UNLOCKED) | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) check_identifier(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	res.Content = accountData["PublicKey"] | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) unlock(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	pin := string(input) | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	if len(input) > 1 { | ||||
| 		if pin != accountData["AccountPIN"] { | ||||
| 			res.FlagSet = append(res.FlagSet, models.USERFLAG_INCORRECTPIN) | ||||
| 			res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_UNLOCKED) | ||||
| 			return res, nil | ||||
| 		} | ||||
| 		if fsd.st.MatchFlag(models.USERFLAG_ACCOUNT_UNLOCKED, false) { | ||||
| 			res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTPIN) | ||||
| 			res.FlagSet = append(res.FlagSet, models.USERFLAG_UNLOCKFORUPDATE) | ||||
| 			res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_UNLOCKED) | ||||
| 		} else { | ||||
| 			res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_UNLOCKED) | ||||
| 		} | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) reset_incorrect_pin(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTPIN) | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) check_account_status(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	//status, err := checkAccountStatus(accountData["TrackingId"])
 | ||||
| 	status, err := handlers.CheckAccountStatus(accountData["TrackingId"]) | ||||
| 
 | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error checking account status:", err) | ||||
| 		return res, nil | ||||
| 	} | ||||
| 
 | ||||
| 	accountData["Status"] = status | ||||
| 
 | ||||
| 	if status == "SUCCESS" { | ||||
| 		res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_SUCCESS) | ||||
| 		res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_PENDING) | ||||
| 	} else { | ||||
| 		res.FlagReset = append(res.FlagSet, models.USERFLAG_ACCOUNT_SUCCESS) | ||||
| 		res.FlagSet = append(res.FlagReset, models.USERFLAG_ACCOUNT_PENDING) | ||||
| 	} | ||||
| 
 | ||||
| 	updatedJsonData, err := json.Marshal(accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) quit(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	switch codeFromCtx(ctx) { | ||||
| 	case "swa": | ||||
| 		res.Content = "Asante kwa kutumia huduma ya Sarafu. Kwaheri!" | ||||
| 	default: | ||||
| 		res.Content = "Thank you for using Sarafu. Goodbye!" | ||||
| 	} | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_UNLOCKED) | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) verify_yob(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	date := string(input) | ||||
| 
 | ||||
| 	dateRegex := regexp.MustCompile(`^\d{2}/\d{2}/\d{4}$`) | ||||
| 	isCorrectFormat := dateRegex.MatchString(date) | ||||
| 	if !isCorrectFormat { | ||||
| 		res.FlagSet = append(res.FlagSet, models.USERFLAG_INCORRECTDATEFORMAT) | ||||
| 	} else { | ||||
| 		res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTDATEFORMAT) | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) reset_incorrect_yob(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTDATEFORMAT) | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) check_balance(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 
 | ||||
| 	fp := fsd.path + "_data" | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	balance, err := handlers.CheckBalance(accountData["PublicKey"]) | ||||
| 	if err != nil { | ||||
| 		return res, nil | ||||
| 	} | ||||
| 	res.Content = balance | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) validate_recipient(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	recipient := string(input) | ||||
| 
 | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	if recipient != "0" { | ||||
| 		// mimic invalid number check
 | ||||
| 		if recipient == "000" { | ||||
| 			res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_RECIPIENT) | ||||
| 			res.Content = recipient | ||||
| 
 | ||||
| 			return res, nil | ||||
| 		} | ||||
| 
 | ||||
| 		accountData["Recipient"] = recipient | ||||
| 
 | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) transaction_reset(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	// reset the recipient
 | ||||
| 	accountData["Recipient"] = "" | ||||
| 
 | ||||
| 	updatedJsonData, err := json.Marshal(accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_INVALID_RECIPIENT, models.USERFLAG_INVALID_RECIPIENT_WITH_INVITE) | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) reset_transaction_amount(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	// reset the amount
 | ||||
| 	accountData["Amount"] = "" | ||||
| 
 | ||||
| 	updatedJsonData, err := json.Marshal(accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_INVALID_AMOUNT) | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) max_amount(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 
 | ||||
| 	// mimic a max amount
 | ||||
| 	res.Content = "10.00" | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) validate_amount(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	amount := string(input) | ||||
| 
 | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	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 | ||||
| 
 | ||||
| 			return res, nil | ||||
| 		} | ||||
| 
 | ||||
| 		res.Content = amount | ||||
| 
 | ||||
| 		accountData["Amount"] = amount | ||||
| 
 | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		return res, nil | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) get_recipient(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	res.Content = accountData["Recipient"] | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) get_profile_info(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	name := accountData["FirstName"] + " " + accountData["FamilyName"] | ||||
| 	gender := accountData["Gender"] | ||||
| 	yob := accountData["YOB"] | ||||
| 	location := accountData["Location"] | ||||
| 	offerings := accountData["Offerings"] | ||||
| 
 | ||||
| 	layout := "02/01/2006" | ||||
| 
 | ||||
| 	birthdate, err := time.Parse(layout, yob) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	currentDate := time.Now() | ||||
| 	formattedDate := currentDate.Format(layout) | ||||
| 	today, err := time.Parse(layout, formattedDate) | ||||
| 	if err != nil { | ||||
| 		return res, nil | ||||
| 	} | ||||
| 	age := utils.CalculateAge(birthdate, today) | ||||
| 
 | ||||
| 	formattedData := fmt.Sprintf("Name: %s\nGender: %s\nAge: %d\nLocation: %s\nYou provide: %s\n", name, gender, age, location, offerings) | ||||
| 	res.Content = formattedData | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) get_sender(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	res.Content = accountData["PublicKey"] | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) quit_with_balance(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	balance, err := handlers.CheckBalance(accountData["PublicKey"]) | ||||
| 	if err != nil { | ||||
| 		return res, nil | ||||
| 	} | ||||
| 	res.Content = fmt.Sprintf("Your account balance is: %s", balance) | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_UNLOCKED) | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) save_pin(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	accountPIN := string(input) | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	accountData["AccountPIN"] = accountPIN | ||||
| 
 | ||||
| 	updatedJsonData, err := json.Marshal(accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (fsd *fsData) verify_pin(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := fsd.path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	if bytes.Equal(input, []byte(accountData["AccountPIN"])) { | ||||
| 		res.FlagSet = []uint32{models.USERFLAG_VALIDPIN} | ||||
| 		res.FlagReset = []uint32{models.USERFLAG_PINMISMATCH} | ||||
| 	} else { | ||||
| 		res.FlagSet = []uint32{models.USERFLAG_PINMISMATCH} | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
| 	scriptDir = path.Join("services", "registration") | ||||
| ) | ||||
| @ -824,39 +71,38 @@ func main() { | ||||
| 	} | ||||
| 
 | ||||
| 	fp := path.Join(dp, sessionId) | ||||
| 	fs := &fsData{ | ||||
| 		path: fp, | ||||
| 		st:   &st, | ||||
| 	} | ||||
| 	rfs.AddLocalFunc("select_language", fs.set_language) | ||||
| 	rfs.AddLocalFunc("create_account", fs.create_account) | ||||
| 	rfs.AddLocalFunc("save_pin", fs.save_pin) | ||||
| 	rfs.AddLocalFunc("verify_pin", fs.verify_pin) | ||||
| 	rfs.AddLocalFunc("check_identifier", fs.check_identifier) | ||||
| 	rfs.AddLocalFunc("check_account_status", fs.check_account_status) | ||||
| 	rfs.AddLocalFunc("unlock_account", fs.unlock) | ||||
| 	rfs.AddLocalFunc("quit", fs.quit) | ||||
| 	rfs.AddLocalFunc("check_balance", fs.check_balance) | ||||
| 	rfs.AddLocalFunc("validate_recipient", fs.validate_recipient) | ||||
| 	rfs.AddLocalFunc("transaction_reset", fs.transaction_reset) | ||||
| 	rfs.AddLocalFunc("max_amount", fs.max_amount) | ||||
| 	rfs.AddLocalFunc("validate_amount", fs.validate_amount) | ||||
| 	rfs.AddLocalFunc("reset_transaction_amount", fs.reset_transaction_amount) | ||||
| 	rfs.AddLocalFunc("get_recipient", fs.get_recipient) | ||||
| 	rfs.AddLocalFunc("get_sender", fs.get_sender) | ||||
| 	rfs.AddLocalFunc("reset_incorrect", fs.reset_incorrect_pin) | ||||
| 	rfs.AddLocalFunc("save_firstname", fs.save_firstname) | ||||
| 	rfs.AddLocalFunc("save_familyname", fs.save_familyname) | ||||
| 	rfs.AddLocalFunc("save_gender", fs.save_gender) | ||||
| 	rfs.AddLocalFunc("save_location", fs.save_location) | ||||
| 	rfs.AddLocalFunc("save_yob", fs.save_yob) | ||||
| 	rfs.AddLocalFunc("save_offerings", fs.save_offerings) | ||||
| 	rfs.AddLocalFunc("quit_with_balance", fs.quit_with_balance) | ||||
| 	rfs.AddLocalFunc("reset_unlocked", fs.reset_account_unlocked) | ||||
| 	rfs.AddLocalFunc("reset_unlock_for_update", fs.reset_unlock_for_update) | ||||
| 	rfs.AddLocalFunc("get_profile_info", fs.get_profile_info) | ||||
| 	rfs.AddLocalFunc("verify_yob", fs.verify_yob) | ||||
| 	rfs.AddLocalFunc("reset_incorrect_date_format", fs.reset_incorrect_yob) | ||||
| 
 | ||||
| 	ussdHandlers := ussd.NewHandlers(fp, &st) | ||||
| 
 | ||||
| 	rfs.AddLocalFunc("select_language", ussdHandlers.SetLanguage) | ||||
| 	rfs.AddLocalFunc("create_account", ussdHandlers.CreateAccount) | ||||
| 	rfs.AddLocalFunc("save_pin", ussdHandlers.SavePin) | ||||
| 	rfs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin) | ||||
| 	rfs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier) | ||||
| 	rfs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus) | ||||
| 	rfs.AddLocalFunc("unlock_account", ussdHandlers.Unlock) | ||||
| 	rfs.AddLocalFunc("quit", ussdHandlers.Quit) | ||||
| 	rfs.AddLocalFunc("check_balance", ussdHandlers.CheckBalance) | ||||
| 	rfs.AddLocalFunc("validate_recipient", ussdHandlers.ValidateRecipient) | ||||
| 	rfs.AddLocalFunc("transaction_reset", ussdHandlers.TransactionReset) | ||||
| 	rfs.AddLocalFunc("max_amount", ussdHandlers.MaxAmount) | ||||
| 	rfs.AddLocalFunc("validate_amount", ussdHandlers.ValidateAmount) | ||||
| 	rfs.AddLocalFunc("reset_transaction_amount", ussdHandlers.ResetTransactionAmount) | ||||
| 	rfs.AddLocalFunc("get_recipient", ussdHandlers.GetRecipient) | ||||
| 	rfs.AddLocalFunc("get_sender", ussdHandlers.GetSender) | ||||
| 	rfs.AddLocalFunc("reset_incorrect", ussdHandlers.ResetIncorrectPin) | ||||
| 	rfs.AddLocalFunc("save_firstname", ussdHandlers.SaveFirstname) | ||||
| 	rfs.AddLocalFunc("save_familyname", ussdHandlers.SaveFamilyname) | ||||
| 	rfs.AddLocalFunc("save_gender", ussdHandlers.SaveGender) | ||||
| 	rfs.AddLocalFunc("save_location", ussdHandlers.SaveLocation) | ||||
| 	rfs.AddLocalFunc("save_yob", ussdHandlers.SaveYob) | ||||
| 	rfs.AddLocalFunc("save_offerings", ussdHandlers.SaveOfferings) | ||||
| 	rfs.AddLocalFunc("quit_with_balance", ussdHandlers.QuitWithBalance) | ||||
| 	rfs.AddLocalFunc("reset_unlocked", ussdHandlers.ResetAccountUnlocked) | ||||
| 	rfs.AddLocalFunc("reset_unlock_for_update", ussdHandlers.ResetUnlockForUpdate) | ||||
| 	rfs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo) | ||||
| 	rfs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob) | ||||
| 	rfs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob) | ||||
| 
 | ||||
| 	cont, err := en.Init(ctx) | ||||
| 	en.SetDebugger(engine.NewSimpleDebug(nil)) | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| package handlers | ||||
| package server | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| @ -9,7 +9,6 @@ import ( | ||||
| 	"git.grassecon.net/urdt/ussd/internal/models" | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| func CheckAccountStatus(trackingId string) (string, error) { | ||||
| 	resp, err := http.Get(config.TrackStatusURL + trackingId) | ||||
| 	if err != nil { | ||||
| @ -31,4 +30,4 @@ func CheckAccountStatus(trackingId string) (string, error) { | ||||
| 	status := trackResp.Result.Transaction.Status | ||||
| 
 | ||||
| 	return status, nil | ||||
| } | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| package handlers | ||||
| package server | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| @ -1,4 +1,4 @@ | ||||
| package handlers | ||||
| package server | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
							
								
								
									
										780
									
								
								internal/handlers/ussd/menuhandler.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										780
									
								
								internal/handlers/ussd/menuhandler.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,780 @@ | ||||
| package ussd | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"regexp" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"git.defalsify.org/vise.git/engine" | ||||
| 	"git.defalsify.org/vise.git/lang" | ||||
| 	"git.defalsify.org/vise.git/resource" | ||||
| 	"git.defalsify.org/vise.git/state" | ||||
| 	"git.grassecon.net/urdt/ussd/internal/models" | ||||
| 	"git.grassecon.net/urdt/ussd/internal/handlers/server" | ||||
| 	"git.grassecon.net/urdt/ussd/internal/utils" | ||||
| ) | ||||
| 
 | ||||
| type FSData struct { | ||||
| 	Path string | ||||
| 	St   *state.State | ||||
| } | ||||
| 
 | ||||
| type Handlers struct { | ||||
| 	fs *FSData | ||||
| } | ||||
| 
 | ||||
| func NewHandlers(path string, st *state.State) *Handlers { | ||||
| 	return &Handlers{ | ||||
| 		fs: &FSData{ | ||||
| 			Path: path, | ||||
| 			St:   st, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	inputStr := string(input) | ||||
| 	res := resource.Result{} | ||||
| 	switch inputStr { | ||||
| 	case "0": | ||||
| 		res.FlagSet = []uint32{state.FLAG_LANG} | ||||
| 		res.Content = "eng" | ||||
| 	case "1": | ||||
| 		res.FlagSet = []uint32{state.FLAG_LANG} | ||||
| 		res.Content = "swa" | ||||
| 	default: | ||||
| 	} | ||||
| 
 | ||||
| 	res.FlagSet = append(res.FlagSet, models.USERFLAG_LANGUAGE_SET) | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 	f, err := os.OpenFile(fp, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	f.Close() | ||||
| 	accountResp, err := server.CreateAccount() | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Failed to create account:", err) | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	accountData := map[string]string{ | ||||
| 		"TrackingId":  accountResp.Result.TrackingId, | ||||
| 		"PublicKey":   accountResp.Result.PublicKey, | ||||
| 		"CustodialId": accountResp.Result.CustodialId.String(), | ||||
| 		"Status":      "PENDING", | ||||
| 	} | ||||
| 
 | ||||
| 	jsonData, err := json.Marshal(accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	err = os.WriteFile(fp, jsonData, 0644) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_CREATED) | ||||
| 	return res, err | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	accountPIN := string(input) | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	accountData["AccountPIN"] = accountPIN | ||||
| 
 | ||||
| 	updatedJsonData, err := json.Marshal(accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	if bytes.Equal(input, []byte(accountData["AccountPIN"])) { | ||||
| 		res.FlagSet = []uint32{models.USERFLAG_VALIDPIN} | ||||
| 		res.FlagReset = []uint32{models.USERFLAG_PINMISMATCH} | ||||
| 	} else { | ||||
| 		res.FlagSet = []uint32{models.USERFLAG_PINMISMATCH} | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func codeFromCtx(ctx context.Context) string { | ||||
| 	var code string | ||||
| 	engine.Logg.DebugCtxf(ctx, "in msg", "ctx", ctx, "val", code) | ||||
| 	if ctx.Value("Language") != nil { | ||||
| 		lang := ctx.Value("Language").(lang.Language) | ||||
| 		code = lang.Code | ||||
| 	} | ||||
| 	return code | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) SaveFirstname(cxt context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if len(input) > 0 { | ||||
| 		name := string(input) | ||||
| 		accountData["FirstName"] = name | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) SaveFamilyname(cxt context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if len(input) > 0 { | ||||
| 		//Save name
 | ||||
| 		secondname := string(input) | ||||
| 		accountData["FamilyName"] = secondname | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) SaveYob(cxt context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if len(input) > 0 { | ||||
| 		yob := string(input) | ||||
| 		accountData["YOB"] = yob | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) SaveLocation(cxt context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if len(input) > 0 { | ||||
| 		location := string(input) | ||||
| 		accountData["Location"] = location | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if len(input) > 0 { | ||||
| 		gender := string(input) | ||||
| 
 | ||||
| 		switch gender { | ||||
| 		case "1": | ||||
| 			gender = "Male" | ||||
| 		case "2": | ||||
| 			gender = "Female" | ||||
| 		case "3": | ||||
| 			gender = "Other" | ||||
| 		} | ||||
| 		accountData["Gender"] = gender | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	if len(input) > 0 { | ||||
| 		offerings := string(input) | ||||
| 		accountData["Offerings"] = offerings | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) ResetUnlockForUpdate(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_UNLOCKFORUPDATE) | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) ResetAccountUnlocked(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_UNLOCKED) | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	res.Content = accountData["PublicKey"] | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) Unlock(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	pin := string(input) | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	if len(input) > 1 { | ||||
| 		if pin != accountData["AccountPIN"] { | ||||
| 			res.FlagSet = append(res.FlagSet, models.USERFLAG_INCORRECTPIN) | ||||
| 			res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_UNLOCKED) | ||||
| 			return res, nil | ||||
| 		} | ||||
| 		if h.fs.St.MatchFlag(models.USERFLAG_ACCOUNT_UNLOCKED, false) { | ||||
| 			res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTPIN) | ||||
| 			res.FlagSet = append(res.FlagSet, models.USERFLAG_UNLOCKFORUPDATE) | ||||
| 			res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_UNLOCKED) | ||||
| 		} else { | ||||
| 			res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_UNLOCKED) | ||||
| 		} | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) ResetIncorrectPin(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTPIN) | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	//status, err := checkAccountStatus(accountData["TrackingId"])
 | ||||
| 	status, err := server.CheckAccountStatus(accountData["TrackingId"]) | ||||
| 
 | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error checking account status:", err) | ||||
| 		return res, nil | ||||
| 	} | ||||
| 
 | ||||
| 	accountData["Status"] = status | ||||
| 
 | ||||
| 	if status == "SUCCESS" { | ||||
| 		res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_SUCCESS) | ||||
| 		res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_PENDING) | ||||
| 	} else { | ||||
| 		res.FlagReset = append(res.FlagSet, models.USERFLAG_ACCOUNT_SUCCESS) | ||||
| 		res.FlagSet = append(res.FlagReset, models.USERFLAG_ACCOUNT_PENDING) | ||||
| 	} | ||||
| 
 | ||||
| 	updatedJsonData, err := json.Marshal(accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) Quit(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	switch codeFromCtx(ctx) { | ||||
| 	case "swa": | ||||
| 		res.Content = "Asante kwa kutumia huduma ya Sarafu. Kwaheri!" | ||||
| 	default: | ||||
| 		res.Content = "Thank you for using Sarafu. Goodbye!" | ||||
| 	} | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_UNLOCKED) | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	date := string(input) | ||||
| 
 | ||||
| 	dateRegex := regexp.MustCompile(`^\d{2}/\d{2}/\d{4}$`) | ||||
| 	isCorrectFormat := dateRegex.MatchString(date) | ||||
| 	if !isCorrectFormat { | ||||
| 		res.FlagSet = append(res.FlagSet, models.USERFLAG_INCORRECTDATEFORMAT) | ||||
| 	} else { | ||||
| 		res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTDATEFORMAT) | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) ResetIncorrectYob(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_INCORRECTDATEFORMAT) | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 
 | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	balance, err := server.CheckBalance(accountData["PublicKey"]) | ||||
| 	if err != nil { | ||||
| 		return res, nil | ||||
| 	} | ||||
| 	res.Content = balance | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	recipient := string(input) | ||||
| 
 | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	if recipient != "0" { | ||||
| 		// mimic invalid number check
 | ||||
| 		if recipient == "000" { | ||||
| 			res.FlagSet = append(res.FlagSet, models.USERFLAG_INVALID_RECIPIENT) | ||||
| 			res.Content = recipient | ||||
| 
 | ||||
| 			return res, nil | ||||
| 		} | ||||
| 
 | ||||
| 		accountData["Recipient"] = recipient | ||||
| 
 | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	// reset the recipient
 | ||||
| 	accountData["Recipient"] = "" | ||||
| 
 | ||||
| 	updatedJsonData, err := json.Marshal(accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_INVALID_RECIPIENT, models.USERFLAG_INVALID_RECIPIENT_WITH_INVITE) | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	// reset the amount
 | ||||
| 	accountData["Amount"] = "" | ||||
| 
 | ||||
| 	updatedJsonData, err := json.Marshal(accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_INVALID_AMOUNT) | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| 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" | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	amount := string(input) | ||||
| 
 | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	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 | ||||
| 
 | ||||
| 			return res, nil | ||||
| 		} | ||||
| 
 | ||||
| 		res.Content = amount | ||||
| 
 | ||||
| 		accountData["Amount"] = amount | ||||
| 
 | ||||
| 		updatedJsonData, err := json.Marshal(accountData) | ||||
| 		if err != nil { | ||||
| 			return res, err | ||||
| 		} | ||||
| 
 | ||||
| 		err = os.WriteFile(fp, updatedJsonData, 0644) | ||||
| 		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{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	res.Content = accountData["Recipient"] | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) GetProfileInfo(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	name := accountData["FirstName"] + " " + accountData["FamilyName"] | ||||
| 	gender := accountData["Gender"] | ||||
| 	yob := accountData["YOB"] | ||||
| 	location := accountData["Location"] | ||||
| 	offerings := accountData["Offerings"] | ||||
| 
 | ||||
| 	layout := "02/01/2006" | ||||
| 
 | ||||
| 	birthdate, err := time.Parse(layout, yob) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	currentDate := time.Now() | ||||
| 	formattedDate := currentDate.Format(layout) | ||||
| 	today, err := time.Parse(layout, formattedDate) | ||||
| 	if err != nil { | ||||
| 		return res, nil | ||||
| 	} | ||||
| 	age := utils.CalculateAge(birthdate, today) | ||||
| 
 | ||||
| 	formattedData := fmt.Sprintf("Name: %s\nGender: %s\nAge: %d\nLocation: %s\nYou provide: %s\n", name, gender, age, location, offerings) | ||||
| 	res.Content = formattedData | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	res.Content = accountData["PublicKey"] | ||||
| 
 | ||||
| 	return res, nil | ||||
| } | ||||
| 
 | ||||
| func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) { | ||||
| 	res := resource.Result{} | ||||
| 	fp := h.fs.Path + "_data" | ||||
| 
 | ||||
| 	jsonData, err := os.ReadFile(fp) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	var accountData map[string]string | ||||
| 	err = json.Unmarshal(jsonData, &accountData) | ||||
| 	if err != nil { | ||||
| 		return res, err | ||||
| 	} | ||||
| 	balance, err := server.CheckBalance(accountData["PublicKey"]) | ||||
| 	if err != nil { | ||||
| 		return res, nil | ||||
| 	} | ||||
| 	res.Content = fmt.Sprintf("Your account balance is: %s", balance) | ||||
| 	res.FlagReset = append(res.FlagReset, models.USERFLAG_ACCOUNT_UNLOCKED) | ||||
| 	return res, nil | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user