Merge pull request #184 from loki-project/friend-request-fix
Friend request fixes
This commit is contained in:
commit
82c824a7a6
2
Pods
2
Pods
|
@ -1 +1 @@
|
|||
Subproject commit 04c71c59e4c3b060f8ff96b072efca3a74c4980f
|
||||
Subproject commit a10cec6cd837552a4b0a88462636cf06494644c4
|
|
@ -10,12 +10,11 @@ public final class SignalMessage : NSObject {
|
|||
@objc(ttl)
|
||||
public let objc_ttl: UInt64
|
||||
@objc public let isPing: Bool
|
||||
@objc public let isFriendRequest: Bool
|
||||
|
||||
public var ttl: UInt64? { return objc_ttl != 0 ? objc_ttl : nil }
|
||||
|
||||
@objc public init(type: SSKProtoEnvelope.SSKProtoEnvelopeType, timestamp: UInt64, senderID: String, senderDeviceID: UInt32,
|
||||
content: String, recipientID: String, ttl: UInt64, isPing: Bool, isFriendRequest: Bool) {
|
||||
content: String, recipientID: String, ttl: UInt64, isPing: Bool) {
|
||||
self.type = type
|
||||
self.timestamp = timestamp
|
||||
self.senderID = senderID
|
||||
|
@ -24,7 +23,6 @@ public final class SignalMessage : NSObject {
|
|||
self.recipientID = recipientID
|
||||
self.objc_ttl = ttl
|
||||
self.isPing = isPing
|
||||
self.isFriendRequest = isFriendRequest
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,8 @@ public final class FriendRequestProtocol : NSObject {
|
|||
print("[Loki] Invalid Session ID: \(hexEncodedPublicKey).")
|
||||
return
|
||||
}
|
||||
let userHexEncodedPublicKey = getUserHexEncodedPublicKey()
|
||||
let userLinkedDevices = LokiDatabaseUtilities.getLinkedDeviceHexEncodedPublicKeys(for: userHexEncodedPublicKey, in: transaction)
|
||||
// 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 linkedDevices = LokiDatabaseUtilities.getLinkedDeviceHexEncodedPublicKeys(for: hexEncodedPublicKey, in: transaction)
|
||||
|
@ -117,7 +119,7 @@ public final class FriendRequestProtocol : NSObject {
|
|||
storage.setFriendRequestStatus(.friends, for: device, transaction: transaction)
|
||||
sendFriendRequestAcceptanceMessage(to: device, using: transaction)
|
||||
// Send a contact sync message if needed
|
||||
guard !LokiDatabaseUtilities.isUserLinkedDevice(hexEncodedPublicKey, transaction: transaction) else { return }
|
||||
guard !userLinkedDevices.contains(hexEncodedPublicKey) else { return }
|
||||
let masterHexEncodedPublicKey = storage.getMasterHexEncodedPublicKey(for: hexEncodedPublicKey, in: transaction) ?? hexEncodedPublicKey
|
||||
let syncManager = SSKEnvironment.shared.syncManager
|
||||
syncManager.syncContact(masterHexEncodedPublicKey, transaction: transaction)
|
||||
|
@ -165,6 +167,14 @@ public final class FriendRequestProtocol : NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
@objc(shouldUpdateFriendRequestStatusFromMessage:)
|
||||
public static func shouldUpdateFriendRequestStatus(from message: TSOutgoingMessage) -> Bool {
|
||||
// The order of these checks matters
|
||||
if (message as? DeviceLinkMessage)?.kind == .request { return true }
|
||||
if message is SessionRequestMessage { return false }
|
||||
return message is FriendRequestMessage
|
||||
}
|
||||
|
||||
@objc(setFriendRequestStatusToSendingIfNeededForHexEncodedPublicKey:transaction:)
|
||||
public static func setFriendRequestStatusToSendingIfNeeded(for hexEncodedPublicKey: String, transaction: YapDatabaseReadWriteTransaction) {
|
||||
let friendRequestStatus = storage.getFriendRequestStatus(for: hexEncodedPublicKey, transaction: transaction)
|
||||
|
|
|
@ -428,7 +428,7 @@ class FriendRequestProtocolTests : XCTestCase {
|
|||
self.storage.setFriendRequestStatus(status, for: bob, transaction: transaction)
|
||||
}
|
||||
|
||||
let expectation = self.expectation(description: "sent message")
|
||||
let expectation = self.expectation(description: "Send message")
|
||||
|
||||
let messageSender = self.messageSender
|
||||
messageSender.sendMessageWasCalledBlock = { sentMessage in
|
||||
|
@ -447,6 +447,32 @@ class FriendRequestProtocolTests : XCTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
func test_acceptFriendRequestShouldNotSendAFriendRequestMessageToOurOwnDevice() {
|
||||
let statuses: [LKFriendRequestStatus] = [ .none, .requestExpired ]
|
||||
for status in statuses {
|
||||
let ourDevice = LokiTestUtilities.getCurrentUserHexEncodedPublicKey()
|
||||
|
||||
storage.dbReadWriteConnection.readWrite { transaction in
|
||||
self.storage.setFriendRequestStatus(status, for: ourDevice, transaction: transaction)
|
||||
}
|
||||
|
||||
let expectation = self.expectation(description: "Send message")
|
||||
|
||||
let messageSender = self.messageSender
|
||||
messageSender.sendMessageWasCalledBlock = { sentMessage in
|
||||
XCTFail("Expected message not to be sent.")
|
||||
}
|
||||
|
||||
storage.dbReadWriteConnection.readWrite { transaction in
|
||||
FriendRequestProtocol.acceptFriendRequest(from: ourDevice, using: transaction)
|
||||
}
|
||||
|
||||
expectation.fulfillAfter(2)
|
||||
wait(for: [ expectation ], timeout: 2)
|
||||
messageSender.sendMessageWasCalledBlock = nil
|
||||
}
|
||||
}
|
||||
|
||||
func test_acceptFriendRequestShouldNotDoAnythingIfRequestHasBeenSent() {
|
||||
// Case: We sent Bob a friend request.
|
||||
// We can't accept because we don't have keys to communicate with Bob.
|
||||
|
@ -594,4 +620,21 @@ class FriendRequestProtocolTests : XCTestCase {
|
|||
XCTAssertTrue(self.isFriendRequestStatus(.none, for: otherSlave, transaction: transaction))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - shouldUpdateFriendRequestStatus
|
||||
func test_shouldUpdateFriendRequestStatusReturnsTheCorrectValue() {
|
||||
let thread = LokiTestUtilities.createContactThread(for: LokiTestUtilities.generateHexEncodedPublicKey())
|
||||
|
||||
let message = TSOutgoingMessage(in: thread, messageBody: nil, attachmentId: nil)
|
||||
let friendRequest = FriendRequestMessage(timestamp: 1, thread: thread, body: "")
|
||||
let sessionRequest = SessionRequestMessage(thread: thread)
|
||||
guard let deviceLinkRequest = DeviceLinkMessage(in: thread, masterHexEncodedPublicKey: "", slaveHexEncodedPublicKey: "", masterSignature: nil, slaveSignature: Data(capacity: 0)),
|
||||
let deviceLinkAuthorisation = DeviceLinkMessage(in: thread, masterHexEncodedPublicKey: "", slaveHexEncodedPublicKey: "", masterSignature: Data(capacity: 0), slaveSignature: Data(capacity: 0)) else { return XCTFail() }
|
||||
|
||||
XCTAssertTrue(FriendRequestProtocol.shouldUpdateFriendRequestStatus(from: friendRequest))
|
||||
XCTAssertTrue(FriendRequestProtocol.shouldUpdateFriendRequestStatus(from: deviceLinkRequest))
|
||||
XCTAssertFalse(FriendRequestProtocol.shouldUpdateFriendRequestStatus(from: message))
|
||||
XCTAssertFalse(FriendRequestProtocol.shouldUpdateFriendRequestStatus(from: sessionRequest))
|
||||
XCTAssertFalse(FriendRequestProtocol.shouldUpdateFriendRequestStatus(from: deviceLinkAuthorisation))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,4 +4,6 @@
|
|||
NS_SWIFT_NAME(FriendRequestMessage)
|
||||
@interface LKFriendRequestMessage : TSOutgoingMessage
|
||||
|
||||
- (_Nonnull instancetype)initWithTimestamp:(uint64_t)timestamp thread:(nullable TSThread *)thread body:(nullable NSString *)body;
|
||||
|
||||
@end
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
|
||||
@implementation LKFriendRequestMessage
|
||||
|
||||
#pragma mark Initialization
|
||||
- (instancetype)initWithTimestamp:(uint64_t)timestamp thread:(nullable TSThread *)thread body:(nullable NSString *)body {
|
||||
return [self initOutgoingMessageWithTimestamp:timestamp inThread:thread messageBody:body attachmentIds:@[] expiresInSeconds:0 expireStartedAt:0
|
||||
isVoiceMessage:false groupMetaMessage:TSGroupMetaMessageUnspecified quotedMessage:nil contactShare:nil linkPreview:nil];
|
||||
}
|
||||
|
||||
#pragma mark Building
|
||||
- (SSKProtoContentBuilder *)prepareCustomContentBuilder:(SignalRecipient *)recipient {
|
||||
SSKProtoContentBuilder *contentBuilder = SSKProtoContent.builder;
|
||||
|
|
|
@ -14,6 +14,6 @@ NS_SWIFT_NAME(DeviceLinkMessage)
|
|||
@property (nonatomic, readonly) NSData *slaveSignature;
|
||||
@property (nonatomic, readonly) LKDeviceLinkMessageKind kind;
|
||||
|
||||
- (instancetype)initInThread:(TSThread *)thread masterHexEncodedPublicKey:(NSString *)masterHexEncodedPublicKey slaveHexEncodedPublicKey:(NSString *)slaveHexEncodedPublicKey masterSignature:(NSData *)masterSignature slaveSignature:(NSData *)slaveSignature;
|
||||
- (instancetype)initInThread:(TSThread *)thread masterHexEncodedPublicKey:(NSString *)masterHexEncodedPublicKey slaveHexEncodedPublicKey:(NSString *)slaveHexEncodedPublicKey masterSignature:(NSData * _Nullable)masterSignature slaveSignature:(NSData *)slaveSignature;
|
||||
|
||||
@end
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
}
|
||||
|
||||
#pragma mark Initialization
|
||||
- (instancetype)initInThread:(TSThread *)thread masterHexEncodedPublicKey:(NSString *)masterHexEncodedPublicKey slaveHexEncodedPublicKey:(NSString *)slaveHexEncodedPublicKey masterSignature:(NSData *)masterSignature slaveSignature:(NSData *)slaveSignature {
|
||||
- (instancetype)initInThread:(TSThread *)thread masterHexEncodedPublicKey:(NSString *)masterHexEncodedPublicKey slaveHexEncodedPublicKey:(NSString *)slaveHexEncodedPublicKey masterSignature:(NSData * _Nullable)masterSignature slaveSignature:(NSData *)slaveSignature {
|
||||
self = [self initOutgoingMessageWithTimestamp:NSDate.ows_millisecondTimeStamp inThread:thread messageBody:@"" attachmentIds:[NSMutableArray<NSString *> new]
|
||||
expiresInSeconds:0 expireStartedAt:0 isVoiceMessage:NO groupMetaMessage:TSGroupMetaMessageUnspecified quotedMessage:nil contactShare:nil linkPreview:nil];
|
||||
if (self) {
|
||||
|
|
|
@ -151,10 +151,7 @@ public final class MultiDeviceProtocol : NSObject {
|
|||
@objc(getAutoGeneratedMultiDeviceFRMessageForHexEncodedPublicKey:in:)
|
||||
public static func getAutoGeneratedMultiDeviceFRMessage(for hexEncodedPublicKey: String, in transaction: YapDatabaseReadWriteTransaction) -> FriendRequestMessage {
|
||||
let thread = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction)
|
||||
let result = FriendRequestMessage(outgoingMessageWithTimestamp: NSDate.ows_millisecondTimeStamp(), in: thread,
|
||||
messageBody: "Please accept to enable messages to be synced across devices",
|
||||
attachmentIds: [], expiresInSeconds: 0, expireStartedAt: 0, isVoiceMessage: false,
|
||||
groupMetaMessage: .unspecified, quotedMessage: nil, contactShare: nil, linkPreview: nil)
|
||||
let result = FriendRequestMessage(timestamp: NSDate.ows_millisecondTimeStamp(), thread: thread, body: "Please accept to enable messages to be synced across devices")
|
||||
result.skipSave = true // TODO: Why is this necessary again?
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@ enum LokiTestUtilities {
|
|||
return Curve25519.generateKeyPair()
|
||||
}
|
||||
|
||||
public static func getCurrentUserHexEncodedPublicKey() -> String {
|
||||
return OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey
|
||||
}
|
||||
|
||||
public static func generateHexEncodedPublicKey() -> String {
|
||||
return generateKeyPair().hexEncodedPublicKey
|
||||
}
|
||||
|
|
|
@ -1177,14 +1177,14 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
NSString *recipientID = signalMessageInfo[@"destination"];
|
||||
uint64_t ttl = ((NSNumber *)signalMessageInfo[@"ttl"]).unsignedIntegerValue;
|
||||
BOOL isPing = ((NSNumber *)signalMessageInfo[@"isPing"]).boolValue;
|
||||
BOOL isFriendRequest = ((NSNumber *)signalMessageInfo[@"isFriendRequest"]).boolValue;
|
||||
LKSignalMessage *signalMessage = [[LKSignalMessage alloc] initWithType:type timestamp:timestamp senderID:senderID senderDeviceID:senderDeviceID content:content recipientID:recipientID ttl:ttl isPing:isPing isFriendRequest:isFriendRequest];
|
||||
LKSignalMessage *signalMessage = [[LKSignalMessage alloc] initWithType:type timestamp:timestamp senderID:senderID senderDeviceID:senderDeviceID content:content recipientID:recipientID ttl:ttl isPing:isPing];
|
||||
BOOL shouldUpdateFriendRequestStatus = [LKFriendRequestProtocol shouldUpdateFriendRequestStatusFromMessage:message];
|
||||
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
if (!message.skipSave) {
|
||||
// Update the PoW calculation status
|
||||
[message saveIsCalculatingProofOfWork:YES withTransaction:transaction];
|
||||
}
|
||||
if (signalMessage.isFriendRequest) {
|
||||
if (shouldUpdateFriendRequestStatus) {
|
||||
[LKFriendRequestProtocol setFriendRequestStatusToSendingIfNeededForHexEncodedPublicKey:recipientID transaction:transaction];
|
||||
}
|
||||
}];
|
||||
|
@ -1196,7 +1196,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
// Update the PoW calculation status
|
||||
[message saveIsCalculatingProofOfWork:NO withTransaction:transaction];
|
||||
}
|
||||
if (signalMessage.isFriendRequest) {
|
||||
if (shouldUpdateFriendRequestStatus) {
|
||||
[LKFriendRequestProtocol setFriendRequestStatusToFailedIfNeededForHexEncodedPublicKey:recipientID transaction:transaction];
|
||||
}
|
||||
}];
|
||||
|
@ -1216,7 +1216,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
if (isSuccess) { return; } // Succeed as soon as the first promise succeeds
|
||||
[NSNotificationCenter.defaultCenter postNotificationName:NSNotification.messageSent object:[[NSNumber alloc] initWithUnsignedLongLong:signalMessage.timestamp]];
|
||||
isSuccess = YES;
|
||||
if (signalMessage.isFriendRequest) {
|
||||
if (shouldUpdateFriendRequestStatus) {
|
||||
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
if (!message.skipSave) {
|
||||
// Update the message
|
||||
|
@ -1803,18 +1803,17 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
OWSFailDebug(@"Failed to encrypt friend request for: %@.", recipientId);
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
OWSMessageServiceParams *messageParams =
|
||||
[[OWSMessageServiceParams alloc] initWithType:TSFriendRequestMessageType
|
||||
recipientId:recipientId
|
||||
device:[deviceId intValue]
|
||||
content:serializedMessage
|
||||
isSilent:false
|
||||
isOnline:false
|
||||
registrationId:0
|
||||
ttl:message.ttl
|
||||
isPing:false
|
||||
isFriendRequest:true];
|
||||
[[OWSMessageServiceParams alloc] initWithType:TSFriendRequestMessageType
|
||||
recipientId:recipientId
|
||||
device:[deviceId intValue]
|
||||
content:serializedMessage
|
||||
isSilent:false
|
||||
isOnline:false
|
||||
registrationId:0
|
||||
ttl:message.ttl
|
||||
isPing:false];
|
||||
|
||||
NSError *error;
|
||||
NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error];
|
||||
|
@ -1849,7 +1848,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
@(OWSDevicePrimaryDeviceId));
|
||||
}
|
||||
|
||||
BOOL isFriendRequest = [messageSend.message isKindOfClass:LKFriendRequestMessage.class];
|
||||
BOOL isFriendRequestMessage = [messageSend.message isKindOfClass:LKFriendRequestMessage.class];
|
||||
BOOL isDeviceLinkMessage = [messageSend.message isKindOfClass:LKDeviceLinkMessage.class]
|
||||
&& ((LKDeviceLinkMessage *)messageSend.message).kind == LKDeviceLinkMessageKindRequest;
|
||||
|
||||
|
@ -1879,7 +1878,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
paddedPlaintext:[plainText paddedMessageBody]
|
||||
senderCertificate:messageSend.senderCertificate
|
||||
protocolContext:transaction
|
||||
isFriendRequest:isFriendRequest || isDeviceLinkMessage
|
||||
useFallbackSessionCipher:isFriendRequestMessage || isDeviceLinkMessage
|
||||
error:&error];
|
||||
|
||||
SCKRaiseIfExceptionWrapperError(error);
|
||||
|
@ -1910,8 +1909,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
isOnline:isOnline
|
||||
registrationId:[cipher throws_remoteRegistrationId:transaction]
|
||||
ttl:message.ttl
|
||||
isPing:isPing
|
||||
isFriendRequest:isFriendRequest || isDeviceLinkMessage];
|
||||
isPing:isPing];
|
||||
|
||||
NSError *error;
|
||||
NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error];
|
||||
|
|
|
@ -30,9 +30,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// Loki: Wether this message is a p2p ping
|
||||
@property (nonatomic, readonly) BOOL isPing;
|
||||
|
||||
// Loki: Wether this message is a friend request
|
||||
@property (nonatomic, readonly) BOOL isFriendRequest;
|
||||
|
||||
- (instancetype)initWithType:(TSWhisperMessageType)type
|
||||
recipientId:(NSString *)destination
|
||||
device:(int)deviceId
|
||||
|
@ -41,8 +38,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
isOnline:(BOOL)isOnline
|
||||
registrationId:(int)registrationId
|
||||
ttl:(uint)ttl
|
||||
isPing:(BOOL)isPing
|
||||
isFriendRequest:(BOOL)isFriendRequest;
|
||||
isPing:(BOOL)isPing;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
registrationId:(int)registrationId
|
||||
ttl:(uint)ttl
|
||||
isPing:(BOOL)isPing
|
||||
isFriendRequest:(BOOL)isFriendRequest
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
@ -41,7 +40,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
_online = isOnline;
|
||||
_ttl = ttl;
|
||||
_isPing = isPing;
|
||||
_isFriendRequest = isFriendRequest;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue