Support for `remoteRegistrationId`.

1) Supporting `remoteRegistrationId` on sending messages. Now showing
warning before sending the message if key conflict exists. Fixes #574
2) Upgrading dependencies: adapting to new libPhoneNumber API.
3) Fixes race condition in database code.
4) Fixing ordering bug. Hopefully once and for good.
pull/1/head
Frederic Jacobs 10 years ago
parent cbc7a59a5c
commit dfdd0a1974

@ -5,13 +5,13 @@ inhibit_all_warnings!
link_with ["Signal", "SignalTests"]
pod 'SocketRocket', :git => 'https://github.com/FredericJacobs/SocketRocket.git', :commit => '73d8a19'
pod 'OpenSSL', '~> 1.0.200'
pod 'libPhoneNumber-iOS', '~> 0.7'
pod 'AxolotlKit', '~> 0.5'
pod 'OpenSSL', '~> 1.0.200'
pod 'libPhoneNumber-iOS', '~> 0.8.2'
pod 'AxolotlKit', '~> 0.6.2'
pod 'PastelogKit', '~> 1.2'
pod 'TwistedOakCollapsingFutures','~> 1.0'
pod 'YapDatabase/SQLCipher'
pod 'AFNetworking', '~> 2.5'
pod 'AFNetworking', '~> 2.5.1'
pod 'Mantle', '~> 1.5'
pod 'SSKeychain'
pod 'JSQMessagesViewController', :git => 'https://github.com/WhisperSystems/JSQMessagesViewController', :branch => 'JSignalQ'

@ -1,31 +1,31 @@
PODS:
- 25519 (1.8)
- AFNetworking (2.5.0):
- AFNetworking/NSURLConnection (= 2.5.0)
- AFNetworking/NSURLSession (= 2.5.0)
- AFNetworking/Reachability (= 2.5.0)
- AFNetworking/Security (= 2.5.0)
- AFNetworking/Serialization (= 2.5.0)
- AFNetworking/UIKit (= 2.5.0)
- AFNetworking/NSURLConnection (2.5.0):
- AFNetworking (2.5.1):
- AFNetworking/NSURLConnection (= 2.5.1)
- AFNetworking/NSURLSession (= 2.5.1)
- AFNetworking/Reachability (= 2.5.1)
- AFNetworking/Security (= 2.5.1)
- AFNetworking/Serialization (= 2.5.1)
- AFNetworking/UIKit (= 2.5.1)
- AFNetworking/NSURLConnection (2.5.1):
- AFNetworking/Reachability
- AFNetworking/Security
- AFNetworking/Serialization
- AFNetworking/NSURLSession (2.5.0):
- AFNetworking/NSURLSession (2.5.1):
- AFNetworking/Reachability
- AFNetworking/Security
- AFNetworking/Serialization
- AFNetworking/Reachability (2.5.0)
- AFNetworking/Security (2.5.0)
- AFNetworking/Serialization (2.5.0)
- AFNetworking/UIKit (2.5.0):
- AFNetworking/Reachability (2.5.1)
- AFNetworking/Security (2.5.1)
- AFNetworking/Serialization (2.5.1)
- AFNetworking/UIKit (2.5.1):
- AFNetworking/NSURLConnection
- AFNetworking/NSURLSession
- APDropDownNavToolbar (1.1)
- AxolotlKit (0.5):
- AxolotlKit (0.6.2):
- 25519 (~> 1.8)
- HKDFKit (~> 0.0.3)
- ProtocolBuffers (~> 1.9.2)
- ProtocolBuffers (~> 1.9.7)
- CocoaLumberjack (1.9.2):
- CocoaLumberjack/Extensions (= 1.9.2)
- CocoaLumberjack/Core (1.9.2)
@ -34,10 +34,10 @@ PODS:
- DJWActionSheet (1.0.4)
- FFCircularProgressView (0.5)
- HKDFKit (0.0.3)
- JSQMessagesViewController (6.1.1):
- JSQSystemSoundPlayer (~> 2.0.0)
- JSQMessagesViewController (6.1.3):
- JSQSystemSoundPlayer (~> 2.0.1)
- JSQSystemSoundPlayer (2.0.1)
- libPhoneNumber-iOS (0.7.6)
- libPhoneNumber-iOS (0.8.2)
- Mantle (1.5.4):
- Mantle/extobjc (= 1.5.4)
- Mantle/extobjc (1.5.4)
@ -62,13 +62,13 @@ PODS:
- YapDatabase/common
DEPENDENCIES:
- AFNetworking (~> 2.5)
- AFNetworking (~> 2.5.1)
- APDropDownNavToolbar (from `https://github.com/corbett/APDropDownNavToolbar.git`, branch `master`)
- AxolotlKit (~> 0.5)
- AxolotlKit (~> 0.6.2)
- DJWActionSheet
- FFCircularProgressView (>= 0.1)
- JSQMessagesViewController (from `https://github.com/WhisperSystems/JSQMessagesViewController`, branch `JSignalQ`)
- libPhoneNumber-iOS (~> 0.7)
- libPhoneNumber-iOS (~> 0.8.2)
- Mantle (~> 1.5)
- OpenSSL (~> 1.0.200)
- PastelogKit (~> 1.2)
@ -97,7 +97,7 @@ CHECKOUT OPTIONS:
:commit: cf63307d5e3833b16caa9a07f3b5ea06359913f9
:git: https://github.com/corbett/APDropDownNavToolbar.git
JSQMessagesViewController:
:commit: 26fb5cbcf4a2bf15b6f384d29028b15a5e1a62f5
:commit: bfb0c58785b33fa30ac3c88ef38477e49a674912
:git: https://github.com/WhisperSystems/JSQMessagesViewController
SocketRocket:
:commit: 73d8a19
@ -105,16 +105,16 @@ CHECKOUT OPTIONS:
SPEC CHECKSUMS:
25519: 601ffb5d258aa33d642062d6fa4096db210e02e7
AFNetworking: 0f54cb5d16ce38c1b76948faffb8d5fb705021c7
AFNetworking: 8bee59492a6ff15d69130efa4d0dc67e0094a52a
APDropDownNavToolbar: 62131873890d3a30a2fdc98ffdda180a11e49aa4
AxolotlKit: eec4d036d5b021258dc8b6b0212f3c04edeaf15b
AxolotlKit: c8d6fdd73754aa6432a106ae73f4c24385e253da
CocoaLumberjack: 205769c032b5fef85b92472046bcc8b7e7c8a817
DJWActionSheet: d88b302d7c29523e1e9fb9b62cfac46f59bb90d9
FFCircularProgressView: 723b7a84c412b5d9d2a5531bc716b99965ad7192
HKDFKit: 5998cf1bbb611e7ecc6bd3eaaef8c7a7da7be949
JSQMessagesViewController: 554430bbaeb0b2dbed8d4aaa2bdf64559e67f353
JSQMessagesViewController: 4cc4ff3b26599e8743166b7e8e908528c8f01a80
JSQSystemSoundPlayer: 55528c699a283aae2220d3ae7b8b527d2ecef4b4
libPhoneNumber-iOS: d4316d494d4997c40a6059faf35a970d7f4eb1c0
libPhoneNumber-iOS: 2b5a6aeb7fd720ae856f133aea9937336bd47819
Mantle: d5fbaf30fbc58031223af13812c060e15934a1fe
OpenSSL: 4c7be3eca71139f52984542d8c4c0752154d26c3
PastelogKit: 8bab71b1d187617a83e7124cffe9eb1a600e6695

@ -1 +1 @@
Subproject commit cf26bdeb6884a541de1b72146d01b96a217cc8c9
Subproject commit 70c45af296f1ca37139e06f1c1850e3a42ca1383

@ -305,6 +305,9 @@
B60FB9AD1A46F831006A5A66 /* UIImage+contentTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = B60FB9AC1A46F831006A5A66 /* UIImage+contentTypes.m */; };
B60FB9B01A4711D4006A5A66 /* TSAttachmentEncryptionResult.m in Sources */ = {isa = PBXBuildFile; fileRef = B60FB9AF1A4711D4006A5A66 /* TSAttachmentEncryptionResult.m */; };
B62D53F71A23CCAD009AAF82 /* TSMessageAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = B62D53F61A23CCAD009AAF82 /* TSMessageAdapter.m */; };
B62EFBEC1A91352F0072ADD3 /* TSInvalidIdentityKeyErrorMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = B62EFBE71A91352F0072ADD3 /* TSInvalidIdentityKeyErrorMessage.m */; };
B62EFBED1A91352F0072ADD3 /* TSInvalidIdentityKeyReceivingErrorMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = B62EFBE91A91352F0072ADD3 /* TSInvalidIdentityKeyReceivingErrorMessage.m */; };
B62EFBEE1A91352F0072ADD3 /* TSInvalidIdentityKeySendingErrorMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = B62EFBEB1A91352F0072ADD3 /* TSInvalidIdentityKeySendingErrorMessage.m */; };
B633C5801A1D190B0059AC12 /* archive@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C4FE1A1D190B0059AC12 /* archive@2x.png */; };
B633C5831A1D190B0059AC12 /* backspace.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5011A1D190B0059AC12 /* backspace.png */; };
B633C5841A1D190B0059AC12 /* backspace@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B633C5021A1D190B0059AC12 /* backspace@2x.png */; };
@ -365,7 +368,6 @@
B68112ED1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.m in Sources */ = {isa = PBXBuildFile; fileRef = B68112EC1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.m */; };
B684A46D19C3446200B11029 /* PushManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B684A46C19C3446200B11029 /* PushManagerTest.m */; };
B6850E5A1995A4710068E715 /* whisperFake.cer in Resources */ = {isa = PBXBuildFile; fileRef = B6850E591995A4710068E715 /* whisperFake.cer */; };
B68B0E8A1A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = B68B0E891A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.m */; };
B692BF071A76EF0F002786DA /* TSDatabaseSecondaryIndexes.m in Sources */ = {isa = PBXBuildFile; fileRef = B692BF061A76EF0F002786DA /* TSDatabaseSecondaryIndexes.m */; };
B69CD25119773E79005CE69A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B69CD25019773E79005CE69A /* XCTest.framework */; };
B6A3EB4B1A423B3800B2236B /* TSAttachmentAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = B6A3EB4A1A423B3800B2236B /* TSAttachmentAdapter.m */; };
@ -908,6 +910,12 @@
B60FB9AF1A4711D4006A5A66 /* TSAttachmentEncryptionResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttachmentEncryptionResult.m; sourceTree = "<group>"; };
B62D53F51A23CCAD009AAF82 /* TSMessageAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSMessageAdapter.h; sourceTree = "<group>"; };
B62D53F61A23CCAD009AAF82 /* TSMessageAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSMessageAdapter.m; sourceTree = "<group>"; };
B62EFBE61A91352F0072ADD3 /* TSInvalidIdentityKeyErrorMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSInvalidIdentityKeyErrorMessage.h; sourceTree = "<group>"; };
B62EFBE71A91352F0072ADD3 /* TSInvalidIdentityKeyErrorMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSInvalidIdentityKeyErrorMessage.m; sourceTree = "<group>"; };
B62EFBE81A91352F0072ADD3 /* TSInvalidIdentityKeyReceivingErrorMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSInvalidIdentityKeyReceivingErrorMessage.h; sourceTree = "<group>"; };
B62EFBE91A91352F0072ADD3 /* TSInvalidIdentityKeyReceivingErrorMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSInvalidIdentityKeyReceivingErrorMessage.m; sourceTree = "<group>"; };
B62EFBEA1A91352F0072ADD3 /* TSInvalidIdentityKeySendingErrorMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSInvalidIdentityKeySendingErrorMessage.h; sourceTree = "<group>"; };
B62EFBEB1A91352F0072ADD3 /* TSInvalidIdentityKeySendingErrorMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSInvalidIdentityKeySendingErrorMessage.m; sourceTree = "<group>"; };
B633C4FE1A1D190B0059AC12 /* archive@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "archive@2x.png"; sourceTree = "<group>"; };
B633C5011A1D190B0059AC12 /* backspace.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = backspace.png; sourceTree = "<group>"; };
B633C5021A1D190B0059AC12 /* backspace@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "backspace@2x.png"; sourceTree = "<group>"; };
@ -993,8 +1001,6 @@
B68112EC1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "JSQMessagesCollectionViewCell+menuBarItems.m"; path = "views/JSQMessagesCollectionViewCell+menuBarItems.m"; sourceTree = "<group>"; };
B684A46C19C3446200B11029 /* PushManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PushManagerTest.m; path = Signal/test/push/PushManagerTest.m; sourceTree = SOURCE_ROOT; };
B6850E591995A4710068E715 /* whisperFake.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = whisperFake.cer; sourceTree = "<group>"; };
B68B0E881A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSInvalidIdentityKeyErrorMessage.h; sourceTree = "<group>"; };
B68B0E891A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSInvalidIdentityKeyErrorMessage.m; sourceTree = "<group>"; };
B68B0E8D1A542AD700DE8A02 /* TSErrorMessage_privateConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSErrorMessage_privateConstructor.h; sourceTree = "<group>"; };
B692BF051A76EF0F002786DA /* TSDatabaseSecondaryIndexes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSDatabaseSecondaryIndexes.h; sourceTree = "<group>"; };
B692BF061A76EF0F002786DA /* TSDatabaseSecondaryIndexes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSDatabaseSecondaryIndexes.m; sourceTree = "<group>"; };
@ -2132,6 +2138,19 @@
name = TSMessageAdapters;
sourceTree = "<group>";
};
B62EFBE51A91352F0072ADD3 /* InvalidKeyMessages */ = {
isa = PBXGroup;
children = (
B62EFBE61A91352F0072ADD3 /* TSInvalidIdentityKeyErrorMessage.h */,
B62EFBE71A91352F0072ADD3 /* TSInvalidIdentityKeyErrorMessage.m */,
B62EFBE81A91352F0072ADD3 /* TSInvalidIdentityKeyReceivingErrorMessage.h */,
B62EFBE91A91352F0072ADD3 /* TSInvalidIdentityKeyReceivingErrorMessage.m */,
B62EFBEA1A91352F0072ADD3 /* TSInvalidIdentityKeySendingErrorMessage.h */,
B62EFBEB1A91352F0072ADD3 /* TSInvalidIdentityKeySendingErrorMessage.m */,
);
path = InvalidKeyMessages;
sourceTree = "<group>";
};
B633C4FD1A1D190B0059AC12 /* Images */ = {
isa = PBXGroup;
children = (
@ -2347,6 +2366,7 @@
isa = PBXGroup;
children = (
B6FAAAE91A41C7CC007FEC1D /* Attachement */,
B62EFBE51A91352F0072ADD3 /* InvalidKeyMessages */,
B6B096011A1D25ED008BFAA6 /* IncomingPushMessageSignal.pb.h */,
B6B096021A1D25ED008BFAA6 /* IncomingPushMessageSignal.pb.m */,
B6B096051A1D25ED008BFAA6 /* TSCall.h */,
@ -2354,8 +2374,6 @@
B6B096071A1D25ED008BFAA6 /* TSErrorMessage.h */,
B68B0E8D1A542AD700DE8A02 /* TSErrorMessage_privateConstructor.h */,
B6B096081A1D25ED008BFAA6 /* TSErrorMessage.m */,
B68B0E881A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.h */,
B68B0E891A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.m */,
B6B0960B1A1D25ED008BFAA6 /* TSIncomingMessage.h */,
B6B0960C1A1D25ED008BFAA6 /* TSIncomingMessage.m */,
B6B0960D1A1D25ED008BFAA6 /* TSInfoMessage.h */,
@ -3104,6 +3122,7 @@
B60C16651988999D00E97A6C /* VersionMigrations.m in Sources */,
76EB062A18170B33006006FC /* BadState.m in Sources */,
B97940271832BD2400BD66CB /* UIUtil.m in Sources */,
B62EFBEC1A91352F0072ADD3 /* TSInvalidIdentityKeyErrorMessage.m in Sources */,
B6B096861A1D25ED008BFAA6 /* SecurityUtils.m in Sources */,
76EB05BE18170B33006006FC /* ConfirmPacket.m in Sources */,
76EB058618170B33006006FC /* PreferencesUtil.m in Sources */,
@ -3116,7 +3135,7 @@
76EB05EC18170B33006006FC /* CallState.m in Sources */,
76EB05D218170B33006006FC /* ZrtpInitiator.m in Sources */,
76EB05E018170B33006006FC /* NetworkStream.m in Sources */,
B68B0E8A1A54284100DE8A02 /* TSInvalidIdentityKeyErrorMessage.m in Sources */,
B62EFBEE1A91352F0072ADD3 /* TSInvalidIdentityKeySendingErrorMessage.m in Sources */,
B6B0968A1A1D25ED008BFAA6 /* TSStorageManager+SessionStore.m in Sources */,
FCFA64B71A24F6730007FB87 /* UIFont+OWS.m in Sources */,
B6B096891A1D25ED008BFAA6 /* TSStorageManager+PreKeyStore.m in Sources */,
@ -3288,6 +3307,7 @@
BFB074C719A5611000F2947C /* FutureUtil.m in Sources */,
FCD274E21A5AFD8000202277 /* PrivacySettingsTableViewController.m in Sources */,
76EB057218170B33006006FC /* RecentCall.m in Sources */,
B62EFBED1A91352F0072ADD3 /* TSInvalidIdentityKeyReceivingErrorMessage.m in Sources */,
76EB060418170B33006006FC /* PhoneNumberDirectoryFilter.m in Sources */,
B97CBFA818860EA3008E0DE9 /* CountryCodeViewController.m in Sources */,
B6B1013C196D213F007E3930 /* SignalKeyingStorage.m in Sources */,

@ -97,8 +97,6 @@ static NSString* const kCallSegue = @"2.0_6.0_Call_Segue";
[DebugLogger.sharedInstance enableFileLogging];
}
[[TSStorageManager sharedManager] setupDatabase];
self.notificationTracker = [NotificationTracker notificationTracker];
CategorizingLogger* logger = [CategorizingLogger categorizingLogger];
@ -107,6 +105,8 @@ static NSString* const kCallSegue = @"2.0_6.0_Call_Segue";
[Environment.getCurrent.phoneDirectoryManager startUntilCancelled:nil];
[Environment.getCurrent.contactsManager doAfterEnvironmentInitSetup];
[[TSStorageManager sharedManager] setupDatabase];
[self performUpdateCheck]; // this call must be made after environment has been initialized because in general upgrade may depend on environment

@ -3,8 +3,9 @@
#import "Util.h"
#import "PreferencesUtil.h"
#import "Environment.h"
#import "NBPhoneNumber.h"
#import "PhoneNumberUtil.h"
#import "NBAsYouTypeFormatter.h"
#import "NBPhoneNumber.h"
static NSString *const RPDefaultsKeyPhoneNumberString = @"RPDefaultsKeyPhoneNumberString";
static NSString *const RPDefaultsKeyPhoneNumberCanonical = @"RPDefaultsKeyPhoneNumberCanonical";
@ -15,7 +16,7 @@ static NSString *const RPDefaultsKeyPhoneNumberCanonical = @"RPDefaultsKeyPhoneN
require(text != nil);
require(regionCode != nil);
NBPhoneNumberUtil *phoneUtil = NBPhoneNumberUtil.sharedInstance;
NBPhoneNumberUtil *phoneUtil = [PhoneNumberUtil sharedInstance].nbPhoneNumberUtil;
NSError* parseError = nil;
NBPhoneNumber *number = [phoneUtil parse:text
@ -73,7 +74,7 @@ static NSString *const RPDefaultsKeyPhoneNumberCanonical = @"RPDefaultsKeyPhoneN
+(NSString*) regionCodeFromCountryCodeString:(NSString*) countryCodeString {
NBPhoneNumberUtil* phoneUtil = NBPhoneNumberUtil.sharedInstance;
NBPhoneNumberUtil* phoneUtil = [PhoneNumberUtil sharedInstance].nbPhoneNumberUtil;
NSString* regionCode = [phoneUtil getRegionCodeForCountryCode:@([[countryCodeString substringFromIndex:1] integerValue])];
return regionCode;
}
@ -136,11 +137,11 @@ static NSString *const RPDefaultsKeyPhoneNumberCanonical = @"RPDefaultsKeyPhoneN
}
-(BOOL)isValid {
return [NBPhoneNumberUtil.sharedInstance isValidNumber:phoneNumber];
return [[PhoneNumberUtil sharedInstance].nbPhoneNumberUtil isValidNumber:phoneNumber];
}
-(NSString *)localizedDescriptionForUser {
NBPhoneNumberUtil *phoneUtil = NBPhoneNumberUtil.sharedInstance;
NBPhoneNumberUtil *phoneUtil = [PhoneNumberUtil sharedInstance].nbPhoneNumberUtil;
NSError* formatError = nil;
NSString* pretty = [phoneUtil format:phoneNumber

@ -6,6 +6,8 @@
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#include <stdlib.h>
#import "Constraints.h"
#import "NSData+Base64.h"
#import "NSData+hexString.h"
@ -55,11 +57,11 @@
registrationID = [[transaction objectForKey:TSStorageLocalRegistrationId inCollection:TSStorageUserAccountCollection] intValue];
}];
if (!registrationID) {
int localIdentifier = random()%16380;
if (!registrationID ) {
uint32_t localIdentifier = arc4random_uniform(16380);
[dbConn readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[transaction setObject:[NSNumber numberWithInt:localIdentifier]
[transaction setObject:[NSNumber numberWithUnsignedInt:localIdentifier]
forKey:TSStorageLocalRegistrationId
inCollection:TSStorageUserAccountCollection];
}];

@ -9,6 +9,8 @@
#import <Foundation/Foundation.h>
#import "TSYapDatabaseObject.h"
@class TSInteraction;
typedef NS_ENUM(NSInteger, TSLastActionType) {
TSLastActionNone,
@ -61,17 +63,15 @@ typedef NS_ENUM(NSInteger, TSLastActionType) {
- (UIImage*)image;
@property (getter=isBlocked) BOOL blocked;
@property (nonatomic) NSString* latestMessageId;
@property NSDate *archivalDate;
@property (nonatomic) NSDate *creationDate;
- (NSDate*)lastMessageDate;
- (NSString*)lastMessageLabel;
- (void)updateWithLastMessage:(TSInteraction*)lastMessage transaction:(YapDatabaseReadWriteTransaction*)transaction;
- (TSLastActionType)lastAction;
- (BOOL)hasUnreadMessages;
@property NSDate *archivalDate;
@end

@ -7,7 +7,6 @@
//
#import "TSThread.h"
#import "Environment.h"
#import "ContactsManager.h"
#import "TSInteraction.h"
#import "TSStorageManager.h"
@ -18,6 +17,14 @@
#import "TSInfoMessage.h"
#import "TSErrorMessage.h"
@interface TSThread ()
@property (nonatomic, retain) NSDate *creationDate;
@property (nonatomic, retain) NSDate *lastMessageDate;
@property (nonatomic, copy ) NSString *latestMessageId;
@end
@implementation TSThread
+ (NSString *)collection{
@ -28,9 +35,9 @@
self = [super initWithUniqueId:uniqueId];
if (self) {
_blocked = NO;
_latestMessageId = nil;
_creationDate = [NSDate date];
_lastMessageDate = nil;
_creationDate = [NSDate date];
}
return self;
@ -41,22 +48,10 @@
return FALSE;
}
- (NSDate*)lastMessageDate{
__block NSDate *date;
if (self.latestMessageId) {
[[TSStorageManager sharedManager].dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
date = [TSInteraction fetchObjectWithUniqueID:self.latestMessageId transaction:transaction].date;
}];
if (date) {
return date;
}
else {
return [NSDate date];
}
}
else {
- (NSDate *)lastMessageDate{
if (_lastMessageDate) {
return _lastMessageDate;
} else {
return _creationDate;
}
}
@ -139,6 +134,14 @@
return hasUnread;
}
- (void)updateWithLastMessage:(TSInteraction*)lastMessage transaction:(YapDatabaseReadWriteTransaction*)transaction {
if (!_lastMessageDate || [lastMessage.date timeIntervalSinceDate:self.lastMessageDate] > 0) {
_latestMessageId = lastMessage.uniqueId;
_lastMessageDate = lastMessage.date;
[self saveWithTransaction:transaction];
}
}
- (NSString *)name{
NSAssert(FALSE, @"Should be implemented in subclasses");
return nil;

@ -0,0 +1,16 @@
//
// TSInvalidIdentityKeyErrorMessage.h
// Signal
//
// Created by Frederic Jacobs on 15/02/15.
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
//
#import "TSErrorMessage.h"
@interface TSInvalidIdentityKeyErrorMessage : TSErrorMessage
- (void)acceptNewIdentityKey;
- (NSString*)newIdentityKey;
@end

@ -0,0 +1,21 @@
//
// TSInvalidIdentityKeyErrorMessage.m
// Signal
//
// Created by Frederic Jacobs on 15/02/15.
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
//
#import "TSInvalidIdentityKeyErrorMessage.h"
@implementation TSInvalidIdentityKeyErrorMessage
- (void)acceptNewIdentityKey{
NSAssert(NO, @"Method needs to be implemented in subclasses of TSInvalidIdentityKeyErrorMessage.");
}
- (NSString*)newIdentityKey{
NSAssert(NO, @"Method needs to be implemented in subclasses of TSInvalidIdentityKeyErrorMessage.");
return nil;
}
@end

@ -6,13 +6,10 @@
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import "TSErrorMessage.h"
#import "TSInvalidIdentityKeyErrorMessage.h"
@interface TSInvalidIdentityKeyErrorMessage : TSErrorMessage
@interface TSInvalidIdentityKeyReceivingErrorMessage : TSInvalidIdentityKeyErrorMessage
+ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction;
- (void)acceptNewIdentityKey;
- (NSString*)newIdentityKey;
@end

@ -9,7 +9,7 @@
#import <YapDatabase/YapDatabaseTransaction.h>
#import <YapDatabase/YapDatabaseView.h>
#import "TSInvalidIdentityKeyErrorMessage.h"
#import "TSInvalidIdentityKeyReceivingErrorMessage.h"
#import "TSErrorMessage_privateConstructor.h"
#import "TSDatabaseView.h"
#import "TSStorageManager.h"
@ -19,7 +19,7 @@
#import "TSMessagesManager.h"
#import "TSFingerprintGenerator.h"
@implementation TSInvalidIdentityKeyErrorMessage
@implementation TSInvalidIdentityKeyReceivingErrorMessage
- (instancetype)initForUnknownIdentityKeyWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread incomingPushSignal:(NSData*)signal{
self = [self initWithTimestamp:timestamp inThread:thread failedMessageType:TSErrorMessageWrongTrustedIdentityKey];
@ -33,7 +33,7 @@
+ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:preKeyMessage.source transaction:transaction];
TSInvalidIdentityKeyErrorMessage *errorMessage = [[self alloc] initForUnknownIdentityKeyWithTimestamp:preKeyMessage.timestamp inThread:contactThread incomingPushSignal:preKeyMessage.data];
TSInvalidIdentityKeyReceivingErrorMessage *errorMessage = [[self alloc] initForUnknownIdentityKeyWithTimestamp:preKeyMessage.timestamp inThread:contactThread incomingPushSignal:preKeyMessage.data];
return errorMessage;
}
@ -60,7 +60,7 @@
DDLogVerbose(@"Interaction type: %@", interaction.description);
if ([interaction isKindOfClass:[TSInvalidIdentityKeyErrorMessage class]]) {
TSInvalidIdentityKeyErrorMessage *invalidKeyMessage = (TSInvalidIdentityKeyErrorMessage*)interaction;
TSInvalidIdentityKeyErrorMessage *invalidKeyMessage = (TSInvalidIdentityKeyReceivingErrorMessage*)interaction;
IncomingPushMessageSignal *invalidMessageSignal = [IncomingPushMessageSignal parseFromData:invalidKeyMessage.pushSignal];
PreKeyWhisperMessage *pkwm = [[PreKeyWhisperMessage alloc] initWithData:invalidMessageSignal.message];
NSData *newKeyCandidate = [pkwm.identityKey removeKeyType];
@ -73,7 +73,7 @@
}];
for (TSInvalidIdentityKeyErrorMessage *errorMessage in messagesToDecrypt) {
for (TSInvalidIdentityKeyReceivingErrorMessage *errorMessage in messagesToDecrypt) {
[[TSMessagesManager sharedManager] handleMessageSignal:[IncomingPushMessageSignal parseFromData:errorMessage.pushSignal]];
@ -85,7 +85,7 @@
}
- (NSString *)newIdentityKey{
if (self.errorType != TSErrorMessageWrongTrustedIdentityKey || !self.pushSignal) {
if (!self.pushSignal) {
return @"";
}

@ -0,0 +1,24 @@
//
// TSInvalidIdentityKeySendingErrorMessage.h
// Signal
//
// Created by Frederic Jacobs on 15/02/15.
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
//
#import "TSInvalidIdentityKeyErrorMessage.h"
@class PreKeyBundle;
@interface TSInvalidIdentityKeySendingErrorMessage : TSInvalidIdentityKeyErrorMessage
#define TSInvalidPreKeyBundleKey @"TSInvalidPreKeyBundleKey"
#define TSInvalidRecipientKey @"TSInvalidRecipientKey"
+ (instancetype)untrustedKeyWithOutgoingMessage:(TSOutgoingMessage*)outgoingMessage
inThread:(TSThread*)thread
forRecipient:(NSString*)recipientId
preKeyBundle:(PreKeyBundle*)preKeyBundle
withTransaction:(YapDatabaseReadWriteTransaction*)transaction;
@end

@ -0,0 +1,86 @@
//
// TSInvalidIdentityKeySendingErrorMessage.m
// Signal
//
// Created by Frederic Jacobs on 15/02/15.
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
//
#import "TSOutgoingMessage.h"
#import <AxolotlKit/NSData+keyVersionByte.h>
#import "NSDate+millisecondTimeStamp.h"
#import "PreKeyBundle+jsonDict.h"
#import "TSInvalidIdentityKeySendingErrorMessage.h"
#import "TSFingerprintGenerator.h"
#import "TSErrorMessage_privateConstructor.h"
#import "TSStorageManager+IdentityKeyStore.h"
#import "TSMessagesManager+sendMessages.h"
@interface TSInvalidIdentityKeySendingErrorMessage()
@property (nonatomic, readonly) PreKeyBundle *preKeyBundle;
@property (nonatomic, readonly) NSString *recipientId;
@property (nonatomic, readonly) NSString *messageId;
@end
@implementation TSInvalidIdentityKeySendingErrorMessage
- (instancetype)initWithOutgoingMessage:(TSOutgoingMessage*)message
inThread:(TSThread*)thread
forRecipient:(NSString*)recipientId
preKeyBundle:(PreKeyBundle*)preKeyBundle
transaction:(YapDatabaseReadWriteTransaction*)transaction
{
self = [super initWithTimestamp:message.timestamp inThread:thread failedMessageType:TSErrorMessageWrongTrustedIdentityKey];
if (self) {
_messageId = message.uniqueId;
_preKeyBundle = preKeyBundle;
_recipientId = recipientId;
}
return self;
}
+ (instancetype)untrustedKeyWithOutgoingMessage:(TSOutgoingMessage*)outgoingMessage
inThread:(TSThread*)thread
forRecipient:(NSString*)recipientId
preKeyBundle:(PreKeyBundle*)preKeyBundle
withTransaction:(YapDatabaseReadWriteTransaction*)transaction
{
TSInvalidIdentityKeySendingErrorMessage *message = [[self alloc] initWithOutgoingMessage:outgoingMessage inThread:thread forRecipient:recipientId preKeyBundle:preKeyBundle transaction:transaction];
return message;
}
- (void)acceptNewIdentityKey {
[[TSStorageManager sharedManager] saveRemoteIdentity:[self newKey] recipientId:_recipientId];
__block TSOutgoingMessage *message;
__block TSThread *thread;
[[TSStorageManager sharedManager].newDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
thread = [TSContactThread fetchObjectWithUniqueID:self.uniqueThreadId transaction:transaction];
message = [TSOutgoingMessage fetchObjectWithUniqueID:_messageId transaction:transaction];
[self removeWithTransaction:transaction];
}];
if (message) {
[[TSMessagesManager sharedManager] sendMessage:message inThread:thread];
}
}
- (NSString*)newIdentityKey {
NSData *identityKey = [self newKey];
return [TSFingerprintGenerator getFingerprintForDisplay:identityKey];
}
- (NSData*)newKey {
return [self.preKeyBundle.identityKey removeKeyType];
}
@end

@ -12,6 +12,11 @@
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread failedMessageType:(TSErrorMessageType)errorMessageType NS_DESIGNATED_INITIALIZER;
@property NSData *pushSignal;
@property NSData *pushSignal;
@property NSDictionary *pendingOutgoingMessage;
#define TSPendingOutgoingMessageKey @"TSPendingOutgoingMessageKey"
#define TSPendingOutgoingMessageRecipientKey @"TSPendingOutgoingMessageRecipientKey"
@end

@ -108,11 +108,9 @@ const struct TSMessageEdges TSMessageEdges = {
TSThread *fetchedThread = [TSThread fetchObjectWithUniqueID:self.uniqueThreadId
transaction:transaction];
if (!fetchedThread.latestMessageId || [self.date timeIntervalSinceDate:fetchedThread.lastMessageDate] > 0) {
fetchedThread.latestMessageId = self.uniqueId;
}
[fetchedThread saveWithTransaction:transaction];
[fetchedThread updateWithLastMessage:self transaction:transaction];
}
@end

@ -120,6 +120,7 @@ dispatch_queue_t sendingQueue() {
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
long statuscode = response.statusCode;
NSData *responseData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
switch (statuscode) {
case 404:{
@ -135,10 +136,23 @@ dispatch_queue_t sendingQueue() {
// Mismatched devices
DDLogError(@"Missing some devices");
break;
case 410:
case 410:{
// staledevices
DDLogWarn(@"Stale devices");
if (!responseData) {
DDLogWarn(@"Stale devices but server didn't specify devices in response.");
return;
}
[self handleStaleDevicesWithResponse:responseData recipientId:recipient.uniqueId];
dispatch_async(sendingQueue(), ^{
[self sendMessage:message toRecipient:recipient inThread:thread withAttemps:remainingAttempts];
});
break;
}
default:
[self sendMessage:message toRecipient:recipient inThread:thread withAttemps:remainingAttempts];
break;
@ -169,7 +183,7 @@ dispatch_queue_t sendingQueue() {
}
}
@catch (NSException *exception) {
[self processException:exception outgoingMessage:message];
[self processException:exception outgoingMessage:message inThread:thread];
return;
}
}
@ -180,7 +194,7 @@ dispatch_queue_t sendingQueue() {
- (NSDictionary*)encryptedMessageWithPlaintext:(NSData*)plainText toRecipient:(NSString*)identifier deviceId:(NSNumber*)deviceNumber keyingStorage:(TSStorageManager*)storage{
if (![storage containsSession:identifier deviceId:[deviceNumber intValue]]) {
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
__block dispatch_semaphore_t sema = dispatch_semaphore_create(0);
__block PreKeyBundle *bundle;
[[TSNetworkManager sharedManager] queueAuthenticatedRequest:[[TSRecipientPrekeyRequest alloc] initWithRecipient:identifier deviceId:[deviceNumber stringValue]] success:^(NSURLSessionDataTask *task, id responseObject) {
@ -201,7 +215,15 @@ dispatch_queue_t sendingQueue() {
identityKeyStore:storage
recipientId:identifier
deviceId:[deviceNumber intValue]];
[builder processPrekeyBundle:bundle];
@try {
[builder processPrekeyBundle:bundle];
}
@catch (NSException *exception) {
if ([exception.name isEqualToString:UntrustedIdentityKeyException]) {
@throw [NSException exceptionWithName:UntrustedIdentityKeyException reason:nil userInfo:@{TSInvalidPreKeyBundleKey:bundle, TSInvalidRecipientKey:identifier}];
}
@throw exception;
}
}
}
@ -220,7 +242,8 @@ dispatch_queue_t sendingQueue() {
TSServerMessage *serverMessage = [[TSServerMessage alloc] initWithType:messageType
destination:identifier
device:[deviceNumber intValue]
body:serializedMessage];
body:serializedMessage
registrationId:cipher.remoteRegistrationId];
return [MTLJSONAdapter JSONDictionaryFromModel:serverMessage];
@ -322,4 +345,20 @@ dispatch_queue_t sendingQueue() {
return [builder.build data];
}
- (void)handleStaleDevicesWithResponse:(NSData*)responseData recipientId:(NSString*)identifier {
dispatch_async(sendingQueue(), ^{
NSDictionary *serialization = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
NSArray *devices = serialization[@"staleDevices"];
if (!([devices count] > 0)) {
return;
}
for (NSUInteger i = 0; i < [devices count]; i++) {
int deviceNumber = [devices[i] intValue];
[[TSStorageManager sharedManager] deleteSessionForContact:identifier deviceId:deviceNumber];
}
});
}
@end

@ -10,6 +10,7 @@
#import "IncomingPushMessageSignal.pb.h"
#import "TSIncomingMessage.h"
#import "TSOutgoingMessage.h"
#import "TSInvalidIdentityKeySendingErrorMessage.h"
@interface TSMessagesManager : NSObject
@ -19,11 +20,11 @@
- (void)handleMessageSignal:(IncomingPushMessageSignal*)messageSignal;
- (void)processException:(NSException*)exception outgoingMessage:(TSOutgoingMessage*)message;
- (void)processException:(NSException*)exception outgoingMessage:(TSOutgoingMessage*)message inThread:(TSThread*)thread;
- (void)handleReceivedMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content attachments:(NSArray*)attachments;
- (void)handleReceivedMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content attachments:(NSArray*)attachments completionBlock:(void (^)(NSString* messageIdentifier))completionBlock ;
-(void)handleSendToMyself:(TSOutgoingMessage*)outgoingMessage;
- (void)handleSendToMyself:(TSOutgoingMessage*)outgoingMessage;
@end

@ -19,7 +19,7 @@
#import "TSIncomingMessage.h"
#import "TSErrorMessage.h"
#import "TSInvalidIdentityKeyErrorMessage.h"
#import "TSInvalidIdentityKeyReceivingErrorMessage.h"
#import "TSInfoMessage.h"
#import "TSStorageManager+keyingMaterial.h"
@ -278,11 +278,11 @@
}
else if(content.group.type==PushMessageContentGroupContextTypeQuit) {
NSString *nameString = [[Environment.getCurrent contactsManager] nameStringForPhoneIdentifier:message.source];
if (!nameString) {
nameString = message.source;
}
NSString* updateGroupInfo = [NSString stringWithFormat:@"%@ has left group",nameString];
NSMutableArray *newGroupMembers = [NSMutableArray arrayWithArray:gThread.groupModel.groupMemberIds];
[newGroupMembers removeObject:message.source];
@ -360,7 +360,7 @@
} else if ([exception.name isEqualToString:InvalidVersionException]){
errorMessage = [TSErrorMessage invalidVersionWithSignal:signal withTransaction:transaction];
} else if ([exception.name isEqualToString:UntrustedIdentityKeyException]){
errorMessage = [TSInvalidIdentityKeyErrorMessage untrustedKeyWithSignal:signal withTransaction:transaction];
errorMessage = [TSInvalidIdentityKeyReceivingErrorMessage untrustedKeyWithSignal:signal withTransaction:transaction];
} else {
errorMessage = [TSErrorMessage corruptedMessageWithSignal:signal withTransaction:transaction];
}
@ -369,15 +369,24 @@
}];
}
- (void)processException:(NSException*)exception outgoingMessage:(TSOutgoingMessage*)message{
- (void)processException:(NSException*)exception outgoingMessage:(TSOutgoingMessage*)message inThread:(TSThread*)thread {
DDLogWarn(@"Got exception: %@", exception.description);
if(message.groupMetaMessage==TSGroupMessageNone) {
// Only update this with exception if it is not a group message as group messages may except for one group send but not another and the UI doesn't know how to handle that
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
TSErrorMessage *errorMessage;
if ([exception.name isEqualToString:UntrustedIdentityKeyException]) {
errorMessage = [TSInvalidIdentityKeySendingErrorMessage untrustedKeyWithOutgoingMessage:message inThread:thread forRecipient:exception.userInfo[TSInvalidRecipientKey] preKeyBundle:exception.userInfo[TSInvalidPreKeyBundleKey] withTransaction:transaction];
message.messageState = TSOutgoingMessageStateUnsent;
[message saveWithTransaction:transaction];
} else if (message.groupMetaMessage==TSGroupMessageNone) {
// Only update this with exception if it is not a group message as group messages may except for one group send but not another and the UI doesn't know how to handle that
[message setMessageState:TSOutgoingMessageStateUnsent];
[message saveWithTransaction:transaction];
}];
}
}
[errorMessage saveWithTransaction:transaction];
}];
}
- (void)notifyUserForIncomingMessage:(TSIncomingMessage*)message from:(NSString*)name{

@ -14,6 +14,7 @@
- (instancetype)initWithType:(TSWhisperMessageType)type
destination:(NSString*)destination
device:(int)deviceId
body:(NSData*)data;
body:(NSData*)body
registrationId:(int)registrationId;
@end

@ -16,6 +16,7 @@
@property int type;
@property NSString *destination;
@property int destinationDeviceId;
@property int destinationRegistrationId;
@property NSString *body;
@end
@ -30,14 +31,16 @@
destination:(NSString*)destination
device:(int)deviceId
body:(NSData*)body
registrationId:(int)registrationId
{
self = [super init];
if (self) {
_type = type;
_destination = destination;
_destinationDeviceId = deviceId;
_body = [body base64EncodedString];
_type = type;
_destination = destination;
_destinationDeviceId = deviceId;
_destinationRegistrationId = registrationId;
_body = [body base64EncodedString];
}
return self;

@ -13,6 +13,9 @@
@interface TSRegisterPrekeysRequest : TSRequest
- (id)initWithPrekeyArray:(NSArray*)prekeys identityKey:(NSData*)identityKeyPublic signedPreKeyRecord:(SignedPreKeyRecord*)signedRecord preKeyLastResort:(PreKeyRecord*)lastResort;
- (id)initWithPrekeyArray:(NSArray*)prekeys
identityKey:(NSData*)identityKeyPublic
signedPreKeyRecord:(SignedPreKeyRecord*)signedRecord
preKeyLastResort:(PreKeyRecord*)lastResort;
@end

@ -14,6 +14,8 @@
#import <AxolotlKit/SignedPreKeyStore.h>
#import <AxolotlKit/NSData+keyVersionByte.h>
#import "TSStorageManager+IdentityKeyStore.h"
@implementation TSRegisterPrekeysRequest
- (id)initWithPrekeyArray:(NSArray*)prekeys identityKey:(NSData*)identityKeyPublic signedPreKeyRecord:(SignedPreKeyRecord*)signedRecord preKeyLastResort:(PreKeyRecord*)lastResort {
@ -26,8 +28,12 @@
for (PreKeyRecord *preKey in prekeys) {
[serializedPrekeyList addObject:[self dictionaryFromPreKey:preKey]];
}
NSDictionary *serializedKeyRegistrationParameters = @{@"preKeys": serializedPrekeyList, @"lastResortKey":[self dictionaryFromPreKey:lastResort], @"signedPreKey":[self dictionaryFromSignedPreKey:signedRecord] , @"identityKey":publicIdentityKey};
NSDictionary *serializedKeyRegistrationParameters = @{@"preKeys": serializedPrekeyList,
@"lastResortKey":[self dictionaryFromPreKey:lastResort],
@"signedPreKey":[self dictionaryFromSignedPreKey:signedRecord] ,
@"identityKey":publicIdentityKey
};
self.parameters = [serializedKeyRegistrationParameters mutableCopy];

@ -66,7 +66,7 @@ NSString *TSUnreadDatabaseViewExtensionName = @"TSUnreadDatabaseViewExtensionNa
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(NSString *collection, NSString *key, id object) {
if ([object isKindOfClass:[TSThread class]]){
TSThread *thread = (TSThread*)object;
if (thread.archivalDate&&[thread.latestMessageId length]>0) {
if (thread.archivalDate) {
return ([self threadShouldBeInInbox:thread])?TSInboxGroup:TSArchiveGroup;
}
else if(thread.archivalDate) {
@ -82,7 +82,7 @@ NSString *TSUnreadDatabaseViewExtensionName = @"TSUnreadDatabaseViewExtensionNa
YapDatabaseViewSorting *viewSorting = [self threadSorting];
YapDatabaseViewOptions *options = [[YapDatabaseViewOptions alloc] init];
options.isPersistent = YES;
options.isPersistent = NO;
options.allowedCollections = [[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[TSThread collection]]];
YapDatabaseView *databaseView = [[YapDatabaseView alloc] initWithGrouping:viewGrouping
@ -148,12 +148,12 @@ NSString *TSUnreadDatabaseViewExtensionName = @"TSUnreadDatabaseViewExtensionNa
TSThread *thread1 = (TSThread*)object1;
TSThread *thread2 = (TSThread*)object2;
return [thread2.lastMessageDate compare:thread1.lastMessageDate];
return [thread1.lastMessageDate compare:thread2.lastMessageDate];
}
}
return NSOrderedSame;
return NSOrderedSame;
}];
}
+ (YapDatabaseViewSorting*)messagesSorting {

@ -36,9 +36,6 @@
return randomBytes;
}
#pragma mark SHA1
+(NSString*)truncatedSHA1Base64EncodedWithoutPadding:(NSString*)string{

@ -1,7 +1,13 @@
#import <Foundation/Foundation.h>
#import "PhoneNumber.h"
#import "NBPhoneNumberUtil.h"
@interface PhoneNumberUtil : NSObject
MacrosSingletonInterface
@property (nonatomic, retain) NBPhoneNumberUtil *nbPhoneNumberUtil;
+ (NSString *)callingCodeFromCountryCode:(NSString *)code;
+ (NSString *)countryNameFromCountryCode:(NSString *)code;
+ (NSArray *)countryCodesForSearchTerm:(NSString *)searchTerm;

@ -1,10 +1,21 @@
#import "PhoneNumberUtil.h"
#import "ContactsManager.h"
#import "NBPhoneNumberUtil.h"
#import "Util.h"
@implementation PhoneNumberUtil
MacrosSingletonImplemention
- (instancetype)init {
self = [super init];
if (self) {
_nbPhoneNumberUtil = [[NBPhoneNumberUtil alloc] init];
}
return self;
}
// country code -> country name
+ (NSString *)countryNameFromCountryCode:(NSString *)code {
NSDictionary *countryCodeComponent = @{NSLocaleCountryCode: code};
@ -16,7 +27,7 @@
// country code -> calling code
+ (NSString *)callingCodeFromCountryCode:(NSString *)code {
NSNumber *callingCode = [NBPhoneNumberUtil.sharedInstance getCountryCodeForRegion:code];
NSNumber *callingCode = [[[self sharedInstance] nbPhoneNumberUtil] getCountryCodeForRegion:code];
return [NSString stringWithFormat:@"%@%@", COUNTRY_CODE_PREFIX, callingCode];
}
@ -43,7 +54,7 @@
// normalizes a phone number, so parentheses and spaces are stripped
+ (NSString*) normalizePhoneNumber:(NSString *) number {
return [NBPhoneNumberUtil.sharedInstance normalizePhoneNumber:number];
return [[[self sharedInstance] nbPhoneNumberUtil] normalizePhoneNumber:number];
}
// black magic

@ -70,7 +70,7 @@ static NSString *const kCodeSentSegue = @"codeSent";
- (void)populateDefaultCountryNameAndCode {
NSLocale *locale = NSLocale.currentLocale;
NSString *countryCode = [locale objectForKey:NSLocaleCountryCode];
NSNumber *cc = [NBPhoneNumberUtil.sharedInstance getCountryCodeForRegion:countryCode];
NSNumber *cc = [[PhoneNumberUtil sharedInstance].nbPhoneNumberUtil getCountryCodeForRegion:countryCode];
[_countryCodeButton setTitle:[NSString stringWithFormat:@"%@%@",COUNTRY_CODE_PREFIX, cc] forState:UIControlStateNormal];
[_countryNameButton setTitle:[PhoneNumberUtil countryNameFromCountryCode:countryCode] forState:UIControlStateNormal];

@ -262,6 +262,8 @@ static NSString* const kShowSignupFlowSegue = @"showSignupFlow";
-(void) changeToGrouping:(NSString*)grouping {
self.threadMappings = [[YapDatabaseViewMappings alloc] initWithGroups:@[grouping]
view:TSThreadDatabaseViewExtensionName];
[self.threadMappings setIsReversed:YES forGroup:grouping];
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction){
[self.threadMappings updateWithTransaction:transaction];
}];

Loading…
Cancel
Save