improved the ValidateRecipient to check phone numbers, aliases and addresses

This commit is contained in:
Alfred Kamanda 2024-11-20 18:37:35 +03:00
parent 1a3426e729
commit a766f0c01f
Signed by untrusted user: Alfred-mk
GPG Key ID: 7EA3D01708908703

View File

@ -35,12 +35,17 @@ var (
errResponse *api.ErrResponse errResponse *api.ErrResponse
) )
// Define the regex patterns as constants // Define the regex patterns as constants
const ( const (
phoneRegex = `^(?:\+254|254|0)?((?:7[0-9]{8})|(?:1[01][0-9]{7}))$`
pinPattern = `^\d{4}$` pinPattern = `^\d{4}$`
) )
// isValidPIN checks whether the given input is a 4 digit number
func isValidPIN(pin string) bool {
match, _ := regexp.MatchString(pinPattern, pin)
return match
}
// FlagManager handles centralized flag management // FlagManager handles centralized flag management
type FlagManager struct { type FlagManager struct {
parser *asm.FlagParser parser *asm.FlagParser
@ -95,17 +100,6 @@ func NewHandlers(appFlags *asm.FlagParser, userdataStore db.Db, adminstore *util
return h, nil return h, nil
} }
// isValidPIN checks whether the given input is a 4 digit number
func isValidPIN(pin string) bool {
match, _ := regexp.MatchString(pinPattern, pin)
return match
}
func isValidPhoneNumber(phonenumber string) bool {
match, _ := regexp.MatchString(phoneRegex, phonenumber)
return match
}
func (h *Handlers) WithPersister(pe *persist.Persister) *Handlers { func (h *Handlers) WithPersister(pe *persist.Persister) *Handlers {
if h.pe != nil { if h.pe != nil {
panic("persister already set") panic("persister already set")
@ -877,7 +871,7 @@ func (h *Handlers) ValidateBlockedNumber(ctx context.Context, sym string, input
} }
blockedNumber := string(input) blockedNumber := string(input)
_, err = store.ReadEntry(ctx, blockedNumber, common.DATA_PUBLIC_KEY) _, err = store.ReadEntry(ctx, blockedNumber, common.DATA_PUBLIC_KEY)
if !isValidPhoneNumber(blockedNumber) { if !common.IsValidPhoneNumber(blockedNumber) {
res.FlagSet = append(res.FlagSet, flag_unregistered_number) res.FlagSet = append(res.FlagSet, flag_unregistered_number)
return res, nil return res, nil
} }
@ -898,10 +892,9 @@ func (h *Handlers) ValidateBlockedNumber(ctx context.Context, sym string, input
return res, nil return res, nil
} }
// ValidateRecipient validates that the given input is a valid phone number. // ValidateRecipient validates that the given input is valid.
func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result var res resource.Result
var err error
store := h.userdataStore store := h.userdataStore
sessionId, ok := ctx.Value("SessionId").(string) sessionId, ok := ctx.Value("SessionId").(string)
@ -909,13 +902,16 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
return res, fmt.Errorf("missing session") return res, fmt.Errorf("missing session")
} }
recipient := string(input)
flag_invalid_recipient, _ := h.flagManager.GetFlag("flag_invalid_recipient") flag_invalid_recipient, _ := h.flagManager.GetFlag("flag_invalid_recipient")
flag_invalid_recipient_with_invite, _ := h.flagManager.GetFlag("flag_invalid_recipient_with_invite") flag_invalid_recipient_with_invite, _ := h.flagManager.GetFlag("flag_invalid_recipient_with_invite")
flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error")
recipient := string(input)
if recipient != "0" { if recipient != "0" {
if !isValidPhoneNumber(recipient) { recipientType, err := common.CheckRecipient(recipient)
if err != nil {
// Invalid recipient format (not a phone number, address, or valid alias format)
res.FlagSet = append(res.FlagSet, flag_invalid_recipient) res.FlagSet = append(res.FlagSet, flag_invalid_recipient)
res.Content = recipient res.Content = recipient
@ -929,25 +925,54 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
return res, err return res, err
} }
publicKey, err := store.ReadEntry(ctx, recipient, common.DATA_PUBLIC_KEY) switch recipientType {
if err != nil { case "phone number":
if db.IsNotFound(err) { // Check if the phone number is registered
logg.InfoCtxf(ctx, "Unregistered number") publicKey, err := store.ReadEntry(ctx, recipient, common.DATA_PUBLIC_KEY)
if err != nil {
if db.IsNotFound(err) {
logg.InfoCtxf(ctx, "Unregistered phone number: %s", recipient)
res.FlagSet = append(res.FlagSet, flag_invalid_recipient_with_invite)
res.Content = recipient
return res, nil
}
res.FlagSet = append(res.FlagSet, flag_invalid_recipient_with_invite) logg.ErrorCtxf(ctx, "failed to read publicKey entry with", "key", common.DATA_PUBLIC_KEY, "error", err)
res.Content = recipient return res, err
return res, nil
} }
logg.ErrorCtxf(ctx, "failed to read publicKey entry with", "key", common.DATA_PUBLIC_KEY, "error", err) // Save the publicKey as the recipient
return res, err err = store.WriteEntry(ctx, sessionId, common.DATA_RECIPIENT, publicKey)
} if err != nil {
logg.ErrorCtxf(ctx, "failed to write recipient entry with", "key", common.DATA_RECIPIENT, "value", string(publicKey), "error", err)
return res, err
}
err = store.WriteEntry(ctx, sessionId, common.DATA_RECIPIENT, publicKey) case "address":
if err != nil { // Save the valid Ethereum address as the recipient
logg.ErrorCtxf(ctx, "failed to write recipient entry with", "key", common.DATA_RECIPIENT, "value", string(publicKey), "error", err) err = store.WriteEntry(ctx, sessionId, common.DATA_RECIPIENT, []byte(recipient))
return res, nil if err != nil {
logg.ErrorCtxf(ctx, "failed to write recipient entry with", "key", common.DATA_RECIPIENT, "value", recipient, "error", err)
return res, err
}
case "alias":
// Call the API to validate and retrieve the address for the alias
r, aliasErr := h.accountService.CheckAliasAddress(ctx, recipient)
if aliasErr != nil {
res.FlagSet = append(res.FlagSet, flag_api_error)
res.Content = recipient
logg.ErrorCtxf(ctx, "failed on CheckAliasAddress", "error", aliasErr)
return res, err
}
// Alias validation succeeded, save the Ethereum address
err = store.WriteEntry(ctx, sessionId, common.DATA_RECIPIENT, []byte(r.Address))
if err != nil {
logg.ErrorCtxf(ctx, "failed to write recipient entry with", "key", common.DATA_RECIPIENT, "value", r.Address, "error", err)
return res, err
}
} }
} }