mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			221 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Matlab
		
	
		
		
			
		
	
	
			221 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Matlab
		
	
| 
								 
											5 years ago
										 
									 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Copyright (c) 2019 Open Whisper Systems. All rights reserved.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#import "TSErrorMessage.h"
							 | 
						||
| 
								 | 
							
								#import "SSKEnvironment.h"
							 | 
						||
| 
								 | 
							
								#import "TSContactThread.h"
							 | 
						||
| 
								 | 
							
								#import "TSErrorMessage_privateConstructor.h"
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								#import <SignalCoreKit/NSDate+OWS.h>
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								#import <YapDatabase/YapDatabaseConnection.h>
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								
							 | 
						||
| 
								 | 
							
								NS_ASSUME_NONNULL_BEGIN
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								NSUInteger TSErrorMessageSchemaVersion = 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@interface TSErrorMessage ()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@property (nonatomic, getter=wasRead) BOOL read;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@property (nonatomic, readonly) NSUInteger errorMessageSchemaVersion;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#pragma mark -
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@implementation TSErrorMessage
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (nullable instancetype)initWithCoder:(NSCoder *)coder
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    self = [super initWithCoder:coder];
							 | 
						||
| 
								 | 
							
								    if (!self) {
							 | 
						||
| 
								 | 
							
								        return self;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (self.errorMessageSchemaVersion < 1) {
							 | 
						||
| 
								 | 
							
								        _read = YES;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    _errorMessageSchemaVersion = TSErrorMessageSchemaVersion;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (self.isDynamicInteraction) {
							 | 
						||
| 
								 | 
							
								        self.read = YES;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return self;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (instancetype)initWithTimestamp:(uint64_t)timestamp
							 | 
						||
| 
								 | 
							
								                         inThread:(nullable TSThread *)thread
							 | 
						||
| 
								 | 
							
								                failedMessageType:(TSErrorMessageType)errorMessageType
							 | 
						||
| 
								 | 
							
								                      recipientId:(nullable NSString *)recipientId
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    self = [super initMessageWithTimestamp:timestamp
							 | 
						||
| 
								 | 
							
								                                  inThread:thread
							 | 
						||
| 
								 | 
							
								                               messageBody:nil
							 | 
						||
| 
								 | 
							
								                             attachmentIds:@[]
							 | 
						||
| 
								 | 
							
								                          expiresInSeconds:0
							 | 
						||
| 
								 | 
							
								                           expireStartedAt:0
							 | 
						||
| 
								 | 
							
								                             quotedMessage:nil
							 | 
						||
| 
								 | 
							
								                               linkPreview:nil];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!self) {
							 | 
						||
| 
								 | 
							
								        return self;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    _errorType = errorMessageType;
							 | 
						||
| 
								 | 
							
								    _recipientId = recipientId;
							 | 
						||
| 
								 | 
							
								    _errorMessageSchemaVersion = TSErrorMessageSchemaVersion;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (self.isDynamicInteraction) {
							 | 
						||
| 
								 | 
							
								        self.read = YES;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return self;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (instancetype)initWithTimestamp:(uint64_t)timestamp
							 | 
						||
| 
								 | 
							
								                         inThread:(nullable TSThread *)thread
							 | 
						||
| 
								 | 
							
								                failedMessageType:(TSErrorMessageType)errorMessageType
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return [self initWithTimestamp:timestamp inThread:thread failedMessageType:errorMessageType recipientId:nil];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								- (instancetype)initWithEnvelope:(SNProtoEnvelope *)envelope
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								                 withTransaction:(YapDatabaseReadWriteTransaction *)transaction
							 | 
						||
| 
								 | 
							
								               failedMessageType:(TSErrorMessageType)errorMessageType
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								    NSString *source = envelope.source;
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								    TSContactThread *contactThread =
							 | 
						||
| 
								 | 
							
								        [TSContactThread getOrCreateThreadWithContactId:source transaction:transaction];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Legit usage of senderTimestamp. We don't actually currently surface it in the UI, but it serves as
							 | 
						||
| 
								 | 
							
								    // a reference to the envelope which we failed to process.
							 | 
						||
| 
								 | 
							
								    return [self initWithTimestamp:envelope.timestamp inThread:contactThread failedMessageType:errorMessageType];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (OWSInteractionType)interactionType
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return OWSInteractionType_Error;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    switch (_errorType) {
							 | 
						||
| 
								 | 
							
								        case TSErrorMessageNoSession:
							 | 
						||
| 
								 | 
							
								            return NSLocalizedString(@"ERROR_MESSAGE_NO_SESSION", @"");
							 | 
						||
| 
								 | 
							
								        case TSErrorMessageInvalidMessage:
							 | 
						||
| 
								 | 
							
								            return NSLocalizedString(@"ERROR_MESSAGE_INVALID_MESSAGE", @"");
							 | 
						||
| 
								 | 
							
								        case TSErrorMessageInvalidVersion:
							 | 
						||
| 
								 | 
							
								            return NSLocalizedString(@"ERROR_MESSAGE_INVALID_VERSION", @"");
							 | 
						||
| 
								 | 
							
								        case TSErrorMessageDuplicateMessage:
							 | 
						||
| 
								 | 
							
								            return NSLocalizedString(@"ERROR_MESSAGE_DUPLICATE_MESSAGE", @"");
							 | 
						||
| 
								 | 
							
								        case TSErrorMessageInvalidKeyException:
							 | 
						||
| 
								 | 
							
								            return NSLocalizedString(@"ERROR_MESSAGE_INVALID_KEY_EXCEPTION", @"");
							 | 
						||
| 
								 | 
							
								        case TSErrorMessageWrongTrustedIdentityKey:
							 | 
						||
| 
								 | 
							
								            return NSLocalizedString(@"ERROR_MESSAGE_WRONG_TRUSTED_IDENTITY_KEY", @"");
							 | 
						||
| 
								 | 
							
								        case TSErrorMessageNonBlockingIdentityChange: {
							 | 
						||
| 
								 | 
							
								            if (self.recipientId) {
							 | 
						||
| 
								 | 
							
								                NSString *messageFormat = NSLocalizedString(@"ERROR_MESSAGE_NON_BLOCKING_IDENTITY_CHANGE_FORMAT",
							 | 
						||
| 
								 | 
							
								                    @"Shown when signal users safety numbers changed, embeds the user's {{name or phone number}}");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								                NSString *recipientDisplayName = [SSKEnvironment.shared.profileManager profileNameForRecipientWithID:self.recipientId avoidingWriteTransaction:YES];
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								                return [NSString stringWithFormat:messageFormat, recipientDisplayName];
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                // recipientId will be nil for legacy errors
							 | 
						||
| 
								 | 
							
								                return NSLocalizedString(
							 | 
						||
| 
								 | 
							
								                    @"ERROR_MESSAGE_NON_BLOCKING_IDENTITY_CHANGE", @"Shown when signal users safety numbers changed");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        case TSErrorMessageUnknownContactBlockOffer:
							 | 
						||
| 
								 | 
							
								            return NSLocalizedString(@"UNKNOWN_CONTACT_BLOCK_OFFER",
							 | 
						||
| 
								 | 
							
								                @"Message shown in conversation view that offers to block an unknown user.");
							 | 
						||
| 
								 | 
							
								        case TSErrorMessageGroupCreationFailed:
							 | 
						||
| 
								 | 
							
								            return NSLocalizedString(@"GROUP_CREATION_FAILED",
							 | 
						||
| 
								 | 
							
								                @"Message shown in conversation view that indicates there were issues with group creation.");
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								            return NSLocalizedString(@"ERROR_MESSAGE_UNKNOWN_ERROR", @"");
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								+ (instancetype)corruptedMessageWithEnvelope:(SNProtoEnvelope *)envelope
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								                             withTransaction:(YapDatabaseReadWriteTransaction *)transaction
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return [[self alloc] initWithEnvelope:envelope
							 | 
						||
| 
								 | 
							
								                          withTransaction:transaction
							 | 
						||
| 
								 | 
							
								                        failedMessageType:TSErrorMessageInvalidMessage];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								+ (instancetype)corruptedMessageInUnknownThread
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // MJK TODO - Seems like we could safely remove this timestamp
							 | 
						||
| 
								 | 
							
								    return [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
							 | 
						||
| 
								 | 
							
								                                  inThread:nil
							 | 
						||
| 
								 | 
							
								                         failedMessageType:TSErrorMessageInvalidMessage];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								+ (instancetype)invalidVersionWithEnvelope:(SNProtoEnvelope *)envelope
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								                           withTransaction:(YapDatabaseReadWriteTransaction *)transaction
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return [[self alloc] initWithEnvelope:envelope
							 | 
						||
| 
								 | 
							
								                          withTransaction:transaction
							 | 
						||
| 
								 | 
							
								                        failedMessageType:TSErrorMessageInvalidVersion];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								+ (instancetype)invalidKeyExceptionWithEnvelope:(SNProtoEnvelope *)envelope
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								                                withTransaction:(YapDatabaseReadWriteTransaction *)transaction
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return [[self alloc] initWithEnvelope:envelope
							 | 
						||
| 
								 | 
							
								                          withTransaction:transaction
							 | 
						||
| 
								 | 
							
								                        failedMessageType:TSErrorMessageInvalidKeyException];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								+ (instancetype)missingSessionWithEnvelope:(SNProtoEnvelope *)envelope
							 | 
						||
| 
								 
											5 years ago
										 
									 | 
							
								                           withTransaction:(YapDatabaseReadWriteTransaction *)transaction
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return
							 | 
						||
| 
								 | 
							
								        [[self alloc] initWithEnvelope:envelope withTransaction:transaction failedMessageType:TSErrorMessageNoSession];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								+ (instancetype)nonblockingIdentityChangeInThread:(TSThread *)thread recipientId:(NSString *)recipientId
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // MJK TODO - should be safe to remove this senderTimestamp
							 | 
						||
| 
								 | 
							
								    return [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
							 | 
						||
| 
								 | 
							
								                                  inThread:thread
							 | 
						||
| 
								 | 
							
								                         failedMessageType:TSErrorMessageNonBlockingIdentityChange
							 | 
						||
| 
								 | 
							
								                               recipientId:recipientId];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#pragma mark - OWSReadTracking
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (uint64_t)expireStartedAt
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (BOOL)shouldAffectUnreadCounts
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return NO;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- (void)markAsReadAtTimestamp:(uint64_t)readTimestamp
							 | 
						||
| 
								 | 
							
								              sendReadReceipt:(BOOL)sendReadReceipt
							 | 
						||
| 
								 | 
							
								                  transaction:(YapDatabaseReadWriteTransaction *)transaction
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (_read) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    _read = YES;
							 | 
						||
| 
								 | 
							
								    [self saveWithTransaction:transaction];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Ignore sendReadReceipt - it doesn't apply to error messages.
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								NS_ASSUME_NONNULL_END
							 |