forked from Silverfish/proton-bridge
refactor: remove dead code
This commit is contained in:
@ -493,7 +493,7 @@ const customMessageTemplate = `
|
||||
<html>
|
||||
<head></head>
|
||||
<body style="font-family: Arial,'Helvetica Neue',Helvetica,sans-serif; font-size: 14px;">
|
||||
<div style="color:#555; background-color:#cf9696; padding:20px; border-radius: 4px;">
|
||||
<div style="color:#555; background-color:#cf9696; padding:20px; border-radius: 4px;">
|
||||
<strong>Decryption error</strong><br/>
|
||||
Decryption of this message's encrypted content failed.
|
||||
<pre>{{.Error}}</pre>
|
||||
@ -514,15 +514,18 @@ type customMessageData struct {
|
||||
Body string
|
||||
}
|
||||
|
||||
func (im *imapMailbox) customMessage(m *pmapi.Message, err error, attachBody bool) {
|
||||
func (im *imapMailbox) makeCustomMessage(m *pmapi.Message, decodeError error, attachBody bool) (err error) {
|
||||
t := template.Must(template.New("customMessage").Parse(customMessageTemplate))
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
t.Execute(b, customMessageData{
|
||||
Error: err.Error(),
|
||||
|
||||
if err = t.Execute(b, customMessageData{
|
||||
Error: decodeError.Error(),
|
||||
AttachBody: attachBody,
|
||||
Body: m.Body,
|
||||
})
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
m.MIMEType = pmapi.ContentTypeHTML
|
||||
m.Body = b.String()
|
||||
@ -531,6 +534,8 @@ func (im *imapMailbox) customMessage(m *pmapi.Message, err error, attachBody boo
|
||||
if m.Header == nil {
|
||||
m.Header = make(mail.Header)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (im *imapMailbox) writeMessageBody(w io.Writer, m *pmapi.Message) (err error) {
|
||||
@ -546,7 +551,9 @@ func (im *imapMailbox) writeMessageBody(w io.Writer, m *pmapi.Message) (err erro
|
||||
kr := im.user.client.KeyRingForAddressID(m.AddressID)
|
||||
err = message.WriteBody(w, kr, m)
|
||||
if err != nil {
|
||||
im.customMessage(m, err, true)
|
||||
if customMessageErr := im.makeCustomMessage(m, err, true); customMessageErr != nil {
|
||||
im.log.WithError(customMessageErr).Warn("Failed to make custom message")
|
||||
}
|
||||
_, _ = io.WriteString(w, m.Body)
|
||||
err = nil
|
||||
}
|
||||
@ -672,7 +679,9 @@ func (im *imapMailbox) buildMessage(m *pmapi.Message) (structure *message.BodySt
|
||||
|
||||
if errDecrypt != nil && errDecrypt != openpgperrors.ErrSignatureExpired {
|
||||
errNoCache.add(errDecrypt)
|
||||
im.customMessage(m, errDecrypt, true)
|
||||
if customMessageErr := im.makeCustomMessage(m, errDecrypt, true); customMessageErr != nil {
|
||||
im.log.WithError(customMessageErr).Warn("Failed to make custom message")
|
||||
}
|
||||
}
|
||||
|
||||
// Inner function can fail even when message is decrypted.
|
||||
@ -686,7 +695,9 @@ func (im *imapMailbox) buildMessage(m *pmapi.Message) (structure *message.BodySt
|
||||
return nil, nil, err
|
||||
} else if err != nil {
|
||||
errNoCache.add(err)
|
||||
im.customMessage(m, err, true)
|
||||
if customMessageErr := im.makeCustomMessage(m, err, true); customMessageErr != nil {
|
||||
im.log.WithError(customMessageErr).Warn("Failed to make custom message")
|
||||
}
|
||||
structure, msgBody, err = im.buildMessageInner(m, kr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
||||
@ -22,15 +22,9 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
pmmime "github.com/ProtonMail/proton-bridge/pkg/mime"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
"github.com/emersion/go-imap"
|
||||
"github.com/jhillyerd/enmime"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const textPlain = "text/plain"
|
||||
|
||||
func GetBoundary(m *pmapi.Message) string {
|
||||
// The boundary needs to be deterministic because messages are not supposed to
|
||||
// change.
|
||||
@ -43,85 +37,6 @@ func GetRelatedBoundary(m *pmapi.Message) string {
|
||||
return fmt.Sprintf("%x", sha512.Sum512_256([]byte(m.ID+m.ID)))
|
||||
}
|
||||
|
||||
func GetBodyStructure(m *pmapi.Message) (bs *imap.BodyStructure) { //nolint[funlen]
|
||||
bs = &imap.BodyStructure{
|
||||
MIMEType: "multipart",
|
||||
MIMESubType: "mixed",
|
||||
Params: map[string]string{"boundary": GetBoundary(m)},
|
||||
}
|
||||
var inlineParts []*imap.BodyStructure
|
||||
var attParts []*imap.BodyStructure
|
||||
|
||||
for _, att := range m.Attachments {
|
||||
typeParts := strings.SplitN(att.MIMEType, "/", 2)
|
||||
if len(typeParts) != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
if typeParts[0] == "application" && typeParts[1] == "pgp-encrypted" {
|
||||
typeParts[1] = "octet-stream"
|
||||
}
|
||||
|
||||
part := &imap.BodyStructure{
|
||||
MIMEType: typeParts[0],
|
||||
MIMESubType: typeParts[1],
|
||||
Params: map[string]string{"name": att.Name},
|
||||
Encoding: "base64",
|
||||
}
|
||||
|
||||
if strings.Contains(att.Header.Get("Content-Disposition"), "inline") {
|
||||
part.Disposition = "inline"
|
||||
inlineParts = append(inlineParts, part)
|
||||
} else {
|
||||
part.Disposition = "attachment"
|
||||
attParts = append(attParts, part)
|
||||
}
|
||||
}
|
||||
|
||||
if len(inlineParts) > 0 {
|
||||
// Set to multipart-related for inline attachments.
|
||||
relatedPart := &imap.BodyStructure{
|
||||
MIMEType: "multipart",
|
||||
MIMESubType: "related",
|
||||
Params: map[string]string{"boundary": GetRelatedBoundary(m)},
|
||||
}
|
||||
|
||||
subType := "html"
|
||||
|
||||
if m.MIMEType == textPlain {
|
||||
subType = "plain"
|
||||
}
|
||||
|
||||
relatedPart.Parts = append(relatedPart.Parts, &imap.BodyStructure{
|
||||
MIMEType: "text",
|
||||
MIMESubType: subType,
|
||||
Params: map[string]string{"charset": "utf-8"},
|
||||
Encoding: "quoted-printable",
|
||||
Disposition: "inline",
|
||||
})
|
||||
|
||||
bs.Parts = append(bs.Parts, relatedPart)
|
||||
} else {
|
||||
subType := "html"
|
||||
|
||||
if m.MIMEType == textPlain {
|
||||
subType = "plain"
|
||||
}
|
||||
|
||||
bs.Parts = append(bs.Parts, &imap.BodyStructure{
|
||||
MIMEType: "text",
|
||||
MIMESubType: subType,
|
||||
Params: map[string]string{"charset": "utf-8"},
|
||||
Encoding: "quoted-printable",
|
||||
Disposition: "inline",
|
||||
})
|
||||
}
|
||||
|
||||
bs.Parts = append(bs.Parts, attParts...)
|
||||
|
||||
return bs
|
||||
}
|
||||
|
||||
func SeparateInlineAttachments(m *pmapi.Message) (atts, inlines []*pmapi.Attachment) {
|
||||
for _, att := range m.Attachments {
|
||||
if strings.Contains(att.Header.Get("Content-Disposition"), "inline") {
|
||||
@ -132,57 +47,3 @@ func SeparateInlineAttachments(m *pmapi.Message) (atts, inlines []*pmapi.Attachm
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetMIMEBodyStructure(m *pmapi.Message, parsedMsg *enmime.Envelope) (bs *imap.BodyStructure, err error) {
|
||||
// We recursively look through the MIME structure.
|
||||
root := parsedMsg.Root
|
||||
if root == nil {
|
||||
return GetBodyStructure(m), nil
|
||||
}
|
||||
|
||||
mediaType, params, err := pmmime.ParseMediaType(root.ContentType)
|
||||
if err != nil {
|
||||
log.Warnf("Cannot parse Content-Type '%v': %v", root.ContentType, err)
|
||||
err = nil
|
||||
mediaType = textPlain
|
||||
}
|
||||
|
||||
typeParts := strings.SplitN(mediaType, "/", 2)
|
||||
|
||||
bs = &imap.BodyStructure{
|
||||
MIMEType: typeParts[0],
|
||||
Params: params,
|
||||
}
|
||||
|
||||
if len(typeParts) > 1 {
|
||||
bs.MIMESubType = typeParts[1]
|
||||
}
|
||||
|
||||
bs.Parts = getChildrenParts(root)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getChildrenParts(root *enmime.Part) (parts []*imap.BodyStructure) {
|
||||
for child := root.FirstChild; child != nil; child = child.NextSibling {
|
||||
mediaType, params, err := pmmime.ParseMediaType(child.ContentType)
|
||||
if err != nil {
|
||||
log.Warnf("Cannot parse Content-Type '%v': %v", child.ContentType, err)
|
||||
mediaType = textPlain
|
||||
}
|
||||
typeParts := strings.SplitN(mediaType, "/", 2)
|
||||
childrenParts := getChildrenParts(child)
|
||||
part := &imap.BodyStructure{
|
||||
MIMEType: typeParts[0],
|
||||
Params: params,
|
||||
Encoding: child.Charset,
|
||||
Disposition: child.Disposition,
|
||||
Parts: childrenParts,
|
||||
}
|
||||
if len(typeParts) > 1 {
|
||||
part.MIMESubType = typeParts[1]
|
||||
}
|
||||
parts = append(parts, part)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -347,14 +347,6 @@ func (bs *BodyStructure) GetSectionHeader(sectionPath []int) (header textproto.M
|
||||
return
|
||||
}
|
||||
|
||||
func (bs *BodyStructure) Size() uint32 {
|
||||
info, err := bs.getInfo([]int{})
|
||||
if err != nil {
|
||||
return uint32(0)
|
||||
}
|
||||
return uint32(info.size)
|
||||
}
|
||||
|
||||
func (bs *BodyStructure) IMAPBodyStructure(currentPart []int) (imapBS *imap.BodyStructure, err error) {
|
||||
var info *sectionInfo
|
||||
if info, err = bs.getInfo(currentPart); err != nil {
|
||||
|
||||
@ -59,8 +59,6 @@ func TestDecodeHeader(t *testing.T) {
|
||||
for _, val := range testData {
|
||||
if decoded, err := DecodeHeader(val.raw); strings.Compare(val.expected, decoded) != 0 {
|
||||
t.Errorf("Incorrect decoding of header %q expected %q but have %q; Error %v", val.raw, val.expected, decoded, err)
|
||||
} else {
|
||||
// fmt.Println("Header", val.raw, "successfully decoded", decoded, ". Error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,19 +87,17 @@ func changeEncodingAndKeepLastParamDefinition(v string) (out string, err error)
|
||||
return
|
||||
}
|
||||
|
||||
if continuation != nil {
|
||||
for paramKey, contMap := range continuation {
|
||||
value, err := mergeContinuations(paramKey, contMap)
|
||||
if err == nil {
|
||||
params[paramKey+"*"] = value
|
||||
continue
|
||||
}
|
||||
for paramKey, contMap := range continuation {
|
||||
value, err := mergeContinuations(paramKey, contMap)
|
||||
if err == nil {
|
||||
params[paramKey+"*"] = value
|
||||
continue
|
||||
}
|
||||
|
||||
// Fallback.
|
||||
log.Errorln("Merge param", paramKey, ":", err)
|
||||
for ck, cv := range contMap {
|
||||
params[ck] = cv
|
||||
}
|
||||
// Fallback.
|
||||
log.Errorln("Merge param", paramKey, ":", err)
|
||||
for ck, cv := range contMap {
|
||||
params[ck] = cv
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
package pmmime
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -106,50 +105,6 @@ func NewMimeVisitor(targetAccepter VisitAcceptor) *MimeVisitor {
|
||||
return &MimeVisitor{targetAccepter}
|
||||
}
|
||||
|
||||
func GetRawMimePart(rawdata io.Reader, boundary string) (io.Reader, io.Reader) {
|
||||
b, _ := ioutil.ReadAll(rawdata)
|
||||
tee := bytes.NewReader(b)
|
||||
|
||||
reader := bufio.NewReader(bytes.NewReader(b))
|
||||
byteBoundary := []byte(boundary)
|
||||
bodyBuffer := &bytes.Buffer{}
|
||||
for {
|
||||
line, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
return tee, bytes.NewReader(bodyBuffer.Bytes())
|
||||
}
|
||||
if bytes.HasPrefix(line, byteBoundary) {
|
||||
break
|
||||
}
|
||||
}
|
||||
lineEndingLength := 0
|
||||
for {
|
||||
line, isPrefix, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
return tee, bytes.NewReader(bodyBuffer.Bytes())
|
||||
}
|
||||
if bytes.HasPrefix(line, byteBoundary) {
|
||||
break
|
||||
}
|
||||
lineEndingLength = 0
|
||||
bodyBuffer.Write(line)
|
||||
if !isPrefix {
|
||||
reader.UnreadByte()
|
||||
reader.UnreadByte()
|
||||
token, _ := reader.ReadByte()
|
||||
if token == '\r' {
|
||||
lineEndingLength++
|
||||
bodyBuffer.WriteByte(token)
|
||||
}
|
||||
lineEndingLength++
|
||||
bodyBuffer.WriteByte(token)
|
||||
}
|
||||
}
|
||||
ioutil.ReadAll(reader)
|
||||
data := bodyBuffer.Bytes()
|
||||
return tee, bytes.NewReader(data[0 : len(data)-lineEndingLength])
|
||||
}
|
||||
|
||||
func GetAllChildParts(part io.Reader, h textproto.MIMEHeader) (parts []io.Reader, headers []textproto.MIMEHeader, err error) {
|
||||
mediaType, params, err := getContentType(h)
|
||||
if err != nil {
|
||||
@ -272,25 +227,6 @@ func parseAddressComment(raw string) string {
|
||||
return strings.Join(parsed, ", ")
|
||||
}
|
||||
|
||||
func checkHeaders(headers []textproto.MIMEHeader) bool {
|
||||
foundAttachment := false
|
||||
|
||||
for i := 0; i < len(headers); i++ {
|
||||
h := headers[i]
|
||||
|
||||
mediaType, _, _ := getContentType(h)
|
||||
|
||||
if !strings.HasPrefix(mediaType, "text/") {
|
||||
foundAttachment = true
|
||||
} else if foundAttachment {
|
||||
// This means that there is a text part after the first attachment,
|
||||
// so we will have to convert the body from plain->HTML.
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func decodePart(partReader io.Reader, header textproto.MIMEHeader) (decodedPart io.Reader) {
|
||||
decodedPart = DecodeContentEncoding(partReader, header.Get("Content-Transfer-Encoding"))
|
||||
if decodedPart == nil {
|
||||
|
||||
@ -60,6 +60,9 @@ func androidParse(mimeBody string) (body, headers string, atts, attHeaders []str
|
||||
|
||||
h := textproto.MIMEHeader(mm.Header)
|
||||
mmBodyData, err := ioutil.ReadAll(mm.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
printAccepter := NewMIMEPrinter()
|
||||
bodyCollector := NewBodyCollector(printAccepter)
|
||||
|
||||
Reference in New Issue
Block a user