message.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package libcobalt
  2. import (
  3. "github.com/ProtonMail/gopenpgp/helper"
  4. "notabug.org/apiote/gott"
  5. )
  6. type EmailAddress struct {
  7. Address string
  8. Name string
  9. }
  10. type Message struct {
  11. to []EmailAddress
  12. cc []EmailAddress
  13. bcc []EmailAddress
  14. Subject string
  15. MimeType string
  16. Body string
  17. action int // todo 0,1,2 – reply,rAll,fwd
  18. id string
  19. Parent string
  20. // todo attachments
  21. }
  22. func (m *Message) AddTo(to *EmailAddress) {
  23. m.to = append(m.to, *to)
  24. }
  25. func (m *Message) AddCc(cc *EmailAddress) {
  26. m.to = append(m.cc, *cc)
  27. }
  28. func (m *Message) AddBcc(bcc *EmailAddress) {
  29. m.to = append(m.bcc, *bcc)
  30. }
  31. type draftRequestMessage struct {
  32. ToList []EmailAddress
  33. CCList []EmailAddress
  34. BCCList []EmailAddress
  35. Subject string
  36. Unread int
  37. MIMEType string
  38. Sender EmailAddress
  39. AddressID string
  40. Body string
  41. ParentID string
  42. Action int
  43. id string
  44. AttachmentKeyPackets []interface{}
  45. }
  46. type draftRequest struct {
  47. Message draftRequestMessage
  48. }
  49. func selectEncryptKey(values ...interface{}) (interface{}, error) {
  50. address := values[1].(Account).selectedAddress
  51. encryptKeyPair, err := selectKey(address.keys, KEY_ENCRYPT)
  52. if err == nil {
  53. values[2] = encryptKeyPair.public
  54. }
  55. return gott.Tuple(values), err
  56. }
  57. func selectSignKey(values ...interface{}) (interface{}, error) {
  58. address := values[1].(Account).selectedAddress
  59. signKeyPair, err := selectKey(address.keys, KEY_SIGN)
  60. if err == nil {
  61. values[3] = signKeyPair.private
  62. }
  63. return gott.Tuple(values), err
  64. }
  65. func encryptBody(values ...interface{}) (interface{}, error) {
  66. message := values[0].(*Message)
  67. account := values[1].(Account)
  68. encryptKey := values[2].(string)
  69. signKey := values[3].(string)
  70. body, err := helper.EncryptSignMessageArmored(encryptKey, signKey, account.keyPassword, message.Body)
  71. if err == nil {
  72. message.Body = body
  73. values[0] = message
  74. }
  75. return gott.Tuple(values), err
  76. }
  77. func sanatiseMessageArrays(values ...interface{}) interface{} {
  78. message := values[0].(*Message)
  79. if message.to == nil {
  80. message.to = []EmailAddress{}
  81. }
  82. if message.cc == nil {
  83. message.cc = []EmailAddress{}
  84. }
  85. if message.bcc == nil {
  86. message.bcc = []EmailAddress{}
  87. }
  88. values[0] = message
  89. return gott.Tuple(values)
  90. }
  91. func convertMessageToDraft(values ...interface{}) interface{} {
  92. message := values[0].(*Message)
  93. account := values[1].(Account)
  94. address := account.selectedAddress
  95. draft := draftRequestMessage{
  96. ToList: message.to,
  97. CCList: message.cc,
  98. BCCList: message.bcc,
  99. Subject: message.Subject,
  100. Unread: 0,
  101. MIMEType: message.MimeType,
  102. Sender: EmailAddress{Name: address.displayName, Address: address.email},
  103. AddressID: address.id,
  104. Body: message.Body,
  105. ParentID: message.Parent,
  106. Action: message.action,
  107. id: message.id,
  108. AttachmentKeyPackets: []interface{}{},
  109. }
  110. values[0] = draftRequest{Message: draft}
  111. return gott.Tuple(values)
  112. }
  113. func updateMessage(values ...interface{}) interface{} {
  114. message := values[4].(*Message)
  115. response := values[0].(draftResponse)
  116. message.id = response.Message.ID
  117. values[0] = message
  118. return gott.Tuple(values)
  119. }
  120. func (a Account) SaveDraft(m *Message) error {
  121. _, err := gott.NewResult(gott.Tuple{m, a, nil, nil, m}).
  122. Bind(selectEncryptKey).
  123. Bind(selectSignKey).
  124. Bind(encryptBody).
  125. Map(sanatiseMessageArrays).
  126. Map(convertMessageToDraft).
  127. Bind(marshalRequest).
  128. Bind(preparePostDraftRequest).
  129. Map(setHeadersAuthed).
  130. Bind(doRequest).
  131. Bind(checkResponse).
  132. Bind(readResponse).
  133. Bind(unmarshalDraftResponse).
  134. Map(updateMessage).
  135. Finish()
  136. return err
  137. }
  138. func (a Address) SendMessage(m *Message) {
  139. // todo if message has no id -> save draft
  140. // todo send message
  141. }