Compare commits

..

97 Commits

Author SHA1 Message Date
alfred-mk
d2384d3429 Serve the menu on an HTTP server 2024-09-10 13:48:37 +03:00
Carlosokumu
47d39a1c6f remove commented test 2024-09-09 17:24:43 +03:00
Carlosokumu
f5f1cbaaba cleanup 2024-09-09 17:18:07 +03:00
Carlosokumu
134aa96194 implement db for user datastore 2024-09-09 17:16:08 +03:00
Carlosokumu
0cdb23fbea setupmock for user datastore 2024-09-09 17:15:35 +03:00
Carlosokumu
ca655b0cdc add tests 2024-09-09 17:15:04 +03:00
Carlosokumu
da93444d3f remove deprecated code 2024-09-09 10:14:40 +03:00
Carlosokumu
c2564a9b8f remove go-vise subdirectory 2024-09-09 10:12:29 +03:00
Carlosokumu
33c6b35f8f Merge branch 'origin/master' into wip-code-check 2024-09-09 09:56:00 +03:00
Carlosokumu
ba72b3bf44 Merge branch 'master' into wip-code-check 2024-09-09 09:45:29 +03:00
Carlosokumu
e961b6cb6a Merge branch 'wip-code-check' 2024-09-09 09:22:08 +03:00
Carlosokumu
2c059afa7d resolve 2024-09-07 22:05:09 +03:00
Carlosokumu
9aab7d3a9b Merge branch 'master' into wip-code-check 2024-09-07 22:04:30 +03:00
Carlosokumu
a25beb5b80 Merge branch 'wip-code-check' 2024-09-07 21:54:00 +03:00
Carlosokumu
39d27209cd Merge remote-tracking branch 'refs/remotes/origin/wip-code-check' into wip-code-check 2024-09-07 18:10:40 +03:00
Carlosokumu
16a56ef29d add go-vise 2024-09-07 18:09:55 +03:00
Carlosokumu
6d02ea79ec add go-vise 2024-09-07 18:09:13 +03:00
alfred-mk
deb4706b1d Test commit 2024-09-07 17:51:30 +03:00
alfred-mk
e14fd5e496 Return the response and the error 2024-09-07 17:41:05 +03:00
Carlosokumu
01c13ec581 make packKey accessible from tests 2024-09-07 16:25:29 +03:00
Carlosokumu
dd97531861 remove uimplemented tests 2024-09-07 16:24:37 +03:00
Carlosokumu
be33b7458f cleanup code 2024-09-07 16:22:08 +03:00
Carlosokumu
4c3f63a48f create an account only if not found in gdbm 2024-09-07 10:36:00 +03:00
Carlosokumu
d1d5c897d1 refactor 2024-09-07 09:55:59 +03:00
Carlosokumu
04ea11dd6d setup db mock 2024-09-07 09:55:47 +03:00
Carlosokumu
5722552395 remove old mocks 2024-09-07 09:55:13 +03:00
Carlosokumu
421fbe5543 setup mock for the acccount service 2024-09-07 09:55:00 +03:00
alfred-mk
de24ca0648 Mock the gdm nd updated the TestSaveFirstname and TestSaveFamilyname 2024-09-07 09:30:20 +03:00
Carlosokumu
175cbd1983 setup template test 2024-09-06 17:51:07 +03:00
Carlosokumu
8175d6ac12 setup db mock 2024-09-06 17:50:33 +03:00
Carlosokumu
d4bae50ff0 Merge remote-tracking branch 'refs/remotes/origin/wip-code-check' into wip-code-check 2024-09-06 16:54:41 +03:00
Carlosokumu
d7376a4196 format error 2024-09-06 16:53:22 +03:00
alfred-mk
eb9f470ac5 Update the GetProfileInfo to get data from gdbm 2024-09-06 16:17:26 +03:00
Carlosokumu
7a12588744 remove deprecated code 2024-09-06 12:42:24 +03:00
Carlosokumu
6947b1e4a4 rename getflags to getparser 2024-09-06 11:03:01 +03:00
Carlosokumu
2cc85379cc update log 2024-09-06 11:02:33 +03:00
alfred-mk
d001c5a7fc Write and read data from gdbm 2024-09-06 09:33:39 +03:00
alfred-mk
de8c7ce34a Added user data to db.go util 2024-09-06 08:35:01 +03:00
lash
cad8e86c8b Remove manual init calls in handler funcs 2024-09-05 23:55:54 +01:00
lash
0feb013c78 Ensure handler init when state and cache is available 2024-09-05 20:40:40 +01:00
Carlosokumu
643b4d87a9 read account pin of gdbm store 2024-09-05 20:30:28 +03:00
Carlosokumu
5abaf28f49 remove explicit attachment of state to engine 2024-09-05 20:26:52 +03:00
alfred-mk
17804e7641 Save the actual PIN and verify it 2024-09-05 19:50:02 +03:00
lash
db3ec1991d Remove obsolete store and persister global 2024-09-05 16:45:35 +01:00
lash
62b7adb967 Fix missing byte allocation for typ serialize 2024-09-05 15:41:27 +01:00
lash
6fa5f49bc0 Remove impossible nil check in handler 2024-09-05 15:28:53 +01:00
Carlosokumu
2bf7a5c246 setup db keys 2024-09-05 17:12:38 +03:00
Carlosokumu
98c74dffc4 use state from persister 2024-09-05 17:09:30 +03:00
Carlosokumu
771a1e8169 code refactoring 2024-09-05 17:07:20 +03:00
Carlosokumu
220c5b2081 remove commented code 2024-09-04 20:22:25 +03:00
Carlosokumu
2fc8a0e5a7 use fsDb for the resources 2024-09-04 19:57:08 +03:00
Alfred Kamanda
c6c66f956a Merge pull request 'wip-flag-migration' (#28) from wip-flag-migration into master
Reviewed-on: urdt/ussd#28
2024-09-04 11:25:33 +02:00
alfred-mk
1957606bc2 Added log to show debug the flag loaded 2024-09-04 12:19:34 +03:00
alfred-mk
8ffc5d67cc Removed mutex 2024-09-04 12:01:51 +03:00
alfred-mk
2d7b6bd125 Removed unused code 2024-09-03 22:28:48 +03:00
alfred-mk
5105e902f1 Process flags once and make them available across functions 2024-09-03 19:06:37 +03:00
Carlosokumu
19b2fa65fa Merge remote-tracking branch 'refs/remotes/origin/wip-flag-migration' into wip-flag-migration 2024-09-03 18:00:06 +03:00
Carlosokumu
ee4db50e00 remove unused code 2024-09-03 17:59:03 +03:00
alfred-mk
99d18322b2 Append to the correct flag set/reset 2024-09-03 15:34:19 +03:00
Carlosokumu
a07a8703f4 remove flag setting invalid pin entry 2024-09-03 15:13:55 +03:00
Carlosokumu
94f12edeaf Merge remote-tracking branch 'refs/remotes/origin/wip-flag-migration' into wip-flag-migration 2024-09-03 15:08:45 +03:00
Carlosokumu
fee51edade append sessionid to the gdbm file 2024-09-03 15:07:49 +03:00
alfred-mk
f90fde90fb Register flags in debugger from the csv 2024-09-03 15:04:09 +03:00
alfred-mk
ab6433168a Resolve bug on transaction confirmation PIN 2024-09-03 15:02:31 +03:00
Carlosokumu
0c360c0cc4 remove panics after failed execution 2024-09-03 13:19:32 +03:00
Carlosokumu
560714838f fix menu termination on invalid pin entry 2024-09-03 11:51:14 +03:00
Carlosokumu
c365eaa1d1 remove unused code 2024-09-02 21:24:16 +03:00
Carlosokumu
337419c9f2 Merge remote-tracking branch 'refs/remotes/origin/wip-flag-migration' into wip-flag-migration 2024-09-02 21:10:41 +03:00
Carlosokumu
d4c4db09f3 load profile data from gdbm 2024-09-02 21:09:39 +03:00
alfred-mk
3a3ddc9922 Use FlagParser on main.go and delete the flags.go file 2024-09-02 21:06:42 +03:00
Carlosokumu
1c1ea74088 Merge remote-tracking branch 'refs/remotes/origin/wip-flag-migration' into wip-flag-migration 2024-09-02 17:12:01 +03:00
Carlosokumu
14c8230fd4 code cleanup 2024-09-02 17:11:08 +03:00
alfred-mk
b6e4ba7ede Verify PIN using the one in the db 2024-09-02 17:08:57 +03:00
Carlosokumu
2b511aba4c remove commented code 2024-09-02 16:39:04 +03:00
Carlosokumu
626fca1a55 Merge remote-tracking branch 'refs/remotes/origin/wip-flag-migration' into wip-flag-migration 2024-09-02 16:30:58 +03:00
Carlosokumu
0c96831378 use gdbm 2024-09-02 16:05:13 +03:00
Carlosokumu
fe4df78f80 use gdbm for user info storage 2024-09-02 16:04:53 +03:00
alfred-mk
31be1fa221 Use flags from pp.csv on the menuhandler functions and tests 2024-09-02 14:00:02 +03:00
Carlosokumu
ba4d0abcda improve doc line 2024-09-02 10:03:57 +03:00
alfred-mk
632dd860ff Use flags from pp.csv on the Authorize function 2024-08-31 17:16:57 +03:00
Carlosokumu
07c8638a6d use correct symbol name 2024-08-31 15:09:34 +03:00
Carlosokumu
c71f6e76d7 Merge remote-tracking branch 'refs/remotes/origin/wip-flag-migration' into wip-flag-migration 2024-08-31 14:56:18 +03:00
Carlosokumu
2559b4e604 add test profile 2024-08-31 14:55:54 +03:00
alfred-mk
460e6fa2c8 Renamed duplicate flag 2024-08-31 14:50:45 +03:00
alfred-mk
c3c5c83662 Change the order of flags 2024-08-31 14:48:02 +03:00
alfred-mk
143c9b14a1 Renamed the flags 2024-08-31 12:58:48 +03:00
alfred-mk
42ab2dd577 Use preprocessor flags 2024-08-31 12:16:36 +03:00
alfred-mk
26959be149 Fixed bug on transaction pin node 2024-08-31 12:09:02 +03:00
Carlosokumu
118b5577bb Merge remote-tracking branch 'refs/remotes/origin/wip-flag-migration' into wip-flag-migration 2024-08-31 12:06:42 +03:00
Carlosokumu
4e69fa454d use string flags 2024-08-31 12:02:44 +03:00
alfred-mk
9fb3ef8e2a Use preprocessor flags 2024-08-31 11:56:36 +03:00
Carlosokumu
ec4201139a add _flag suffix 2024-08-31 11:35:29 +03:00
alfred-mk
bcc73dec23 Add the flag file during build 2024-08-31 11:27:47 +03:00
alfred-mk
828f9a17fc Added the csv containing string flags 2024-08-31 10:30:10 +03:00
Carlosokumu
de4aaeb02b use script dir for parser 2024-08-31 10:26:49 +03:00
Carlosokumu
cc323707fc setup parser 2024-08-31 10:21:20 +03:00
ef0c207fc4 Merge pull request 'wip-account-creation' (#4) from wip-account-creation into master
Reviewed-on: urdt/ussd#4
Reviewed-by: lash <accounts-grassrootseconomics@holbrook.no>
2024-08-30 14:37:58 +02:00
33 changed files with 1418 additions and 1399 deletions

View File

@@ -4,143 +4,305 @@ import (
"context" "context"
"flag" "flag"
"fmt" "fmt"
"io"
"net/http"
"os" "os"
"path" "path"
"git.defalsify.org/vise.git/cache" "git.defalsify.org/vise.git/asm"
"git.defalsify.org/vise.git/db"
fsdb "git.defalsify.org/vise.git/db/fs"
gdbmdb "git.defalsify.org/vise.git/db/gdbm"
"git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/logging"
"git.defalsify.org/vise.git/persist" "git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/resource"
"git.defalsify.org/vise.git/state"
"git.grassecon.net/urdt/ussd/internal/handlers/ussd" "git.grassecon.net/urdt/ussd/internal/handlers/ussd"
"git.grassecon.net/urdt/ussd/internal/models"
) )
var ( var (
logg = logging.NewVanilla()
scriptDir = path.Join("services", "registration") scriptDir = path.Join("services", "registration")
) )
type LocalHandler struct {
sessionId string
}
func NewLocalHandler() *LocalHandler {
return &LocalHandler{
sessionId: "",
}
}
type RequestParser interface {
GetSessionId(*http.Request) (string, error)
GetInput(*http.Request) ([]byte, error)
}
type DefaultRequestParser struct {
}
func(rp *DefaultRequestParser) GetSessionId(rq *http.Request) (string, error) {
v := rq.Header.Get("X-Vise-Session")
if v == "" {
return "", fmt.Errorf("no session found")
}
return v, nil
}
func(rp *DefaultRequestParser) GetInput(rq *http.Request) ([]byte, error) {
defer rq.Body.Close()
v, err := io.ReadAll(rq.Body)
if err != nil {
return nil, err
}
return v, nil
}
type DefaultSessionHandler struct {
cfgTemplate engine.Config
rp RequestParser
rh *LocalHandler
dbDir string
resourceDir string
}
func NewDefaultSessionHandler(dbDir string, resourceDir string, rp RequestParser, outputSize uint32, flagCount uint32) *DefaultSessionHandler {
rh := NewLocalHandler()
return &DefaultSessionHandler{
cfgTemplate: engine.Config{
OutputSize: outputSize,
Root: "root",
FlagCount: flagCount,
},
rh: rh,
rp: rp,
dbDir: dbDir,
resourceDir: resourceDir,
}
}
func getParser(fp string, debug bool) (*asm.FlagParser, error) {
flagParser := asm.NewFlagParser().WithDebug()
_, err := flagParser.Load(fp)
if err != nil {
return nil, err
}
return flagParser, nil
}
func getHandler(appFlags *asm.FlagParser, rs *resource.DbResource, pe *persist.Persister, userdataStore db.Db) (*ussd.Handlers, error) {
ussdHandlers, err := ussd.NewHandlers(appFlags, pe, userdataStore)
if err != nil {
return nil, err
}
rs.AddLocalFunc("select_language", ussdHandlers.SetLanguage)
rs.AddLocalFunc("create_account", ussdHandlers.CreateAccount)
rs.AddLocalFunc("save_pin", ussdHandlers.SavePin)
rs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin)
rs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier)
rs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus)
rs.AddLocalFunc("authorize_account", ussdHandlers.Authorize)
rs.AddLocalFunc("quit", ussdHandlers.Quit)
rs.AddLocalFunc("check_balance", ussdHandlers.CheckBalance)
rs.AddLocalFunc("validate_recipient", ussdHandlers.ValidateRecipient)
rs.AddLocalFunc("transaction_reset", ussdHandlers.TransactionReset)
rs.AddLocalFunc("max_amount", ussdHandlers.MaxAmount)
rs.AddLocalFunc("validate_amount", ussdHandlers.ValidateAmount)
rs.AddLocalFunc("reset_transaction_amount", ussdHandlers.ResetTransactionAmount)
rs.AddLocalFunc("get_recipient", ussdHandlers.GetRecipient)
rs.AddLocalFunc("get_sender", ussdHandlers.GetSender)
rs.AddLocalFunc("get_amount", ussdHandlers.GetAmount)
rs.AddLocalFunc("reset_incorrect", ussdHandlers.ResetIncorrectPin)
rs.AddLocalFunc("save_firstname", ussdHandlers.SaveFirstname)
rs.AddLocalFunc("save_familyname", ussdHandlers.SaveFamilyname)
rs.AddLocalFunc("save_gender", ussdHandlers.SaveGender)
rs.AddLocalFunc("save_location", ussdHandlers.SaveLocation)
rs.AddLocalFunc("save_yob", ussdHandlers.SaveYob)
rs.AddLocalFunc("save_offerings", ussdHandlers.SaveOfferings)
rs.AddLocalFunc("quit_with_balance", ussdHandlers.QuitWithBalance)
rs.AddLocalFunc("reset_account_authorized", ussdHandlers.ResetAccountAuthorized)
rs.AddLocalFunc("reset_allow_update", ussdHandlers.ResetAllowUpdate)
rs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo)
rs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob)
rs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob)
rs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit)
rs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction)
return ussdHandlers, nil
}
func(f *DefaultSessionHandler) getPersister(ctx context.Context) (*persist.Persister, error) {
err := os.MkdirAll(f.dbDir, 0700)
if err != nil {
return nil, fmt.Errorf("state dir create exited with error: %v\n", err)
}
store := gdbmdb.NewGdbmDb()
storeFile := path.Join(f.dbDir, "state.gdbm")
store.Connect(ctx, storeFile)
pr := persist.NewPersister(store)
return pr, nil
}
func(f *DefaultSessionHandler) getUserdataDb(ctx context.Context) db.Db {
store := gdbmdb.NewGdbmDb()
storeFile := path.Join(f.dbDir, "userdata.gdbm")
store.Connect(ctx, storeFile)
return store
}
func(f *DefaultSessionHandler) getResource(ctx context.Context) (resource.Resource, error) {
store := fsdb.NewFsDb()
err := store.Connect(ctx, f.resourceDir)
if err != nil {
return nil, err
}
rfs := resource.NewDbResource(store)
return rfs, nil
}
func(f *DefaultSessionHandler) getEngine(rs resource.Resource, pr *persist.Persister, sessionId string) *engine.DefaultEngine {
cfg := f.cfgTemplate
cfg.SessionId = sessionId
en := engine.NewEngine(cfg, rs)
en = en.WithPersister(pr)
return en
}
func(f *DefaultSessionHandler) writeError(w http.ResponseWriter, code int, msg string, err error) {
w.Header().Set("X-Vise", msg + ": " + err.Error())
w.Header().Set("Content-Length", "0")
w.WriteHeader(code)
_, err = w.Write([]byte{})
if err != nil {
w.WriteHeader(500)
w.Header().Set("X-Vise", err.Error())
}
return
}
func(f *DefaultSessionHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
var r bool
sessionId, err := f.rp.GetSessionId(req)
if err != nil {
f.writeError(w, 400, "Session missing", err)
return
}
input, err := f.rp.GetInput(req)
if err != nil {
f.writeError(w, 400, "Input read fail", err)
return
}
ctx := req.Context()
ctx = context.WithValue(ctx, "SessionId", sessionId)
pfp := path.Join(scriptDir, "pp.csv")
flagParser, err := getParser(pfp, true)
if err != nil {
f.writeError(w, 500, "flagParser failed with error:", err)
return
}
rs, err := f.getResource(ctx)
if err != nil {
f.writeError(w, 500, "getResource failed with error:", err)
return
}
pr, err := f.getPersister(ctx)
if err != nil {
f.writeError(w, 500, "getPersister failed with error:", err)
return
}
store := f.getUserdataDb(ctx)
dbResource, ok := rs.(*resource.DbResource)
if !ok {
f.writeError(w, 500, "getHandler exited with error:", err)
return
}
hl, err := getHandler(flagParser, dbResource, pr, store)
if err != nil {
f.writeError(w, 500, "getHandler exited with error:", err)
return
}
en := f.getEngine(rs, pr, sessionId)
en = en.WithFirst(hl.Init)
if len(input) == 0 {
r, err = en.Init(ctx)
} else {
r, err = en.Exec(ctx, input)
}
if err != nil {
f.writeError(w, 500, "Engine exec fail", err)
return
}
// _, err = en.Init(ctx)
// if err != nil {
// f.writeError(w, 500, "Engine exec fail", err)
// return
// }
// err = engine.Loop(ctx, en, os.Stdin, os.Stdout)
// if err != nil {
// f.writeError(w, 500, "Loop exec fail", err)
// return
// }
w.WriteHeader(200)
w.Header().Set("Content-Type", "text/plain")
_, err = en.WriteResult(ctx, w)
if err != nil {
f.writeError(w, 500, "Write result fail", err)
return
}
_ = r
}
func main() { func main() {
var dir string var host string
var root string var port string
var dbDir string
var resourceDir string
var size uint var size uint
var flagCount uint
var sessionId string var sessionId string
flag.StringVar(&dir, "d", ".", "resource dir to read from") var debug bool
flag.UintVar(&size, "s", 0, "max size of output") flag.StringVar(&host, "h", "127.0.0.1", "http host")
flag.StringVar(&root, "root", "root", "entry point symbol") flag.StringVar(&port, "p", "7123", "http port")
flag.StringVar(&sessionId, "session-id", "default", "session id") flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
flag.BoolVar(&debug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.UintVar(&flagCount, "f", 16, "flag count")
flag.Parse() flag.Parse()
fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir)
ctx := context.Background() logg.Infof("starting server", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size, "flagCount", flagCount)
st := state.NewState(16)
st.UseDebug()
state.FlagDebugger.Register(models.USERFLAG_LANGUAGE_SET, "LANGUAGE_CHANGE")
state.FlagDebugger.Register(models.USERFLAG_ACCOUNT_CREATED, "ACCOUNT_CREATED")
state.FlagDebugger.Register(models.USERFLAG_ACCOUNT_SUCCESS, "ACCOUNT_SUCCESS")
state.FlagDebugger.Register(models.USERFLAG_ACCOUNT_PENDING, "ACCOUNT_PENDING")
state.FlagDebugger.Register(models.USERFLAG_INCORRECTPIN, "INCORRECTPIN")
state.FlagDebugger.Register(models.USERFLAG_INCORRECTDATEFORMAT, "INVALIDDATEFORMAT")
state.FlagDebugger.Register(models.USERFLAG_INVALID_RECIPIENT, "INVALIDRECIPIENT")
state.FlagDebugger.Register(models.USERFLAG_PINMISMATCH, "PINMISMATCH")
state.FlagDebugger.Register(models.USERFLAG_PIN_SET, "PIN_SET")
state.FlagDebugger.Register(models.USERFLAG_INVALID_RECIPIENT_WITH_INVITE, "INVALIDRECIPIENT_WITH_INVITE")
state.FlagDebugger.Register(models.USERFLAG_INVALID_AMOUNT, "INVALIDAMOUNT")
state.FlagDebugger.Register(models.USERFLAG_ALLOW_UPDATE, "UNLOCKFORUPDATE")
state.FlagDebugger.Register(models.USERFLAG_VALIDPIN, "VALIDPIN")
state.FlagDebugger.Register(models.USERFLAG_VALIDPIN, "ACCOUNTUNLOCKED")
state.FlagDebugger.Register(models.USERFLAG_ACCOUNT_CREATION_FAILED, "ACCOUNT_CREATION_FAILED")
state.FlagDebugger.Register(models.USERFLAG_SINGLE_EDIT, "SINGLEEDIT")
rfs := resource.NewFsResource(scriptDir) rp := &DefaultRequestParser{}
ca := cache.NewCache() h := NewDefaultSessionHandler(dbDir, resourceDir, rp, uint32(size), uint32(flagCount))
cfg := engine.Config{ s := &http.Server{
Root: "root", Addr: fmt.Sprintf("%s:%s", host, port),
SessionId: sessionId, Handler: h,
} }
dp := path.Join(scriptDir, ".state") err := s.ListenAndServe()
err := os.MkdirAll(dp, 0700)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "state dir create exited with error: %v\n", err) fmt.Fprintf(os.Stderr, "Server error: %s", err)
os.Exit(1)
}
pr := persist.NewFsPersister(dp)
en, err := engine.NewPersistedEngine(ctx, cfg, pr, rfs)
if err != nil {
pr = pr.WithContent(&st, ca)
err = pr.Save(cfg.SessionId)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to save state with error: %v\n", err)
}
en, err = engine.NewPersistedEngine(ctx, cfg, pr, rfs)
if err != nil {
fmt.Fprintf(os.Stderr, "engine create exited with error: %v\n", err)
os.Exit(1)
}
}
fp := path.Join(dp, sessionId)
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("authorize_account", ussdHandlers.Authorize)
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("get_amount", ussdHandlers.GetAmount)
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_account_authorized", ussdHandlers.ResetAccountAuthorized)
rfs.AddLocalFunc("reset_allow_update", ussdHandlers.ResetAllowUpdate)
rfs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo)
rfs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob)
rfs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob)
rfs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit)
rfs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction)
cont, err := en.Init(ctx)
en.SetDebugger(engine.NewSimpleDebug(nil))
if err != nil {
fmt.Fprintf(os.Stderr, "engine init exited with error: %v\n", err)
os.Exit(1)
}
if !cont {
_, err = en.WriteResult(ctx, os.Stdout)
if err != nil {
fmt.Fprintf(os.Stderr, "dead init write error: %v\n", err)
os.Exit(1)
}
err = en.Finish()
if err != nil {
fmt.Fprintf(os.Stderr, "engine finish error: %v\n", err)
os.Exit(1)
}
os.Stdout.Write([]byte{0x0a})
os.Exit(0)
}
err = engine.Loop(ctx, en, os.Stdin, os.Stdout)
if err != nil {
fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err)
os.Exit(1) os.Exit(1)
} }
} }

Submodule go-vise deleted from 1f47a674d9

22
go.mod
View File

@@ -2,4 +2,24 @@ module git.grassecon.net/urdt/ussd
go 1.22.6 go 1.22.6
require github.com/stretchr/testify v1.9.0 // indirect require (
github.com/alecthomas/participle/v2 v2.0.0 // indirect
github.com/alecthomas/repr v0.2.0 // indirect
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/stretchr/testify v1.9.0
github.com/x448/float16 v0.8.4 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
require (
git.defalsify.org/vise.git v0.1.0-rc.1.0.20240906020635-400f69d01a89
github.com/alecthomas/assert/v2 v2.2.2
gopkg.in/leonelquinteros/gotext.v1 v1.3.1
)

34
go.sum
View File

@@ -1,2 +1,36 @@
git.defalsify.org/vise.git v0.1.0-rc.1.0.20240906020635-400f69d01a89 h1:YyQODhMwSM5YD9yKHM5jCF0HC0RQtE3MkVXcTnOhXJo=
git.defalsify.org/vise.git v0.1.0-rc.1.0.20240906020635-400f69d01a89/go.mod h1:JDguWmcoWBdsnpw7PUjVZAEpdC/ubBmjdUBy3tjP63M=
github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk=
github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g=
github.com/alecthomas/participle/v2 v2.0.0/go.mod h1:rAKZdJldHu8084ojcWevWAL8KmEU+AT+Olodb+WoN2Y=
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c h1:H9Nm+I7Cg/YVPpEV1RzU3Wq2pjamPc/UtHDgItcb7lE=
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c/go.mod h1:rGod7o6KPeJ+hyBpHfhi4v7blx9sf+QsHsA7KAsdN6U=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 h1:U4kkNYryi/qfbBF8gh7Vsbuz+cVmhf5kt6pE9bYYyLo=
github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4/go.mod h1:zpZDgZFzeq9s0MIeB1P50NIEWDFFHSFBohI/NbaTD/Y=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a h1:0Q3H0YXzMHiciXtRcM+j0jiCe8WKPQHoRgQiRTnfcLY=
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a/go.mod h1:CdTTBOYzS5E4mWS1N8NWP6AHI19MP0A2B18n3hLzRMk=
github.com/peteole/testdata-loader v0.3.0 h1:8jckE9KcyNHgyv/VPoaljvKZE0Rqr8+dPVYH6rfNr9I=
github.com/peteole/testdata-loader v0.3.0/go.mod h1:Mt0ZbRtb56u8SLJpNP+BnQbENljMorYBpqlvt3cS83U=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
package mocks
import (
"context"
"git.defalsify.org/vise.git/lang"
"github.com/stretchr/testify/mock"
)
type MockDb struct {
mock.Mock
}
func (m *MockDb) SetPrefix(prefix uint8) {
m.Called(prefix)
}
func (m *MockDb) Prefix() uint8 {
args := m.Called()
return args.Get(0).(uint8)
}
func (m *MockDb) Safe() bool {
args := m.Called()
return args.Get(0).(bool)
}
func (m *MockDb) SetLanguage(language *lang.Language) {
m.Called(language)
}
func (m *MockDb) SetLock(uint8, bool) error {
args := m.Called()
return args.Error(0)
}
func (m *MockDb) Connect(ctx context.Context, connectionStr string) error {
args := m.Called(ctx, connectionStr)
return args.Error(0)
}
func (m *MockDb) SetSession(sessionId string) {
m.Called(sessionId)
}
func (m *MockDb) Put(ctx context.Context, key, value []byte) error {
args := m.Called(ctx, key, value)
return args.Error(0)
}
func (m *MockDb) Get(ctx context.Context, key []byte) ([]byte, error) {
args := m.Called(ctx, key)
return nil, args.Error(0)
}
func (m *MockDb) Close() error {
args := m.Called(nil)
return args.Error(0)
}

View File

@@ -1,44 +0,0 @@
package mocks
import (
"git.grassecon.net/urdt/ussd/internal/models"
"github.com/stretchr/testify/mock"
)
type MockAccountFileHandler struct {
mock.Mock
}
func (m *MockAccountFileHandler) EnsureFileExists() error {
args := m.Called()
return args.Error(0)
}
func (m *MockAccountFileHandler) ReadAccountData() (map[string]string, error) {
args := m.Called()
return args.Get(0).(map[string]string), args.Error(1)
}
func (m *MockAccountFileHandler) WriteAccountData(data map[string]string) error {
args := m.Called(data)
return args.Error(0)
}
type MockAccountService struct {
mock.Mock
}
func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
args := m.Called()
return args.Get(0).(*models.AccountResponse), args.Error(1)
}
func (m *MockAccountService) CheckAccountStatus(TrackingId string) (string, error) {
args := m.Called()
return args.Get(0).(string), args.Error(1)
}
func (m *MockAccountService) CheckBalance(PublicKey string) (string, error) {
args := m.Called()
return args.Get(0).(string), args.Error(1)
}

View File

@@ -0,0 +1,26 @@
package mocks
import (
"git.grassecon.net/urdt/ussd/internal/models"
"github.com/stretchr/testify/mock"
)
// MockAccountService implements AccountServiceInterface for testing
type MockAccountService struct {
mock.Mock
}
func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
args := m.Called()
return args.Get(0).(*models.AccountResponse), args.Error(1)
}
func (m *MockAccountService) CheckBalance(publicKey string) (string, error) {
args := m.Called(publicKey)
return args.String(0), args.Error(1)
}
func (m *MockAccountService) CheckAccountStatus(trackingId string) (string, error) {
args := m.Called(trackingId)
return args.String(0), args.Error(1)
}

View File

@@ -0,0 +1,69 @@
package mocks
import (
"context"
"git.defalsify.org/vise.git/lang"
"git.grassecon.net/urdt/ussd/internal/utils"
"github.com/stretchr/testify/mock"
)
type MockUserDataStore struct {
mock.Mock
}
func (m *MockUserDataStore) SetPrefix(prefix uint8) {
m.Called(prefix)
}
func (m *MockUserDataStore) SetSession(sessionId string) {
m.Called(sessionId)
}
func (m *MockUserDataStore) Get(ctx context.Context, key []byte) ([]byte, error) {
args := m.Called(ctx, key)
return args.Get(0).([]byte), args.Error(1)
}
func (m *MockUserDataStore) ReadEntry(ctx context.Context, sessionId string, typ utils.DataTyp) ([]byte, error) {
args := m.Called(ctx, sessionId, typ)
return args.Get(0).([]byte), args.Error(1)
}
func (m *MockUserDataStore) WriteEntry(ctx context.Context, sessionId string, typ utils.DataTyp, value []byte) error {
args := m.Called(ctx, sessionId, typ, value)
return args.Error(0)
}
func (m *MockUserDataStore) Prefix() uint8 {
args := m.Called()
return args.Get(0).(uint8)
}
func (m *MockUserDataStore) Safe() bool {
args := m.Called()
return args.Get(0).(bool)
}
func (m *MockUserDataStore) SetLanguage(language *lang.Language) {
m.Called(language)
}
func (m *MockUserDataStore) SetLock(uint8, bool) error {
args := m.Called()
return args.Error(0)
}
func (m *MockUserDataStore) Connect(ctx context.Context, connectionStr string) error {
args := m.Called(ctx, connectionStr)
return args.Error(0)
}
func (m *MockUserDataStore) Put(ctx context.Context, key, value []byte) error {
args := m.Called(ctx, key, value)
return args.Error(0)
}
func (m *MockUserDataStore) Close() error {
args := m.Called(nil)
return args.Error(0)
}

View File

@@ -1,22 +0,0 @@
package models
import "git.defalsify.org/vise.git/state"
const (
USERFLAG_LANGUAGE_SET = iota + state.FLAG_USERSTART
USERFLAG_ACCOUNT_CREATED
USERFLAG_ACCOUNT_PENDING
USERFLAG_ACCOUNT_SUCCESS
USERFLAG_ACCOUNT_AUTHORIZED
USERFLAG_INVALID_RECIPIENT
USERFLAG_INVALID_RECIPIENT_WITH_INVITE
USERFLAG_INCORRECTPIN
USERFLAG_ALLOW_UPDATE
USERFLAG_INVALID_AMOUNT
USERFLAG_PIN_SET
USERFLAG_VALIDPIN
USERFLAG_PINMISMATCH
USERFLAG_INCORRECTDATEFORMAT
USERFLAG_ACCOUNT_CREATION_FAILED
USERFLAG_SINGLE_EDIT
)

View File

@@ -1,46 +1,44 @@
package utils package utils
import ( import (
"context"
"encoding/json" "encoding/json"
"os"
"git.defalsify.org/vise.git/db"
) )
type AccountFileHandler struct { type AccountFileHandler struct {
FilePath string store db.Db
} }
func NewAccountFileHandler(path string) *AccountFileHandler { func NewAccountFileHandler(store db.Db) *AccountFileHandler {
return &AccountFileHandler{FilePath: path} return &AccountFileHandler{
} store: store,
func (afh *AccountFileHandler) ReadAccountData() (map[string]string, error) {
jsonData, err := os.ReadFile(afh.FilePath)
if err != nil {
return nil, err
} }
}
func (afh *AccountFileHandler) ReadAccountData(ctx context.Context, sessionId string) (map[string]string, error) {
var accountData map[string]string var accountData map[string]string
jsonData, err := ReadEntry(ctx, afh.store, sessionId, DATA_ACCOUNT)
if err != nil {
return nil,err
}
err = json.Unmarshal(jsonData, &accountData) err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return accountData, nil return accountData, nil
} }
func (afh *AccountFileHandler) WriteAccountData(accountData map[string]string) error { func (afh *AccountFileHandler) WriteAccountData(ctx context.Context, sessionId string, accountData map[string]string) error {
jsonData, err := json.Marshal(accountData) _, err := json.Marshal(accountData)
if err != nil { if err != nil {
return err return err
} }
return os.WriteFile(afh.FilePath, jsonData, 0644) return nil
} }
func (afh *AccountFileHandler) EnsureFileExists() error { func (afh *AccountFileHandler) EnsureFileExists() error {
f, err := os.OpenFile(afh.FilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) return nil
if err != nil {
return err
}
return f.Close()
} }

58
internal/utils/db.go Normal file
View File

@@ -0,0 +1,58 @@
package utils
import (
"context"
"encoding/binary"
"git.defalsify.org/vise.git/db"
)
type DataTyp uint16
const (
DATA_ACCOUNT DataTyp = iota
DATA_ACCOUNT_CREATED
DATA_TRACKING_ID
DATA_PUBLIC_KEY
DATA_CUSTODIAL_ID
DATA_ACCOUNT_PIN
DATA_ACCOUNT_STATUS
DATA_FIRST_NAME
DATA_FAMILY_NAME
DATA_YOB
DATA_LOCATION
DATA_GENDER
DATA_OFFERINGS
DATA_RECIPIENT
DATA_AMOUNT
)
func typToBytes(typ DataTyp) []byte {
var b [2]byte
binary.BigEndian.PutUint16(b[:], uint16(typ))
return b[:]
}
func PackKey(typ DataTyp, data []byte) []byte {
v := typToBytes(typ)
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)
}

View File

@@ -1,13 +0,0 @@
package utils
type AccountFileHandlerInterface interface {
EnsureFileExists() error
ReadAccountData() (map[string]string, error)
WriteAccountData(data map[string]string) error
}

View File

@@ -0,0 +1,81 @@
package utils
import (
"context"
"git.defalsify.org/vise.git/db"
"git.defalsify.org/vise.git/lang"
)
type DataStore interface {
SetPrefix(prefix uint8)
SetSession(sessionId string)
Get(ctx context.Context, key []byte) ([]byte, error)
ReadEntry(ctx context.Context, sessionId string, typ DataTyp) ([]byte, error)
WriteEntry(ctx context.Context, sessionId string, typ DataTyp, value []byte) error
Connect(ctx context.Context, connStr string) error
SetLanguage(*lang.Language)
Close() error
Prefix() uint8
Put(ctx context.Context, key []byte, val []byte) error
Safe() bool
SetLock(typ uint8, locked bool) error
}
type UserDataStore struct {
Store db.Db
}
func (store UserDataStore) SetPrefix(prefix uint8) {
store.Store.SetPrefix(prefix)
}
func (store UserDataStore) SetLanguage(lang *lang.Language) {
store.Store.SetLanguage(lang)
}
func (store UserDataStore) SetLock(typ uint8, locked bool) error {
return store.Store.SetLock(typ, locked)
}
func (store UserDataStore) Safe() bool {
return store.Store.Safe()
}
func (store UserDataStore) Put(ctx context.Context, key []byte, val []byte) error {
return store.Store.Put(ctx, key, val)
}
func (store UserDataStore) Connect(ctx context.Context, connectionStr string) error {
return store.Store.Connect(ctx, connectionStr)
}
func (store UserDataStore) Close() error {
return store.Store.Close()
}
func (store UserDataStore) Prefix() uint8 {
return store.Store.Prefix()
}
func (store UserDataStore) SetSession(sessionId string) {
store.Store.SetSession(sessionId)
}
func (store UserDataStore) Get(ctx context.Context, key []byte) ([]byte, error) {
return store.Store.Get(ctx, key)
}
// ReadEntry retrieves an entry from the store based on the provided parameters.
func (store UserDataStore) ReadEntry(ctx context.Context, sessionId string, typ DataTyp) ([]byte, error) {
store.Store.SetPrefix(db.DATATYPE_USERDATA)
store.Store.SetSession(sessionId)
k := PackKey(typ, []byte(sessionId))
return store.Get(ctx, k)
}
func (store UserDataStore) WriteEntry(ctx context.Context, sessionId string, typ DataTyp, value []byte) error {
store.Store.SetPrefix(db.DATATYPE_USERDATA)
store.Store.SetSession(sessionId)
k := PackKey(typ, []byte(sessionId))
return store.Store.Put(ctx, k, value)
}

View File

@@ -4,7 +4,7 @@ TXTS = $(wildcard ./*.txt.orig)
# Rule to build .bin files from .vis files # Rule to build .bin files from .vis files
%.vis: %.vis:
go run ../../go-vise/dev/asm $(basename $@).vis > $(basename $@).bin go run ../../go-vise/dev/asm/main.go -f pp.csv $(basename $@).vis > $(basename $@).bin
@echo "Built $(basename $@).bin from $(basename $@).vis" @echo "Built $(basename $@).bin from $(basename $@).vis"
# Rule to copy .orig files to .txt # Rule to copy .orig files to .txt

View File

@@ -1,4 +1,4 @@
RELOAD verify_pin RELOAD verify_pin
CATCH create_pin_mismatch 20 1 CATCH create_pin_mismatch flag_pin_mismatch 1
LOAD quit 0 LOAD quit 0
HALT HALT

View File

@@ -1,3 +1,3 @@
RELOAD check_account_status RELOAD check_account_status
CATCH main 11 1 CATCH main flag_account_success 1
HALT HALT

View File

@@ -5,7 +5,7 @@ MOUT back 0
HALT HALT
LOAD validate_amount 64 LOAD validate_amount 64
RELOAD validate_amount RELOAD validate_amount
CATCH invalid_amount 17 1 CATCH invalid_amount flag_invalid_amount 1
INCMP _ 0 INCMP _ 0
LOAD get_recipient 12 LOAD get_recipient 12
LOAD get_sender 64 LOAD get_sender 64

View File

@@ -1,4 +1,4 @@
LOAD reset_unlocked 0 LOAD reset_account_authorized 0
MOUT my_balance 1 MOUT my_balance 1
MOUT community_balance 2 MOUT community_balance 2
MOUT back 0 MOUT back 0

View File

@@ -1,5 +1,5 @@
LOAD reset_incorrect 0 LOAD reset_incorrect 0
CATCH incorrect_pin 15 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH pin_entry 12 0 CATCH pin_entry flag_account_authorized 0
LOAD quit_with_balance 0 LOAD quit_with_balance 0
HALT HALT

View File

@@ -1,9 +1,9 @@
LOAD create_account 0 LOAD create_account 0
CATCH account_creation_failed 22 1 CATCH account_creation_failed flag_account_creation_failed 1
MOUT exit 0 MOUT exit 0
HALT HALT
LOAD save_pin 0 LOAD save_pin 0
RELOAD save_pin RELOAD save_pin
CATCH . 15 1 CATCH . flag_incorrect_pin 1
INCMP quit 0 INCMP quit 0
INCMP confirm_create_pin * INCMP confirm_create_pin *

View File

@@ -1,12 +1,9 @@
CATCH incorrect_date_format 21 1 CATCH incorrect_date_format flag_incorrect_date_format 1
LOAD save_yob 0 LOAD save_yob 0
CATCH update_success 16 1 CATCH update_success flag_allow_update 1
MOUT back 0 MOUT back 0
HALT HALT
INCMP _ 0 INCMP _ 0
LOAD save_location 0 LOAD save_location 0
CATCH pin_entry 23 1 CATCH pin_entry flag_single_edit 1
INCMP enter_offerings * INCMP enter_offerings *

View File

@@ -1,6 +1,6 @@
LOAD save_location 0 LOAD save_location 0
CATCH incorrect_pin 15 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH update_success 16 1 CATCH update_success flag_allow_update 1
MOUT back 0 MOUT back 0
HALT HALT
LOAD save_offerings 0 LOAD save_offerings 0

View File

@@ -1,9 +1,9 @@
LOAD save_gender 0 LOAD save_gender 0
CATCH update_success 16 1 CATCH update_success flag_allow_update 1
MOUT back 0 MOUT back 0
HALT HALT
INCMP _ 0 INCMP _ 0
LOAD verify_yob 8 LOAD verify_yob 8
LOAD save_yob 0 LOAD save_yob 0
CATCH pin_entry 23 1 CATCH pin_entry flag_single_edit 1
INCMP enter_location * INCMP enter_location *

View File

@@ -1,5 +1,5 @@
LOAD reset_incorrect 0 LOAD reset_incorrect 0
CATCH incorrect_pin 15 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH pin_entry 12 0 CATCH pin_entry flag_account_authorized 0
LOAD quit_with_balance 0 LOAD quit_with_balance 0
HALT HALT

View File

@@ -0,0 +1,16 @@
flag,flag_language_set,8,checks whether the user has set their prefered language
flag,flag_account_created,9,this is set when an account has been created on the API
flag,flag_account_creation_failed,10,this is set when there's an error from the API during account creation
flag,flag_account_pending,11,this is set when an account does not have a status of SUCCESS
flag,flag_account_success,12,this is set when an account has a status of SUCCESS
flag,flag_pin_mismatch,13,this is set when the confirmation PIN matches the initial PIN during registration
flag,flag_pin_set,14,this is set when a newly registered user sets a PIN. This must be present for an account to access the main menu
flag,flag_account_authorized,15,this is set to allow a user access guarded nodes after providing a correct PIN
flag,flag_invalid_recipient,16,this is set when the transaction recipient is invalid
flag,flag_invalid_recipient_with_invite,17,this is set when the transaction recipient is valid but not on the platform
flag,flag_invalid_amount,18,this is set when the given transaction amount is invalid
flag,flag_incorrect_pin,19,this is set when the provided PIN is invalid or does not match the current account's PIN
flag,flag_valid_pin,20,this is set when the given PIN is valid
flag,flag_allow_update,21,this is set to allow a user to update their profile data
flag,flag_single_edit,22,this is set to allow a user to edit a single profile item such as year of birth
flag,flag_incorrect_date_format,23,this is set when the given year of birth is invalid
1 flag flag_language_set 8 checks whether the user has set their prefered language
2 flag flag_account_created 9 this is set when an account has been created on the API
3 flag flag_account_creation_failed 10 this is set when there's an error from the API during account creation
4 flag flag_account_pending 11 this is set when an account does not have a status of SUCCESS
5 flag flag_account_success 12 this is set when an account has a status of SUCCESS
6 flag flag_pin_mismatch 13 this is set when the confirmation PIN matches the initial PIN during registration
7 flag flag_pin_set 14 this is set when a newly registered user sets a PIN. This must be present for an account to access the main menu
8 flag flag_account_authorized 15 this is set to allow a user access guarded nodes after providing a correct PIN
9 flag flag_invalid_recipient 16 this is set when the transaction recipient is invalid
10 flag flag_invalid_recipient_with_invite 17 this is set when the transaction recipient is valid but not on the platform
11 flag flag_invalid_amount 18 this is set when the given transaction amount is invalid
12 flag flag_incorrect_pin 19 this is set when the provided PIN is invalid or does not match the current account's PIN
13 flag flag_valid_pin 20 this is set when the given PIN is valid
14 flag flag_allow_update 21 this is set to allow a user to update their profile data
15 flag flag_single_edit 22 this is set to allow a user to edit a single profile item such as year of birth
16 flag flag_incorrect_date_format 23 this is set when the given year of birth is invalid

View File

@@ -1,7 +1,7 @@
CATCH select_language 8 0 CATCH select_language flag_language_set 0
CATCH terms 9 0 CATCH terms flag_account_created 0
LOAD check_account_status 0 LOAD check_account_status 0
CATCH account_pending 10 1 CATCH account_pending flag_account_pending 1
CATCH create_pin 18 0 CATCH create_pin flag_pin_set 0
CATCH main 11 1 CATCH main flag_account_success 1
HALT HALT

View File

@@ -1,12 +1,12 @@
LOAD save_familyname 0 LOAD save_familyname 0
CATCH update_success 16 1 CATCH update_success flag_allow_update 1
MOUT male 1 MOUT male 1
MOUT female 2 MOUT female 2
MOUT unspecified 3 MOUT unspecified 3
MOUT back 0 MOUT back 0
HALT HALT
LOAD save_gender 0 LOAD save_gender 0
CATCH pin_entry 23 1 CATCH pin_entry flag_single_edit 1
INCMP _ 0 INCMP _ 0
INCMP enter_yob 1 INCMP enter_yob 1
INCMP enter_yob 2 INCMP enter_yob 2

View File

@@ -3,6 +3,6 @@ MOUT back 0
HALT HALT
LOAD validate_recipient 20 LOAD validate_recipient 20
RELOAD validate_recipient RELOAD validate_recipient
CATCH invalid_recipient 13 1 CATCH invalid_recipient flag_invalid_recipient 1
INCMP _ 0 INCMP _ 0
INCMP amount * INCMP amount *

View File

@@ -1,4 +1,6 @@
LOAD reset_incorrect 0 LOAD reset_incorrect 6
CATCH incorrect_pin flag_incorrect_pin 1
CATCH _ flag_account_authorized 0
LOAD get_amount 10 LOAD get_amount 10
MAP get_amount MAP get_amount
RELOAD get_recipient RELOAD get_recipient

View File

@@ -6,10 +6,9 @@ MAP get_sender
MOUT back 0 MOUT back 0
MOUT quit 9 MOUT quit 9
HALT HALT
LOAD authorize_account 1 LOAD authorize_account 6
RELOAD authorize_account RELOAD authorize_account
CATCH incorrect_pin 15 1 CATCH incorrect_pin flag_incorrect_pin 1
INCMP _ 0 INCMP _ 0
INCMP quit 9 INCMP quit 9
MOVE transaction_initiated INCMP transaction_initiated *

View File

@@ -1,8 +1,8 @@
LOAD get_profile_info 0 LOAD get_profile_info 0
MAP get_profile_info MAP get_profile_info
LOAD reset_incorrect 0 LOAD reset_incorrect 6
CATCH incorrect_pin 15 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH pin_entry 12 0 CATCH pin_entry flag_account_authorized 0
MOUT back 0 MOUT back 0
HALT HALT
INCMP _ 0 INCMP _ 0