recall: support pgp/mime messages
PGP/MIME messages are stored encrypted and/or signed in the draft folder for security reasons. Recall will open them through the lib.MessageView interface in order to display the message content properly in the composer tab. If the stored message was encrypted or signed, the recalled message in the composer will also be encrypted or signed. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
parent
a293a39454
commit
e19b411e52
1 changed files with 73 additions and 58 deletions
|
@ -139,67 +139,82 @@ func (Recall) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the main body part and add it to the editor
|
lib.NewMessageStoreView(msgInfo, store, aerc.Crypto, aerc.DecryptKeys,
|
||||||
// TODO: copy all parts of the message over?
|
func(msg lib.MessageView, err error) {
|
||||||
var (
|
|
||||||
path []int
|
|
||||||
part *models.BodyStructure
|
|
||||||
)
|
|
||||||
if len(msgInfo.BodyStructure.Parts) != 0 {
|
|
||||||
path = lib.FindPlaintext(msgInfo.BodyStructure, path)
|
|
||||||
}
|
|
||||||
part, err = msgInfo.BodyStructure.PartAtIndex(path)
|
|
||||||
if part == nil || err != nil {
|
|
||||||
part = msgInfo.BodyStructure
|
|
||||||
}
|
|
||||||
|
|
||||||
store.FetchBodyPart(msgInfo.Uid, path, func(reader io.Reader) {
|
|
||||||
header := message.Header{}
|
|
||||||
header.SetText(
|
|
||||||
"Content-Transfer-Encoding", part.Encoding)
|
|
||||||
header.SetContentType(part.MIMEType, part.Params)
|
|
||||||
header.SetText("Content-Description", part.Description)
|
|
||||||
entity, err := message.New(header, reader)
|
|
||||||
if err != nil {
|
|
||||||
aerc.PushError(err.Error())
|
|
||||||
addTab()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mreader := mail.NewReader(entity)
|
|
||||||
part, err := mreader.NextPart()
|
|
||||||
if err != nil {
|
|
||||||
aerc.PushError(err.Error())
|
|
||||||
addTab()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
composer.SetContents(part.Body)
|
|
||||||
addTab()
|
|
||||||
|
|
||||||
// add attachements if present
|
|
||||||
var mu sync.Mutex
|
|
||||||
parts := lib.FindAllNonMultipart(msgInfo.BodyStructure, nil, nil)
|
|
||||||
for _, p := range parts {
|
|
||||||
if lib.EqualParts(p, path) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
bs, err := msgInfo.BodyStructure.PartAtIndex(p)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
acct.Logger().Println("recall: PartAtIndex:", err)
|
aerc.PushError(err.Error())
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
store.FetchBodyPart(msgInfo.Uid, p, func(reader io.Reader) {
|
|
||||||
mime := fmt.Sprintf("%s/%s", bs.MIMEType, bs.MIMESubType)
|
|
||||||
name, ok := bs.Params["name"]
|
|
||||||
if !ok {
|
|
||||||
name = fmt.Sprintf("%s_%s_%d", bs.MIMEType, bs.MIMESubType, rand.Uint64())
|
|
||||||
}
|
|
||||||
mu.Lock()
|
|
||||||
composer.AddPartAttachment(name, mime, bs.Params, reader)
|
|
||||||
mu.Unlock()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
var (
|
||||||
|
path []int
|
||||||
|
part *models.BodyStructure
|
||||||
|
)
|
||||||
|
if len(msg.BodyStructure().Parts) != 0 {
|
||||||
|
path = lib.FindPlaintext(msg.BodyStructure(), path)
|
||||||
|
}
|
||||||
|
part, err = msg.BodyStructure().PartAtIndex(path)
|
||||||
|
if part == nil || err != nil {
|
||||||
|
part = msg.BodyStructure()
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.FetchBodyPart(path, func(reader io.Reader) {
|
||||||
|
header := message.Header{}
|
||||||
|
header.SetText(
|
||||||
|
"Content-Transfer-Encoding", part.Encoding)
|
||||||
|
header.SetContentType(part.MIMEType, part.Params)
|
||||||
|
header.SetText("Content-Description", part.Description)
|
||||||
|
entity, err := message.New(header, reader)
|
||||||
|
if err != nil {
|
||||||
|
aerc.PushError(err.Error())
|
||||||
|
addTab()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mreader := mail.NewReader(entity)
|
||||||
|
part, err := mreader.NextPart()
|
||||||
|
if err != nil {
|
||||||
|
aerc.PushError(err.Error())
|
||||||
|
addTab()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
composer.SetContents(part.Body)
|
||||||
|
if md := msg.MessageDetails(); md != nil {
|
||||||
|
if md.IsEncrypted {
|
||||||
|
composer.SetEncrypt(md.IsEncrypted)
|
||||||
|
}
|
||||||
|
if md.IsSigned {
|
||||||
|
composer.SetSign(md.IsSigned)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addTab()
|
||||||
|
|
||||||
|
// add attachements if present
|
||||||
|
var mu sync.Mutex
|
||||||
|
parts := lib.FindAllNonMultipart(msg.BodyStructure(), nil, nil)
|
||||||
|
for _, p := range parts {
|
||||||
|
if lib.EqualParts(p, path) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
bs, err := msg.BodyStructure().PartAtIndex(p)
|
||||||
|
if err != nil {
|
||||||
|
acct.Logger().Println("recall: PartAtIndex:", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
msg.FetchBodyPart(p, func(reader io.Reader) {
|
||||||
|
mime := fmt.Sprintf("%s/%s", bs.MIMEType, bs.MIMESubType)
|
||||||
|
name, ok := bs.Params["name"]
|
||||||
|
if !ok {
|
||||||
|
name = fmt.Sprintf("%s_%s_%d", bs.MIMEType, bs.MIMESubType, rand.Uint64())
|
||||||
|
}
|
||||||
|
mu.Lock()
|
||||||
|
composer.AddPartAttachment(name, mime, bs.Params, reader)
|
||||||
|
mu.Unlock()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue