/
messages.go
185 lines (162 loc) · 4.21 KB
/
messages.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package handlers
import (
"fmt"
"net/http"
"net/url"
"regexp"
"strings"
"github.com/axllent/mailpit/config"
"github.com/axllent/mailpit/internal/storage"
"github.com/gorilla/mux"
)
// RedirectToLatestMessage (method: GET) redirects the web UI to the latest message
func RedirectToLatestMessage(w http.ResponseWriter, r *http.Request) {
var messages []storage.MessageSummary
var err error
search := strings.TrimSpace(r.URL.Query().Get("query"))
if search != "" {
messages, _, err = storage.Search(search, "", 0, 1)
if err != nil {
httpError(w, err.Error())
return
}
} else {
messages, err = storage.List(0, 1)
if err != nil {
httpError(w, err.Error())
return
}
}
uri := config.Webroot
if len(messages) == 1 {
uri, err = url.JoinPath(uri, "/view/"+messages[0].ID)
if err != nil {
httpError(w, err.Error())
return
}
}
http.Redirect(w, r, uri, 302)
}
// GetMessageHTML (method: GET) returns a rendered version of a message's HTML part
func GetMessageHTML(w http.ResponseWriter, r *http.Request) {
// swagger:route GET /view/{ID}.html testing GetMessageHTML
//
// # Render message HTML part
//
// Renders just the message's HTML part which can be used for UI integration testing.
// Attached inline images are modified to link to the API provided they exist.
// Note that is the message does not contain a HTML part then an 404 error is returned.
//
// The ID can be set to `latest` to return the latest message.
//
// Produces:
// - text/html
//
// Schemes: http, https
//
// Parameters:
// + name: ID
// in: path
// description: Database ID or latest
// required: true
// type: string
//
// Responses:
// 200: HTMLResponse
// default: ErrorResponse
vars := mux.Vars(r)
id := vars["id"]
if id == "latest" {
var err error
id, err = storage.LatestID(r)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, err.Error())
return
}
}
msg, err := storage.GetMessage(id)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, "Message not found")
return
}
if msg.HTML == "" {
w.WriteHeader(404)
fmt.Fprint(w, "This message does not contain a HTML part")
return
}
html := linkInlineImages(msg)
w.Header().Add("Content-Type", "text/html; charset=utf-8")
_, _ = w.Write([]byte(html))
}
// GetMessageText (method: GET) returns a message's text part
func GetMessageText(w http.ResponseWriter, r *http.Request) {
// swagger:route GET /view/{ID}.txt testing GetMessageText
//
// # Render message text part
//
// Renders just the message's text part which can be used for UI integration testing.
//
// The ID can be set to `latest` to return the latest message.
//
// Produces:
// - text/plain
//
// Schemes: http, https
//
// Parameters:
// + name: ID
// in: path
// description: Database ID or latest
// required: true
// type: string
//
// Responses:
// 200: TextResponse
// default: ErrorResponse
vars := mux.Vars(r)
id := vars["id"]
if id == "latest" {
var err error
id, err = storage.LatestID(r)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, err.Error())
return
}
}
msg, err := storage.GetMessage(id)
if err != nil {
w.WriteHeader(404)
fmt.Fprint(w, "Message not found")
return
}
w.Header().Add("Content-Type", "text/plain; charset=utf-8")
_, _ = w.Write([]byte(msg.Text))
}
// This will rewrite all inline image paths to API URLs
func linkInlineImages(msg *storage.Message) string {
html := msg.HTML
for _, a := range msg.Inline {
if a.ContentID != "" {
re := regexp.MustCompile(`(?i)(=["\']?)(cid:` + regexp.QuoteMeta(a.ContentID) + `)(["|\'|\\s|\\/|>|;])`)
u := config.Webroot + "api/v1/message/" + msg.ID + "/part/" + a.PartID
matches := re.FindAllStringSubmatch(html, -1)
for _, m := range matches {
html = strings.ReplaceAll(html, m[0], m[1]+u+m[3])
}
}
}
for _, a := range msg.Attachments {
if a.ContentID != "" {
re := regexp.MustCompile(`(?i)(=["\']?)(cid:` + regexp.QuoteMeta(a.ContentID) + `)(["|\'|\\s|\\/|>|;])`)
u := config.Webroot + "api/v1/message/" + msg.ID + "/part/" + a.PartID
matches := re.FindAllStringSubmatch(html, -1)
for _, m := range matches {
html = strings.ReplaceAll(html, m[0], m[1]+u+m[3])
}
}
}
return html
}