Merge remote-tracking branch 'origin/release/2.31.0'

pull/1/head
Matthew Chen 7 years ago
commit b90fee08bd

@ -49,7 +49,7 @@
</dict> </dict>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>2.31.0.25</string> <string>2.31.0.26</string>
<key>ITSAppUsesNonExemptEncryption</key> <key>ITSAppUsesNonExemptEncryption</key>
<false/> <false/>
<key>LOGS_EMAIL</key> <key>LOGS_EMAIL</key>

@ -229,6 +229,14 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error);
void (^failureBlock)(void) = ^{ void (^failureBlock)(void) = ^{
OWSLogError(@"Updating service with profile failed."); OWSLogError(@"Updating service with profile failed.");
// We use a "self-only" contact sync to indicate to desktop
// that we've changed our profile and that it should do a
// profile fetch for "self".
//
// NOTE: We also inform the desktop in the failure case,
// since that _may have_ affected service state.
[self.syncManager syncLocalContact];
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
failureBlockParameter(); failureBlockParameter();
}); });
@ -236,6 +244,11 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error);
void (^successBlock)(void) = ^{ void (^successBlock)(void) = ^{
OWSLogInfo(@"Successfully updated service with profile."); OWSLogInfo(@"Successfully updated service with profile.");
// We use a "self-only" contact sync to indicate to desktop
// that we've changed our profile and that it should do a
// profile fetch for "self".
[self.syncManager syncLocalContact];
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
successBlockParameter(); successBlockParameter();
}); });

@ -212,8 +212,9 @@ NS_ASSUME_NONNULL_BEGIN
__block NSMutableArray *result = [NSMutableArray array]; __block NSMutableArray *result = [NSMutableArray array];
for (PhoneNumber *number in [self.parsedPhoneNumbers sortedArrayUsingSelector:@selector(compare:)]) { for (PhoneNumber *number in [self.parsedPhoneNumbers sortedArrayUsingSelector:@selector(compare:)]) {
SignalRecipient *_Nullable signalRecipient = SignalRecipient *_Nullable signalRecipient = [SignalRecipient registeredRecipientForRecipientId:number.toE164
[SignalRecipient registeredRecipientForRecipientId:number.toE164 transaction:transaction]; mustHaveDevices:YES
transaction:transaction];
if (signalRecipient) { if (signalRecipient) {
[result addObject:signalRecipient]; [result addObject:signalRecipient];
} }

@ -103,7 +103,7 @@ NS_ASSUME_NONNULL_BEGIN
[SignalRecipient markRecipientAsRegisteredAndGet:recipientId transaction:transaction]; [SignalRecipient markRecipientAsRegisteredAndGet:recipientId transaction:transaction];
[recipients addObject:recipient]; [recipients addObject:recipient];
} else { } else {
[SignalRecipient removeUnregisteredRecipient:recipientId transaction:transaction]; [SignalRecipient markRecipientAsUnregistered:recipientId transaction:transaction];
} }
} }
}]; }];

@ -10,10 +10,11 @@ NS_ASSUME_NONNULL_BEGIN
// //
// a) It serves as a cache of "known" Signal accounts. When the service indicates // a) It serves as a cache of "known" Signal accounts. When the service indicates
// that an account exists, we make sure that an instance of SignalRecipient exists // that an account exists, we make sure that an instance of SignalRecipient exists
// for that recipient id (using mark as registered). // for that recipient id (using mark as registered) and has at least one device.
// When the service indicates that an account does not exist, we remove any // When the service indicates that an account does not exist, we remove any devices
// SignalRecipient. // from that SignalRecipient - but do not remove it from the database.
// b) We hang the "known device list" for known signal accounts on this entity. // Note that SignalRecipients without any devices are not considered registered.
//// b) We hang the "known device list" for known signal accounts on this entity.
@interface SignalRecipient : TSYapDatabaseObject @interface SignalRecipient : TSYapDatabaseObject
@property (nonatomic, readonly) NSOrderedSet *devices; @property (nonatomic, readonly) NSOrderedSet *devices;
@ -21,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE;
+ (nullable instancetype)registeredRecipientForRecipientId:(NSString *)recipientId + (nullable instancetype)registeredRecipientForRecipientId:(NSString *)recipientId
mustHaveDevices:(BOOL)mustHaveDevices
transaction:(YapDatabaseReadTransaction *)transaction; transaction:(YapDatabaseReadTransaction *)transaction;
+ (instancetype)getOrBuildUnsavedRecipientForRecipientId:(NSString *)recipientId + (instancetype)getOrBuildUnsavedRecipientForRecipientId:(NSString *)recipientId
transaction:(YapDatabaseReadTransaction *)transaction; transaction:(YapDatabaseReadTransaction *)transaction;
@ -40,7 +42,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)markRecipientAsRegistered:(NSString *)recipientId + (void)markRecipientAsRegistered:(NSString *)recipientId
deviceId:(UInt32)deviceId deviceId:(UInt32)deviceId
transaction:(YapDatabaseReadWriteTransaction *)transaction; transaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (void)removeUnregisteredRecipient:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction; + (void)markRecipientAsUnregistered:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction;
@end @end

@ -41,8 +41,9 @@ NS_ASSUME_NONNULL_BEGIN
{ {
OWSAssertDebug(transaction); OWSAssertDebug(transaction);
OWSAssertDebug(recipientId.length > 0); OWSAssertDebug(recipientId.length > 0);
SignalRecipient *_Nullable recipient = [self registeredRecipientForRecipientId:recipientId transaction:transaction]; SignalRecipient *_Nullable recipient =
[self registeredRecipientForRecipientId:recipientId mustHaveDevices:NO transaction:transaction];
if (!recipient) { if (!recipient) {
recipient = [[self alloc] initWithTextSecureIdentifier:recipientId]; recipient = [[self alloc] initWithTextSecureIdentifier:recipientId];
} }
@ -95,14 +96,18 @@ NS_ASSUME_NONNULL_BEGIN
return self; return self;
} }
+ (nullable instancetype)registeredRecipientForRecipientId:(NSString *)recipientId + (nullable instancetype)registeredRecipientForRecipientId:(NSString *)recipientId
mustHaveDevices:(BOOL)mustHaveDevices
transaction:(YapDatabaseReadTransaction *)transaction transaction:(YapDatabaseReadTransaction *)transaction
{ {
OWSAssertDebug(transaction); OWSAssertDebug(transaction);
OWSAssertDebug(recipientId.length > 0); OWSAssertDebug(recipientId.length > 0);
return [self fetchObjectWithUniqueID:recipientId transaction:transaction]; SignalRecipient *_Nullable signalRecipient = [self fetchObjectWithUniqueID:recipientId transaction:transaction];
if (mustHaveDevices && signalRecipient.devices.count < 1) {
return nil;
}
return signalRecipient;
} }
- (void)addDevices:(NSSet *)devices - (void)addDevices:(NSSet *)devices
@ -136,7 +141,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssertDebug(devicesToAdd.count > 0 || devicesToRemove.count > 0); OWSAssertDebug(devicesToAdd.count > 0 || devicesToRemove.count > 0);
// Add before we remove, since removeDevicesFromRecipient:... // Add before we remove, since removeDevicesFromRecipient:...
// can removeUnregisteredRecipient:... if the recipient has // can markRecipientAsUnregistered:... if the recipient has
// no devices left. // no devices left.
if (devicesToAdd.count > 0) { if (devicesToAdd.count > 0) {
[self addDevicesToRegisteredRecipient:[NSSet setWithArray:devicesToAdd] transaction:transaction]; [self addDevicesToRegisteredRecipient:[NSSet setWithArray:devicesToAdd] transaction:transaction];
@ -172,12 +177,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSLogDebug(@"removing devices: %@, from registered recipient: %@", devices, self); OWSLogDebug(@"removing devices: %@, from registered recipient: %@", devices, self);
[self reloadWithTransaction:transaction]; [self reloadWithTransaction:transaction];
[self removeDevices:devices]; [self removeDevices:devices];
[self saveWithTransaction_internal:transaction];
if (self.devices.count > 0) {
[self saveWithTransaction_internal:transaction];
} else {
[SignalRecipient removeUnregisteredRecipient:self.recipientId transaction:transaction];
}
} }
- (NSString *)recipientId - (NSString *)recipientId
@ -190,6 +190,19 @@ NS_ASSUME_NONNULL_BEGIN
return [self.recipientId compare:other.recipientId]; return [self.recipientId compare:other.recipientId];
} }
- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
// We need to distinguish between "users we know to be unregistered" and
// "users whose registration status is unknown". The former correspond to
// instances of SignalRecipient with no devices. The latter do not
// correspond to an instance of SignalRecipient in the database (although
// they may correspond to an "unsaved" instance of SignalRecipient built
// by getOrBuildUnsavedRecipientForRecipientId.
OWSFailDebug(@"Don't call removeWithTransaction.");
[super removeWithTransaction:transaction];
}
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
// We only want to mutate the persisted SignalRecipients in the database // We only want to mutate the persisted SignalRecipients in the database
@ -199,7 +212,7 @@ NS_ASSUME_NONNULL_BEGIN
// reflect "last known registration status". Forcing our codebase to // reflect "last known registration status". Forcing our codebase to
// use those methods helps ensure that we update the cache deliberately. // use those methods helps ensure that we update the cache deliberately.
OWSFailDebug(@"Don't call saveWithTransaction from outside this class."); OWSFailDebug(@"Don't call saveWithTransaction from outside this class.");
[self saveWithTransaction_internal:transaction]; [self saveWithTransaction_internal:transaction];
} }
@ -207,13 +220,12 @@ NS_ASSUME_NONNULL_BEGIN
{ {
[super saveWithTransaction:transaction]; [super saveWithTransaction:transaction];
OWSLogVerbose(@"saved signal recipient: %@", self.recipientId); OWSLogVerbose(@"saved signal recipient: %@ (%lu)", self.recipientId, (unsigned long) self.devices.count);
} }
+ (BOOL)isRegisteredRecipient:(NSString *)recipientId transaction:(YapDatabaseReadTransaction *)transaction + (BOOL)isRegisteredRecipient:(NSString *)recipientId transaction:(YapDatabaseReadTransaction *)transaction
{ {
SignalRecipient *_Nullable instance = [self registeredRecipientForRecipientId:recipientId transaction:transaction]; return nil != [self registeredRecipientForRecipientId:recipientId mustHaveDevices:YES transaction:transaction];
return instance != nil;
} }
+ (SignalRecipient *)markRecipientAsRegisteredAndGet:(NSString *)recipientId + (SignalRecipient *)markRecipientAsRegisteredAndGet:(NSString *)recipientId
@ -222,7 +234,8 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssertDebug(transaction); OWSAssertDebug(transaction);
OWSAssertDebug(recipientId.length > 0); OWSAssertDebug(recipientId.length > 0);
SignalRecipient *_Nullable instance = [self registeredRecipientForRecipientId:recipientId transaction:transaction]; SignalRecipient *_Nullable instance =
[self registeredRecipientForRecipientId:recipientId mustHaveDevices:YES transaction:transaction];
if (!instance) { if (!instance) {
OWSLogDebug(@"creating recipient: %@", recipientId); OWSLogDebug(@"creating recipient: %@", recipientId);
@ -249,17 +262,18 @@ NS_ASSUME_NONNULL_BEGIN
} }
} }
+ (void)removeUnregisteredRecipient:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction + (void)markRecipientAsUnregistered:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction); OWSAssertDebug(transaction);
OWSAssertDebug(recipientId.length > 0); OWSAssertDebug(recipientId.length > 0);
SignalRecipient *_Nullable instance = [self registeredRecipientForRecipientId:recipientId transaction:transaction]; SignalRecipient *instance = [self getOrBuildUnsavedRecipientForRecipientId:recipientId
if (!instance) { transaction:transaction];
return; OWSLogDebug(@"Marking recipient as not registered: %@", recipientId);
if (instance.devices.count > 0) {
[instance removeDevices:instance.devices.set];
} }
OWSLogDebug(@"removing recipient: %@", recipientId); [instance saveWithTransaction_internal:transaction];
[instance removeWithTransaction:transaction];
} }
@end @end

@ -1478,7 +1478,7 @@ NS_ASSUME_NONNULL_BEGIN
// Consult the device list cache we use for message sending // Consult the device list cache we use for message sending
// whether or not we know about this linked device. // whether or not we know about this linked device.
SignalRecipient *_Nullable recipient = SignalRecipient *_Nullable recipient =
[SignalRecipient registeredRecipientForRecipientId:localNumber transaction:transaction]; [SignalRecipient registeredRecipientForRecipientId:localNumber mustHaveDevices:NO transaction:transaction];
if (!recipient) { if (!recipient) {
OWSFailDebug(@"No local SignalRecipient."); OWSFailDebug(@"No local SignalRecipient.");
} else { } else {

@ -787,7 +787,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
return; return;
} }
[SignalRecipient removeUnregisteredRecipient:recipient.recipientId transaction:transaction]; [SignalRecipient markRecipientAsUnregistered:recipient.recipientId transaction:transaction];
[[TSInfoMessage userNotRegisteredMessageInThread:thread recipientId:recipient.recipientId] [[TSInfoMessage userNotRegisteredMessageInThread:thread recipientId:recipient.recipientId]
saveWithTransaction:transaction]; saveWithTransaction:transaction];
@ -1016,7 +1016,11 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
OWSFailDebug(@"sync message has device messages for unknown secondary devices."); OWSFailDebug(@"sync message has device messages for unknown secondary devices.");
} }
} else { } else {
OWSAssertDebug(deviceMessages.count > 0); // This can happen for users who have unregistered.
// We still want to try sending to them in case they have re-registered.
if (deviceMessages.count < 1) {
OWSLogWarn(@"Message send attempt with no device messages.");
}
} }
if (deviceMessages.count == 0) { if (deviceMessages.count == 0) {

@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>2.31.0</string> <string>2.31.0</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>2.31.0.25</string> <string>2.31.0.26</string>
<key>ITSAppUsesNonExemptEncryption</key> <key>ITSAppUsesNonExemptEncryption</key>
<false/> <false/>
<key>NSAppTransportSecurity</key> <key>NSAppTransportSecurity</key>

Loading…
Cancel
Save