verdnatura-chat/ios/Shared/RocketChat/RocketChat.swift

100 lines
2.8 KiB
Swift
Raw Permalink Normal View History

[NEW] E2E Encryption push (iOS) (#2463) * link pods to notification service * push encryption poc * decrypt room key poc * read user key from mmkv and cast into a pkcs * push decrypt poc (iOS) * expose needed watermelon methods * watermelon -> database * indent & simple-crypto update * string extensions * storage * toBase64 -> toData * remove a forced unwrap * remove unused import * database driver * improvement * folder structure & watermelon bridge * more improvement stuff * watermelon -> database * reuse database instance * improvement * database fix: bypass watermelon cache * some code improvements * encryption instances * start api stuff * network layer * improve notification service * improve folder structure * watermelon patch * retry fetch logic * rocketchat class * fix try to decrypt without a roomKey * fallback to original content that is translated * some fixes to rocketchat logic * merge develop * remove unnecessary extension * [CHORE] Improve reply notification code (iOS) * undo sign changes * remove mocked value * import direct from library * send message request * reply notification with encrypted message working properly * revert apple sign * fix api onerror * trick to display sender name on group notifications * revert data.host change * fix some multithread issues * use sendername sent by server * small improvement * Bump crypto lib * Update ios/NotificationService/NotificationService.swift * add experimental string * remove trailing slash * remove trailing slash on reply * fix decrypt messages Co-authored-by: Diego Mello <diegolmello@gmail.com>
2020-09-24 18:34:13 +00:00
//
// RocketChat.swift
// NotificationService
//
// Created by Djorkaeff Alexandre Vilela Pereira on 9/17/20.
// Copyright © 2020 Facebook. All rights reserved.
//
import Foundation
final class RocketChat {
typealias Server = String
typealias RoomId = String
let server: Server
let api: API?
static var instances: [Server: RocketChat] = [:]
var encryptionInstances: [RoomId: Encryption] = [:]
static private var queue = DispatchQueue(label: "chat.rocket.instanceQueue")
private var encryptionQueue = DispatchQueue(label: "chat.rocket.encryptionQueue")
init(server: Server) {
self.server = server
self.api = API(server: server)
}
static func instanceForServer(server: Server) -> RocketChat {
queue.sync {
if let rocketchat = instances[server] {
return rocketchat
}
let rocketchat = RocketChat(server: server)
instances[server] = rocketchat
return rocketchat
}
}
func getPushWithId(_ msgId: String, completion: @escaping((Notification?) -> Void)) {
api?.fetch(request: PushRequest(msgId: msgId), retry: Retry(retries: 4)) { response in
switch response {
case .resource(let response):
let notification = response.data.notification
completion(notification)
case .error:
completion(nil)
break
}
}
}
func sendMessage(rid: String, message: String, completion: @escaping((MessageResponse?) -> Void)) {
let id = String.random(length: 17)
var msg = message
let encrypted = Database(server: server).readRoomEncrypted(rid: rid)
if encrypted {
msg = encryptMessage(rid: rid, id: id, message: message)
}
api?.fetch(request: SendMessageRequest(id: id, roomId: rid, text: msg, messageType: encrypted ? .e2e : nil )) { response in
switch response {
case .resource(let response):
completion(response)
case .error:
completion(nil)
break
}
}
}
func decryptMessage(rid: String, message: String) -> String? {
encryptionQueue.sync {
if let encryption = encryptionInstances[rid] {
return encryption.decryptMessage(message: message)
}
let encryption = Encryption(server: server, rid: rid)
encryptionInstances[rid] = encryption
return encryption.decryptMessage(message: message)
}
}
func encryptMessage(rid: String, id: String, message: String) -> String {
encryptionQueue.sync {
if let encryption = encryptionInstances[rid] {
return encryption.encryptMessage(id: id, message: message)
}
let encryption = Encryption(server: server, rid: rid)
encryptionInstances[rid] = encryption
return encryption.encryptMessage(id: id, message: message)
}
}
}