diff --git a/apps/backend/miogest_handler.go b/apps/backend/miogest_handler.go index 6415106..307715b 100644 --- a/apps/backend/miogest_handler.go +++ b/apps/backend/miogest_handler.go @@ -262,7 +262,8 @@ func processLocatore(tmp *typesdefs.AnnuncioParsed, annuncio *typesdefs.Annuncio if annuncio.Clienti == nil || annuncio.Clienti.Cliente == nil { return } - tmp.Email = annuncio.Clienti.Cliente.Email1 + + tmp.Email = parser.ParseEmail(annuncio.Clienti.Cliente.Email1) var number string for _, tel := range []*string{annuncio.Clienti.Cliente.Tel1, annuncio.Clienti.Cliente.Tel2, annuncio.Clienti.Cliente.Tel3} { diff --git a/apps/backend/parser/parser.go b/apps/backend/parser/parser.go index 4d7447d..4c1a65a 100644 --- a/apps/backend/parser/parser.go +++ b/apps/backend/parser/parser.go @@ -188,3 +188,89 @@ func ParseTipologia(t1, t2 *string) (tipo *string) { return utils.Ptr("Errore") } + +func ParseEmail(input *string) *string { + if input == nil { + return nil + } + email := strings.TrimLeft(*input, " ") + if email == "" { + return nil + } + parts := strings.Split(email, " ") + if len(parts) > 0 { + email = parts[0] + } + email = strings.TrimSpace(email) + if email == "" { + return nil + } + // Basic email validation + if !isValidEmail(email) { + return nil + } + + return &email +} + +func isValidEmail(email string) bool { + // Must contain exactly one @ symbol + atCount := strings.Count(email, "@") + if atCount != 1 { + return false + } + + // Split on @ to get local and domain parts + parts := strings.Split(email, "@") + if len(parts) != 2 { + return false + } + + local := parts[0] + domain := parts[1] + + // Local part cannot be empty + if local == "" { + return false + } + + // Domain part cannot be empty + if domain == "" { + return false + } + + // Domain must contain at least one dot + if !strings.Contains(domain, ".") { + return false + } + + // Domain cannot start or end with dot + if strings.HasPrefix(domain, ".") || strings.HasSuffix(domain, ".") { + return false + } + + // Domain cannot have consecutive dots + if strings.Contains(domain, "..") { + return false + } + + // Local part cannot start or end with dot + if strings.HasPrefix(local, ".") || strings.HasSuffix(local, ".") { + return false + } + + // Local part cannot have consecutive dots + if strings.Contains(local, "..") { + return false + } + + // Basic check for valid characters (this is simplified) + // In production, you might want to use a proper regex or email validation library + for _, char := range email { + if char == ' ' || char == '\t' || char == '\n' || char == '\r' { + return false + } + } + + return true +} diff --git a/apps/backend/parser/parser_test.go b/apps/backend/parser/parser_test.go index 2ed1acf..2cbc301 100644 --- a/apps/backend/parser/parser_test.go +++ b/apps/backend/parser/parser_test.go @@ -416,3 +416,67 @@ func TestProcessTipologia(t *testing.T) { } } } + +func TestParseEmail(t *testing.T) { + tests := []struct { + input *string + want *string + }{ + {input: utils.Ptr(" test@test.it "), want: utils.Ptr("test@test.it")}, + {input: utils.Ptr("user@example.com"), want: utils.Ptr("user@example.com")}, + {input: utils.Ptr("admin@domain.org"), want: utils.Ptr("admin@domain.org")}, + {input: utils.Ptr("contact@company.co.uk"), want: utils.Ptr("contact@company.co.uk")}, + {input: utils.Ptr("user.name@example.com"), want: utils.Ptr("user.name@example.com")}, + {input: utils.Ptr("user+tag@example.com"), want: utils.Ptr("user+tag@example.com")}, + {input: utils.Ptr("123@example.com"), want: utils.Ptr("123@example.com")}, + + // Emails with extra whitespace + {input: utils.Ptr(" email@test.com "), want: utils.Ptr("email@test.com")}, + {input: utils.Ptr("\temail@test.com\t"), want: utils.Ptr("email@test.com")}, + {input: utils.Ptr("\nemail@test.com\n"), want: utils.Ptr("email@test.com")}, + + // Invalid emails (should return nil) + {input: utils.Ptr("invalid-email"), want: nil}, + {input: utils.Ptr("@domain.com"), want: nil}, + {input: utils.Ptr("user@"), want: nil}, + {input: utils.Ptr("user@domain"), want: nil}, + {input: utils.Ptr("user.domain.com"), want: nil}, + {input: utils.Ptr("user@@domain.com"), want: nil}, + {input: utils.Ptr(""), want: nil}, + {input: utils.Ptr(" "), want: nil}, + {input: nil, want: nil}, + + // Edge cases + {input: utils.Ptr("a@b.co"), want: utils.Ptr("a@b.co")}, + {input: utils.Ptr("test@test-domain.com"), want: utils.Ptr("test@test-domain.com")}, + {input: utils.Ptr("user@sub.domain.com"), want: utils.Ptr("user@sub.domain.com")}, + {input: utils.Ptr("lui.stra2006@gmail.com - LUIGINA"), want: utils.Ptr("lui.stra2006@gmail.com")}, + } + for _, tt := range tests { + got := parser.ParseEmail(tt.input) + if tt.want == nil { + if got != nil { + + inputStr := "nil" + if tt.input != nil { + inputStr = *tt.input + } + t.Errorf("got %q, want nil, input: %q", *got, inputStr) + } + } else { + if got == nil { + inputStr := "nil" + if tt.input != nil { + inputStr = *tt.input + } + t.Errorf("got nil, want %q, input: %q", *tt.want, inputStr) + } else if *got != *tt.want { + inputStr := "nil" + if tt.input != nil { + inputStr = *tt.input + } + t.Errorf("got %q, want %q, input: %q", *got, *tt.want, inputStr) + } + } + } +}