Merge pull request #179 from loki-project/multi-device-session-reset

Various Bug Fixes
pull/180/head
Niels Andriesse 5 years ago committed by GitHub
commit 59eb516973
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5419,22 +5419,24 @@ typedef enum : NSUInteger {
}]) {
return;
}
__block TSInteraction *targetInteraction;
[self.thread enumerateInteractionsUsingBlock:^(TSInteraction *interaction) {
if (interaction.timestamp == timestamp.unsignedLongLongValue) {
targetInteraction = interaction;
}
}];
if (targetInteraction == nil || targetInteraction.interactionType != OWSInteractionType_OutgoingMessage) { return; }
NSString *hexEncodedPublicKey = targetInteraction.thread.contactIdentifier;
if (hexEncodedPublicKey == nil) { return; }
__block NSString *masterHexEncodedPublicKey;
[OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
masterHexEncodedPublicKey = [LKDatabaseUtilities getMasterHexEncodedPublicKeyFor:hexEncodedPublicKey in:transaction] ?: hexEncodedPublicKey;
}];
BOOL isSlaveDevice = ![masterHexEncodedPublicKey isEqual:hexEncodedPublicKey];
if (isSlaveDevice) { return; }
dispatch_async(dispatch_get_main_queue(), ^{
__block TSInteraction *targetInteraction;
[OWSPrimaryStorage.sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self.thread enumerateInteractionsWithTransaction:transaction usingBlock:^(TSInteraction *interaction, YapDatabaseReadTransaction *t) {
if (interaction.timestamp == timestamp.unsignedLongLongValue) {
targetInteraction = interaction;
}
}];
}];
if (targetInteraction == nil || targetInteraction.interactionType != OWSInteractionType_OutgoingMessage) { return; }
NSString *hexEncodedPublicKey = targetInteraction.thread.contactIdentifier;
if (hexEncodedPublicKey == nil) { return; }
__block NSString *masterHexEncodedPublicKey;
[OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
masterHexEncodedPublicKey = [LKDatabaseUtilities getMasterHexEncodedPublicKeyFor:hexEncodedPublicKey in:transaction] ?: hexEncodedPublicKey;
}];
BOOL isSlaveDevice = ![masterHexEncodedPublicKey isEqual:hexEncodedPublicKey];
if (isSlaveDevice) { return; }
if (progress <= self.progressIndicatorView.progress) { return; }
self.progressIndicatorView.alpha = 1;
[self.progressIndicatorView setProgress:progress animated:YES];

@ -81,7 +81,6 @@ public final class LokiPoller : NSObject {
seal.fulfill(())
}.catch(on: LokiAPI.errorHandlingQueue) { [weak self] error in
if let error = error as? Error, error == .pollLimitReached {
print("[Loki] Polling limit for \(nextSnode) reached; switching to next snode.")
self?.pollCount = 0
} else {
print("[Loki] Polling \(nextSnode) failed; dropping it and switching to next snode.")

@ -12,7 +12,7 @@ public final class LokiPublicChatPoller : NSObject {
// MARK: Settings
private let pollForNewMessagesInterval: TimeInterval = 4
private let pollForDeletedMessagesInterval: TimeInterval = 20
private let pollForDeletedMessagesInterval: TimeInterval = 60
private let pollForModeratorsInterval: TimeInterval = 10 * 60
private let pollForDisplayNamesInterval: TimeInterval = 60

@ -60,6 +60,7 @@ public final class FriendRequestProtocol : NSObject {
// Accept all outstanding friend requests associated with this user and try to establish sessions with the
// subset of their devices that haven't sent a friend request.
let linkedDeviceThreads = LokiDatabaseUtilities.getLinkedDeviceThreads(for: hexEncodedPublicKey, in: transaction) // This doesn't create new threads if they don't exist yet
// FIXME: Capture send failures
for thread in linkedDeviceThreads {
if thread.hasPendingFriendRequest {
sendFriendRequestAcceptanceMessage(to: thread.contactIdentifier(), in: thread, using: transaction) // NOT hexEncodedPublicKey

@ -41,7 +41,7 @@ public final class MultiDeviceProtocol : NSObject {
return !(message is DeviceLinkMessage) && !message.thread.isGroupThread()
}
private static func copy(_ messageSend: OWSMessageSend, for destination: MultiDeviceDestination, with seal: Resolver<TSContactThread>) -> OWSMessageSend {
private static func copy(_ messageSend: OWSMessageSend, for destination: MultiDeviceDestination, with seal: Resolver<Void>) -> OWSMessageSend {
var recipient: SignalRecipient!
storage.dbReadConnection.read { transaction in
recipient = SignalRecipient.getOrBuildUnsavedRecipient(forRecipientId: destination.hexEncodedPublicKey, transaction: transaction)
@ -49,47 +49,47 @@ public final class MultiDeviceProtocol : NSObject {
// TODO: Why is it okay that the thread, sender certificate, etc. don't get changed?
return OWSMessageSend(message: messageSend.message, thread: messageSend.thread, recipient: recipient,
senderCertificate: messageSend.senderCertificate, udAccess: messageSend.udAccess, localNumber: messageSend.localNumber, success: {
seal.fulfill(messageSend.message.thread as! TSContactThread)
seal.fulfill(())
}, failure: { error in
seal.reject(error)
})
}
private static func sendMessage(_ messageSend: OWSMessageSend, to destination: MultiDeviceDestination, in transaction: YapDatabaseReadTransaction) -> Promise<Void> {
let (promise, seal) = Promise<TSContactThread>.pending()
let message = messageSend.message
let messageSender = SSKEnvironment.shared.messageSender
promise.done(on: OWSDispatch.sendingQueue()) { thread in
let (threadPromise, threadPromiseSeal) = Promise<TSContactThread>.pending()
if let thread = TSContactThread.getWithContactId(destination.hexEncodedPublicKey, transaction: transaction) {
threadPromiseSeal.fulfill(thread)
} else {
// Dispatch async on the main queue to avoid nested write transactions
DispatchQueue.main.async {
storage.dbReadWriteConnection.readWrite { transaction in
let thread = TSContactThread.getOrCreateThread(withContactId: destination.hexEncodedPublicKey, transaction: transaction)
threadPromiseSeal.fulfill(thread)
}
}
}
return threadPromise.then(on: OWSDispatch.sendingQueue()) { thread -> Promise<Void> in
let message = messageSend.message
let messageSender = SSKEnvironment.shared.messageSender
let (promise, seal) = Promise<Void>.pending()
let shouldSendAutoGeneratedFR = !thread.isContactFriend && !(message is FriendRequestMessage)
&& message.shouldBeSaved() // shouldBeSaved indicates it isn't a transient message
if !shouldSendAutoGeneratedFR {
let messageSendCopy = copy(messageSend, for: destination, with: seal)
messageSender.sendMessage(messageSendCopy)
} else {
// Dispatch async on the main queue to avoid nested write transactions
DispatchQueue.main.async {
storage.dbReadWriteConnection.readWrite { transaction in
getAutoGeneratedMultiDeviceFRMessageSend(for: destination.hexEncodedPublicKey, in: transaction)
getAutoGeneratedMultiDeviceFRMessageSend(for: destination.hexEncodedPublicKey, in: transaction, seal: seal)
.done(on: OWSDispatch.sendingQueue()) { autoGeneratedFRMessageSend in
messageSender.sendMessage(autoGeneratedFRMessageSend)
}
}
}
}
return promise
}
promise.catch(on: OWSDispatch.sendingQueue()) { error in
print("[Loki] Couldn't get thread for destination: \(destination.hexEncodedPublicKey).")
}
if let thread = TSContactThread.getWithContactId(destination.hexEncodedPublicKey, transaction: transaction) {
seal.fulfill(thread)
} else {
DispatchQueue.main.async {
storage.dbReadWriteConnection.readWrite { transaction in
let thread = TSContactThread.getOrCreateThread(withContactId: destination.hexEncodedPublicKey, transaction: transaction)
seal.fulfill(thread)
}
}
}
return promise.map { _ in }
}
@objc(sendMessageToDestinationAndLinkedDevices:in:)
@ -166,7 +166,7 @@ public final class MultiDeviceProtocol : NSObject {
return AnyPromise.from(getAutoGeneratedMultiDeviceFRMessageSend(for: hexEncodedPublicKey, in: transaction))
}
public static func getAutoGeneratedMultiDeviceFRMessageSend(for hexEncodedPublicKey: String, in transaction: YapDatabaseReadWriteTransaction) -> Promise<OWSMessageSend> {
public static func getAutoGeneratedMultiDeviceFRMessageSend(for hexEncodedPublicKey: String, in transaction: YapDatabaseReadWriteTransaction, seal externalSeal: Resolver<Void>? = nil) -> Promise<OWSMessageSend> {
let thread = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction)
let message = getAutoGeneratedMultiDeviceFRMessage(for: hexEncodedPublicKey, in: transaction)
thread.friendRequestStatus = .requestSending
@ -183,11 +183,15 @@ public final class MultiDeviceProtocol : NSObject {
}
let messageSend = OWSMessageSend(message: message, thread: thread, recipient: recipient, senderCertificate: senderCertificate,
udAccess: recipientUDAccess, localNumber: getUserHexEncodedPublicKey(), success: {
externalSeal?.fulfill(())
// Dispatch async on the main queue to avoid nested write transactions
DispatchQueue.main.async {
thread.friendRequestStatus = .requestSent
thread.save()
}
}, failure: { _ in
}, failure: { error in
externalSeal?.reject(error)
// Dispatch async on the main queue to avoid nested write transactions
DispatchQueue.main.async {
thread.friendRequestStatus = .none
thread.save()

Loading…
Cancel
Save