diff --git a/Passepartout-iOS/Global/IssueReporter.swift b/Passepartout-iOS/Global/IssueReporter.swift index b4fd850d..5b2d0373 100644 --- a/Passepartout-iOS/Global/IssueReporter.swift +++ b/Passepartout-iOS/Global/IssueReporter.swift @@ -27,6 +27,22 @@ import Foundation import MessageUI class IssueReporter: NSObject { + struct Attachments { + let debugLog: Bool + + let configurationURL: URL? + + init(debugLog: Bool, configurationURL: URL?) { + self.debugLog = debugLog + self.configurationURL = configurationURL + } + + init(debugLog: Bool, profile: ConnectionProfile) { + let url = TransientStore.shared.service.configurationURL(for: profile) + self.init(debugLog: debugLog, configurationURL: url) + } + } + static let shared = IssueReporter() private weak var viewController: UIViewController? @@ -35,7 +51,7 @@ class IssueReporter: NSObject { super.init() } - func present(in viewController: UIViewController) { + func present(in viewController: UIViewController, withAttachments attachments: Attachments) { guard MFMailComposeViewController.canSendMail() else { let alert = Macros.alert(L10n.IssueReporter.title, L10n.IssueReporter.Alerts.EmailNotConfigured.message) alert.addCancelAction(L10n.Global.ok) @@ -45,17 +61,21 @@ class IssueReporter: NSObject { self.viewController = viewController - let alert = Macros.alert(L10n.IssueReporter.title, L10n.IssueReporter.message) - alert.addDefaultAction(L10n.IssueReporter.Buttons.accept) { - VPN.shared.requestDebugLog(fallback: AppConstants.Log.debugSnapshot) { - self.composeEmail(withDebugLog: $0) + if attachments.debugLog { + let alert = Macros.alert(L10n.IssueReporter.title, L10n.IssueReporter.message) + alert.addDefaultAction(L10n.IssueReporter.Buttons.accept) { + VPN.shared.requestDebugLog(fallback: AppConstants.Log.debugSnapshot) { + self.composeEmail(withDebugLog: $0, configurationURL: attachments.configurationURL) + } } + alert.addCancelAction(L10n.Global.cancel) + viewController.present(alert, animated: true, completion: nil) + } else { + composeEmail(withDebugLog: nil, configurationURL: attachments.configurationURL) } - alert.addCancelAction(L10n.Global.cancel) - viewController.present(alert, animated: true, completion: nil) } - private func composeEmail(withDebugLog debugLog: String?) { + private func composeEmail(withDebugLog debugLog: String?, configurationURL: URL?) { let metadata = DebugLog(raw: "--").decoratedString() let vc = MFMailComposeViewController() @@ -64,7 +84,10 @@ class IssueReporter: NSObject { vc.setMessageBody(L10n.IssueReporter.Email.body(metadata), isHTML: false) if let raw = debugLog { let attachment = DebugLog(raw: raw).decoratedData() - vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.attachmentMIME, fileName: AppConstants.Log.debugFilename) + vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.MIME.debugLog, fileName: AppConstants.IssueReporter.Filenames.debugLog) + } + if let cfg = configurationURL, let attachment = try? Data(contentsOf: cfg) { + vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.MIME.configuration, fileName: AppConstants.IssueReporter.Filenames.configuration) } vc.mailComposeDelegate = self vc.apply(Theme.current) diff --git a/Passepartout-iOS/Scenes/DebugLogViewController.swift b/Passepartout-iOS/Scenes/DebugLogViewController.swift index 34bc5b57..7ed14daa 100644 --- a/Passepartout-iOS/Scenes/DebugLogViewController.swift +++ b/Passepartout-iOS/Scenes/DebugLogViewController.swift @@ -64,7 +64,7 @@ class DebugLogViewController: UIViewController { } let data = DebugLog(raw: raw).decoratedData() - let path = NSTemporaryDirectory().appending(AppConstants.Log.debugFilename) + let path = NSTemporaryDirectory().appending(AppConstants.IssueReporter.Filenames.debugLog) let url = URL(fileURLWithPath: path) do { try data.write(to: url) diff --git a/Passepartout-iOS/Scenes/ServiceViewController.swift b/Passepartout-iOS/Scenes/ServiceViewController.swift index be20305f..e3b27951 100644 --- a/Passepartout-iOS/Scenes/ServiceViewController.swift +++ b/Passepartout-iOS/Scenes/ServiceViewController.swift @@ -361,7 +361,8 @@ class ServiceViewController: UIViewController, TableModelHost { } private func reportConnectivityIssue() { - IssueReporter.shared.present(in: self) + let attach = IssueReporter.Attachments(debugLog: true, profile: uncheckedProfile) + IssueReporter.shared.present(in: self, withAttachments: attach) } // MARK: Notifications diff --git a/Passepartout/Resources/en.lproj/Localizable.strings b/Passepartout/Resources/en.lproj/Localizable.strings index b1ec559b..67e26879 100644 --- a/Passepartout/Resources/en.lproj/Localizable.strings +++ b/Passepartout/Resources/en.lproj/Localizable.strings @@ -174,7 +174,7 @@ "issue_reporter.message" = "The debug log of your latest connections is crucial to resolve your connectivity issues and is completely anonymous."; "issue_reporter.buttons.accept" = "I understand"; "issue_reporter.alerts.email_not_configured.message" = "No e-mail account is configured."; -"issue_reporter.email.subject" = "%@ - Debug log"; +"issue_reporter.email.subject" = "%@ - Report issue"; "issue_reporter.email.body" = "Hi,\n\ndescription of the issue:\n\n%@\n\nRegards"; "about.title" = "About"; diff --git a/Passepartout/Sources/AppConstants.swift b/Passepartout/Sources/AppConstants.swift index 8c22f975..b04ce544 100644 --- a/Passepartout/Sources/AppConstants.swift +++ b/Passepartout/Sources/AppConstants.swift @@ -96,13 +96,6 @@ class AppConstants { static var debugSnapshot: () -> String = { TransientStore.shared.service.vpnLog } - static var debugFilename: String { - let fmt = DateFormatter() - fmt.dateFormat = "yyyyMMdd-HHmmss" - let iso = fmt.string(from: Date()) - return "debug-\(iso).txt" - } - static let viewerRefreshInterval: TimeInterval = 3.0 static func configure() { @@ -116,7 +109,22 @@ class AppConstants { class IssueReporter { static let recipient = "issues@\(Domain.name)" - static let attachmentMIME = "text/plain" + class Filenames { + static var debugLog: String { + let fmt = DateFormatter() + fmt.dateFormat = "yyyyMMdd-HHmmss" + let iso = fmt.string(from: Date()) + return "debug-\(iso).txt" + } + + static let configuration = "profile.ovpn" + } + + class MIME { + static let debugLog = "text/plain" + + static let configuration = "application/x-openvpn-profile" + } } class URLs { diff --git a/Passepartout/Sources/SwiftGen+Strings.swift b/Passepartout/Sources/SwiftGen+Strings.swift index 24dad087..14840762 100644 --- a/Passepartout/Sources/SwiftGen+Strings.swift +++ b/Passepartout/Sources/SwiftGen+Strings.swift @@ -324,7 +324,7 @@ internal enum L10n { internal static func body(_ p1: String) -> String { return L10n.tr("Localizable", "issue_reporter.email.body", p1) } - /// %@ - Debug log + /// %@ - Report issue internal static func subject(_ p1: String) -> String { return L10n.tr("Localizable", "issue_reporter.email.subject", p1) }