A minimal email TUI where you read with Markdown and write in Neovim. neomd.ssp.sh/docs
email markdown neovim tui
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix review

+17 -5
+15 -3
internal/integration_test.go
··· 75 75 }) 76 76 } 77 77 78 + // ccRecipient returns ", addr" if NEOMD_TEST_CC is set, empty string otherwise. 79 + // Used to optionally CC test emails to a live inbox for manual inspection. 80 + func (e testEnv) ccRecipient() string { 81 + if cc := os.Getenv("NEOMD_TEST_CC"); cc != "" { 82 + return ", " + cc 83 + } 84 + return "" 85 + } 86 + 78 87 func (e testEnv) smtpConfig() smtp.Config { 79 88 return smtp.Config{ 80 89 Host: e.smtpHost, ··· 968 977 969 978 *sent from [neomd](https://neomd.ssp.sh)*` 970 979 971 - err := smtp.Send(env.smtpConfig(), env.user+", simon@ssp.sh", "", "", subject, body, []string{realDoc, fakeImg}) 980 + err := smtp.Send(env.smtpConfig(), env.user+env.ccRecipient(), "", "", subject, body, []string{realDoc, fakeImg}) 972 981 if err != nil { 973 982 t.Fatalf("Send: %v", err) 974 983 } ··· 1041 1050 1042 1051 // Send normally — the HTML will contain the markdown-rendered content. 1043 1052 // To also test raw HTML injection, we build a custom message with injected tags. 1044 - raw, err := smtp.BuildMessage(env.from, env.user+", simon@ssp.sh", "", subject, body, nil, "") 1053 + raw, err := smtp.BuildMessage(env.from, env.user+env.ccRecipient(), "", subject, body, nil, "") 1045 1054 if err != nil { 1046 1055 t.Fatalf("BuildMessage: %v", err) 1047 1056 } ··· 1059 1068 rawStr = rawStr[:idx] + injection + rawStr[idx:] 1060 1069 } 1061 1070 1062 - allRecipients := []string{env.user, "simon@ssp.sh"} 1071 + allRecipients := []string{env.user} 1072 + if cc := env.ccRecipient(); cc != "" { 1073 + allRecipients = append(allRecipients, strings.TrimPrefix(cc, ", ")) 1074 + } 1063 1075 if err := smtp.SendRaw(env.smtpConfig(), allRecipients, []byte(rawStr)); err != nil { 1064 1076 t.Fatalf("SendRaw: %v", err) 1065 1077 }
+2 -2
internal/render/html.go
··· 68 68 // SanitizeForBrowser injects a restrictive CSP into raw HTML to block scripts 69 69 // and frames while allowing images. For use when opening untrusted email HTML. 70 70 func SanitizeForBrowser(html string) string { 71 - // Skip if CSP already present (e.g. from htmlTemplate via ToHTML). 72 - if strings.Contains(html, "Content-Security-Policy") { 71 + // Skip if our exact CSP is already present (e.g. from htmlTemplate via ToHTML). 72 + if strings.Contains(html, browserCSP) { 73 73 return html 74 74 } 75 75 // Insert after <head> if present, otherwise prepend.