diff --git a/pkg/analyzer/content.go b/pkg/analyzer/content.go index 0d53c94..95e32aa 100644 --- a/pkg/analyzer/content.go +++ b/pkg/analyzer/content.go @@ -27,7 +27,6 @@ import ( "net/http" "net/url" "regexp" - "slices" "strings" "time" "unicode" @@ -38,9 +37,8 @@ import ( // ContentAnalyzer analyzes email content (HTML, links, images) type ContentAnalyzer struct { - Timeout time.Duration - httpClient *http.Client - listUnsubscribeURLs []string // URLs from List-Unsubscribe header + Timeout time.Duration + httpClient *http.Client } // NewContentAnalyzer creates a new content analyzer with configurable timeout @@ -112,9 +110,6 @@ func (c *ContentAnalyzer) AnalyzeContent(email *EmailMessage) *ContentResults { results.IsMultipart = len(email.Parts) > 1 - // Parse List-Unsubscribe header URLs for use in link detection - c.listUnsubscribeURLs = email.GetListUnsubscribeURLs() - // Get HTML and text parts htmlParts := email.GetHTMLParts() textParts := email.GetTextParts() @@ -336,11 +331,6 @@ func (c *ContentAnalyzer) getAttr(n *html.Node, key string) string { // isUnsubscribeLink checks if a link is an unsubscribe link func (c *ContentAnalyzer) isUnsubscribeLink(href string, node *html.Node) bool { - // First check: does the href match a URL from the List-Unsubscribe header? - if slices.Contains(c.listUnsubscribeURLs, href) { - return true - } - // Check href for unsubscribe keywords lowerHref := strings.ToLower(href) unsubKeywords := []string{"unsubscribe", "opt-out", "optout", "remove", "list-unsubscribe"} @@ -449,8 +439,7 @@ func (c *ContentAnalyzer) hasDomainMisalignment(href, linkText string) bool { // Extract the actual destination domain/email based on scheme var actualDomain string - switch parsedURL.Scheme { - case "mailto": + if parsedURL.Scheme == "mailto" { // Extract email address from mailto: URL // Format can be: mailto:user@domain.com or mailto:user@domain.com?subject=... mailtoAddr := parsedURL.Opaque @@ -468,8 +457,7 @@ func (c *ContentAnalyzer) hasDomainMisalignment(href, linkText string) bool { } else { return false // Invalid mailto } - case "http": - case "https": + } else if parsedURL.Scheme == "http" || parsedURL.Scheme == "https" { // Check if URL has a host if parsedURL.Host == "" { return false @@ -481,7 +469,7 @@ func (c *ContentAnalyzer) hasDomainMisalignment(href, linkText string) bool { actualDomain = actualDomain[:idx] } actualDomain = strings.ToLower(actualDomain) - default: + } else { // Skip checks for other URL schemes (tel, etc.) return false } @@ -504,8 +492,10 @@ func (c *ContentAnalyzer) hasDomainMisalignment(href, linkText string) bool { "email us", "contact us", "send email", "get in touch", "reach out", "contact", "email", "write to us", } - if slices.Contains(genericTexts, linkText) { - return false + for _, generic := range genericTexts { + if linkText == generic { + return false + } } // Extract domain-like patterns from link text using regex @@ -572,8 +562,10 @@ func (c *ContentAnalyzer) isSuspiciousURL(urlStr string, parsedURL *url.URL) boo "bit.ly", "tinyurl.com", "goo.gl", "ow.ly", "t.co", "buff.ly", "is.gd", "bl.ink", "short.io", } - if slices.Contains(shorteners, strings.ToLower(parsedURL.Host)) { - return true + for _, shortener := range shorteners { + if strings.ToLower(parsedURL.Host) == shortener { + return true + } } // Check for excessive subdomains (possible obfuscation) diff --git a/pkg/analyzer/parser.go b/pkg/analyzer/parser.go index 79d8310..ca3cb46 100644 --- a/pkg/analyzer/parser.go +++ b/pkg/analyzer/parser.go @@ -301,20 +301,3 @@ func (e *EmailMessage) GetHeaderValue(key string) string { func (e *EmailMessage) HasHeader(key string) bool { return e.Header.Get(key) != "" } - -// GetListUnsubscribeURLs parses the List-Unsubscribe header and returns all URLs. -// The header format is: , , ... -func (e *EmailMessage) GetListUnsubscribeURLs() []string { - value := e.Header.Get("List-Unsubscribe") - if value == "" { - return nil - } - var urls []string - for _, part := range strings.Split(value, ",") { - part = strings.TrimSpace(part) - if strings.HasPrefix(part, "<") && strings.HasSuffix(part, ">") { - urls = append(urls, part[1:len(part)-1]) - } - } - return urls -}