Skip to content

Commit 2f16f57

Browse files
authored
Merge pull request #591 from jorgeblacio/use_re_encrypt
Now using re encrypt when decryption fails on external emails.
2 parents c08125b + 1fd64bc commit 2f16f57

File tree

3 files changed

+202
-95
lines changed

3 files changed

+202
-95
lines changed

iOS-Email-Client/Libs/EventHandler.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class EventHandler {
101101
DBManager.refresh()
102102
switch(cmd){
103103
case Event.newEmail.rawValue:
104-
self.handleNewEmailCommand(params: params, finishCallback: handleEventResponse)
104+
self.handleNewEmailCommand(params: params, eventId: docId ?? rowId, finishCallback: handleEventResponse)
105105
case Event.emailStatus.rawValue:
106106
self.handleEmailStatusCommand(params: params, finishCallback: handleEventResponse)
107107
case Event.preKeys.rawValue:
@@ -182,11 +182,11 @@ class EventHandler {
182182
}
183183
}
184184

185-
func handleNewEmailCommand(params: [String: Any], finishCallback: @escaping (_ successfulEvent: Bool, _ email: Event.EventResult) -> Void){
185+
func handleNewEmailCommand(params: [String: Any], eventId: Any, finishCallback: @escaping (_ success: Bool, _ email: Event.EventResult) -> Void){
186186
let handler = NewEmailHandler(accountId: self.accountId, queue: self.queue)
187187
handler.api = self.apiManager
188188
handler.signal = self.signalHandler
189-
handler.command(params: params) { (result) in
189+
handler.command(params: params, eventId: eventId) { (result) in
190190
guard let email = result.email else {
191191
finishCallback(result.success, .Empty)
192192
return

iOS-Email-Client/Shared/NewEmailHandler.swift

Lines changed: 175 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ class NewEmailHandler {
2525
self.queue = queue
2626
}
2727

28+
enum ResultType {
29+
case Success
30+
case Failure
31+
case UnableToDecrypt
32+
case UnableToDecryptExternal
33+
case TooManyRequests
34+
}
35+
2836
struct Result {
2937
let email: Email?
3038
let success: Bool
@@ -40,15 +48,30 @@ class NewEmailHandler {
4048
}
4149
}
4250

43-
func command(params: [String: Any], completion: @escaping (_ result: Result) -> Void){
51+
struct EmailProcessResult {
52+
let email: Email?
53+
let type: ResultType
54+
55+
init(type: ResultType) {
56+
self.type = type
57+
self.email = nil
58+
}
59+
60+
init(email: Email) {
61+
self.email = email
62+
self.type = .Success
63+
}
64+
}
65+
66+
func command(params: [String: Any], eventId: Any, completion: @escaping (_ result: Result) -> Void){
4467
guard let myAccount = database.getAccountById(accountId) else {
4568
completion(Result(success: false))
4669
return
4770
}
4871

4972
guard let event = try? NewEmail.init(params: params),
5073
let recipientId = event.recipientId else {
51-
completion(Result(success: false))
74+
completion(Result(success: false))
5275
return
5376
}
5477

@@ -60,23 +83,67 @@ class NewEmailHandler {
6083
}
6184
let defaults = CriptextDefaults()
6285
defaults.deleteEmailStrike(id: email.compoundKey)
63-
completion(Result(success: true))
86+
completion(Result(success: false))
6487
return
6588
}
89+
self.getEmailBody(event: event, recipientId: recipientId, eventId: eventId, myAccount: myAccount) { (result) in
90+
switch(result.type){
91+
case .UnableToDecryptExternal:
92+
guard let account = self.database.getAccountById(self.accountId) else {
93+
completion(Result(success: false))
94+
return
95+
}
96+
self.reEncryptEmail(event: event, eventId: eventId, jwt: account.jwt) { (result) in
97+
switch(result.type){
98+
case .TooManyRequests:
99+
let content = String.localize("CONTENT_UNENCRYPTED")
100+
guard let unencryptedEmail = self.constructEmail(content: content, event: event, myAccount: account) else {
101+
completion(Result(success: false))
102+
return
103+
}
104+
completion(Result(email: unencryptedEmail))
105+
default:
106+
completion(Result(success: result.type == .Success))
107+
}
108+
}
109+
default:
110+
guard let email = result.email else {
111+
completion(Result(success: false))
112+
return
113+
}
114+
completion(Result(email: email))
115+
}
116+
}
66117

118+
}
119+
120+
private func reEncryptEmail(event: NewEmail, eventId: Any, jwt: String, completion: @escaping (_ result: EmailProcessResult) -> Void){
121+
self.api.reEncryptEmail(metadataKey: event.metadataKey, eventId: eventId, token: jwt) { (responseData) in
122+
switch(responseData){
123+
case .TooManyRequests:
124+
completion(EmailProcessResult(type: .TooManyRequests))
125+
case .Success:
126+
completion(EmailProcessResult(type: .Success))
127+
default:
128+
completion(EmailProcessResult(type: .Failure))
129+
}
130+
}
131+
}
132+
133+
private func getEmailBody(event: NewEmail, recipientId: String, eventId: Any, myAccount: Account, completion: @escaping (_ result: EmailProcessResult) -> Void){
67134
api.getEmailBody(metadataKey: event.metadataKey, token: myAccount.jwt, queue: self.queue) { (responseData) in
68135
var unsent = false
69136
var content = ""
70137
var contentHeader: String? = nil
71138
guard let myAccount = self.database.getAccountById(self.accountId) else {
72-
completion(Result(success: false))
139+
completion(EmailProcessResult(type: .Failure))
73140
return
74141
}
75142
if case .Missing = responseData {
76143
unsent = true
77144
} else if case let .SuccessDictionary(data) = responseData {
78145
guard let bodyString = data["body"] as? String else {
79-
completion(Result(success: false))
146+
completion(EmailProcessResult(type: .Failure))
80147
return
81148
}
82149
let decryptedContentResult = self.handleContentByMessageType(
@@ -95,9 +162,12 @@ class NewEmailHandler {
95162
defaults.deleteEmailStrike(id: emailId)
96163
} else {
97164
defaults.addEmailStrike(id: emailId)
98-
completion(Result(success: false))
165+
completion(EmailProcessResult(type: .Failure))
99166
return
100167
}
168+
case .UnableToDecryptExternal:
169+
completion(EmailProcessResult(type: .UnableToDecryptExternal))
170+
return
101171
default:
102172
content = String.localize("CONTENT_UNENCRYPTED")
103173
}
@@ -108,109 +178,121 @@ class NewEmailHandler {
108178
contentHeader = headersResult
109179
}
110180
} else {
111-
completion(Result(success: false))
181+
completion(EmailProcessResult(type: .Failure))
112182
return
113183
}
114184

115-
guard !FileUtils.existBodyFile(email: myAccount.email, metadataKey: "\(event.metadataKey)") else {
116-
if let email = self.database.getMail(key: event.metadataKey, account: myAccount) {
117-
completion(Result(email: email))
118-
return
119-
}
120-
completion(Result(success: true))
185+
let finalEmail = self.constructEmail(content: content, event: event, myAccount: myAccount, unsent: unsent, contentHeader: contentHeader)
186+
guard finalEmail != nil else {
187+
completion(EmailProcessResult(type: .Success))
121188
return
122189
}
123190

124-
var replyThreadId = event.threadId
125-
if let inReplyTo = event.inReplyTo,
126-
let replyEmail = SharedDB.getEmail(messageId: inReplyTo, account: myAccount) {
127-
replyThreadId = replyEmail.threadId
191+
completion(EmailProcessResult(email: finalEmail!))
192+
}
193+
}
194+
195+
func constructEmail(content: String, event: NewEmail, myAccount: Account, unsent: Bool = false, contentHeader: String? = nil) -> Email? {
196+
guard !FileUtils.existBodyFile(email: myAccount.email, metadataKey: "\(event.metadataKey)") else {
197+
if let email = self.database.getMail(key: event.metadataKey, account: myAccount) {
198+
return email
128199
}
129-
130-
let contentPreview = self.getContentPreview(content: content)
131-
let email = Email()
132-
email.account = myAccount
133-
email.threadId = replyThreadId
134-
email.subject = event.subject
135-
email.key = event.metadataKey
136-
email.messageId = event.messageId
137-
email.boundary = event.boundary ?? ""
138-
email.date = event.date
139-
email.unread = true
140-
email.secure = event.guestEncryption == 1 || event.guestEncryption == 3 ? true : false
141-
email.preview = contentPreview.0
142-
email.replyTo = event.replyTo ?? ""
143-
email.buildCompoundKey()
144-
145-
if(unsent){
146-
email.unsentDate = email.date
147-
email.delivered = Email.Status.unsent.rawValue
148-
} else {
149-
FileUtils.saveEmailToFile(email: myAccount.email, metadataKey: "\(event.metadataKey)", body: contentPreview.1, headers: contentHeader)
200+
return nil
201+
}
202+
203+
var replyThreadId = event.threadId
204+
if let inReplyTo = event.inReplyTo,
205+
let replyEmail = SharedDB.getEmail(messageId: inReplyTo, account: myAccount) {
206+
replyThreadId = replyEmail.threadId
207+
}
208+
209+
let contentPreview = self.getContentPreview(content: content)
210+
let email = Email()
211+
email.account = myAccount
212+
email.threadId = replyThreadId
213+
email.subject = event.subject
214+
email.key = event.metadataKey
215+
email.messageId = event.messageId
216+
email.boundary = event.boundary ?? ""
217+
email.date = event.date
218+
email.unread = true
219+
email.secure = event.guestEncryption == 1 || event.guestEncryption == 3 ? true : false
220+
email.preview = contentPreview.0
221+
email.replyTo = event.replyTo ?? ""
222+
email.buildCompoundKey()
223+
224+
if(unsent){
225+
email.unsentDate = email.date
226+
email.delivered = Email.Status.unsent.rawValue
227+
} else {
228+
FileUtils.saveEmailToFile(email: myAccount.email, metadataKey: "\(event.metadataKey)", body: contentPreview.1, headers: contentHeader)
229+
}
230+
231+
guard let recipientId = event.recipientId else {
232+
return nil
233+
}
234+
235+
self.handleAttachments(recipientId: recipientId, event: event, email: email, myAccount: myAccount, body: contentPreview.1)
236+
237+
email.fromAddress = event.from
238+
var fromMe = false
239+
if self.isFromMe(email: email, account: myAccount, event: event),
240+
let sentLabel = SharedDB.getLabel(SystemLabel.sent.id) {
241+
fromMe = true
242+
if !unsent {
243+
email.delivered = Email.Status.sent.rawValue
150244
}
151-
152-
self.handleAttachments(recipientId: recipientId, event: event, email: email, myAccount: myAccount, body: contentPreview.1)
153-
154-
email.fromAddress = event.from
155-
var fromMe = false
156-
if self.isFromMe(email: email, account: myAccount, event: event),
157-
let sentLabel = SharedDB.getLabel(SystemLabel.sent.id) {
158-
fromMe = true
159-
if !unsent {
160-
email.delivered = Email.Status.sent.rawValue
161-
}
162-
email.unread = false
163-
email.labels.append(sentLabel)
164-
if self.isMeARecipient(email: email, account: myAccount, event: event),
165-
let inboxLabel = SharedDB.getLabel(SystemLabel.inbox.id) {
166-
email.unread = true
167-
email.labels.append(inboxLabel)
168-
}
169-
} else if let inboxLabel = SharedDB.getLabel(SystemLabel.inbox.id) {
245+
email.unread = false
246+
email.labels.append(sentLabel)
247+
if self.isMeARecipient(email: email, account: myAccount, event: event),
248+
let inboxLabel = SharedDB.getLabel(SystemLabel.inbox.id) {
249+
email.unread = true
170250
email.labels.append(inboxLabel)
171-
let fromContact = self.database.getContact(ContactUtils.parseContact(event.from, account: myAccount).email)
172-
if(fromContact != nil){
173-
if(fromContact?.spamScore ?? 0 >= 2){
174-
let spamLabel = SharedDB.getLabel(SystemLabel.spam.id)
175-
email.labels.append(spamLabel!)
176-
}
177-
}
178-
}
179-
180-
if(!event.labels.isEmpty){
181-
let labels = event.labels.reduce([Label](), { (labelsArray, labelText) -> [Label] in
182-
guard let label = SharedDB.getLabel(text: labelText),
183-
(!fromMe || label.id != SystemLabel.spam.id) else {
184-
return labelsArray
185-
}
186-
return labelsArray.appending(label)
187-
})
188-
email.labels.append(objectsIn: labels)
189-
}
190-
191-
guard self.database.store(email) else {
192-
completion(Result(success: true))
193-
return
194251
}
195-
196-
ContactUtils.parseEmailContacts([event.from], email: email, type: .from, account: myAccount)
197-
ContactUtils.parseEmailContacts(event.to, email: email, type: .to, account: myAccount)
198-
ContactUtils.parseEmailContacts(event.cc, email: email, type: .cc, account: myAccount)
199-
ContactUtils.parseEmailContacts(event.bcc, email: email, type: .bcc, account: myAccount)
200-
201-
if let myContact = SharedDB.getContact(myAccount.email),
202-
myContact.displayName != myAccount.name {
203-
SharedDB.update(contact: myContact, name: myAccount.name)
252+
} else if let inboxLabel = SharedDB.getLabel(SystemLabel.inbox.id) {
253+
email.labels.append(inboxLabel)
254+
let fromContact = self.database.getContact(ContactUtils.parseContact(event.from, account: myAccount).email)
255+
if(fromContact != nil){
256+
if(fromContact?.spamScore ?? 0 >= 2){
257+
let spamLabel = SharedDB.getLabel(SystemLabel.spam.id)
258+
email.labels.append(spamLabel!)
259+
}
204260
}
205-
206-
completion(Result(email: email))
207261
}
262+
263+
if(!event.labels.isEmpty){
264+
let labels = event.labels.reduce([Label](), { (labelsArray, labelText) -> [Label] in
265+
guard let label = SharedDB.getLabel(text: labelText),
266+
(!fromMe || label.id != SystemLabel.spam.id) else {
267+
return labelsArray
268+
}
269+
return labelsArray.appending(label)
270+
})
271+
email.labels.append(objectsIn: labels)
272+
}
273+
274+
guard self.database.store(email) else {
275+
return nil
276+
}
277+
278+
ContactUtils.parseEmailContacts([event.from], email: email, type: .from, account: myAccount)
279+
ContactUtils.parseEmailContacts(event.to, email: email, type: .to, account: myAccount)
280+
ContactUtils.parseEmailContacts(event.cc, email: email, type: .cc, account: myAccount)
281+
ContactUtils.parseEmailContacts(event.bcc, email: email, type: .bcc, account: myAccount)
282+
283+
if let myContact = SharedDB.getContact(myAccount.email),
284+
myContact.displayName != myAccount.name {
285+
SharedDB.update(contact: myContact, name: myAccount.name)
286+
}
287+
return email
208288
}
209289

210290
enum DecryptResult {
211291
case Content(String)
212292
case Duplicated
213293
case NoSession
294+
case UnableToDecrypt
295+
case UnableToDecryptExternal
214296
case Uknown
215297
}
216298

@@ -240,6 +322,8 @@ class NewEmailHandler {
240322
return .Duplicated
241323
} else if (error.name.rawValue == "AxolotlNoSessionException") {
242324
return .NoSession
325+
} else if(isExternal){
326+
return .UnableToDecryptExternal
243327
} else {
244328
return .Uknown
245329
}

0 commit comments

Comments
 (0)