-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathEmailComposable.swift
152 lines (134 loc) · 5.05 KB
/
EmailComposable.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//
// EmailComposable.swift
// Lockdown
//
// Created by Alexander Parshakov on 12/2/22
// Copyright © 2022 Confirmed Inc. All rights reserved.
//
import CocoaLumberjackSwift
import Foundation
import MessageUI
protocol EmailComposable: MFMailComposeViewControllerDelegate {
func composeEmail(_ email: Email, to recipient: String, errorBody: String?, attachments: [EmailAttachment])
}
extension EmailComposable where Self: BaseViewController {
func composeEmail(_ email: Email,
to recipient: String = EmailAddress.team,
errorBody: String? = nil,
attachments: [EmailAttachment] = []) {
writeUserLogs()
var message = email.body
if let errorBody = errorBody {
message += "\n\nError Details: " + errorBody
}
message += email.needsFurtherUserInput ? "\n\n\n" : ""
if MFMailComposeViewController.canSendMail() {
let composeVC = MFMailComposeViewController()
composeVC.mailComposeDelegate = self
composeVC.setToRecipients([recipient])
composeVC.setSubject(email.subject)
composeVC.setMessageBody(message, isHTML: false)
attachments.forEach {
composeVC.addAttachmentData($0.data, mimeType: $0.mimeType, fileName: $0.fileName)
}
present(composeVC, animated: true)
} else {
guard let mailtoURL = Mailto.generateURL(recipient: recipient, subject: email.subject, body: message) else {
DDLogError("Failed to generate mailto url")
return
}
UIApplication.shared.open(mailtoURL, options: [:]) { (success) in
guard !success else { return }
self.showPopupDialog(
title: .localized("Couldn't Find Your Email Client"),
message: .localized("Please make sure you have added an e-mail account to your iOS device and try again."),
acceptButton: .localizedOK)
}
}
}
private func writeUserLogs() {
DDLogInfo("")
DDLogInfo("UserId: \(keychain[kVPNCredentialsId] ?? "No User ID")")
DDLogInfo("UserReceipt: \(keychain[kVPNCredentialsKeyBase64] ?? "No User Receipt")")
if Client.hasValidCookie() {
DDLogInfo("Has loaded cookie.")
}
DDLogInfo("")
PacketTunnelProviderLogs.flush()
DDLogInfo("")
}
}
enum Email {
case helpOrFeedback
case deleteAccount(email: String, userId: String)
case termsAndPrivacyPolicy
case blockingImprovementIdeas
case custom(subject: String, body: String)
var subject: String {
var appendString = ""
if getUserWantsVPNEnabled() {
appendString += " - S"
}
switch self {
case .helpOrFeedback:
return "Lockdown Question or Feedback (iOS \(Bundle.main.versionString))" + appendString
case .deleteAccount:
return "Delete Account"
case .termsAndPrivacyPolicy:
return "Lockdown Privacy Policy Question or Feedback (iOS \(Bundle.main.versionString))" + appendString
case .blockingImprovementIdeas:
return "Lockdown Blocking Improvement Ideas (iOS \(Bundle.main.versionString))"
case .custom(let subject, _):
return subject
}
}
var body: String {
switch self {
case .helpOrFeedback:
return "Hi, my question or feedback for Lockdown is: "
case .deleteAccount(let email, let userId):
return "Please, delete my entire account record, along with associated personal data.\n\nDeletion credentials: \n\(email)\n\(userId)"
case .termsAndPrivacyPolicy:
return "Hi, my question or feedback for Lockdown Privacy Policy is: "
case .blockingImprovementIdeas:
return "Hi, my blocking improvement ideas for Lockdown Privacy are: "
case .custom(_, let body):
return body
}
}
/// Defines whether the e-mail form expects user to type some additional info below the email body.
/// If yes, 3 new lines will be inserted.
var needsFurtherUserInput: Bool {
switch self {
case .helpOrFeedback, .termsAndPrivacyPolicy, .blockingImprovementIdeas, .custom:
return true
case .deleteAccount:
return false
}
}
}
enum EmailAttachment {
case diagnostics
var data: Data {
switch self {
case .diagnostics:
let attachmentData = NSMutableData()
for logFileData in logFileDataArray {
attachmentData.append(logFileData as Data)
}
return attachmentData as Data
}
}
var mimeType: String {
switch self {
case .diagnostics:
return "text/plain"
}
}
var fileName: String {
switch self {
case .diagnostics:
return "diagnostics.txt"
}
}
}