@@ -18,6 +18,7 @@ import (
1818 "github.com/axllent/mailpit/server/websockets"
1919 "github.com/jhillyerd/enmime"
2020 "github.com/klauspost/compress/zstd"
21+ "github.com/mattn/go-shellwords"
2122 "github.com/ostafen/clover/v2"
2223)
2324
@@ -327,21 +328,58 @@ func List(mailbox string, start, limit int) ([]data.Summary, error) {
327328}
328329
329330// Search returns a summary of items mathing a search. It searched the SearchText field.
330- func Search (mailbox , search string , start , limit int ) ([]data.Summary , error ) {
331+ func Search (mailbox , s string , start , limit int ) ([]data.Summary , error ) {
331332 mailbox = sanitizeMailboxName (mailbox )
332333
333- sq := fmt .Sprintf ("(?i)%s" , cleanString (regexp .QuoteMeta (search )))
334+ s = strings .ToLower (s )
335+ s = strings .Replace (s , "'" , `\'` , - 1 )
336+ s = strings .Replace (s , "(" , `` , - 1 )
337+ s = strings .Replace (s , ")" , `` , - 1 )
338+ // add another quote if quotes are odd
339+ quotes := strings .Count (s , `"` )
340+ if quotes % 2 != 0 {
341+ s += `"`
342+ }
343+
344+ p := shellwords .NewParser ()
345+ args , err := p .Parse (s )
346+ if err != nil {
347+ return nil , errors .New ("Your search contains invalid characters" )
348+ }
349+
350+ results := []data.Summary {}
351+ include := []string {}
352+
353+ for _ , w := range args {
354+ word := cleanString (w )
355+ if word != "" {
356+ include = append (include , fmt .Sprintf ("%s" , regexp .QuoteMeta (word )))
357+ }
358+ }
359+
360+ if len (include ) == 0 {
361+ return results , nil
362+ }
363+
364+ var where clover.Criteria
365+
366+ for i , w := range include {
367+ if i == 0 {
368+ where = clover .Field ("SearchText" ).Like (w )
369+ } else {
370+ where = where .And (clover .Field ("SearchText" ).Like (w ))
371+ }
372+ }
373+
334374 q , err := db .FindAll (clover .NewQuery (mailbox ).
335375 Skip (start ).
336376 Limit (limit ).
337377 Sort (clover.SortOption {Field : "Created" , Direction : - 1 }).
338- Where (clover . Field ( "SearchText" ). Like ( sq ) ))
378+ Where (where ))
339379 if err != nil {
340380 return nil , err
341381 }
342382
343- results := []data.Summary {}
344-
345383 for _ , d := range q {
346384 cs := & data.Summary {}
347385 if err := d .Unmarshal (cs ); err != nil {
0 commit comments