forked from Silverfish/proton-bridge
refactor: remove dead code
This commit is contained in:
@ -493,7 +493,7 @@ const customMessageTemplate = `
|
|||||||
<html>
|
<html>
|
||||||
<head></head>
|
<head></head>
|
||||||
<body style="font-family: Arial,'Helvetica Neue',Helvetica,sans-serif; font-size: 14px;">
|
<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/>
|
<strong>Decryption error</strong><br/>
|
||||||
Decryption of this message's encrypted content failed.
|
Decryption of this message's encrypted content failed.
|
||||||
<pre>{{.Error}}</pre>
|
<pre>{{.Error}}</pre>
|
||||||
@ -514,15 +514,18 @@ type customMessageData struct {
|
|||||||
Body string
|
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))
|
t := template.Must(template.New("customMessage").Parse(customMessageTemplate))
|
||||||
|
|
||||||
b := new(bytes.Buffer)
|
b := new(bytes.Buffer)
|
||||||
t.Execute(b, customMessageData{
|
|
||||||
Error: err.Error(),
|
if err = t.Execute(b, customMessageData{
|
||||||
|
Error: decodeError.Error(),
|
||||||
AttachBody: attachBody,
|
AttachBody: attachBody,
|
||||||
Body: m.Body,
|
Body: m.Body,
|
||||||
})
|
}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
m.MIMEType = pmapi.ContentTypeHTML
|
m.MIMEType = pmapi.ContentTypeHTML
|
||||||
m.Body = b.String()
|
m.Body = b.String()
|
||||||
@ -531,6 +534,8 @@ func (im *imapMailbox) customMessage(m *pmapi.Message, err error, attachBody boo
|
|||||||
if m.Header == nil {
|
if m.Header == nil {
|
||||||
m.Header = make(mail.Header)
|
m.Header = make(mail.Header)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (im *imapMailbox) writeMessageBody(w io.Writer, m *pmapi.Message) (err error) {
|
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)
|
kr := im.user.client.KeyRingForAddressID(m.AddressID)
|
||||||
err = message.WriteBody(w, kr, m)
|
err = message.WriteBody(w, kr, m)
|
||||||
if err != nil {
|
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)
|
_, _ = io.WriteString(w, m.Body)
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
@ -672,7 +679,9 @@ func (im *imapMailbox) buildMessage(m *pmapi.Message) (structure *message.BodySt
|
|||||||
|
|
||||||
if errDecrypt != nil && errDecrypt != openpgperrors.ErrSignatureExpired {
|
if errDecrypt != nil && errDecrypt != openpgperrors.ErrSignatureExpired {
|
||||||
errNoCache.add(errDecrypt)
|
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.
|
// 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
|
return nil, nil, err
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
errNoCache.add(err)
|
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)
|
structure, msgBody, err = im.buildMessageInner(m, kr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
|||||||
@ -22,15 +22,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
pmmime "github.com/ProtonMail/proton-bridge/pkg/mime"
|
|
||||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
"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 {
|
func GetBoundary(m *pmapi.Message) string {
|
||||||
// The boundary needs to be deterministic because messages are not supposed to
|
// The boundary needs to be deterministic because messages are not supposed to
|
||||||
// change.
|
// change.
|
||||||
@ -43,85 +37,6 @@ func GetRelatedBoundary(m *pmapi.Message) string {
|
|||||||
return fmt.Sprintf("%x", sha512.Sum512_256([]byte(m.ID+m.ID)))
|
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) {
|
func SeparateInlineAttachments(m *pmapi.Message) (atts, inlines []*pmapi.Attachment) {
|
||||||
for _, att := range m.Attachments {
|
for _, att := range m.Attachments {
|
||||||
if strings.Contains(att.Header.Get("Content-Disposition"), "inline") {
|
if strings.Contains(att.Header.Get("Content-Disposition"), "inline") {
|
||||||
@ -132,57 +47,3 @@ func SeparateInlineAttachments(m *pmapi.Message) (atts, inlines []*pmapi.Attachm
|
|||||||
}
|
}
|
||||||
return
|
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
|
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) {
|
func (bs *BodyStructure) IMAPBodyStructure(currentPart []int) (imapBS *imap.BodyStructure, err error) {
|
||||||
var info *sectionInfo
|
var info *sectionInfo
|
||||||
if info, err = bs.getInfo(currentPart); err != nil {
|
if info, err = bs.getInfo(currentPart); err != nil {
|
||||||
|
|||||||
@ -59,8 +59,6 @@ func TestDecodeHeader(t *testing.T) {
|
|||||||
for _, val := range testData {
|
for _, val := range testData {
|
||||||
if decoded, err := DecodeHeader(val.raw); strings.Compare(val.expected, decoded) != 0 {
|
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)
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if continuation != nil {
|
for paramKey, contMap := range continuation {
|
||||||
for paramKey, contMap := range continuation {
|
value, err := mergeContinuations(paramKey, contMap)
|
||||||
value, err := mergeContinuations(paramKey, contMap)
|
if err == nil {
|
||||||
if err == nil {
|
params[paramKey+"*"] = value
|
||||||
params[paramKey+"*"] = value
|
continue
|
||||||
continue
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback.
|
// Fallback.
|
||||||
log.Errorln("Merge param", paramKey, ":", err)
|
log.Errorln("Merge param", paramKey, ":", err)
|
||||||
for ck, cv := range contMap {
|
for ck, cv := range contMap {
|
||||||
params[ck] = cv
|
params[ck] = cv
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,6 @@
|
|||||||
package pmmime
|
package pmmime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -106,50 +105,6 @@ func NewMimeVisitor(targetAccepter VisitAcceptor) *MimeVisitor {
|
|||||||
return &MimeVisitor{targetAccepter}
|
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) {
|
func GetAllChildParts(part io.Reader, h textproto.MIMEHeader) (parts []io.Reader, headers []textproto.MIMEHeader, err error) {
|
||||||
mediaType, params, err := getContentType(h)
|
mediaType, params, err := getContentType(h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -272,25 +227,6 @@ func parseAddressComment(raw string) string {
|
|||||||
return strings.Join(parsed, ", ")
|
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) {
|
func decodePart(partReader io.Reader, header textproto.MIMEHeader) (decodedPart io.Reader) {
|
||||||
decodedPart = DecodeContentEncoding(partReader, header.Get("Content-Transfer-Encoding"))
|
decodedPart = DecodeContentEncoding(partReader, header.Get("Content-Transfer-Encoding"))
|
||||||
if decodedPart == nil {
|
if decodedPart == nil {
|
||||||
|
|||||||
@ -60,6 +60,9 @@ func androidParse(mimeBody string) (body, headers string, atts, attHeaders []str
|
|||||||
|
|
||||||
h := textproto.MIMEHeader(mm.Header)
|
h := textproto.MIMEHeader(mm.Header)
|
||||||
mmBodyData, err := ioutil.ReadAll(mm.Body)
|
mmBodyData, err := ioutil.ReadAll(mm.Body)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
printAccepter := NewMIMEPrinter()
|
printAccepter := NewMIMEPrinter()
|
||||||
bodyCollector := NewBodyCollector(printAccepter)
|
bodyCollector := NewBodyCollector(printAccepter)
|
||||||
|
|||||||
Reference in New Issue
Block a user