Merge branch 'mkirk/profile-key-flag'

pull/1/head
Michael Kirk 8 years ago
commit 1aeccc6a4e

@ -149,6 +149,8 @@
45464DBC1DFA041F001D3FD6 /* DataChannelMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45464DBB1DFA041F001D3FD6 /* DataChannelMessage.swift */; };
454EBAB31F2BC08800ACE0BB /* OWSSwiftUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C921F2937CC00D284D6 /* OWSSwiftUtils.swift */; };
454EBAB41F2BE14C00ACE0BB /* OWSAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */; };
4556FA681F54AA9500AF40DD /* DebugUIProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4556FA671F54AA9500AF40DD /* DebugUIProfile.swift */; };
4556FA691F54AA9500AF40DD /* DebugUIProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4556FA671F54AA9500AF40DD /* DebugUIProfile.swift */; };
455A16DD1F1FEA0000F86704 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 455A16DB1F1FEA0000F86704 /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
455A16DE1F1FEA0000F86704 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 455A16DC1F1FEA0000F86704 /* MetalKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
455AC69B1F4F79E500134004 /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 455AC69A1F4F79E500134004 /* ImageCache.swift */; };
@ -608,6 +610,7 @@
4542F0951EBB9E9A00C7EE92 /* Promise+retainUntilComplete.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Promise+retainUntilComplete.swift"; sourceTree = "<group>"; };
45464DBB1DFA041F001D3FD6 /* DataChannelMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataChannelMessage.swift; sourceTree = "<group>"; };
454B35071D08EED80026D658 /* mk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = mk; path = translations/mk.lproj/Localizable.strings; sourceTree = "<group>"; };
4556FA671F54AA9500AF40DD /* DebugUIProfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugUIProfile.swift; sourceTree = "<group>"; };
455A16DB1F1FEA0000F86704 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
455A16DC1F1FEA0000F86704 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
455AC69A1F4F79E500134004 /* ImageCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCache.swift; sourceTree = "<group>"; };
@ -1136,6 +1139,7 @@
34D8C0251ED3673300188D7C /* DebugUITableViewController.h */,
34D8C0261ED3673300188D7C /* DebugUITableViewController.m */,
45638BDB1F3DD0D400128435 /* DebugUICalling.swift */,
4556FA671F54AA9500AF40DD /* DebugUIProfile.swift */,
);
path = DebugUI;
sourceTree = "<group>";
@ -2289,6 +2293,7 @@
34F3089F1ECA580B00BB7697 /* OWSUnreadIndicatorCell.m in Sources */,
34B3F8861E8DF1700035BE1A /* NotificationSettingsOptionsViewController.m in Sources */,
452ECA4D1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */,
4556FA681F54AA9500AF40DD /* DebugUIProfile.swift in Sources */,
452EA0971EA662330078744B /* AttachmentPointerAdapter.swift in Sources */,
34DFCB851E8E04B500053165 /* AddToBlockListViewController.m in Sources */,
45855F371D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */,
@ -2452,6 +2457,7 @@
954AEE6A1DF33E01002E5410 /* ContactsPickerTest.swift in Sources */,
B660F77B1C29988E00687D6E /* Queue.m in Sources */,
455AC69C1F4F79E500134004 /* ImageCache.swift in Sources */,
4556FA691F54AA9500AF40DD /* DebugUIProfile.swift in Sources */,
45666F581D9B2880008FE134 /* OWSScrubbingLogFormatterTest.m in Sources */,
B660F77F1C29988E00687D6E /* DateUtil.m in Sources */,
B660F7811C29988E00687D6E /* FunctionalUtil.m in Sources */,

@ -17,6 +17,7 @@ extern const NSUInteger kOWSProfileManager_MaxAvatarDiameter;
@class TSThread;
@class OWSAES256Key;
@class OWSMessageSender;
// This class can be safely accessed and used from any thread.
@interface OWSProfileManager : NSObject <ProfileManagerProtocol>
@ -78,6 +79,12 @@ extern const NSUInteger kOWSProfileManager_MaxAvatarDiameter;
profileNameEncrypted:(nullable NSData *)profileNameEncrypted
avatarUrlPath:(nullable NSString *)avatarUrlPath;
#pragma mark - User Interface
- (void)presentAddThreadToProfileWhitelist:(TSThread *)thread
fromViewController:(UIViewController *)fromViewController
success:(void (^)())successHandler;
@end
NS_ASSUME_NONNULL_END

@ -1024,7 +1024,10 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
NSURLRequest *request = [NSURLRequest requestWithURL:avatarUrlPath];
NSURLSessionDownloadTask *downloadTask = [self.avatarHTTPManager downloadTaskWithRequest:request
progress:^(NSProgress *_Nonnull downloadProgress) {
DDLogVerbose(@"%@ Downloading avatar for %@", self.tag, userProfile.recipientId);
DDLogVerbose(@"%@ Downloading avatar for %@ %f",
self.tag,
userProfile.recipientId,
downloadProgress.fractionCompleted);
}
destination:^NSURL *_Nonnull(NSURL *_Nonnull targetPath, NSURLResponse *_Nonnull response) {
return [NSURL fileURLWithPath:tempFilePath];
@ -1332,6 +1335,62 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
}
}
#pragma mark - User Interface
- (void)presentAddThreadToProfileWhitelist:(TSThread *)thread
fromViewController:(UIViewController *)fromViewController
success:(void (^)())successHandler
{
AssertIsOnMainThread();
UIAlertController *alertController =
[UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
NSString *shareTitle = NSLocalizedString(@"CONVERSATION_SETTINGS_VIEW_SHARE_PROFILE",
@"Button to confirm that user wants to share their profile with a user or group.");
[alertController addAction:[UIAlertAction actionWithTitle:shareTitle
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[self userAddedThreadToProfileWhitelist:thread
success:successHandler];
}]];
[alertController addAction:[OWSAlerts cancelAction]];
[fromViewController presentViewController:alertController animated:YES completion:nil];
}
- (void)userAddedThreadToProfileWhitelist:(TSThread *)thread
success:(void (^)())successHandler
{
AssertIsOnMainThread();
OWSProfileKeyMessage *message =
[[OWSProfileKeyMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:thread];
BOOL isFeatureEnabled = NO;
if (!isFeatureEnabled) {
DDLogWarn(@"%@ skipping sending profile-key message because the feature is not yet fully available.", self.tag);
[OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread];
successHandler();
return;
}
[self.messageSender sendMessage:message
success:^{
DDLogInfo(@"%@ Successfully sent profile key message to thread: %@", self.tag, thread);
[OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread];
dispatch_async(dispatch_get_main_queue(), ^{
successHandler();
});
}
failure:^(NSError *_Nonnull error) {
dispatch_async(dispatch_get_main_queue(), ^{
DDLogError(@"%@ Failed to send profile key message to thread: %@", self.tag, thread);
});
}];
}
#pragma mark - Notifications
- (void)applicationDidBecomeActive:(NSNotification *)notification

@ -60,7 +60,7 @@ class ProfileFetcherJob: NSObject {
if remainingRetries > 0 {
self.updateProfile(recipientId: recipientId, remainingRetries: remainingRetries - 1)
} else {
owsFail("\(self.TAG) in \(#function) failed to get profile with error: \(error)")
Logger.error("\(self.TAG) in \(#function) failed to get profile with error: \(error)")
}
}
}.retainUntilComplete()

@ -70,6 +70,7 @@
#import <SignalServiceKit/OWSMessageReceiver.h>
#import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/OWSOutgoingCallMessage.h>
#import <SignalServiceKit/OWSProfileKeyMessage.h>
#import <SignalServiceKit/OWSRecipientIdentity.h>
#import <SignalServiceKit/OWSSignalService.h>
#import <SignalServiceKit/OWSSyncContactsMessage.h>

@ -78,6 +78,7 @@
#import <SignalServiceKit/OWSDisappearingMessagesConfiguration.h>
#import <SignalServiceKit/OWSIdentityManager.h>
#import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/OWSProfileKeyMessage.h>
#import <SignalServiceKit/OWSVerificationStateChangeMessage.h>
#import <SignalServiceKit/SignalRecipient.h>
#import <SignalServiceKit/TSAccountManager.h>
@ -900,22 +901,9 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
return;
}
UIAlertController *alertController =
[UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *whitelistAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"CONVERSATION_SETTINGS_VIEW_SHARE_PROFILE",
@"Button to confirm that user wants to share their profile with a user or group.")
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *_Nonnull action) {
[OWSProfileManager.sharedManager addThreadToProfileWhitelist:self.thread];
[self ensureBannerState];
}];
[alertController addAction:whitelistAction];
[alertController addAction:[OWSAlerts cancelAction]];
[self presentViewController:alertController animated:YES completion:nil];
[self presentAddThreadToProfileWhitelistWithSuccess:^{
[self ensureBannerState];
}];
}
- (void)noLongerVerifiedBannerViewWasTapped:(UIGestureRecognizer *)sender
@ -2782,34 +2770,28 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
- (void)tappedAddToProfileWhitelistOfferMessage:(OWSContactOffersInteraction *)interaction
{
// This is accessed via the contact offer. Group whitelisting happens via a different interaction.
if (![self.thread isKindOfClass:[TSContactThread class]]) {
OWSFail(@"%@ unexpected thread: %@ in %s", self.tag, self.thread, __PRETTY_FUNCTION__);
return;
}
TSContactThread *contactThread = (TSContactThread *)self.thread;
UIAlertController *alertController =
[UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *leaveAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"CONVERSATION_SETTINGS_VIEW_SHARE_PROFILE",
@"Button to confirm that user wants to share their profile with a user or group.")
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *_Nonnull action) {
[OWSProfileManager.sharedManager addThreadToProfileWhitelist:self.thread];
// Delete the offers.
[self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
contactThread.hasDismissedOffers = YES;
[contactThread saveWithTransaction:transaction];
[interaction removeWithTransaction:transaction];
}];
}];
[alertController addAction:leaveAction];
[alertController addAction:[OWSAlerts cancelAction]];
[self presentAddThreadToProfileWhitelistWithSuccess:^() {
// Delete the offers.
[self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
contactThread.hasDismissedOffers = YES;
[contactThread saveWithTransaction:transaction];
[interaction removeWithTransaction:transaction];
}];
}];
}
[self presentViewController:alertController animated:YES completion:nil];
- (void)presentAddThreadToProfileWhitelistWithSuccess:(void (^)())successHandler
{
[[OWSProfileManager sharedManager] presentAddThreadToProfileWhitelist:self.thread
fromViewController:self
success:successHandler];
}
#pragma mark - OWSSystemMessageCellDelegate

@ -53,20 +53,6 @@ NS_ASSUME_NONNULL_BEGIN
actionBlock:^{
[DebugUIMisc setManualCensorshipCircumventionEnabled:NO];
}]];
#ifdef DEBUG
[items addObject:[OWSTableItem itemWithTitle:@"Clear Profile Whitelist"
actionBlock:^{
[OWSProfileManager.sharedManager clearProfileWhitelist];
}]];
[items addObject:[OWSTableItem itemWithTitle:@"Log Profile Whitelist"
actionBlock:^{
[OWSProfileManager.sharedManager logProfileWhitelist];
}]];
[items addObject:[OWSTableItem itemWithTitle:@"Regenerate Profile/ProfileKey"
actionBlock:^{
[[OWSProfileManager sharedManager] regenerateLocalProfile];
}]];
#endif
[items addObject:[OWSTableItem itemWithTitle:@"Clear hasDismissedOffers"
actionBlock:^{
[DebugUIMisc clearHasDismissedOffers];

@ -0,0 +1,50 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
import Foundation
class DebugUIProfile: DebugUIPage {
let TAG = "[DebugUIProfile]"
// MARK: Dependencies
var messageSender: MessageSender {
return Environment.getCurrent().messageSender
}
var profileManager: OWSProfileManager {
return OWSProfileManager.shared()
}
// MARK: Overrides
override func name() -> String {
return "Profile"
}
override func section(thread aThread: TSThread?) -> OWSTableSection? {
let sectionItems = [
OWSTableItem(title: "Clear Profile Whitelist") {
self.profileManager.clearProfileWhitelist()
},
OWSTableItem(title: "Log Profile Whitelist") {
self.profileManager.logProfileWhitelist()
},
OWSTableItem(title: "Regenerate Profile/ProfileKey") {
self.profileManager.regenerateLocalProfile()
},
OWSTableItem(title: "Send profile key message.") {
let message = OWSProfileKeyMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: aThread)
self.messageSender.sendPromise(message: message).then {
Logger.info("Successfully sent profile key message to thread: \(String(describing: aThread))")
}.catch { _ in
owsFail("Failed to send profile key message to thread: \(String(describing: aThread))")
}
}
]
return OWSTableSection(title: "Profile", items: sectionItems)
}
}

@ -95,6 +95,7 @@ NS_ASSUME_NONNULL_BEGIN
[subsectionItems
addObject:[self itemForSubsection:[DebugUICalling new] viewController:viewController thread:thread]];
}
[subsectionItems addObject:[self itemForSubsection:[DebugUIProfile new] viewController:viewController thread:thread]];
[subsectionItems addObject:[self itemForSubsection:[DebugUIMisc new] viewController:viewController thread:thread]];
[contents addSection:[OWSTableSection sectionWithTitle:@"Sections" items:subsectionItems]];

@ -785,27 +785,11 @@ NS_ASSUME_NONNULL_BEGIN
{
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
UIAlertController *alertController =
[UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *leaveAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"CONVERSATION_SETTINGS_VIEW_SHARE_PROFILE",
@"Button to confirm that user wants to share their profile with a user or group.")
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *_Nonnull action) {
[self shareProfile];
}];
[alertController addAction:leaveAction];
[alertController addAction:[OWSAlerts cancelAction]];
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)shareProfile
{
[OWSProfileManager.sharedManager addThreadToProfileWhitelist:self.thread];
[self updateTableContents];
[OWSProfileManager.sharedManager presentAddThreadToProfileWhitelist:self.thread
fromViewController:self
success:^{
[self updateTableContents];
}];
}
- (void)showVerificationView

@ -82,6 +82,7 @@ message DataMessage {
enum Flags {
END_SESSION = 1;
EXPIRATION_TIMER_UPDATE = 2;
PROFILE_KEY = 4;
}
optional string body = 1;

@ -0,0 +1,13 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "TSOutgoingMessage.h"
NS_ASSUME_NONNULL_BEGIN
@interface OWSProfileKeyMessage : TSOutgoingMessage
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,50 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSProfileKeyMessage.h"
#import "OWSSignalServiceProtos.pb.h"
#import "ProfileManagerProtocol.h"
#import "ProtoBuf+OWS.h"
#import "TextSecureKitEnv.h"
NS_ASSUME_NONNULL_BEGIN
@implementation OWSProfileKeyMessage
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
// override superclass with no-op.
//
// There's no need to save this message, since it's not displayed to the user.
}
- (BOOL)shouldSyncTranscript
{
return NO;
}
- (OWSSignalServiceProtosDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId
{
OWSAssert(self.thread);
OWSSignalServiceProtosDataMessageBuilder *builder = [self dataMessageBuilder];
[builder addLocalProfileKey];
[builder setFlags:OWSSignalServiceProtosDataMessageFlagsProfileKey];
if (recipientId.length > 0) {
// Once we've shared our profile key with a user (perhaps due to being
// a member of a whitelisted group), make sure they're whitelisted.
id<ProfileManagerProtocol> profileManager = [TextSecureKitEnv sharedEnv].profileManager;
// FIXME PERF avoid this dispatch. It's going to happen for *each* recipient in a group message.
dispatch_async(dispatch_get_main_queue(), ^{
[profileManager addUserToProfileWhitelist:recipientId];
});
}
return [builder build];
}
@end
NS_ASSUME_NONNULL_END

@ -112,6 +112,7 @@ NSString *NSStringFromOWSSignalServiceProtosEnvelopeType(OWSSignalServiceProtosE
typedef NS_ENUM(SInt32, OWSSignalServiceProtosDataMessageFlags) {
OWSSignalServiceProtosDataMessageFlagsEndSession = 1,
OWSSignalServiceProtosDataMessageFlagsExpirationTimerUpdate = 2,
OWSSignalServiceProtosDataMessageFlagsProfileKey = 4,
};
BOOL OWSSignalServiceProtosDataMessageFlagsIsValidValue(OWSSignalServiceProtosDataMessageFlags value);

@ -3103,6 +3103,7 @@ BOOL OWSSignalServiceProtosDataMessageFlagsIsValidValue(OWSSignalServiceProtosDa
switch (value) {
case OWSSignalServiceProtosDataMessageFlagsEndSession:
case OWSSignalServiceProtosDataMessageFlagsExpirationTimerUpdate:
case OWSSignalServiceProtosDataMessageFlagsProfileKey:
return YES;
default:
return NO;
@ -3114,6 +3115,8 @@ NSString *NSStringFromOWSSignalServiceProtosDataMessageFlags(OWSSignalServicePro
return @"OWSSignalServiceProtosDataMessageFlagsEndSession";
case OWSSignalServiceProtosDataMessageFlagsExpirationTimerUpdate:
return @"OWSSignalServiceProtosDataMessageFlagsExpirationTimerUpdate";
case OWSSignalServiceProtosDataMessageFlagsProfileKey:
return @"OWSSignalServiceProtosDataMessageFlagsProfileKey";
default:
return nil;
}

@ -167,10 +167,9 @@ NS_ASSUME_NONNULL_BEGIN
{
OWSAssert(envelope != nil);
return [NSString stringWithFormat:@"<Envelope type: %@, source: %@.%d, timestamp: %llu content.length: %lu />",
return [NSString stringWithFormat:@"<Envelope type: %@, source: %@, timestamp: %llu content.length: %lu />",
[self descriptionForEnvelopeType:envelope],
envelope.source,
(unsigned int)envelope.sourceDevice,
envelopeAddress(envelope),
envelope.timestamp,
(unsigned long)envelope.content.length];
}
@ -205,15 +204,15 @@ NS_ASSUME_NONNULL_BEGIN
NSMutableString *description = [NSMutableString new];
if (dataMessage.hasGroup) {
[description appendString:@"GroupDataMessage: "];
} else {
[description appendString:@"DataMessage: "];
[description appendString:@"(Group:YES) "];
}
if ((dataMessage.flags & OWSSignalServiceProtosDataMessageFlagsEndSession) != 0) {
[description appendString:@"EndSession"];
} else if ((dataMessage.flags & OWSSignalServiceProtosDataMessageFlagsExpirationTimerUpdate) != 0) {
[description appendString:@"ExpirationTimerUpdate"];
} else if ((dataMessage.flags & OWSSignalServiceProtosDataMessageFlagsProfileKey) != 0) {
[description appendString:@"ProfileKey"];
} else if (dataMessage.attachments.count > 0) {
[description appendString:@"MessageWithAttachment"];
} else {
@ -296,10 +295,9 @@ NS_ASSUME_NONNULL_BEGIN
DDLogDebug(@"%@ handled secure message.", self.tag);
if (error) {
DDLogError(
@"%@ handling secure message from address: %@.%d failed with error: %@",
@"%@ handling secure message from address: %@ failed with error: %@",
self.tag,
envelope.source,
(unsigned int)envelope.sourceDevice,
envelopeAddress(envelope),
error);
OWSProdError(
[OWSAnalyticsEvents messageManagerErrorCouldNotHandleSecureMessage]);
@ -314,11 +312,10 @@ NS_ASSUME_NONNULL_BEGIN
completion:^(NSError *_Nullable error) {
DDLogDebug(@"%@ handled pre-key whisper message", self.tag);
if (error) {
DDLogError(@"%@ handling pre-key whisper message from address: %@.%d failed "
DDLogError(@"%@ handling pre-key whisper message from address: %@ failed "
@"with error: %@",
self.tag,
envelope.source,
(unsigned int)envelope.sourceDevice,
envelopeAddress(envelope),
error);
OWSProdError(
[OWSAnalyticsEvents messageManagerErrorCouldNotHandlePrekeyBundle]);
@ -478,7 +475,10 @@ NS_ASSUME_NONNULL_BEGIN
sourceId:envelope.source
sourceDeviceId:envelope.sourceDevice];
if (duplicateEnvelope) {
DDLogInfo(@"%@ Ignoring previously received envelope from %@.%d with timestamp: %llu", self.tag, envelope.source, (unsigned int)envelope.sourceDevice, envelope.timestamp);
DDLogInfo(@"%@ Ignoring previously received envelope from %@ with timestamp: %llu",
self.tag,
envelopeAddress(envelope),
envelope.timestamp);
return;
}
@ -500,7 +500,7 @@ NS_ASSUME_NONNULL_BEGIN
} else if (envelope.hasLegacyMessage) { // DEPRECATED - Remove after all clients have been upgraded.
OWSSignalServiceProtosDataMessage *dataMessage =
[OWSSignalServiceProtosDataMessage parseFromData:plaintextData];
DDLogInfo(@"%@ handling dataMessage: %@", self.tag, [self descriptionForDataMessage:dataMessage]);
DDLogInfo(@"%@ handling message: <DataMessage: %@ />", self.tag, [self descriptionForDataMessage:dataMessage]);
[self handleIncomingEnvelope:envelope withDataMessage:dataMessage];
} else {
@ -543,9 +543,9 @@ NS_ASSUME_NONNULL_BEGIN
}
// FIXME: https://github.com/WhisperSystems/Signal-iOS/issues/1340
DDLogInfo(@"%@ Received message from group that I left or don't know about from: %@.",
DDLogInfo(@"%@ Received message from group that I left or don't know about from: %@",
self.tag,
incomingEnvelope.source);
envelopeAddress(incomingEnvelope));
NSString *recipientId = incomingEnvelope.source;
@ -574,6 +574,8 @@ NS_ASSUME_NONNULL_BEGIN
[self handleEndSessionMessageWithEnvelope:incomingEnvelope dataMessage:dataMessage];
} else if ((dataMessage.flags & OWSSignalServiceProtosDataMessageFlagsExpirationTimerUpdate) != 0) {
[self handleExpirationTimerUpdateMessageWithEnvelope:incomingEnvelope dataMessage:dataMessage];
} else if ((dataMessage.flags & OWSSignalServiceProtosDataMessageFlagsProfileKey) != 0) {
[self handleProfileKeyMessageWithEnvelope:incomingEnvelope dataMessage:dataMessage];
} else if (dataMessage.attachments.count > 0) {
[self handleReceivedMediaWithEnvelope:incomingEnvelope dataMessage:dataMessage];
} else {
@ -837,6 +839,29 @@ NS_ASSUME_NONNULL_BEGIN
[message save];
}
- (void)handleProfileKeyMessageWithEnvelope:(OWSSignalServiceProtosEnvelope *)incomingEnvelope
dataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
{
NSString *recipientId = incomingEnvelope.source;
if (!dataMessage.hasProfileKey) {
OWSFail(@"%@ received profile key message without profile key from: %@",
self.tag,
envelopeAddress(incomingEnvelope));
return;
}
NSData *profileKey = dataMessage.profileKey;
if (profileKey.length != kAES256_KeyByteLength) {
OWSFail(@"%@ received profile key of unexpected length:%lu from:%@",
self.tag,
(unsigned long)profileKey.length,
envelopeAddress(incomingEnvelope));
return;
}
id<ProfileManagerProtocol> profileManager = [TextSecureKitEnv sharedEnv].profileManager;
[profileManager setProfileKeyData:profileKey forRecipientId:recipientId];
}
- (void)handleReceivedTextMessageWithEnvelope:(OWSSignalServiceProtosEnvelope *)textMessageEnvelope
dataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
{
@ -978,15 +1003,28 @@ NS_ASSUME_NONNULL_BEGIN
break;
}
case OWSSignalServiceProtosGroupContextTypeDeliver: {
incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timestamp
inThread:gThread
authorId:envelope.source
sourceDeviceId:envelope.sourceDevice
messageBody:body
attachmentIds:attachmentIds
expiresInSeconds:dataMessage.expireTimer];
DDLogDebug(@"%@ incoming group text message: %@", self.tag, incomingMessage.debugDescription);
[incomingMessage saveWithTransaction:transaction];
if (body.length == 0) {
DDLogWarn(@"%@ ignoring empty incoming message from: %@ for group: %@ with timestampe: %lu",
self.tag,
envelopeAddress(envelope),
groupId,
(unsigned long)timestamp);
} else {
DDLogDebug(@"%@ incoming message from: %@ for group: %@ with timestampe: %lu",
self.tag,
envelopeAddress(envelope),
groupId,
(unsigned long)timestamp);
incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timestamp
inThread:gThread
authorId:envelope.source
sourceDeviceId:envelope.sourceDevice
messageBody:body
attachmentIds:attachmentIds
expiresInSeconds:dataMessage.expireTimer];
[incomingMessage saveWithTransaction:transaction];
}
break;
}
default: {
@ -996,20 +1034,31 @@ NS_ASSUME_NONNULL_BEGIN
thread = gThread;
} else {
TSContactThread *cThread = [TSContactThread getOrCreateThreadWithContactId:envelope.source
transaction:transaction
relay:envelope.relay];
incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timestamp
inThread:cThread
authorId:[cThread contactIdentifier]
sourceDeviceId:envelope.sourceDevice
messageBody:body
attachmentIds:attachmentIds
expiresInSeconds:dataMessage.expireTimer];
DDLogDebug(@"%@ incoming 1:1 text message: %@", self.tag, incomingMessage.debugDescription);
[incomingMessage saveWithTransaction:transaction];
thread = cThread;
if (body.length == 0) {
DDLogWarn(@"%@ ignoring empty incoming message from: %@ with timestampe: %lu",
self.tag,
envelopeAddress(envelope),
(unsigned long)timestamp);
} else {
DDLogDebug(@"%@ incoming message from: %@ with timestampe: %lu",
self.tag,
envelopeAddress(envelope),
(unsigned long)timestamp);
TSContactThread *cThread = [TSContactThread getOrCreateThreadWithContactId:envelope.source
transaction:transaction
relay:envelope.relay];
incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timestamp
inThread:cThread
authorId:[cThread contactIdentifier]
sourceDeviceId:envelope.sourceDevice
messageBody:body
attachmentIds:attachmentIds
expiresInSeconds:dataMessage.expireTimer];
[incomingMessage saveWithTransaction:transaction];
thread = cThread;
}
}
if (thread && incomingMessage) {
@ -1025,7 +1074,7 @@ NS_ASSUME_NONNULL_BEGIN
// Other clients allow attachments to be sent along with body, we want the text displayed as a separate
// message
if ([attachmentIds count] > 0 && body != nil && ![body isEqualToString:@""]) {
if ([attachmentIds count] > 0 && body != nil && body.length > 0) {
// We want the text to be displayed under the attachment
uint64_t textMessageTimestamp = timestamp + 1;
TSIncomingMessage *textMessage = [[TSIncomingMessage alloc] initWithTimestamp:textMessageTimestamp
@ -1041,7 +1090,7 @@ NS_ASSUME_NONNULL_BEGIN
}
}];
if (incomingMessage && thread) {
if (thread && incomingMessage) {
// In case we already have a read receipt for this new message (happens sometimes).
OWSReadReceiptsProcessor *readReceiptsProcessor =
[[OWSReadReceiptsProcessor alloc] initWithIncomingMessage:incomingMessage
@ -1091,10 +1140,7 @@ NS_ASSUME_NONNULL_BEGIN
} else if ([exception.name isEqualToString:UntrustedIdentityKeyException]) {
// Should no longer get here, since we now record the new identity for incoming messages.
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorUntrustedIdentityKeyException], envelope);
OWSFail(@"%@ Failed to trust identity on incoming message from: %@.%d",
self.tag,
envelope.source,
(unsigned int)envelope.sourceDevice);
OWSFail(@"%@ Failed to trust identity on incoming message from: %@", self.tag, envelopeAddress(envelope));
return;
} else {
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorCorruptMessage], envelope);
@ -1117,6 +1163,12 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - helpers
// used in log formatting
NSString *envelopeAddress(OWSSignalServiceProtosEnvelope *envelope)
{
return [NSString stringWithFormat:@"%@.%d", envelope.source, (unsigned int)envelope.sourceDevice];
}
- (BOOL)isDataMessageGroupAvatarUpdate:(OWSSignalServiceProtosDataMessage *)dataMessage
{
return dataMessage.hasGroup

@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSSignalServiceProtosDataMessageBuilder (OWS)
- (void)addLocalProfileKeyIfNecessary:(TSThread *)thread recipientId:(NSString *_Nullable)recipientId;
- (void)addLocalProfileKey;
@end

@ -64,6 +64,11 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (void)addLocalProfileKey
{
[self setProfileKey:self.localProfileKey.keyData];
}
@end
#pragma mark -

Loading…
Cancel
Save