Merge branch 'charlesmchen/verificationStateChangeMessages'

pull/1/head
Matthew Chen 9 years ago
commit f2f654af19

@ -0,0 +1,26 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSRecipientIdentity.h"
#import "TSInfoMessage.h"
NS_ASSUME_NONNULL_BEGIN
@class TSThread;
@interface OWSVerificationStateChangeMessage : TSInfoMessage
@property (nonatomic, readonly) NSString *recipientId;
@property (nonatomic, readonly) OWSVerificationState verificationState;
@property (nonatomic, readonly) BOOL isLocalChange;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
thread:(TSThread *)thread
recipientId:(NSString *)recipientId
verificationState:(OWSVerificationState)verificationState
isLocalChange:(BOOL)isLocalChange;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,34 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSVerificationStateChangeMessage.h"
#import "OWSDisappearingMessagesConfiguration.h"
NS_ASSUME_NONNULL_BEGIN
@implementation OWSVerificationStateChangeMessage
- (instancetype)initWithTimestamp:(uint64_t)timestamp
thread:(TSThread *)thread
recipientId:(NSString *)recipientId
verificationState:(OWSVerificationState)verificationState
isLocalChange:(BOOL)isLocalChange
{
OWSAssert(recipientId.length > 0);
self = [super initWithTimestamp:timestamp inThread:thread messageType:TSInfoMessageVerificationStateChange];
if (!self) {
return self;
}
_recipientId = recipientId;
_verificationState = verificationState;
_isLocalChange = isLocalChange;
return self;
}
@end
NS_ASSUME_NONNULL_END

@ -18,6 +18,7 @@ typedef NS_ENUM(NSInteger, TSInfoMessageType) {
TSInfoMessageTypeGroupQuit,
TSInfoMessageTypeDisappearingMessagesUpdate,
TSInfoMessageAddToContactsOffer,
TSInfoMessageVerificationStateChange,
};
+ (instancetype)userNotRegisteredMessageInThread:(TSThread *)thread;

@ -37,6 +37,8 @@ extern const NSUInteger kIdentityKeyLength;
- (OWSVerificationState)verificationStateForRecipientId:(NSString *)recipientId;
- (nullable OWSRecipientIdentity *)recipientIdentityForRecipientId:(NSString *)recipientId;
/**
* @param recipientId unique stable identifier for the recipient, e.g. e164 phone number
* @returns nil if the recipient does not exist, or is trusted for sending

@ -3,9 +3,11 @@
//
#import "OWSIdentityManager.h"
#import "NSDate+millisecondTimeStamp.h"
#import "NotificationsProtocol.h"
#import "OWSMessageSender.h"
#import "OWSRecipientIdentity.h"
#import "OWSVerificationStateChangeMessage.h"
#import "OWSVerificationStateSyncMessage.h"
#import "TSAccountManager.h"
#import "TSContactThread.h"
@ -190,6 +192,12 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
// Cancel any pending verification state sync messages for this recipient.
[self clearSyncMessageForRecipientId:recipientId];
if (existingIdentity.verificationState != verificationState) {
[self saveChangeMessagesForRecipientId:recipientId
verificationState:verificationState
isLocalChange:YES];
}
[self fireIdentityStateChangeNotification];
return YES;
@ -241,6 +249,8 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
// Cancel any pending verification state sync messages for this recipient.
[self clearSyncMessageForRecipientId:recipientId];
}
[self saveChangeMessagesForRecipientId:recipientId verificationState:verificationState isLocalChange:YES];
}
[self fireIdentityStateChangeNotification];
@ -263,6 +273,16 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
}
}
- (nullable OWSRecipientIdentity *)recipientIdentityForRecipientId:(NSString *)recipientId
{
OWSAssert(recipientId.length > 0);
@synchronized(self)
{
return [OWSRecipientIdentity fetchObjectWithUniqueID:recipientId];
}
}
- (nullable OWSRecipientIdentity *)untrustedIdentityForSendingToRecipientId:(NSString *)recipientId
{
OWSAssert(recipientId.length > 0);
@ -385,18 +405,25 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
{
OWSAssert(recipientId != nil);
NSMutableArray<TSMessage *> *messages = [NSMutableArray new];
TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:recipientId];
OWSAssert(contactThread != nil);
TSErrorMessage *errorMessage =
[TSErrorMessage nonblockingIdentityChangeInThread:contactThread recipientId:recipientId];
[errorMessage save];
[messages addObject:errorMessage];
[[TextSecureKitEnv sharedEnv].notificationsManager notifyUserForErrorMessage:errorMessage inThread:contactThread];
for (TSGroupThread *groupThread in [TSGroupThread groupThreadsWithRecipientId:recipientId]) {
[[TSErrorMessage nonblockingIdentityChangeInThread:groupThread recipientId:recipientId] save];
[messages addObject:[TSErrorMessage nonblockingIdentityChangeInThread:groupThread recipientId:recipientId]];
}
[self.storageManager.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
for (TSMessage *message in messages) {
[message saveWithTransaction:transaction];
}
}];
}
- (void)enqueueSyncMessageForVerificationState:(OWSVerificationState)verificationState
@ -497,6 +524,14 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
OWSAssert(message);
OWSAssert(message.recipientIds.count > 0);
if (YES) {
// Don't actually transmit any verification state sync messages
// until we finalize the proto schema changes.
//
// TODO: Remove.
return;
}
[self.messageSender sendMessage:message
success:^{
DDLogInfo(@"%@ Successfully sent verification state sync message", self.tag);
@ -625,6 +660,9 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
OWSVerificationStateToString(verificationState));
[recipientIdentity updateWithVerificationState:verificationState];
// No need to call [saveChangeMessagesForRecipientId:..] since this is
// a new recipient.
} else {
// There's an existing recipient identity for this recipient.
// We should update it.
@ -668,10 +706,44 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
}
[recipientIdentity updateWithVerificationState:verificationState];
[self saveChangeMessagesForRecipientId:recipientId verificationState:verificationState isLocalChange:NO];
}
}
}
- (void)saveChangeMessagesForRecipientId:(NSString *)recipientId
verificationState:(OWSVerificationState)verificationState
isLocalChange:(BOOL)isLocalChange
{
OWSAssert(recipientId.length > 0);
NSMutableArray<TSMessage *> *messages = [NSMutableArray new];
TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:recipientId];
OWSAssert(contactThread);
[messages addObject:[[OWSVerificationStateChangeMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:contactThread
recipientId:recipientId
verificationState:verificationState
isLocalChange:isLocalChange]];
for (TSGroupThread *groupThread in [TSGroupThread groupThreadsWithRecipientId:recipientId]) {
[messages
addObject:[[OWSVerificationStateChangeMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:groupThread
recipientId:recipientId
verificationState:verificationState
isLocalChange:isLocalChange]];
}
[self.storageManager.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
for (TSMessage *message in messages) {
[message saveWithTransaction:transaction];
}
}];
}
#pragma mark - Notifications
- (void)applicationDidBecomeActive:(NSNotification *)notification

Loading…
Cancel
Save