Rewriting outgoing pipeline with GCD.
This commit is contained in:
parent
8514836032
commit
1eff2b3ad5
2
Podfile
2
Podfile
|
@ -8,7 +8,7 @@ pod 'UICKeyChainStore', :podspec => 'Podspecs/UICKeyChainStore.podspec
|
|||
pod 'SocketRocket', :git => 'https://github.com/square/SocketRocket.git', :commit => 'd0585af165'
|
||||
pod 'OpenSSL', '~> 1.0.110'
|
||||
pod 'libPhoneNumber-iOS', '~> 0.7'
|
||||
pod 'AxolotlKit', '~> 0.1'
|
||||
pod 'AxolotlKit', '~> 0.3'
|
||||
pod 'PastelogKit', '~> 1.2'
|
||||
pod 'TwistedOakCollapsingFutures','~> 1.0'
|
||||
pod 'YapDatabase/SQLCipher'
|
||||
|
|
18
Podfile.lock
18
Podfile.lock
|
@ -21,7 +21,7 @@ PODS:
|
|||
- AFNetworking/UIKit (2.5.0):
|
||||
- AFNetworking/NSURLConnection
|
||||
- AFNetworking/NSURLSession
|
||||
- AxolotlKit (0.1):
|
||||
- AxolotlKit (0.3):
|
||||
- 25519 (~> 1.8)
|
||||
- HKDFKit (~> 0.0.3)
|
||||
- ProtocolBuffers (~> 1.9.2)
|
||||
|
@ -32,7 +32,7 @@ PODS:
|
|||
- CocoaLumberjack/Core
|
||||
- DJWActionSheet (1.0.4)
|
||||
- HKDFKit (0.0.3)
|
||||
- JSQMessagesViewController (6.0.0):
|
||||
- JSQMessagesViewController (6.1.0):
|
||||
- JSQSystemSoundPlayer (~> 2.0.0)
|
||||
- JSQSystemSoundPlayer (2.0.0)
|
||||
- libPhoneNumber-iOS (0.7.3)
|
||||
|
@ -51,15 +51,15 @@ PODS:
|
|||
- UnionFind (~> 1.0)
|
||||
- UICKeyChainStore (1.0.7)
|
||||
- UnionFind (1.0.1)
|
||||
- YapDatabase/common (2.5.3):
|
||||
- YapDatabase/common (2.5.4):
|
||||
- CocoaLumberjack (~> 1)
|
||||
- YapDatabase/SQLCipher (2.5.3):
|
||||
- YapDatabase/SQLCipher (2.5.4):
|
||||
- SQLCipher/fts
|
||||
- YapDatabase/common
|
||||
|
||||
DEPENDENCIES:
|
||||
- AFNetworking (~> 2.5)
|
||||
- AxolotlKit (~> 0.1)
|
||||
- AxolotlKit (~> 0.3)
|
||||
- DJWActionSheet
|
||||
- JSQMessagesViewController (from `https://github.com/dtsbourg/JSQMessagesViewController`, branch `JSignalQ`)
|
||||
- libPhoneNumber-iOS (~> 0.7)
|
||||
|
@ -83,7 +83,7 @@ EXTERNAL SOURCES:
|
|||
|
||||
CHECKOUT OPTIONS:
|
||||
JSQMessagesViewController:
|
||||
:commit: 597670e44663c9fa70b6a2deec2b19147c763048
|
||||
:commit: 5fc12f5cba461203046a6f0b2c62d1b1470197a4
|
||||
:git: https://github.com/dtsbourg/JSQMessagesViewController
|
||||
SocketRocket:
|
||||
:commit: d0585af165
|
||||
|
@ -92,11 +92,11 @@ CHECKOUT OPTIONS:
|
|||
SPEC CHECKSUMS:
|
||||
25519: 601ffb5d258aa33d642062d6fa4096db210e02e7
|
||||
AFNetworking: 0f54cb5d16ce38c1b76948faffb8d5fb705021c7
|
||||
AxolotlKit: 395c3302e840a1b9f053e9733002d586d4b10ce0
|
||||
AxolotlKit: 19a7a6482e3deb6621e0f81a1733f60301802d40
|
||||
CocoaLumberjack: 205769c032b5fef85b92472046bcc8b7e7c8a817
|
||||
DJWActionSheet: d88b302d7c29523e1e9fb9b62cfac46f59bb90d9
|
||||
HKDFKit: 5998cf1bbb611e7ecc6bd3eaaef8c7a7da7be949
|
||||
JSQMessagesViewController: 49f449221a8f1da43403e6468ae2015fa0114a9e
|
||||
JSQMessagesViewController: fb0f6e71c0a8009d210d6c7d73ba2b94bb77dc9b
|
||||
JSQSystemSoundPlayer: c98443b1cbb3b45db09d0d3d6c2355cf78294981
|
||||
libPhoneNumber-iOS: 98fc07d70c8fdb5e6a8e3442c37e97353065c20e
|
||||
Mantle: d7c5ac734579ec751c58fecbf56189853056c58c
|
||||
|
@ -108,6 +108,6 @@ SPEC CHECKSUMS:
|
|||
TwistedOakCollapsingFutures: 07aab84fd3958dc94d55ef705b12857d9fbe61d1
|
||||
UICKeyChainStore: eef407137f0397e95a3df32cdf05f7e2ddd99647
|
||||
UnionFind: 45777a8b6878d3a602af3654cc3a09b87389d356
|
||||
YapDatabase: 096e860167b04e629b88bea33dfb7a4153279bb0
|
||||
YapDatabase: c1d6912df1b4a160f7373ee7657d360e29bb00fd
|
||||
|
||||
COCOAPODS: 0.35.0
|
||||
|
|
|
@ -327,6 +327,8 @@
|
|||
B63761ED19E1FBE8005735D1 /* HttpRequestOrResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = B63761E719E1FBE8005735D1 /* HttpRequestOrResponse.m */; };
|
||||
B63761EE19E1FBE8005735D1 /* HttpRequestUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B63761E919E1FBE8005735D1 /* HttpRequestUtil.m */; };
|
||||
B63761EF19E1FBE8005735D1 /* HttpResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = B63761EB19E1FBE8005735D1 /* HttpResponse.m */; };
|
||||
B63885CD1A26772D00A226A6 /* TSMessagesManager+callRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = B63885CC1A26772D00A226A6 /* TSMessagesManager+callRecorder.m */; };
|
||||
B63885D01A2685D700A226A6 /* PreKeyBundle+jsonDict.m in Sources */ = {isa = PBXBuildFile; fileRef = B63885CF1A2685D700A226A6 /* PreKeyBundle+jsonDict.m */; };
|
||||
B63AF5C71A1F757900D01AAD /* TSContactsIntersectionRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5AD1A1F757900D01AAD /* TSContactsIntersectionRequest.m */; };
|
||||
B63AF5C81A1F757900D01AAD /* TSUnregisterAccountRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5AF1A1F757900D01AAD /* TSUnregisterAccountRequest.m */; };
|
||||
B63AF5C91A1F757900D01AAD /* TSRecipientPrekeyRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5B11A1F757900D01AAD /* TSRecipientPrekeyRequest.m */; };
|
||||
|
@ -905,6 +907,10 @@
|
|||
B63761E919E1FBE8005735D1 /* HttpRequestUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HttpRequestUtil.m; sourceTree = "<group>"; };
|
||||
B63761EA19E1FBE8005735D1 /* HttpResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpResponse.h; sourceTree = "<group>"; };
|
||||
B63761EB19E1FBE8005735D1 /* HttpResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HttpResponse.m; sourceTree = "<group>"; };
|
||||
B63885CB1A26772D00A226A6 /* TSMessagesManager+callRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TSMessagesManager+callRecorder.h"; sourceTree = "<group>"; };
|
||||
B63885CC1A26772D00A226A6 /* TSMessagesManager+callRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "TSMessagesManager+callRecorder.m"; sourceTree = "<group>"; };
|
||||
B63885CE1A2685D700A226A6 /* PreKeyBundle+jsonDict.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PreKeyBundle+jsonDict.h"; sourceTree = "<group>"; };
|
||||
B63885CF1A2685D700A226A6 /* PreKeyBundle+jsonDict.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "PreKeyBundle+jsonDict.m"; sourceTree = "<group>"; };
|
||||
B63AF5AC1A1F757900D01AAD /* TSContactsIntersectionRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSContactsIntersectionRequest.h; sourceTree = "<group>"; };
|
||||
B63AF5AD1A1F757900D01AAD /* TSContactsIntersectionRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSContactsIntersectionRequest.m; sourceTree = "<group>"; };
|
||||
B63AF5AE1A1F757900D01AAD /* TSUnregisterAccountRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSUnregisterAccountRequest.h; sourceTree = "<group>"; };
|
||||
|
@ -1829,6 +1835,8 @@
|
|||
76EB04F018170B33006006FC /* protocols */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B63885CE1A2685D700A226A6 /* PreKeyBundle+jsonDict.h */,
|
||||
B63885CF1A2685D700A226A6 /* PreKeyBundle+jsonDict.m */,
|
||||
76EB04F118170B33006006FC /* Terminable.h */,
|
||||
76EB04F218170B33006006FC /* utilities */,
|
||||
);
|
||||
|
@ -2671,6 +2679,8 @@
|
|||
B6B096101A1D25ED008BFAA6 /* TSInteraction.m */,
|
||||
B6B096111A1D25ED008BFAA6 /* TSMessage.h */,
|
||||
B6B096121A1D25ED008BFAA6 /* TSMessage.m */,
|
||||
B63885CB1A26772D00A226A6 /* TSMessagesManager+callRecorder.h */,
|
||||
B63885CC1A26772D00A226A6 /* TSMessagesManager+callRecorder.m */,
|
||||
B6B096131A1D25ED008BFAA6 /* TSMessagesManager+sendMessages.h */,
|
||||
B6B096141A1D25ED008BFAA6 /* TSMessagesManager+sendMessages.m */,
|
||||
B6B096151A1D25ED008BFAA6 /* TSMessagesManager.h */,
|
||||
|
@ -3498,6 +3508,7 @@
|
|||
FC31962D1A06A2190094C78E /* FingerprintViewController.m in Sources */,
|
||||
76EB061418170B33006006FC /* AnonymousConditionLogger.m in Sources */,
|
||||
76EB05C018170B33006006FC /* DhPacket.m in Sources */,
|
||||
B63885D01A2685D700A226A6 /* PreKeyBundle+jsonDict.m in Sources */,
|
||||
765052A1182945EF008313E1 /* LocalizableCustomFontLabel.m in Sources */,
|
||||
FC3196301A0814130094C78E /* SettingsTableViewController.m in Sources */,
|
||||
7038632818F70C0700D4A43F /* EvpSymetricUtil.m in Sources */,
|
||||
|
@ -3594,6 +3605,7 @@
|
|||
B97CBFAE1886100E008E0DE9 /* CountryCodeTableViewCell.m in Sources */,
|
||||
B63761E319E1F487005735D1 /* AFHTTPSessionManager+SignalMethods.m in Sources */,
|
||||
76EB05CC18170B33006006FC /* ShortAuthenticationStringGenerator.m in Sources */,
|
||||
B63885CD1A26772D00A226A6 /* TSMessagesManager+callRecorder.m in Sources */,
|
||||
E16E5BEF18AAC40200B7C403 /* EC25KeyAgreementProtocol.m in Sources */,
|
||||
B6B096901A1D25ED008BFAA6 /* Cryptography.m in Sources */,
|
||||
76EB064018170B33006006FC /* AnonymousTerminator.m in Sources */,
|
||||
|
|
|
@ -136,7 +136,7 @@
|
|||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
[self.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
|
||||
[self.window.rootViewController presentViewController:callViewController animated:NO completion:nil];
|
||||
} onThread:NSThread.mainThread untilCancelled:nil];
|
||||
|
|
|
@ -51,7 +51,7 @@ typedef BOOL (^SearchTermConditionalBlock)(RecentCall*, NSUInteger, BOOL*);
|
|||
require(phoneManager != nil);
|
||||
|
||||
[phoneManager.currentCallObservable watchLatestValue:^(CallState* latestCall) {
|
||||
if (latestCall != nil && Environment.preferences.getHistoryLogEnabled) {
|
||||
if (latestCall != nil) {
|
||||
[self addCall:latestCall];
|
||||
}
|
||||
} onThread:NSThread.mainThread untilCancelled:untilCancelledToken];
|
||||
|
@ -101,7 +101,6 @@ typedef BOOL (^SearchTermConditionalBlock)(RecentCall*, NSUInteger, BOOL*);
|
|||
|
||||
- (void)addRecentCall:(RecentCall *)recentCall {
|
||||
[_allRecents insertObject:recentCall atIndex:0];
|
||||
[Environment.preferences setFreshInstallTutorialsEnabled:NO];
|
||||
[observableRecentsController updateValue:_allRecents.copy];
|
||||
[self saveContactsToDefaults];
|
||||
}
|
||||
|
|
|
@ -75,11 +75,7 @@ static NSString *const DEFAULTS_KEY_DATE = @"DefaultsKeyDate";
|
|||
}
|
||||
|
||||
- (UIImage *)image {
|
||||
if (Environment.preferences.getContactImagesEnabled) {
|
||||
return image;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
- (BOOL)isTextSecureContact{
|
||||
|
|
|
@ -12,18 +12,6 @@
|
|||
-(NSTimeInterval) getCachedOrDefaultDesiredBufferDepth;
|
||||
-(void) setCachedDesiredBufferDepth:(double)value;
|
||||
|
||||
-(BOOL) getFreshInstallTutorialsEnabled;
|
||||
-(BOOL) getContactImagesEnabled;
|
||||
-(BOOL) getAutocorrectEnabled;
|
||||
-(BOOL) getHistoryLogEnabled;
|
||||
|
||||
-(void) setFreshInstallTutorialsEnabled:(BOOL)enabled;
|
||||
-(void) setContactImagesEnabled:(BOOL)enabled;
|
||||
-(void) setAutocorrectEnabled:(BOOL)enabled;
|
||||
-(void) setHistoryLogEnabled:(BOOL)enabled;
|
||||
-(BOOL) encounteredRevokedPushPermission;
|
||||
-(void) setRevokedPushPermission:(BOOL)revoked;
|
||||
|
||||
-(BOOL)loggingIsEnabled;
|
||||
-(void)setLoggingEnabled:(BOOL)flag;
|
||||
|
||||
|
|
|
@ -156,6 +156,7 @@
|
|||
[NSUserDefaults.standardUserDefaults setObject:[NSString stringWithFormat:@"%@", NSBundle.mainBundle.infoDictionary[@"CFBundleVersion"]]
|
||||
forKey:kSignalVersionKey];
|
||||
[NSUserDefaults.standardUserDefaults synchronize];
|
||||
|
||||
return lastVersion;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,4 @@
|
|||
-(id) adjustAndTryGetNewValueForKey:(NSString*)key afterAdjuster:(id (^)(id oldValue))adjuster;
|
||||
-(void) clear;
|
||||
|
||||
-(NSData*) secureDataStoreAdjustAndTryGetNewValueForKey:(NSString *)key afterAdjuster:(id (^)(id))adjuster;
|
||||
-(NSString*) secureStringStoreAdjustAndTryGetNewValueForKey:(NSString *)key afterAdjuster:(id (^)(id))adjuster;
|
||||
|
||||
@end
|
||||
|
|
|
@ -34,61 +34,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
#pragma mark KeyChain store
|
||||
|
||||
-(void) secureTrySetValueForKey:(NSString *)key toValue:(id)value {
|
||||
require(key != nil);
|
||||
@synchronized(self) {
|
||||
if (value == nil) {
|
||||
[UICKeyChainStore removeItemForKey:key];
|
||||
DDLogWarn(@"Removing object for key: %@", key);
|
||||
} else {
|
||||
if ([value isKindOfClass:NSData.class]) {
|
||||
[UICKeyChainStore setData:value forKey:key];
|
||||
} else if ([value isKindOfClass:NSString.class]){
|
||||
[UICKeyChainStore setString:value forKey:key];
|
||||
} else{
|
||||
DDLogError(@"Unexpected class stored in the Keychain.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(NSData*) secureTryGetDataForKey:(NSString *)key {
|
||||
require(key != nil);
|
||||
@synchronized(self) {
|
||||
return [UICKeyChainStore dataForKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
-(NSString*) secureTryGetStringForKey:(NSString *)key {
|
||||
require(key != nil);
|
||||
@synchronized(self) {
|
||||
return [UICKeyChainStore stringForKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
-(NSData*) secureDataStoreAdjustAndTryGetNewValueForKey:(NSString *)key afterAdjuster:(id (^)(id))adjuster {
|
||||
require(key != nil);
|
||||
require(adjuster != nil);
|
||||
@synchronized(self) {
|
||||
NSData* oldValue = [self secureTryGetDataForKey:key];
|
||||
NSData* newValue = adjuster(oldValue);
|
||||
[UICKeyChainStore setData:newValue forKey:key];
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
|
||||
-(NSString*) secureStringStoreAdjustAndTryGetNewValueForKey:(NSString *)key afterAdjuster:(id (^)(id))adjuster {
|
||||
require(key != nil);
|
||||
require(adjuster != nil);
|
||||
@synchronized(self) {
|
||||
NSString *oldValue = [self secureTryGetStringForKey:key];
|
||||
NSString *newValue = adjuster(oldValue);
|
||||
[UICKeyChainStore setString:newValue forKey:key];
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
RPAPICall *apiCall = [self defaultAPICall];
|
||||
apiCall.method = HTTP_GET;
|
||||
apiCall.endPoint = @"/users/directory";
|
||||
apiCall.requestSerializer = [self otpAuthenticationSerializer];
|
||||
apiCall.requestSerializer = [self basicAuthenticationSerializer];
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,6 @@
|
|||
RPAPICall *apiCall = [self defaultAPICall];
|
||||
apiCall.method = HTTP_DELETE;
|
||||
apiCall.endPoint = @"/apn";
|
||||
apiCall.requestSerializer = [self otpAuthenticationSerializer];
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "TSInteraction.h"
|
||||
#import "Contact.h"
|
||||
|
||||
@interface TSCall : TSInteraction
|
||||
|
||||
|
@ -22,9 +23,11 @@ typedef NS_ENUM(NSInteger, TSCallType) {
|
|||
@property (nonatomic, readonly) NSNumber *duration;
|
||||
@property (nonatomic, readonly) BOOL wasCaller;
|
||||
@property (nonatomic, readonly) TSCallType callType;
|
||||
@property (nonatomic) NSString *redPhoneNumber;
|
||||
|
||||
- (instancetype)initWithTimestamp:(uint64_t)timeStamp inThread:(TSThread*)thread
|
||||
wasCaller:(BOOL)caller callType:(TSCallType)callType
|
||||
duration:(NSNumber*)duration;
|
||||
- (instancetype)initWithTimestamp:(uint64_t)timeStamp
|
||||
withCallNumber:(NSString*)contactNumber
|
||||
wasCaller:(BOOL)caller callType:(TSCallType)callType
|
||||
duration:(NSNumber*)duration;
|
||||
|
||||
@end
|
||||
|
|
|
@ -10,15 +10,18 @@
|
|||
|
||||
@implementation TSCall
|
||||
|
||||
- (instancetype)initWithTimestamp:(uint64_t)timeStamp inThread:(TSThread*)thread
|
||||
- (instancetype)initWithTimestamp:(uint64_t)timeStamp
|
||||
withCallNumber:(NSString*)contactNumber
|
||||
wasCaller:(BOOL)caller callType:(TSCallType)callType
|
||||
duration:(NSNumber*)duration{
|
||||
self = [super initWithTimestamp:timeStamp inThread:thread];
|
||||
duration:(NSNumber*)duration
|
||||
{
|
||||
self = [super initWithTimestamp:timeStamp inThread:nil];
|
||||
|
||||
if (self) {
|
||||
_wasCaller = caller;
|
||||
_callType = callType;
|
||||
_duration = duration;
|
||||
_wasCaller = caller;
|
||||
_callType = callType;
|
||||
_duration = duration;
|
||||
_redPhoneNumber = contactNumber;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
|
|
@ -22,13 +22,11 @@ typedef NS_ENUM(int32_t, TSErrorMessageType){
|
|||
TSErrorMessageInvalidVersion
|
||||
};
|
||||
|
||||
+ (instancetype)invalidProtocolBufferWithException:(NSException*)exception;
|
||||
+ (instancetype)duplicateMessageWithSignal:(IncomingPushMessageSignal*)preKeyMessage;
|
||||
+ (instancetype)invalidVersionWithSignal:(IncomingPushMessageSignal*)preKeyMessage;
|
||||
+ (instancetype)missingKeyIdWithSignal:(IncomingPushMessageSignal*)preKeyMessage;
|
||||
+ (instancetype)invalidKeyExceptionWithSignal:(IncomingPushMessageSignal*)preKeyMessage;
|
||||
+ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage;
|
||||
+ (instancetype)missingSessionWithSignal:(IncomingPushMessageSignal*)preKeyMessage;
|
||||
+ (instancetype)invalidVersionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction;
|
||||
+ (instancetype)missingKeyIdWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction;
|
||||
+ (instancetype)invalidKeyExceptionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction;
|
||||
+ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction;
|
||||
+ (instancetype)missingSessionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction;
|
||||
|
||||
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread failedMessageType:(TSErrorMessageType)errorMessageType;
|
||||
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
//
|
||||
|
||||
#import "TSErrorMessage.h"
|
||||
#import "NSDate+millisecondTimeStamp.h"
|
||||
|
||||
@implementation TSErrorMessage
|
||||
|
||||
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread failedMessageType:(TSErrorMessageType)errorMessageType{
|
||||
self = [super initWithTimestamp:timestamp inThread:thread messageBody:@"Error Message" attachements:nil];
|
||||
self = [super initWithTimestamp:timestamp inThread:thread messageBody:@"" attachements:nil];
|
||||
|
||||
if (self) {
|
||||
_errorType = errorMessageType;
|
||||
|
@ -20,4 +21,34 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)invalidVersionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
|
||||
TSContactThread *contactThread = [TSContactThread threadWithContactId:preKeyMessage.source transaction:transaction];
|
||||
TSErrorMessage *errorMessage = [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:contactThread failedMessageType:TSErrorMessageInvalidVersion];
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
+ (instancetype)missingKeyIdWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
|
||||
TSContactThread *contactThread = [TSContactThread threadWithContactId:preKeyMessage.source transaction:transaction];
|
||||
TSErrorMessage *errorMessage = [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:contactThread failedMessageType:TSErrorMessageMissingKeyId];
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
+ (instancetype)invalidKeyExceptionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
|
||||
TSContactThread *contactThread = [TSContactThread threadWithContactId:preKeyMessage.source transaction:transaction];
|
||||
TSErrorMessage *errorMessage = [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:contactThread failedMessageType:TSErrorMessageInvalidKeyException];
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
+ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
|
||||
TSContactThread *contactThread = [TSContactThread threadWithContactId:preKeyMessage.source transaction:transaction];
|
||||
TSErrorMessage *errorMessage = [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:contactThread failedMessageType:TSErrorMessageWrongTrustedIdentityKey];
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
+ (instancetype)missingSessionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{
|
||||
TSContactThread *contactThread = [TSContactThread threadWithContactId:preKeyMessage.source transaction:transaction];
|
||||
TSErrorMessage *errorMessage = [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:contactThread failedMessageType:TSErrorMessageNoSession];
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -17,6 +17,5 @@ typedef NS_ENUM(NSInteger, TSInfoMessageType){
|
|||
@property TSInfoMessageType messageType;
|
||||
|
||||
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSContactThread *)contact messageType:(TSInfoMessageType)infoMessage;
|
||||
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSGroupThread *)thread authorId:(NSString *)authorId messageType:(TSInfoMessageType)infoMessage;
|
||||
|
||||
@end
|
||||
|
|
|
@ -10,4 +10,14 @@
|
|||
|
||||
@implementation TSInfoMessage
|
||||
|
||||
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSContactThread *)contact messageType:(TSInfoMessageType)infoMessage{
|
||||
self = [super initWithTimestamp:timestamp inThread:contact messageBody:nil attachements:nil];
|
||||
|
||||
if (self) {
|
||||
_messageType = infoMessage;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// TSMessagesManager+callRecorder.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 26/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSMessagesManager.h"
|
||||
#import "TSCall.h"
|
||||
|
||||
@interface TSMessagesManager (callRecorder)
|
||||
|
||||
- (void)storePhoneCall:(TSCall*)call;
|
||||
|
||||
@end
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// TSMessagesManager+callRecorder.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 26/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSMessagesManager+callRecorder.h"
|
||||
#import <YapDatabase/YapDatabaseConnection.h>
|
||||
|
||||
#import "Environment.h"
|
||||
#import "ContactsManager.h"
|
||||
|
||||
@implementation TSMessagesManager (callRecorder)
|
||||
|
||||
- (void)storePhoneCall:(TSCall*)call{
|
||||
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[call saveWithTransaction:transaction];
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -8,7 +8,9 @@
|
|||
|
||||
#import "TSMessagesManager+sendMessages.h"
|
||||
|
||||
#import <AxolotlKit/AxolotlExceptions.h>
|
||||
#import <AxolotlKit/SessionCipher.h>
|
||||
#import <AxolotlKit/SessionBuilder.h>
|
||||
#import <Mantle/Mantle.h>
|
||||
|
||||
#import "IncomingPushMessageSignal.pb.h"
|
||||
|
@ -18,33 +20,53 @@
|
|||
#import "TSStorageManager+PreKeyStore.h"
|
||||
#import "TSStorageManager+SignedPreKeyStore.h"
|
||||
|
||||
#import "PreKeyBundle+jsonDict.h"
|
||||
#import "TSErrorMessage.h"
|
||||
|
||||
#import "TSNetworkManager.h"
|
||||
#import "TSServerMessage.h"
|
||||
#import "TSSubmitMessageRequest.h"
|
||||
#import "TSRecipientPrekeyRequest.h"
|
||||
|
||||
#import "TSContactThread.h"
|
||||
#import "TSGroupThread.h"
|
||||
#import "TSRecipient.h"
|
||||
|
||||
@interface TSMessagesManager ()
|
||||
dispatch_queue_t sendingQueue(void);
|
||||
@end
|
||||
|
||||
typedef void (^messagesQueue)(NSArray *messages);
|
||||
|
||||
@implementation TSMessagesManager (sendMessages)
|
||||
|
||||
- (void)sendMessage:(TSOutgoingMessage*)message inThread:(TSThread*)thread{
|
||||
if ([thread isKindOfClass:[TSGroupThread class]]) {
|
||||
NSLog(@"Currently unsupported");
|
||||
} else if([thread isKindOfClass:[TSContactThread class]]){
|
||||
TSContactThread *contactThread = (TSContactThread*)thread;
|
||||
__block TSRecipient *recipient;
|
||||
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
recipient = [contactThread recipientWithTransaction:transaction];
|
||||
}];
|
||||
|
||||
[self sendMessage:message
|
||||
toRecipient:recipient
|
||||
inThread:thread
|
||||
withAttemps:3];
|
||||
}
|
||||
dispatch_queue_t sendingQueue() {
|
||||
static dispatch_once_t queueCreationGuard;
|
||||
static dispatch_queue_t queue;
|
||||
dispatch_once(&queueCreationGuard, ^{
|
||||
queue = dispatch_queue_create("org.whispersystems.signal.sendQueue", NULL);
|
||||
});
|
||||
return queue;
|
||||
}
|
||||
|
||||
- (void)sendMessage:(TSOutgoingMessage*)message inThread:(TSThread*)thread{
|
||||
dispatch_async(sendingQueue(), ^{
|
||||
if ([thread isKindOfClass:[TSGroupThread class]]) {
|
||||
NSLog(@"Currently unsupported");
|
||||
} else if([thread isKindOfClass:[TSContactThread class]]){
|
||||
TSContactThread *contactThread = (TSContactThread*)thread;
|
||||
__block TSRecipient *recipient;
|
||||
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
recipient = [contactThread recipientWithTransaction:transaction];
|
||||
}];
|
||||
|
||||
[self sendMessage:message
|
||||
toRecipient:recipient
|
||||
inThread:thread
|
||||
withAttemps:3];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)sendMessage:(TSOutgoingMessage*)message
|
||||
toRecipient:(TSRecipient*)recipient
|
||||
|
@ -54,35 +76,32 @@
|
|||
if (remainingAttempts > 0) {
|
||||
remainingAttempts -= 1;
|
||||
|
||||
NSArray *outgoingMessages = [self outgoingMessages:message toRecipient:recipient];
|
||||
|
||||
TSSubmitMessageRequest *request = [[TSSubmitMessageRequest alloc] initWithRecipient:recipient.uniqueId messages:outgoingMessages relay:recipient.relay timeStamp:message.timeStamp];
|
||||
|
||||
[[TSNetworkManager sharedManager] queueAuthenticatedRequest:request success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
|
||||
[self handleMessageSent:message inThread:thread];
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
|
||||
long statuscode = response.statusCode;
|
||||
|
||||
//TODO: Handle failures
|
||||
|
||||
switch (statuscode) {
|
||||
case 404:
|
||||
// Recipient not found
|
||||
break;
|
||||
case 409:
|
||||
// Mismatched devices
|
||||
|
||||
break;
|
||||
case 410:
|
||||
// staledevices
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
[self outgoingMessages:message toRecipient:recipient completion:^(NSArray *messages) {
|
||||
TSSubmitMessageRequest *request = [[TSSubmitMessageRequest alloc] initWithRecipient:recipient.uniqueId messages:messages relay:recipient.relay timeStamp:message.timeStamp];
|
||||
|
||||
[[TSNetworkManager sharedManager] queueAuthenticatedRequest:request success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
[self handleMessageSent:message inThread:thread];
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
|
||||
long statuscode = response.statusCode;
|
||||
|
||||
switch (statuscode) {
|
||||
case 404:
|
||||
// Recipient not found
|
||||
DDLogError(@"Recipient not found");
|
||||
break;
|
||||
case 409:
|
||||
// Mismatched devices
|
||||
DDLogError(@"Missing some devices");
|
||||
break;
|
||||
case 410:
|
||||
// staledevices
|
||||
DDLogWarn(@"Stale devices");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
@ -97,44 +116,75 @@
|
|||
}];
|
||||
}
|
||||
|
||||
- (NSArray*)outgoingMessages:(TSOutgoingMessage*)message toRecipient:(TSRecipient*)recipient{
|
||||
|
||||
- (void)outgoingMessages:(TSOutgoingMessage*)message toRecipient:(TSRecipient*)recipient completion:(messagesQueue)sendMessages{
|
||||
NSMutableArray *messagesArray = [NSMutableArray arrayWithCapacity:recipient.devices.count];
|
||||
TSStorageManager *storage = [TSStorageManager sharedManager];
|
||||
NSData *plainText = [self plainTextForMessage:message];
|
||||
|
||||
for (NSNumber *deviceNumber in recipient.devices) {
|
||||
if (![storage containsSession:recipient.uniqueId deviceId:[deviceNumber intValue]]) {
|
||||
// Needs to fetch prekey;
|
||||
}
|
||||
|
||||
@try{
|
||||
SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storage
|
||||
preKeyStore:storage
|
||||
signedPreKeyStore:storage
|
||||
identityKeyStore:storage
|
||||
recipientId:recipient.uniqueId
|
||||
deviceId:[deviceNumber intValue]];
|
||||
|
||||
id<CipherMessage> encryptedMessage = [cipher encryptMessage:plainText];
|
||||
NSData *serializedMessage = encryptedMessage.serialized;
|
||||
TSWhisperMessageType messageType = [self messageTypeForCipherMessage:encryptedMessage];
|
||||
|
||||
|
||||
TSServerMessage *serverMessage = [[TSServerMessage alloc] initWithType:messageType
|
||||
destination:recipient.uniqueId
|
||||
device:[deviceNumber intValue]
|
||||
body:serializedMessage];
|
||||
|
||||
|
||||
[messagesArray addObject:[MTLJSONAdapter JSONDictionaryFromModel:serverMessage]];
|
||||
|
||||
}@catch (NSException *exception) {
|
||||
for (NSNumber *deviceNumber in recipient.devices) {
|
||||
@try {
|
||||
NSDictionary *messageDict = [self encryptedMessageWithPlaintext:plainText toRecipient:recipient.uniqueId deviceId:deviceNumber keyingStorage:storage];
|
||||
if (messageDict) {
|
||||
[messagesArray addObject:messageDict];
|
||||
} else{
|
||||
@throw [NSException exceptionWithName:InvalidMessageException reason:@"Failed to encrypt message" userInfo:nil];
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
[self processException:exception outgoingMessage:message];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return messagesArray;
|
||||
sendMessages(messagesArray);
|
||||
}
|
||||
|
||||
- (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 PreKeyBundle *bundle;
|
||||
|
||||
[[TSNetworkManager sharedManager] queueAuthenticatedRequest:[[TSRecipientPrekeyRequest alloc] initWithRecipient:identifier deviceId:[deviceNumber stringValue]] success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
bundle = [PreKeyBundle preKeyBundleFromDictionary:responseObject forDeviceNumber:deviceNumber];
|
||||
dispatch_semaphore_signal(sema);
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
dispatch_semaphore_signal(sema);
|
||||
}];
|
||||
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
|
||||
|
||||
if (!bundle) {
|
||||
@throw [NSException exceptionWithName:InvalidVersionException reason:@"Can't get a prekey bundle from the server with required information" userInfo:nil];
|
||||
} else{
|
||||
SessionBuilder *builder = [[SessionBuilder alloc] initWithSessionStore:storage
|
||||
preKeyStore:storage
|
||||
signedPreKeyStore:storage
|
||||
identityKeyStore:storage
|
||||
recipientId:identifier
|
||||
deviceId:[deviceNumber intValue]];
|
||||
[builder processPrekeyBundle:bundle];
|
||||
}
|
||||
}
|
||||
|
||||
SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storage
|
||||
preKeyStore:storage
|
||||
signedPreKeyStore:storage
|
||||
identityKeyStore:storage
|
||||
recipientId:identifier
|
||||
deviceId:[deviceNumber intValue]];
|
||||
|
||||
id<CipherMessage> encryptedMessage = [cipher encryptMessage:plainText];
|
||||
NSData *serializedMessage = encryptedMessage.serialized;
|
||||
TSWhisperMessageType messageType = [self messageTypeForCipherMessage:encryptedMessage];
|
||||
|
||||
|
||||
TSServerMessage *serverMessage = [[TSServerMessage alloc] initWithType:messageType
|
||||
destination:identifier
|
||||
device:[deviceNumber intValue]
|
||||
body:serializedMessage];
|
||||
|
||||
|
||||
return [MTLJSONAdapter JSONDictionaryFromModel:serverMessage];
|
||||
}
|
||||
|
||||
- (TSWhisperMessageType)messageTypeForCipherMessage:(id<CipherMessage>)cipherMessage{
|
||||
|
@ -151,7 +201,6 @@
|
|||
|
||||
PushMessageContentBuilder *builder = [PushMessageContentBuilder new];
|
||||
[builder setBody:message.body];
|
||||
|
||||
return [builder.build data];
|
||||
|
||||
//TO-DO: DEAL WITH ATTACHEMENTS AND GROUPS STUFF
|
||||
|
|
|
@ -104,9 +104,10 @@
|
|||
|
||||
if (![storageManager containsSession:recipientId deviceId:deviceId]) {
|
||||
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
TSErrorMessage *errorMessage = [TSErrorMessage missingSessionWithSignal:secureMessage];
|
||||
TSErrorMessage *errorMessage = [TSErrorMessage missingSessionWithSignal:secureMessage withTransaction:transaction];
|
||||
[errorMessage saveWithTransaction:transaction];
|
||||
}];
|
||||
return;
|
||||
}
|
||||
|
||||
PushMessageContent *content;
|
||||
|
@ -237,9 +238,12 @@
|
|||
|
||||
}
|
||||
|
||||
|
||||
- (void)processException:(NSException*)exception outgoingMessage:(TSOutgoingMessage*)message{
|
||||
NSLog(@"Got exception: %@", exception.description);
|
||||
DDLogWarn(@"Got exception: %@", exception.description);
|
||||
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[message setMessageState:TSOutgoingMessageStateUnsent];
|
||||
[message saveWithTransaction:transaction];
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -9,5 +9,7 @@
|
|||
#import "TSRequest.h"
|
||||
@class TSContact;
|
||||
@interface TSRecipientPrekeyRequest : TSRequest
|
||||
-(TSRequest*) initWithRecipient:(TSContact*) contact;
|
||||
|
||||
-(TSRequest*) initWithRecipient:(NSString*)recipientNumber deviceId:(NSString*)deviceId;
|
||||
|
||||
@end
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
|
||||
@implementation TSRecipientPrekeyRequest
|
||||
|
||||
-(TSRequest*) initWithRecipient:(NSString*)recipientNumber {
|
||||
NSString* recipientInformation = recipientNumber;
|
||||
|
||||
self = [super initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@/*", textSecureKeysAPI, recipientInformation]]];
|
||||
-(TSRequest*) initWithRecipient:(NSString*)recipientNumber deviceId:(NSString*)deviceId{
|
||||
NSString* recipientInformation = recipientNumber;
|
||||
|
||||
[self setHTTPMethod:@"GET"];
|
||||
|
||||
return self;
|
||||
self = [super initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@/%@", textSecureKeysAPI, recipientInformation, deviceId]]];
|
||||
|
||||
[self setHTTPMethod:@"GET"];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
self = [super initWithURL:[NSURL URLWithString:textSecureKeysAPI]];
|
||||
self.HTTPMethod = @"PUT";
|
||||
|
||||
NSString *publicIdentityKey = [[identityKeyPublic prependKeyType] base64EncodedStringWithOptions:0];
|
||||
NSMutableArray *serializedPrekeyList = [NSMutableArray array];
|
||||
NSString *publicIdentityKey = [[identityKeyPublic prependKeyType] base64EncodedStringWithOptions:0];
|
||||
NSMutableArray *serializedPrekeyList = [NSMutableArray array];
|
||||
|
||||
for (PreKeyRecord *preKey in prekeys) {
|
||||
[serializedPrekeyList addObject:[self dictionaryFromPreKey:preKey]];
|
||||
|
|
|
@ -43,4 +43,5 @@ extern NSString *const TSUIDatabaseConnectionDidUpdateNotification;
|
|||
|
||||
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
|
||||
|
||||
- (void)wipe;
|
||||
@end
|
||||
|
|
|
@ -16,7 +16,17 @@
|
|||
// returns the NSData representation of the base64 string
|
||||
//
|
||||
+ (NSData *)dataFromBase64String:(NSString *)aString {
|
||||
return [[NSData alloc] initWithBase64EncodedString:aString options:NSDataBase64DecodingIgnoreUnknownCharacters];
|
||||
int padding = aString.length%4;
|
||||
|
||||
NSMutableString *strResult = [aString mutableCopy];
|
||||
if (padding != 0) {
|
||||
int charsToAdd = 4 - padding;
|
||||
for (int i = 0; i < charsToAdd; i++) {
|
||||
[strResult appendString:@"="];
|
||||
}
|
||||
}
|
||||
|
||||
return [[NSData alloc] initWithBase64EncodedString:strResult options:NSDataBase64DecodingIgnoreUnknownCharacters];
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// PreKeyBundle+jsonDict.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 26/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "PreKeyBundle.h"
|
||||
|
||||
@interface PreKeyBundle (jsonDict)
|
||||
|
||||
+ (PreKeyBundle*)preKeyBundleFromDictionary:(NSDictionary*)dictionary forDeviceNumber:(NSNumber*)number;
|
||||
|
||||
@end
|
|
@ -0,0 +1,99 @@
|
|||
//
|
||||
// PreKeyBundle+jsonDict.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 26/11/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Constraints.h"
|
||||
#import "PreKeyBundle+jsonDict.h"
|
||||
#import "NSData+Base64.h"
|
||||
|
||||
@implementation PreKeyBundle (jsonDict)
|
||||
|
||||
+ (PreKeyBundle*)preKeyBundleFromDictionary:(NSDictionary*)dictionary forDeviceNumber:(NSNumber*)number{
|
||||
PreKeyBundle *bundle = nil;
|
||||
NSString *identityKeyString = [dictionary objectForKey:@"identityKey"];
|
||||
NSArray *devicesArray = [dictionary objectForKey:@"devices"];
|
||||
|
||||
if (!(identityKeyString && [devicesArray isKindOfClass:[NSArray class]])) {
|
||||
DDLogError(@"Failed to get identity key or messages array from server request");
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSData *identityKey = [NSData dataFromBase64String:identityKeyString];
|
||||
NSLog(@"IDentityKey %@", identityKey);
|
||||
|
||||
for (NSDictionary *deviceDict in devicesArray) {
|
||||
NSNumber *registrationIdString = [deviceDict objectForKey:@"registrationId"];
|
||||
NSNumber *deviceIdString = [deviceDict objectForKey:@"deviceId"];
|
||||
|
||||
if (!(registrationIdString && deviceIdString)) {
|
||||
DDLogError(@"Failed to get the registration id and device id");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (![deviceIdString isEqualToNumber:number]) {
|
||||
DDLogWarn(@"Got a keyid for another device");
|
||||
return nil;
|
||||
}
|
||||
|
||||
int registrationId = [registrationIdString intValue];
|
||||
int deviceId = [deviceIdString intValue];
|
||||
|
||||
NSDictionary *preKey = [deviceDict objectForKey:@"preKey"];
|
||||
int prekeyId;
|
||||
NSData *preKeyPublic = nil;
|
||||
|
||||
if (!preKey) {
|
||||
prekeyId = -1;
|
||||
} else{
|
||||
prekeyId = [[preKey objectForKey:@"keyId"] intValue];
|
||||
NSString *preKeyPublicString = [preKey objectForKey:@"publicKey"];
|
||||
preKeyPublic = [NSData dataFromBase64String:preKeyPublicString];
|
||||
}
|
||||
|
||||
NSDictionary *signedPrekey = [deviceDict objectForKey:@"signedPreKey"];
|
||||
|
||||
if (![signedPrekey isKindOfClass:[NSDictionary class]]) {
|
||||
DDLogError(@"Device doesn't have signed prekeys registered");
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSNumber *signedKeyIdNumber = [signedPrekey objectForKey:@"keyId"];
|
||||
NSString *signedSignatureString = [signedPrekey objectForKey:@"signature"];
|
||||
NSString *signedPublicKeyString = [signedPrekey objectForKey:@"publicKey"];
|
||||
|
||||
|
||||
|
||||
if (!(signedKeyIdNumber && signedPublicKeyString && signedSignatureString)) {
|
||||
DDLogError(@"Missing signed key material");
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSData *signedPrekeyPublic = [NSData dataFromBase64String:signedPublicKeyString];
|
||||
NSData *signedPreKeySignature = [NSData dataFromBase64String:signedSignatureString];
|
||||
|
||||
if (!(signedPrekeyPublic && signedPreKeySignature)) {
|
||||
DDLogError(@"Failed to parse signed keying material");
|
||||
return nil;
|
||||
}
|
||||
|
||||
int signedPreKeyId = [signedKeyIdNumber intValue];
|
||||
|
||||
bundle = [[self alloc] initWithRegistrationId:registrationId
|
||||
deviceId:deviceId
|
||||
preKeyId:prekeyId
|
||||
preKeyPublic:preKeyPublic
|
||||
signedPreKeyPublic:signedPrekeyPublic
|
||||
signedPreKeyId:signedPreKeyId
|
||||
signedPreKeySignature:signedPreKeySignature
|
||||
identityKey:identityKey];
|
||||
|
||||
}
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@end
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#import "CodeVerificationViewController.h"
|
||||
|
||||
#import "Environment.h"
|
||||
#import "PhoneNumberDirectoryFilterManager.h"
|
||||
#import "RPServerRequestsManager.h"
|
||||
#import "LocalizableText.h"
|
||||
#import "PushManager.h"
|
||||
|
@ -39,11 +41,11 @@
|
|||
//TODO: Lock UI interactions
|
||||
|
||||
[self registerWithSuccess:^{
|
||||
[Environment.getCurrent.phoneDirectoryManager forceUpdate];
|
||||
[self performSegueWithIdentifier:@"verifiedSegue" sender:self];
|
||||
} failure:^(NSError *error) {
|
||||
// TODO: Unlock UI
|
||||
NSLog(@"Failed to register");
|
||||
|
||||
[self showAlertForError:error];
|
||||
}];
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#import "SettingsTableViewCell.h"
|
||||
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSStorageManager.h"
|
||||
|
||||
#import "RPServerRequestsManager.h"
|
||||
|
||||
|
@ -119,11 +120,11 @@ typedef enum {
|
|||
break;
|
||||
|
||||
case kUnregisterCell:
|
||||
[[RPServerRequestsManager sharedInstance] performRequest:[RPAPICall unregister] success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
NSLog(@"YEAH!");
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
NSLog(@"Fail");
|
||||
NSLog(@"error: %@ ", error.debugDescription);
|
||||
[TSAccountManager unregisterTextSecureWithSuccess:^{
|
||||
[[TSStorageManager sharedManager] wipe];
|
||||
exit(0);
|
||||
} failure:^(NSError *error) {
|
||||
SignalAlertView(@"Failed to unregister", @"");
|
||||
}];
|
||||
break;
|
||||
|
||||
|
@ -133,6 +134,4 @@ typedef enum {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
@property (nonatomic, copy) NSDate *messageDate;
|
||||
@property (nonatomic, retain) NSString *messageBody;
|
||||
|
||||
@property NSUInteger identifier;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -38,7 +40,8 @@
|
|||
|
||||
TSMessageAdapter *adapter = [[TSMessageAdapter alloc] init];
|
||||
adapter.messageDate = interaction.date;
|
||||
|
||||
adapter.identifier = (NSUInteger)interaction.uniqueId;
|
||||
|
||||
if ([thread isKindOfClass:[TSContactThread class]]) {
|
||||
adapter.thread = (TSContactThread*)thread;
|
||||
if ([interaction isKindOfClass:[TSIncomingMessage class]]) {
|
||||
|
@ -60,7 +63,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
if ([interaction isKindOfClass:[TSMessage class]]) {
|
||||
if ([interaction isKindOfClass:[TSIncomingMessage class]] || [interaction isKindOfClass:[TSOutgoingMessage class]]) {
|
||||
TSMessage *message = (TSMessage*)interaction;
|
||||
adapter.messageBody = message.body;
|
||||
} else if ([interaction isKindOfClass:[TSCall class]]){
|
||||
|
@ -74,7 +77,6 @@
|
|||
return adapter;
|
||||
}
|
||||
|
||||
|
||||
- (NSString*)senderId{
|
||||
if (_senderId) {
|
||||
return _senderId;
|
||||
|
@ -103,4 +105,8 @@
|
|||
return self.messageBody;
|
||||
}
|
||||
|
||||
- (NSUInteger)hash{
|
||||
return self.identifier;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue