From 994bf22cd23bea10de29f0cffcd49814734428a9 Mon Sep 17 00:00:00 2001
From: Dariusz Rybicki <dariusz@elixxir.io>
Date: Mon, 15 Aug 2022 15:12:50 +0100
Subject: [PATCH] Use SendReport in SingleChatViewModel

---
 .../Controllers/SingleChatController.swift    |   3 +-
 .../ViewModels/SingleChatViewModel.swift      | 118 ++++--------------
 2 files changed, 29 insertions(+), 92 deletions(-)

diff --git a/Sources/ChatFeature/Controllers/SingleChatController.swift b/Sources/ChatFeature/Controllers/SingleChatController.swift
index 1a066b20..f4206db0 100644
--- a/Sources/ChatFeature/Controllers/SingleChatController.swift
+++ b/Sources/ChatFeature/Controllers/SingleChatController.swift
@@ -432,7 +432,8 @@ public final class SingleChatController: UIViewController {
                 drawer.dismiss(animated: true) { [weak self] in
                     guard let self = self else { return }
                     self.drawerCancellables.removeAll()
-                    self.viewModel.proceeedWithReport(screenshot: try! self.makeAppScreenshot()) {
+                    let screenshot = try! self.makeAppScreenshot()
+                    self.viewModel.report(screenshot: screenshot) {
                         self.navigationController?.popViewController(animated: true)
                     }
                 }
diff --git a/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift b/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift
index 2a1e3493..e4dae1d4 100644
--- a/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift
+++ b/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift
@@ -11,6 +11,7 @@ import Defaults
 import Permissions
 import ToastFeature
 import DifferenceKit
+import ReportingFeature
 import DependencyInjection
 
 enum SingleChatNavigationRoutes: Equatable {
@@ -29,6 +30,7 @@ final class SingleChatViewModel: NSObject {
     @Dependency private var session: SessionType
     @Dependency private var permissions: PermissionHandling
     @Dependency private var toastController: ToastController
+    @Dependency private var sendReport: SendReport
 
     @KeyObject(.username, defaultValue: nil) var username: String?
 
@@ -252,30 +254,8 @@ final class SingleChatViewModel: NSObject {
     func section(at index: Int) -> ChatSection? {
         sectionsRelay.value.count > 0 ? sectionsRelay.value[index].model : nil
     }
-}
-
-extension SingleChatViewModel {
-    struct Report: Encodable {
-        struct ReportUser: Encodable {
-            var userId: String
-            var username: String
-        }
-
-        var sender: ReportUser
-        var recipient: ReportUser
-        var type: String
-        var screenshot: String
-    }
-
-    private func blockContact() {
-        var contact = contact
-        contact.isBlocked = true
-        _ = try? session.dbManager.saveContact(contact)
-    }
-
-    private func makeReportRequest(with screenshot: UIImage) -> URLRequest {
-        let url = URL(string: "https://3.74.237.181:11420/report")
 
+    func report(screenshot: UIImage, completion: @escaping () -> Void) {
         let report = Report(
             sender: .init(
                 userId: contact.id.base64EncodedString(),
@@ -284,86 +264,42 @@ extension SingleChatViewModel {
             recipient: .init(
                 userId: session.myId.base64EncodedString(),
                 username: username!
-            ), type: "dm",
-            screenshot: screenshot.jpegData(compressionQuality: 0.1)!.base64EncodedString())
-
-        var request = try! URLRequest(url: url!, method: .post)
-        request.httpBody = try! JSONEncoder().encode(report)
-        return request
-    }
-
-    private func enqueueBlockedToast() {
-        let name = (contact.nickname ?? contact.username) ?? ""
-        toastController.enqueueToast(model: .init(
-            title: "Your report has been sent and \(name) is now blocked.",
-            leftImage: Asset.requestSentToaster.image
-        ))
-    }
-
-    private func uploadReport(
-        _ request: URLRequest,
-        completion: @escaping (Result<Void, Error>) -> Void
-    ) {
-        URLSession(configuration: .default, delegate: self, delegateQueue: nil)
-            .dataTask(with: request) { data, response, error in
-            if let error = error as? NSError {
-                completion(.failure(error))
-                return
-            }
-
-            if let data = data {
-                completion(.success(()))
-            }
-        }.resume()
-    }
+            ),
+            type: .dm,
+            screenshot: screenshot.pngData()!
+        )
 
-    func proceeedWithReport(screenshot: UIImage, completion: @escaping () -> Void) {
         hudRelay.send(.on)
-
-        uploadReport(makeReportRequest(with: screenshot)) { [weak self] in
-            guard let self = self else { return }
-
-            switch $0 {
-            case .success:
+        sendReport(report) { result in
+            switch result {
+            case .failure(let error):
                 DispatchQueue.main.async {
-                    self.blockContact()
-                    self.enqueueBlockedToast()
-                    self.hudRelay.send(.none)
+                    self.hudRelay.send(.error(.init(with: error)))
                     completion()
                 }
 
-            case .failure(let error):
+            case .success(_):
+                self.blockContact()
                 DispatchQueue.main.async {
-                    self.hudRelay.send(.error(.init(with: error)))
+                    self.hudRelay.send(.none)
+                    self.presentReportConfirmation()
                     completion()
                 }
             }
         }
     }
-}
 
-extension SingleChatViewModel: URLSessionDelegate {
-    func urlSession(
-        _ session: URLSession,
-        didReceive challenge: URLAuthenticationChallenge,
-        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
-    ) {
-        let serverTrust = challenge.protectionSpace.serverTrust
-        let certificate = SecTrustGetCertificateAtIndex(serverTrust!, 0)
-
-        let policies = NSMutableArray()
-        policies.add(SecPolicyCreateSSL(true, challenge.protectionSpace.host as CFString))
-        SecTrustSetPolicies(serverTrust!, policies)
-
-        let remoteCertificateData: NSData = SecCertificateCopyData(certificate!)
-        let pathToCert = Bundle.module.path(forResource: "report_cert", ofType: "crt")
-        let localCertificate: NSData = NSData(contentsOfFile: pathToCert!)!
-
-        if (remoteCertificateData.isEqual(to: localCertificate as Data)) {
-            let credential: URLCredential = URLCredential(trust: serverTrust!)
-            completionHandler(.useCredential, credential)
-        } else {
-            completionHandler(.cancelAuthenticationChallenge, nil)
-        }
+    private func blockContact() {
+        var contact = contact
+        contact.isBlocked = true
+        _ = try? session.dbManager.saveContact(contact)
+    }
+
+    private func presentReportConfirmation() {
+        let name = (contact.nickname ?? contact.username) ?? "the contact"
+        toastController.enqueueToast(model: .init(
+            title: "Your report has been sent and \(name) is now blocked.",
+            leftImage: Asset.requestSentToaster.image
+        ))
     }
 }
-- 
GitLab