WIP: delete from storage server

This commit is contained in:
Ryan Zhao 2021-08-02 17:07:29 +10:00
parent 08360273e6
commit e8f0d0d124
3 changed files with 56 additions and 6 deletions

View File

@ -980,6 +980,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
- (void)deleteRemotelyAction
{
// TODO: closed group and one-on-one chat
TSMessage *message = (TSMessage *)self.interaction;
if (self.isGroupThread) {
TSGroupThread *groupThread = (TSGroupThread *)self.interaction.thread;
@ -988,13 +989,8 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
OWSInteractionType interationType = self.interaction.interactionType;
if (interationType != OWSInteractionType_IncomingMessage && interationType != OWSInteractionType_OutgoingMessage) return;
if (groupThread.isClosedGroup) {
}
if (groupThread.isOpenGroup) {
// Make sure it's an open group message
TSMessage *message = (TSMessage *)self.interaction;
if (!message.isOpenGroupMessage) return;
// Get the open group
@ -1012,8 +1008,15 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
// Roll back
[self.interaction save];
}) retainUntilComplete];
} else {
NSString *groupPublicKey = [LKGroupUtilities getDecodedGroupID:groupThread.groupModel.groupId];
[SNSnodeAPI deleteMessageForPublickKey:groupPublicKey serverHash:message.serverHash];
}
} else {
TSContactThread *contactThread = (TSContactThread *)self.interaction.thread;
[SNSnodeAPI deleteMessageForPublickKey:contactThread.contactSessionID serverHash:message.serverHash];
}
}
- (BOOL)hasBodyTextActionContent

View File

@ -14,6 +14,7 @@ public final class Snode : NSObject, NSCoding { // NSObject/NSCoding conformance
case getSwarm = "get_snodes_for_pubkey"
case getMessages = "retrieve"
case sendMessage = "store"
case deleteMessage = "delete"
case oxenDaemonRPCCall = "oxend_request"
case getInfo = "info"
case clearAllData = "delete_all"

View File

@ -454,7 +454,53 @@ public final class SnodeAPI : NSObject {
return promise
}
// public static func deleteMessage() -> Promise
@objc(deleteMessageForPublickKey:serverHash:)
public static func objc_deleteMessage(publicKey: String, serverHash: String) -> AnyPromise {
AnyPromise.from(deleteMessage(publicKey: publicKey, serverHash: serverHash))
}
public static func deleteMessage(publicKey: String, serverHash: String) -> Promise<RawResponsePromise> {
let storage = SNSnodeKitConfiguration.shared.storage
guard let userX25519PublicKey = storage.getUserPublicKey(),
let userED25519KeyPair = storage.getUserED25519KeyPair() else { return Promise(error: Error.noKeyPair) }
let publicKey = Features.useTestnet ? publicKey.removing05PrefixIfNeeded() : publicKey
let (promise, seal) = Promise<RawResponsePromise>.pending()
Threading.workQueue.async {
getTargetSnodes(for: publicKey).map2 { targetSnodes in
let snode = targetSnodes.first!
let verificationData = (Snode.Method.deleteMessage.rawValue + serverHash).data(using: String.Encoding.utf8)!
guard let signature = sodium.sign.signature(message: Bytes(verificationData), secretKey: userED25519KeyPair.secretKey) else { throw Error.signingFailed }
let parameters: JSON = [
"pubkey" : userX25519PublicKey,
"pubkey_ed25519" : userED25519KeyPair.publicKey.toHexString(),
"messages": [serverHash],
"signature": signature.toBase64()!
]
return attempt(maxRetryCount: maxRetryCount, recoveringOn: Threading.workQueue) {
invoke(.deleteMessage, on: snode, associatedWith: publicKey, parameters: parameters).map2{ rawResponse -> RawResponse in
guard let json = rawResponse as? JSON else { throw HTTP.Error.invalidJSON }
var result = false
let isFailed = json["failed"] as? Bool ?? false
if !isFailed {
guard let hashes = json["deleted"] as? [String], let signature = json["signature"] as? String else { throw HTTP.Error.invalidJSON }
// The signature format is ( PUBKEY_HEX || RMSG[0] || ... || RMSG[N] || DMSG[0] || ... || DMSG[M] )
let verificationData = (publicKey + serverHash + hashes.joined(separator: "")).data(using: String.Encoding.utf8)!
let isValid = sodium.sign.verify(message: Bytes(verificationData), publicKey: Bytes(Data(hex: snode.publicKeySet.ed25519Key)), signature: Bytes(Data(base64Encoded: signature)!))
result = isValid
} else {
if let reason = json["reason"] as? String, let statusCode = json["code"] as? String {
SNLog("Couldn't delete message with hash: \(serverHash) due to error: \(reason) (\(statusCode)).")
} else {
SNLog("Couldn't delete message with hash: \(serverHash).")
}
}
return result
}
}
}.done2 { seal.fulfill($0) }.catch2 { seal.reject($0) }
}
return promise
}
/// Clears all the user's data from their swarm. Returns a dictionary of snode public key to deletion confirmation.
public static func clearAllData() -> Promise<[String:Bool]> {