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 GRDB
import SessionUtilitiesKit
import SessionSnodeKit
public enum DisappearingMessagesJob: JobExecutor {
public static let maxFailureCount: Int = -1
@ -67,6 +68,16 @@ public extension DisappearingMessagesJob {
}
@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
let changeCount: Int? = try? Interaction
.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
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)
}

@ -728,25 +728,30 @@ public final class SnodeAPI {
public static func updateExpiry(
publicKey: String,
edKeyPair: Box.KeyPair,
updatedExpiryMs: UInt64,
updatedExpiryMs: Int64,
serverHashes: [String]
) -> 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 updatedExpiryMsWithNetworkOffset: UInt64 = UInt64(updatedExpiryMs + SnodeAPI.clockOffset.wrappedValue)
return attempt(maxRetryCount: maxRetryCount, recoveringOn: Threading.workQueue) {
getSwarm(for: publicKey)
.then2 { swarm -> Promise<[String: (hashes: [String], expiry: UInt64)]> in
// "expire" || expiry || messages[0] || ... || messages[N]
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)
guard
let snode = swarm.randomElement(),
let signature = sodium.sign.signature(
message: verificationBytes,
secretKey: edKeyPair.secretKey
secretKey: userED25519KeyPair.secretKey
)
else {
throw SnodeAPIError.signingFailed
@ -754,8 +759,8 @@ public final class SnodeAPI {
let parameters: JSON = [
"pubkey" : publicKey,
"pubkey_ed25519" : edKeyPair.publicKey.toHexString(),
"expiry": updatedExpiryMs,
"pubkey_ed25519" : userED25519KeyPair.publicKey.toHexString(),
"expiry": updatedExpiryMsWithNetworkOffset,
"messages": serverHashes,
"signature": signature.toBase64()
]

Loading…
Cancel
Save