update ttl after read when disappear after read is set

pull/941/head
Ryan Zhao 2 years ago
parent 02240e5940
commit e54a37ead0

@ -3,6 +3,7 @@
import Foundation import Foundation
import GRDB import GRDB
import SessionUtilitiesKit import SessionUtilitiesKit
import SessionSnodeKit
public enum DisappearingMessagesJob: JobExecutor { public enum DisappearingMessagesJob: JobExecutor {
public static let maxFailureCount: Int = -1 public static let maxFailureCount: Int = -1
@ -67,6 +68,16 @@ public extension DisappearingMessagesJob {
} }
@discardableResult static func updateNextRunIfNeeded(_ db: Database, interactionIds: [Int64], startedAtMs: Double) -> Job? { @discardableResult static func updateNextRunIfNeeded(_ db: Database, interactionIds: [Int64], startedAtMs: Double) -> Job? {
let interactionsByExpiresInSeconds: [TimeInterval?: [Interaction]]? = try? Interaction
.filter(interactionIds.contains(Interaction.Columns.id))
.filter(
Interaction.Columns.expiresInSeconds != nil &&
Interaction.Columns.expiresStartedAtMs == nil
)
.fetchAll(db)
.grouped(by: \.expiresInSeconds)
// Update the expiring messages expiresStartedAtMs value // Update the expiring messages expiresStartedAtMs value
let changeCount: Int? = try? Interaction let changeCount: Int? = try? Interaction
.filter(interactionIds.contains(Interaction.Columns.id)) .filter(interactionIds.contains(Interaction.Columns.id))
@ -79,6 +90,18 @@ public extension DisappearingMessagesJob {
// If there were no changes then none of the provided `interactionIds` are expiring messages // If there were no changes then none of the provided `interactionIds` are expiring messages
guard (changeCount ?? 0) > 0 else { return nil } guard (changeCount ?? 0) > 0 else { return nil }
interactionsByExpiresInSeconds?.forEach { expiresInSeconds, interactions in
let serverHashes = interactions.compactMap { $0.serverHash }
guard let expiresInSeconds = expiresInSeconds, !serverHashes.isEmpty else { return }
SnodeAPI.updateExpiry(
publicKey: getUserHexEncodedPublicKey(db),
updatedExpiryMs: Int64(ceil(startedAtMs + expiresInSeconds)),
serverHashes: serverHashes
)
.retainUntilComplete()
}
return updateNextRunIfNeeded(db) return updateNextRunIfNeeded(db)
} }

@ -728,25 +728,30 @@ public final class SnodeAPI {
public static func updateExpiry( public static func updateExpiry(
publicKey: String, publicKey: String,
edKeyPair: Box.KeyPair, updatedExpiryMs: Int64,
updatedExpiryMs: UInt64,
serverHashes: [String] serverHashes: [String]
) -> Promise<[String: (hashes: [String], expiry: UInt64)]> { ) -> Promise<[String: (hashes: [String], expiry: UInt64)]> {
guard let userED25519KeyPair = Identity.fetchUserEd25519KeyPair() else {
return Promise(error: SnodeAPIError.noKeyPair)
}
let publicKey = (Features.useTestnet ? publicKey.removingIdPrefixIfNeeded() : publicKey) let publicKey = (Features.useTestnet ? publicKey.removingIdPrefixIfNeeded() : publicKey)
let updatedExpiryMsWithNetworkOffset: UInt64 = UInt64(updatedExpiryMs + SnodeAPI.clockOffset.wrappedValue)
return attempt(maxRetryCount: maxRetryCount, recoveringOn: Threading.workQueue) { return attempt(maxRetryCount: maxRetryCount, recoveringOn: Threading.workQueue) {
getSwarm(for: publicKey) getSwarm(for: publicKey)
.then2 { swarm -> Promise<[String: (hashes: [String], expiry: UInt64)]> in .then2 { swarm -> Promise<[String: (hashes: [String], expiry: UInt64)]> in
// "expire" || expiry || messages[0] || ... || messages[N] // "expire" || expiry || messages[0] || ... || messages[N]
let verificationBytes = SnodeAPIEndpoint.expire.rawValue.bytes let verificationBytes = SnodeAPIEndpoint.expire.rawValue.bytes
.appending(contentsOf: "\(updatedExpiryMs)".data(using: .ascii)?.bytes) .appending(contentsOf: "\(updatedExpiryMsWithNetworkOffset)".data(using: .ascii)?.bytes)
.appending(contentsOf: serverHashes.joined().bytes) .appending(contentsOf: serverHashes.joined().bytes)
guard guard
let snode = swarm.randomElement(), let snode = swarm.randomElement(),
let signature = sodium.sign.signature( let signature = sodium.sign.signature(
message: verificationBytes, message: verificationBytes,
secretKey: edKeyPair.secretKey secretKey: userED25519KeyPair.secretKey
) )
else { else {
throw SnodeAPIError.signingFailed throw SnodeAPIError.signingFailed
@ -754,8 +759,8 @@ public final class SnodeAPI {
let parameters: JSON = [ let parameters: JSON = [
"pubkey" : publicKey, "pubkey" : publicKey,
"pubkey_ed25519" : edKeyPair.publicKey.toHexString(), "pubkey_ed25519" : userED25519KeyPair.publicKey.toHexString(),
"expiry": updatedExpiryMs, "expiry": updatedExpiryMsWithNetworkOffset,
"messages": serverHashes, "messages": serverHashes,
"signature": signature.toBase64() "signature": signature.toBase64()
] ]

Loading…
Cancel
Save