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
		
	
	
	
		
			Objective-C
		
	
			
		
		
	
	
			221 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Objective-C
		
	
//
 | 
						|
//  Copyright (c) 2019 Open Whisper Systems. All rights reserved.
 | 
						|
//
 | 
						|
 | 
						|
#import "TSErrorMessage.h"
 | 
						|
#import "SSKEnvironment.h"
 | 
						|
#import "TSContactThread.h"
 | 
						|
#import "TSErrorMessage_privateConstructor.h"
 | 
						|
#import <SignalCoreKit/NSDate+OWS.h>
 | 
						|
#import <YapDatabase/YapDatabaseConnection.h>
 | 
						|
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
 | 
						|
 | 
						|
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];
 | 
						|
}
 | 
						|
 | 
						|
- (instancetype)initWithEnvelope:(SNProtoEnvelope *)envelope
 | 
						|
                 withTransaction:(YapDatabaseReadWriteTransaction *)transaction
 | 
						|
               failedMessageType:(TSErrorMessageType)errorMessageType
 | 
						|
{
 | 
						|
    NSString *source = envelope.source;
 | 
						|
    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}}");
 | 
						|
 | 
						|
                NSString *recipientDisplayName = [SSKEnvironment.shared.profileManager profileNameForRecipientWithID:self.recipientId avoidingWriteTransaction:YES];
 | 
						|
                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;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
+ (instancetype)corruptedMessageWithEnvelope:(SNProtoEnvelope *)envelope
 | 
						|
                             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];
 | 
						|
}
 | 
						|
 | 
						|
+ (instancetype)invalidVersionWithEnvelope:(SNProtoEnvelope *)envelope
 | 
						|
                           withTransaction:(YapDatabaseReadWriteTransaction *)transaction
 | 
						|
{
 | 
						|
    return [[self alloc] initWithEnvelope:envelope
 | 
						|
                          withTransaction:transaction
 | 
						|
                        failedMessageType:TSErrorMessageInvalidVersion];
 | 
						|
}
 | 
						|
 | 
						|
+ (instancetype)invalidKeyExceptionWithEnvelope:(SNProtoEnvelope *)envelope
 | 
						|
                                withTransaction:(YapDatabaseReadWriteTransaction *)transaction
 | 
						|
{
 | 
						|
    return [[self alloc] initWithEnvelope:envelope
 | 
						|
                          withTransaction:transaction
 | 
						|
                        failedMessageType:TSErrorMessageInvalidKeyException];
 | 
						|
}
 | 
						|
 | 
						|
+ (instancetype)missingSessionWithEnvelope:(SNProtoEnvelope *)envelope
 | 
						|
                           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
 |