mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Moving away from custom HTTP stack
This commit is contained in:
parent
510831d701
commit
d05791e699
28 changed files with 17973 additions and 4955 deletions
2
Podfile
2
Podfile
|
@ -7,6 +7,6 @@ pod 'UICKeyChainStore', :podspec => 'Podspecs/UICKeyChainStore.podspec
|
|||
pod 'OpenSSL', '~> 1.0.109'
|
||||
pod 'MMDrawerController', '~> 0.5.7'
|
||||
pod 'libPhoneNumber-iOS', '~> 0.7'
|
||||
pod 'PastelogKit', '~> 1.1'
|
||||
pod 'PastelogKit', '~> 1.2'
|
||||
pod 'AFNetworking', '~> 2.4.1'
|
||||
pod 'TwistedOakCollapsingFutures','~> 1.0'
|
||||
|
|
|
@ -39,7 +39,7 @@ PODS:
|
|||
- MMDrawerController/Subclass (0.5.7):
|
||||
- MMDrawerController/Core
|
||||
- OpenSSL (1.0.109)
|
||||
- PastelogKit (1.1):
|
||||
- PastelogKit (1.2):
|
||||
- CocoaLumberjack (~> 1.9)
|
||||
- TwistedOakCollapsingFutures (1.0.0):
|
||||
- UnionFind (~> 1.0)
|
||||
|
@ -51,7 +51,7 @@ DEPENDENCIES:
|
|||
- libPhoneNumber-iOS (~> 0.7)
|
||||
- MMDrawerController (~> 0.5.7)
|
||||
- OpenSSL (~> 1.0.109)
|
||||
- PastelogKit (~> 1.1)
|
||||
- PastelogKit (~> 1.2)
|
||||
- TwistedOakCollapsingFutures (~> 1.0)
|
||||
- UICKeyChainStore (from `Podspecs/UICKeyChainStore.podspec`)
|
||||
|
||||
|
@ -65,7 +65,7 @@ SPEC CHECKSUMS:
|
|||
libPhoneNumber-iOS: 98fc07d70c8fdb5e6a8e3442c37e97353065c20e
|
||||
MMDrawerController: c3ab7a318ddc7e2bcd133139c3161af08c6e1197
|
||||
OpenSSL: 4810adf5c99b0e2cd20670a11a987c805e8a521c
|
||||
PastelogKit: 32836ec27e587a8876326abeaf9a1b5e2bc484ea
|
||||
PastelogKit: 8bab71b1d187617a83e7124cffe9eb1a600e6695
|
||||
TwistedOakCollapsingFutures: 07aab84fd3958dc94d55ef705b12857d9fbe61d1
|
||||
UICKeyChainStore: eef407137f0397e95a3df32cdf05f7e2ddd99647
|
||||
UnionFind: 45777a8b6878d3a602af3654cc3a09b87389d356
|
||||
|
|
2
Pods
2
Pods
|
@ -1 +1 @@
|
|||
Subproject commit e77476e6f8ddec69fb20785f9ff61db0ea95035a
|
||||
Subproject commit 585c9e6ca1b55e99fb5c09aa31a6d590c2be5c58
|
File diff suppressed because it is too large
Load diff
|
@ -59,9 +59,9 @@
|
|||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
launchStyle = "1"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "Ad-Hoc Distribution"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
DDLogError(@"No previous version found. Possibly first launch since install.");
|
||||
[Environment resetAppData]; // We clean previous keychain entries in case their are some entries remaining.
|
||||
} else if ([currentVersion compare:previousVersion options:NSNumericSearch] == NSOrderedDescending){
|
||||
[Environment resetAppData];
|
||||
// Application was updated, let's see if we have a migration scheme for it.
|
||||
if ([previousVersion isEqualToString:@"1.0.2"]) {
|
||||
// Migrate from custom preferences to NSUserDefaults
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#define NOTIFICATION_DIRECTORY_UPDATE @"NOTIFICATION_DIRECTORY_UPDATE"
|
||||
#define NOTIFICATION_DIRECTORY_WAS_UPDATED @"NOTIFICATION_DIRECTORY_WAS_UPDATED"
|
||||
#define NOTIFICATION_DIRECTORY_FAILED @"NOTIFICATION_DIRECTORY_FAILED"
|
||||
#define NOTIFICATION_NEW_USERS_AVAILABLE @"NOTIFICATION_NEW_USERS_AVAILABLE"
|
||||
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@
|
|||
|
||||
#pragma mark - Contact Intersection
|
||||
|
||||
#define TIMEOUT NSLocalizedString(@"TIMEOUT",@"")
|
||||
#define TIMEOUT NSLocalizedString(@"ERROR_WAS_DETECTED_TITLE",@"")
|
||||
#define TIMEOUT_CONTACTS_DETAIL NSLocalizedString(@"TIMEOUT_CONTACTS_DETAIL", @"")
|
||||
|
||||
NSDictionary* makeCallProgressLocalizedTextDictionary(void);
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
//
|
||||
// AFFutureRequest.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 05/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface AFFutureRequest : NSObject
|
||||
|
||||
@end
|
|
@ -1,13 +0,0 @@
|
|||
//
|
||||
// AFFutureRequest.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 05/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AFFutureRequest.h"
|
||||
|
||||
@implementation AFFutureRequest
|
||||
|
||||
@end
|
|
@ -6,7 +6,7 @@
|
|||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <TwistedOakCollapsingFutures/CollapsingFutures.h>
|
||||
#import <CollapsingFutures.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#import "PreferencesUtil.h"
|
||||
#import "PushManager.h"
|
||||
#import "Environment.h"
|
||||
#import "CallServerRequestsManager.h"
|
||||
#import "RPServerRequestsManager.h"
|
||||
#import "FutureUtil.h"
|
||||
|
||||
@interface PushManager ()
|
||||
|
@ -104,7 +104,7 @@
|
|||
-(TOCFuture*)registerForPushFutureWithToken:(NSData*)token{
|
||||
self.registerWithServerFutureSource = [TOCFutureSource new];
|
||||
|
||||
[CallServerRequestsManager.sharedInstance registerPushToken:token success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
[RPServerRequestsManager.sharedInstance performRequest:[RPAPICall registerPushNotificationWithPushToken:token] success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
if ([task.response isKindOfClass: NSHTTPURLResponse.class]){
|
||||
NSInteger statusCode = [(NSHTTPURLResponse*) task.response statusCode];
|
||||
if (statusCode == 200) {
|
||||
|
@ -116,10 +116,11 @@
|
|||
} else{
|
||||
[self.registerWithServerFutureSource trySetFailure:@NO];
|
||||
}
|
||||
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
[self.registerWithServerFutureSource trySetFailure:@NO];
|
||||
}];
|
||||
|
||||
|
||||
return self.registerWithServerFutureSource.future;
|
||||
}
|
||||
|
||||
|
|
23
Signal/src/network/http/AFHTTPSessionManager+SignalMethods.h
Normal file
23
Signal/src/network/http/AFHTTPSessionManager+SignalMethods.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// AFHTTPSessionManager+SignalMethods.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 05/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AFHTTPSessionManager.h"
|
||||
|
||||
@interface AFHTTPSessionManager (SignalMethods)
|
||||
|
||||
- (NSURLSessionDataTask *)BUSY:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
|
||||
|
||||
- (NSURLSessionDataTask *)RING:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
|
||||
|
||||
@end
|
49
Signal/src/network/http/AFHTTPSessionManager+SignalMethods.m
Normal file
49
Signal/src/network/http/AFHTTPSessionManager+SignalMethods.m
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// AFHTTPSessionManager+SignalMethods.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 05/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AFHTTPSessionManager+SignalMethods.h"
|
||||
|
||||
@interface AFHTTPSessionManager ()
|
||||
|
||||
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
|
||||
URLString:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *, id))success
|
||||
failure:(void (^)(NSURLSessionDataTask *, NSError *))failure;
|
||||
|
||||
@end
|
||||
|
||||
@implementation AFHTTPSessionManager (SignalMethods)
|
||||
|
||||
- (NSURLSessionDataTask *)BUSY:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure{
|
||||
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"BUSY" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
[dataTask resume];
|
||||
|
||||
return dataTask;
|
||||
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)RING:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure{
|
||||
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"RING" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
[dataTask resume];
|
||||
|
||||
return dataTask;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
|
@ -1,18 +0,0 @@
|
|||
//
|
||||
// CallServerRequests.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 31/07/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AFNetworking/AFNetworking.h>
|
||||
|
||||
@interface CallServerRequestsManager : NSObject
|
||||
|
||||
MacrosSingletonInterface
|
||||
|
||||
- (void)registerPushToken:(NSData*)deviceToken success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
|
||||
|
||||
@end
|
|
@ -1,62 +0,0 @@
|
|||
//
|
||||
// CallServerRequests.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 31/07/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
#import "HttpRequest.h"
|
||||
#import "CallServerRequestsManager.h"
|
||||
#import "DataUtil.h"
|
||||
#import "Environment.h"
|
||||
#import "HostNameEndPoint.h"
|
||||
#import "SGNKeychainUtil.h"
|
||||
|
||||
#define defaultRequestTimeout
|
||||
|
||||
@interface CallServerRequestsManager ()
|
||||
|
||||
@property (nonatomic, retain)AFHTTPSessionManager *operationManager;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation CallServerRequestsManager
|
||||
|
||||
MacrosSingletonImplemention
|
||||
|
||||
- (id)init{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
HostNameEndPoint *endpoint = Environment.getCurrent.masterServerSecureEndPoint.hostNameEndPoint;
|
||||
NSURL *endPointURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@:%hu", endpoint.hostname, endpoint.port]];
|
||||
NSURLSessionConfiguration *sessionConf = NSURLSessionConfiguration.ephemeralSessionConfiguration;
|
||||
self.operationManager = [[AFHTTPSessionManager alloc] initWithBaseURL:endPointURL sessionConfiguration:sessionConf];
|
||||
self.operationManager.responseSerializer = [AFJSONResponseSerializer serializer];
|
||||
self.operationManager.securityPolicy.allowInvalidCertificates = YES;
|
||||
NSString *certPath = [NSBundle.mainBundle pathForResource:@"whisperReal" ofType:@"cer"];
|
||||
NSData *certData = [NSData dataWithContentsOfFile:certPath];
|
||||
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(certData));
|
||||
self.operationManager.securityPolicy.pinnedCertificates = @[(__bridge_transfer NSData *)SecCertificateCopyData(cert)];
|
||||
self.operationManager.securityPolicy.SSLPinningMode = AFSSLPinningModeCertificate;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)registerPushToken:(NSData*)deviceToken success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure{
|
||||
self.operationManager.requestSerializer = [self basicAuthenticationSerializer];
|
||||
|
||||
[self.operationManager PUT:[NSString stringWithFormat:@"/apn/%@",deviceToken.encodedAsHexString] parameters:@{} success:success failure:failure];
|
||||
}
|
||||
|
||||
- (AFHTTPRequestSerializer*)basicAuthenticationSerializer{
|
||||
AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
|
||||
[serializer setValue:[HttpRequest computeBasicAuthorizationTokenForLocalNumber:SGNKeychainUtil.localNumber
|
||||
andPassword:SGNKeychainUtil.serverAuthPassword]
|
||||
forHTTPHeaderField:@"Authorization"];
|
||||
return serializer;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,7 +1,6 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "NetworkEndPoint.h"
|
||||
#import "Logging.h"
|
||||
#import "HttpRequestOrResponse.h"
|
||||
#import "Terminable.h"
|
||||
#import "Queue.h"
|
||||
#import "PacketHandler.h"
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
if (optionalBody != nil) {
|
||||
headers[@"Content-Length"] = [@(optionalBody.length) stringValue];
|
||||
}
|
||||
|
||||
|
||||
HttpRequest* s = [HttpRequest new];
|
||||
s->_method = method;
|
||||
s->_location = location;
|
||||
|
@ -145,10 +145,10 @@
|
|||
}
|
||||
-(bool) isEqualToHttpRequest:(HttpRequest *)other {
|
||||
return [self.toHttp isEqualToString:other.toHttp]
|
||||
&& [self.method isEqualToString:other.method]
|
||||
&& [self.location isEqualToString:other.location]
|
||||
&& (self.optionalBody == other.optionalBody || [self.optionalBody isEqualToString:[other optionalBody]])
|
||||
&& [self.headers isEqualToDictionary:other.headers];
|
||||
&& [self.method isEqualToString:other.method]
|
||||
&& [self.location isEqualToString:other.location]
|
||||
&& (self.optionalBody == other.optionalBody || [self.optionalBody isEqualToString:[other optionalBody]])
|
||||
&& [self.headers isEqualToDictionary:other.headers];
|
||||
}
|
||||
|
||||
-(NSString*) description {
|
||||
|
@ -156,8 +156,9 @@
|
|||
self.method,
|
||||
self.location,
|
||||
self.optionalBody == nil ? @""
|
||||
: self.optionalBody.length == 0 ? @" [empty body]"
|
||||
: @" [...body...]"];
|
||||
: self.optionalBody.length == 0 ? @" [empty body]"
|
||||
: @" [...body...]"];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
47
Signal/src/network/http/RPAPICall.h
Normal file
47
Signal/src/network/http/RPAPICall.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// RedPhoneAPICall.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 05/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AFNetworking/AFNetworking.h>
|
||||
@class PhoneNumber;
|
||||
|
||||
@interface RPAPICall : NSObject
|
||||
|
||||
typedef NS_ENUM(NSInteger, HTTPMethod) {
|
||||
HTTP_GET,
|
||||
HTTP_POST,
|
||||
HTTP_PUT,
|
||||
HTTP_DELETE,
|
||||
SIGNAL_RING,
|
||||
SIGNAL_BUSY
|
||||
};
|
||||
|
||||
#pragma mark API Call Properties
|
||||
|
||||
@property (nonatomic, readonly) NSString *endPoint;
|
||||
@property (nonatomic, readonly) HTTPMethod method;
|
||||
@property (nonatomic, readonly) NSDictionary *parameters;
|
||||
@property (nonatomic, readonly) AFHTTPRequestSerializer <AFURLRequestSerialization> *requestSerializer;
|
||||
@property (nonatomic, readonly) AFHTTPResponseSerializer <AFURLResponseSerialization> *responseSerializer;
|
||||
|
||||
#pragma mark API Call Contstructors
|
||||
|
||||
+ (RPAPICall*)requestVerificationCode;
|
||||
+ (RPAPICall*)requestVerificationCodeWithVoice;
|
||||
+ (RPAPICall*)verifyVerificationCode:(NSString*)verificationCode;
|
||||
+ (RPAPICall*)registerPushNotificationWithPushToken:(NSData*)pushToken;
|
||||
+ (RPAPICall*)unregister;
|
||||
|
||||
+ (RPAPICall*)fetchBloomFilter;
|
||||
|
||||
//+ (RPAPICall*)requestToOpenPortWithSessionId:(int64_t)sessionId;
|
||||
//+ (RPAPICall*)requestToRingWithSessionId:(int64_t)sessionId;
|
||||
//+ (RPAPICall*)requestToSignalBusyWithSessionId:(int64_t)sessionId;
|
||||
//+ (RPAPICall*)requestToInitiateToRemoteNumber:(PhoneNumber*)remoteNumber;
|
||||
|
||||
@end
|
168
Signal/src/network/http/RPAPICall.m
Normal file
168
Signal/src/network/http/RPAPICall.m
Normal file
|
@ -0,0 +1,168 @@
|
|||
//
|
||||
// RedPhoneAPICall.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 05/10/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Constraints.h"
|
||||
#import "CryptoTools.h"
|
||||
#import "PhoneNumber.h"
|
||||
#import "RPAPICall.h"
|
||||
#import "SignalUtil.h"
|
||||
#import "SGNKeychainUtil.h"
|
||||
#import "Util.h"
|
||||
|
||||
#define CLAIMED_INTEROP_VERSION_IN_INITIATE_SIGNAL 1
|
||||
|
||||
@interface RPAPICall ()
|
||||
@property (nonatomic, readwrite) NSString *endPoint;
|
||||
@property (nonatomic, readwrite) HTTPMethod method;
|
||||
@property (nonatomic, readwrite) NSDictionary *parameters;
|
||||
@property (nonatomic, readwrite) AFHTTPRequestSerializer <AFURLRequestSerialization> *requestSerializer;
|
||||
@property (nonatomic, readwrite) AFHTTPResponseSerializer <AFURLResponseSerialization> *responseSerializer;
|
||||
@end
|
||||
|
||||
@implementation RPAPICall
|
||||
|
||||
+ (RPAPICall*)defaultAPICall {
|
||||
RPAPICall *apiCall = [[RPAPICall alloc] init];
|
||||
apiCall.parameters = @{};
|
||||
apiCall.requestSerializer = [self basicAuthenticationSerializer];
|
||||
apiCall.responseSerializer = [AFHTTPResponseSerializer serializer];
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
|
||||
+ (RPAPICall*)requestVerificationCode {
|
||||
[SGNKeychainUtil generateServerAuthPassword];
|
||||
RPAPICall *apiCall = [self defaultAPICall];
|
||||
apiCall.method = HTTP_GET;
|
||||
apiCall.endPoint = @"/users/verification";
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
+ (RPAPICall*)requestVerificationCodeWithVoice {
|
||||
RPAPICall *apiCall = [self requestVerificationCode];
|
||||
apiCall.endPoint = [apiCall.endPoint stringByAppendingString:@"/voice"];
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
+ (RPAPICall*)verifyVerificationCode:(NSString*)verificationCode {
|
||||
RPAPICall *apiCall = [self defaultAPICall];
|
||||
[SGNKeychainUtil generateSignaling];
|
||||
apiCall.method = HTTP_PUT;
|
||||
apiCall.endPoint = [NSString stringWithFormat:@"/users/verification/%@", SGNKeychainUtil.localNumber];
|
||||
|
||||
NSData* signalingCipherKey = SGNKeychainUtil.signalingCipherKey;
|
||||
NSData* signalingMacKey = SGNKeychainUtil.signalingMacKey;
|
||||
NSData* signalingExtraKeyData = SGNKeychainUtil.signalingCipherKey;
|
||||
NSString* encodedSignalingKey = @[signalingCipherKey, signalingMacKey, signalingExtraKeyData].concatDatas.encodedAsBase64;
|
||||
apiCall.parameters = @{@"key" : encodedSignalingKey, @"challenge" : verificationCode};
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
+ (RPAPICall*)registerPushNotificationWithPushToken:(NSData*)pushToken {
|
||||
RPAPICall *apiCall = [self defaultAPICall];
|
||||
apiCall.method = HTTP_PUT;
|
||||
apiCall.endPoint = [NSString stringWithFormat:@"/apn/%@", pushToken.encodedAsHexString];
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
+ (RPAPICall*)fetchBloomFilter {
|
||||
RPAPICall *apiCall = [self defaultAPICall];
|
||||
apiCall.method = HTTP_GET;
|
||||
apiCall.endPoint = @"/users/directory";
|
||||
apiCall.requestSerializer = [self otpAuthenticationSerializer];
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
+ (RPAPICall*)unregister {
|
||||
RPAPICall *apiCall = [self defaultAPICall];
|
||||
apiCall.method = HTTP_GET;
|
||||
apiCall.endPoint = @"/users/directory";
|
||||
apiCall.requestSerializer = [self otpAuthenticationSerializer];
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
+ (RPAPICall*)requestToOpenPortWithSessionId:(int64_t)sessionId {
|
||||
RPAPICall *apiCall = [self defaultAPICall];
|
||||
apiCall.method = HTTP_GET;
|
||||
apiCall.endPoint = [NSString stringWithFormat:@"/open/%lld", sessionId];
|
||||
apiCall.requestSerializer = [self unauthenticatedSerializer];
|
||||
apiCall.responseSerializer = [AFHTTPResponseSerializer serializer];
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
+ (RPAPICall*)requestToRingWithSessionId:(int64_t)sessionId {
|
||||
RPAPICall *apiCall = [self defaultAPICall];
|
||||
apiCall.method = SIGNAL_RING;
|
||||
apiCall.endPoint = [NSString stringWithFormat:@"/session/%lld", sessionId];
|
||||
apiCall.requestSerializer = [self otpAuthenticationSerializer];
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
+ (RPAPICall*)requestToSignalBusyWithSessionId:(int64_t)sessionId {
|
||||
RPAPICall *apiCall = [self defaultAPICall];
|
||||
apiCall.method = SIGNAL_BUSY;
|
||||
apiCall.endPoint = [NSString stringWithFormat:@"/session/%lld", sessionId];
|
||||
apiCall.requestSerializer = [self otpAuthenticationSerializer];
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
+ (RPAPICall*)requestToInitiateToRemoteNumber:(PhoneNumber*)remoteNumber {
|
||||
RPAPICall *apiCall = [self defaultAPICall];
|
||||
|
||||
require(remoteNumber != nil);
|
||||
|
||||
NSString* formattedRemoteNumber = remoteNumber.toE164;
|
||||
NSString* interopVersionInsert = (CLAIMED_INTEROP_VERSION_IN_INITIATE_SIGNAL == 0)? @"" : [NSString stringWithFormat:@"/%d", CLAIMED_INTEROP_VERSION_IN_INITIATE_SIGNAL];
|
||||
|
||||
apiCall.method = HTTP_GET;
|
||||
apiCall.endPoint = [NSString stringWithFormat:@"/session%@/%@",
|
||||
interopVersionInsert,
|
||||
formattedRemoteNumber];
|
||||
apiCall.requestSerializer = [self otpAuthenticationSerializer];
|
||||
return apiCall;
|
||||
}
|
||||
|
||||
#pragma mark Authorization Headers
|
||||
|
||||
+ (AFHTTPRequestSerializer*)basicAuthenticationSerializer {
|
||||
AFHTTPRequestSerializer *serializer = [AFJSONRequestSerializer serializer];
|
||||
[serializer setAuthorizationHeaderFieldWithUsername:SGNKeychainUtil.localNumber.toE164 password:SGNKeychainUtil.serverAuthPassword];
|
||||
return serializer;
|
||||
}
|
||||
|
||||
+ (AFHTTPRequestSerializer*)otpAuthenticationSerializer {
|
||||
AFHTTPRequestSerializer *serializer = [AFJSONRequestSerializer serializer];
|
||||
[serializer setAuthorizationHeaderFieldWithUsername:SGNKeychainUtil.localNumber.toE164 password:SGNKeychainUtil.serverAuthPassword];
|
||||
return serializer;
|
||||
}
|
||||
|
||||
+ (AFHTTPRequestSerializer*)unauthenticatedSerializer {
|
||||
return [AFHTTPRequestSerializer serializer];
|
||||
}
|
||||
|
||||
+ (NSString*) computeOtpAuthorizationTokenForLocalNumber:(PhoneNumber*)localNumber
|
||||
andCounterValue:(int64_t)counterValue
|
||||
andPassword:(NSString*)password {
|
||||
require(localNumber != nil);
|
||||
require(password != nil);
|
||||
|
||||
NSString* rawToken = [NSString stringWithFormat:@"%@:%@:%lld",
|
||||
localNumber.toE164,
|
||||
[CryptoTools computeOtpWithPassword:password andCounter:counterValue],
|
||||
counterValue];
|
||||
return [@"OTP " stringByAppendingString:rawToken.encodedAsUtf8.encodedAsBase64];
|
||||
}
|
||||
|
||||
+ (NSString*) computeBasicAuthorizationTokenForLocalNumber:(PhoneNumber*)localNumber andPassword:(NSString*)password {
|
||||
NSString* rawToken = [NSString stringWithFormat:@"%@:%@",
|
||||
localNumber.toE164,
|
||||
password];
|
||||
return [@"Basic " stringByAppendingString:rawToken.encodedAsUtf8.encodedAsBase64];
|
||||
}
|
||||
|
||||
@end
|
22
Signal/src/network/http/RPServerRequestsManager.h
Normal file
22
Signal/src/network/http/RPServerRequestsManager.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// CallServerRequests.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 31/07/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "RPAPICall.h"
|
||||
|
||||
#import <CollapsingFutures.h>
|
||||
|
||||
@interface RPServerRequestsManager : NSObject
|
||||
|
||||
MacrosSingletonInterface
|
||||
|
||||
- (void)performRequest:(RPAPICall*)apiCall success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
|
||||
|
||||
- (TOCFuture*)futureForRequest:(RPAPICall*)apiCall;
|
||||
|
||||
@end
|
96
Signal/src/network/http/RPServerRequestsManager.m
Normal file
96
Signal/src/network/http/RPServerRequestsManager.m
Normal file
|
@ -0,0 +1,96 @@
|
|||
//
|
||||
// CallServerRequests.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 31/07/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
#import "HttpRequest.h"
|
||||
#import "RPServerRequestsManager.h"
|
||||
#import "Constraints.h"
|
||||
#import "CryptoTools.h"
|
||||
#import "DataUtil.h"
|
||||
#import "Environment.h"
|
||||
#import "HostNameEndPoint.h"
|
||||
#import "SGNKeychainUtil.h"
|
||||
#import "Util.h"
|
||||
|
||||
#import "AFHTTPSessionManager+SignalMethods.h"
|
||||
|
||||
@interface RPServerRequestsManager ()
|
||||
|
||||
@property (nonatomic, retain)AFHTTPSessionManager *operationManager;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation RPServerRequestsManager
|
||||
|
||||
MacrosSingletonImplemention
|
||||
|
||||
- (id)init{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
HostNameEndPoint *endpoint = Environment.getCurrent.masterServerSecureEndPoint.hostNameEndPoint;
|
||||
NSURL *endPointURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@:%hu", endpoint.hostname, endpoint.port]];
|
||||
NSURLSessionConfiguration *sessionConf = NSURLSessionConfiguration.ephemeralSessionConfiguration;
|
||||
self.operationManager = [[AFHTTPSessionManager alloc] initWithBaseURL:endPointURL sessionConfiguration:sessionConf];
|
||||
self.operationManager.responseSerializer = [AFJSONResponseSerializer serializer];
|
||||
self.operationManager.securityPolicy.allowInvalidCertificates = YES;
|
||||
NSString *certPath = [NSBundle.mainBundle pathForResource:@"whisperReal" ofType:@"cer"];
|
||||
NSData *certData = [NSData dataWithContentsOfFile:certPath];
|
||||
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(certData));
|
||||
self.operationManager.securityPolicy.pinnedCertificates = @[(__bridge_transfer NSData *)SecCertificateCopyData(cert)];
|
||||
self.operationManager.securityPolicy.SSLPinningMode = AFSSLPinningModeCertificate;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)performRequest:(RPAPICall*)apiCall success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure{
|
||||
|
||||
self.operationManager.requestSerializer = apiCall.requestSerializer;
|
||||
self.operationManager.responseSerializer = apiCall.responseSerializer;
|
||||
|
||||
switch (apiCall.method) {
|
||||
case HTTP_GET:
|
||||
[self.operationManager GET:apiCall.endPoint parameters:apiCall.parameters success:success failure:failure];
|
||||
break;
|
||||
|
||||
case HTTP_PUT:
|
||||
[self.operationManager PUT:apiCall.endPoint parameters:apiCall.parameters success:success failure:failure];
|
||||
break;
|
||||
|
||||
case HTTP_POST:
|
||||
[self.operationManager POST:apiCall.endPoint parameters:apiCall.parameters success:success failure:failure];
|
||||
break;
|
||||
|
||||
case HTTP_DELETE:
|
||||
[self.operationManager DELETE:apiCall.endPoint parameters:apiCall.parameters success:success failure:failure];
|
||||
break;
|
||||
|
||||
case SIGNAL_BUSY:
|
||||
[self.operationManager BUSY:apiCall.endPoint parameters:apiCall.parameters success:success failure:failure];
|
||||
break;
|
||||
|
||||
case SIGNAL_RING:
|
||||
[self.operationManager RING:apiCall.endPoint parameters:apiCall.parameters success:success failure:failure];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (TOCFuture*)futureForRequest:(RPAPICall*)apiCall{
|
||||
TOCFutureSource *requestFutureSource = [TOCFutureSource new];
|
||||
|
||||
[self performRequest:apiCall success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
NSLog(@"ResponseObject: %@", responseObject);
|
||||
[requestFutureSource trySetResult:task.response];
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
[requestFutureSource trySetFailure:error];
|
||||
}];
|
||||
|
||||
return [requestFutureSource future];
|
||||
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,7 +1,6 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "BloomFilter.h"
|
||||
#import "PhoneNumber.h"
|
||||
#import "HttpResponse.h"
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -18,7 +17,7 @@
|
|||
+(PhoneNumberDirectoryFilter*) phoneNumberDirectoryFilterDefault;
|
||||
+(PhoneNumberDirectoryFilter*) phoneNumberDirectoryFilterWithBloomFilter:(BloomFilter*)bloomFilter
|
||||
andExpirationDate:(NSDate*)expirationDate;
|
||||
+(PhoneNumberDirectoryFilter*) phoneNumberDirectoryFilterFromHttpResponse:(HttpResponse*)response;
|
||||
+(PhoneNumberDirectoryFilter*) phoneNumberDirectoryFilterFromURLResponse:(NSHTTPURLResponse*)response body:(NSData*)data;
|
||||
|
||||
-(bool) containsPhoneNumber:(PhoneNumber*)phoneNumber;
|
||||
-(NSDate*) getExpirationDate;
|
||||
|
|
|
@ -32,18 +32,18 @@
|
|||
return expirationDate;
|
||||
}
|
||||
|
||||
+(PhoneNumberDirectoryFilter*) phoneNumberDirectoryFilterFromHttpResponse:(HttpResponse*)response {
|
||||
+(PhoneNumberDirectoryFilter*) phoneNumberDirectoryFilterFromURLResponse:(NSHTTPURLResponse*)response body:(NSData*)data {
|
||||
require(response != nil);
|
||||
|
||||
checkOperation(response.isOkResponse);
|
||||
checkOperation(response.statusCode == 200);
|
||||
|
||||
NSString* hashCountHeader = response.getHeaders[HASH_COUNT_HEADER_KEY];
|
||||
NSString* hashCountHeader = response.allHeaderFields[HASH_COUNT_HEADER_KEY];
|
||||
checkOperation(hashCountHeader != nil);
|
||||
|
||||
int hashCountValue = [hashCountHeader intValue];
|
||||
checkOperation(hashCountValue > 0);
|
||||
|
||||
NSData* responseBody = response.getOptionalBodyData;
|
||||
NSData* responseBody = data;
|
||||
checkOperation(responseBody.length > 0);
|
||||
|
||||
BloomFilter* bloomFilter = [BloomFilter bloomFilterWithHashCount:(NSUInteger)hashCountValue
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#import "Environment.h"
|
||||
#import "NotificationManifest.h"
|
||||
#import "PreferencesUtil.h"
|
||||
#import "RPServerRequestsManager.h"
|
||||
#import "SignalUtil.h"
|
||||
#import "ThreadManager.h"
|
||||
#import "Util.h"
|
||||
|
@ -47,7 +48,9 @@
|
|||
}
|
||||
-(void) scheduleUpdateAt:(NSDate*)date {
|
||||
void(^doUpdate)(void) = ^{
|
||||
[self update];
|
||||
if (Environment.isRegistered) {
|
||||
[self update];
|
||||
}
|
||||
};
|
||||
|
||||
[currentUpdateLifetime cancel];
|
||||
|
@ -59,55 +62,28 @@
|
|||
unlessCancelled:currentUpdateLifetime.token];
|
||||
}
|
||||
|
||||
-(TOCFuture*) asyncQueryCurrentDirectory {
|
||||
TOCUntilOperation startAwaitDirectoryOperation = ^(TOCCancelToken* untilCancelledToken) {
|
||||
HttpRequest* directoryRequest = [HttpRequest httpRequestForPhoneNumberDirectoryFilter];
|
||||
|
||||
TOCFuture* futureDirectoryResponse = [HttpManager asyncOkResponseFromMasterServer:directoryRequest
|
||||
unlessCancelled:untilCancelledToken
|
||||
andErrorHandler:Environment.errorNoter];
|
||||
|
||||
return [futureDirectoryResponse thenTry:^(HttpResponse* response) {
|
||||
return [PhoneNumberDirectoryFilter phoneNumberDirectoryFilterFromHttpResponse:response];
|
||||
}];
|
||||
};
|
||||
|
||||
return [TOCFuture futureFromUntilOperation:[TOCFuture operationTry:startAwaitDirectoryOperation]
|
||||
withOperationTimeout:DIRECTORY_UPDATE_TIMEOUT_PERIOD
|
||||
until:lifetimeToken];
|
||||
}
|
||||
|
||||
-(PhoneNumberDirectoryFilter*) sameDirectoryWithRetryTimeout {
|
||||
BloomFilter* filter = [phoneNumberDirectoryFilter bloomFilter];
|
||||
NSDate* retryDate = [NSDate dateWithTimeInterval:DIRECTORY_UPDATE_RETRY_PERIOD
|
||||
sinceDate:[NSDate date]];
|
||||
return [PhoneNumberDirectoryFilter phoneNumberDirectoryFilterWithBloomFilter:filter
|
||||
andExpirationDate:retryDate];
|
||||
}
|
||||
-(void) signalDirectoryQueryFailed:(id)failure {
|
||||
NSString* desc = [NSString stringWithFormat:@"Failed to retrieve directory. Retrying in %f hours.",
|
||||
DIRECTORY_UPDATE_RETRY_PERIOD/HOUR];
|
||||
Environment.errorNoter(desc, failure, false);
|
||||
}
|
||||
-(TOCFuture*) asyncQueryCurrentDirectoryWithDefaultOnFail {
|
||||
TOCFuture* futureDirectory = [self asyncQueryCurrentDirectory];
|
||||
|
||||
return [futureDirectory catchTry:^PhoneNumberDirectoryFilter*(id error) {
|
||||
[self signalDirectoryQueryFailed:error];
|
||||
return [self sameDirectoryWithRetryTimeout];
|
||||
}];
|
||||
}
|
||||
|
||||
-(void) update {
|
||||
TOCFuture* eventualDirectory = [self asyncQueryCurrentDirectoryWithDefaultOnFail];
|
||||
|
||||
[eventualDirectory thenDo:^(PhoneNumberDirectoryFilter* directory) {
|
||||
[[RPServerRequestsManager sharedInstance] performRequest:[RPAPICall fetchBloomFilter] success:^(NSURLSessionDataTask *task, NSData *responseObject) {
|
||||
PhoneNumberDirectoryFilter *directory = [PhoneNumberDirectoryFilter phoneNumberDirectoryFilterFromURLResponse:(NSHTTPURLResponse*)task.response body:responseObject];
|
||||
|
||||
@synchronized(self) {
|
||||
phoneNumberDirectoryFilter = directory;
|
||||
}
|
||||
|
||||
[Environment.preferences setSavedPhoneNumberDirectory:directory];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_DIRECTORY_WAS_UPDATED object:nil];
|
||||
[self scheduleUpdate];
|
||||
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
NSString* desc = [NSString stringWithFormat:@"Failed to retrieve directory. Retrying in %f hours.",
|
||||
DIRECTORY_UPDATE_RETRY_PERIOD/HOUR];
|
||||
Environment.errorNoter(desc, error, false);
|
||||
BloomFilter* filter = [phoneNumberDirectoryFilter bloomFilter];
|
||||
NSDate* retryDate = [NSDate dateWithTimeInterval:DIRECTORY_UPDATE_RETRY_PERIOD
|
||||
sinceDate:[NSDate date]];
|
||||
[PhoneNumberDirectoryFilter phoneNumberDirectoryFilterWithBloomFilter:filter
|
||||
andExpirationDate:retryDate];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_DIRECTORY_FAILED object:nil];
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
@property (nonatomic, strong) IBOutlet SearchBarTitleView *searchBarTitleView;
|
||||
@property (nonatomic, strong) IBOutlet UIView *notificationView;
|
||||
@property (nonatomic, retain) UIRefreshControl *refreshControl;
|
||||
@property (nonatomic) NSTimer *refreshTimer;
|
||||
|
||||
- (IBAction)notificationViewTapped:(id)sender;
|
||||
- (void)showNotificationForNewWhisperUsers:(NSArray *)users;
|
||||
|
|
|
@ -34,6 +34,7 @@ static NSString *const CONTACT_BROWSE_TABLE_CELL_IDENTIFIER = @"ContactTableView
|
|||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contactsDidRefresh) name:NOTIFICATION_DIRECTORY_WAS_UPDATED object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contactRefreshFailed) name:NOTIFICATION_DIRECTORY_FAILED object:nil];
|
||||
UIRefreshControl *refreshControl = [[UIRefreshControl alloc]
|
||||
init];
|
||||
[refreshControl addTarget:self action:@selector(refreshContacts) forControlEvents:UIControlEventValueChanged];
|
||||
|
@ -252,17 +253,15 @@ static NSString *const CONTACT_BROWSE_TABLE_CELL_IDENTIFIER = @"ContactTableView
|
|||
|
||||
- (void)refreshContacts{
|
||||
[Environment.getCurrent.phoneDirectoryManager forceUpdate];
|
||||
self.refreshTimer = [NSTimer scheduledTimerWithTimeInterval:REFRESH_TIMEOUT target:self selector:@selector(contactRefreshDidTimeout) userInfo:nil repeats:NO];
|
||||
}
|
||||
|
||||
- (void)contactRefreshDidTimeout{
|
||||
- (void)contactRefreshFailed{
|
||||
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:TIMEOUT message:TIMEOUT_CONTACTS_DETAIL delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"") otherButtonTitles:nil];
|
||||
[alert show];
|
||||
[self.refreshControl endRefreshing];
|
||||
}
|
||||
|
||||
- (void)contactsDidRefresh{
|
||||
[self.refreshTimer invalidate];
|
||||
[self.refreshControl endRefreshing];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#import "RPServerRequestsManager.h"
|
||||
#import "Environment.h"
|
||||
#import "HttpManager.h"
|
||||
#import "LocalizableText.h"
|
||||
|
@ -8,6 +9,7 @@
|
|||
#import "PreferencesUtil.h"
|
||||
#import "PushManager.h"
|
||||
#import "RegisterViewController.h"
|
||||
#import "RPServerRequestsManager.h"
|
||||
#import "SignalUtil.h"
|
||||
#import "SGNKeychainUtil.h"
|
||||
#import "ThreadManager.h"
|
||||
|
@ -114,32 +116,6 @@
|
|||
[self presentViewController:countryCodeController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
-(TOCFuture*) asyncRegister:(PhoneNumber*)phoneNumber untilCancelled:(TOCCancelToken*)cancelToken {
|
||||
[SGNKeychainUtil generateServerAuthPassword];
|
||||
[SGNKeychainUtil setLocalNumberTo:phoneNumber];
|
||||
|
||||
TOCUntilOperation regStarter = ^TOCFuture *(TOCCancelToken* internalUntilCancelledToken) {
|
||||
HttpRequest *registerRequest = [HttpRequest httpRequestToStartRegistrationOfPhoneNumber];
|
||||
|
||||
return [HttpManager asyncOkResponseFromMasterServer:registerRequest
|
||||
unlessCancelled:internalUntilCancelledToken
|
||||
andErrorHandler:Environment.errorNoter];
|
||||
};
|
||||
TOCFuture *futurePhoneRegistrationStarted = [TOCFuture futureFromUntilOperation:[TOCFuture operationTry:regStarter]
|
||||
withOperationTimeout:SERVER_TIMEOUT_SECONDS
|
||||
until:cancelToken];
|
||||
|
||||
return [futurePhoneRegistrationStarted thenTry:^(id _) {
|
||||
[self showViewNumber:CHALLENGE_VIEW_NUMBER];
|
||||
[self.challengeNumberLabel setText:[phoneNumber description]];
|
||||
[_registerCancelButton removeFromSuperview];
|
||||
[self startVoiceVerificationCountdownTimer];
|
||||
self->futureChallengeAcceptedSource = [TOCFutureSource new];
|
||||
return futureChallengeAcceptedSource.future;
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
- (void)registerPhoneNumberTapped {
|
||||
NSString *phoneNumber = [NSString stringWithFormat:@"%@%@", _countryCodeLabel.text, _phoneNumberTextField.text];
|
||||
PhoneNumber* localNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:phoneNumber];
|
||||
|
@ -147,16 +123,21 @@
|
|||
|
||||
[_phoneNumberTextField resignFirstResponder];
|
||||
|
||||
TOCFuture* futureFinished = [self asyncRegister:localNumber untilCancelled:life.token];
|
||||
[_registerActivityIndicator startAnimating];
|
||||
_registerButton.enabled = NO;
|
||||
|
||||
[futureFinished catchDo:^(id error) {
|
||||
NSError *err = ((NSError*)error);
|
||||
[SGNKeychainUtil setLocalNumberTo:localNumber];
|
||||
|
||||
[[RPServerRequestsManager sharedInstance]performRequest:[RPAPICall requestVerificationCode] success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
[self showViewNumber:CHALLENGE_VIEW_NUMBER];
|
||||
[self.challengeNumberLabel setText:[phoneNumber description]];
|
||||
[_registerCancelButton removeFromSuperview];
|
||||
[self startVoiceVerificationCountdownTimer];
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
[_registerActivityIndicator stopAnimating];
|
||||
_registerButton.enabled = YES;
|
||||
|
||||
DDLogError(@"Registration failed with information %@", err.description);
|
||||
DDLogError(@"Registration failed with information %@", error.description);
|
||||
|
||||
UIAlertView *registrationErrorAV = [[UIAlertView alloc]initWithTitle:REGISTER_ERROR_ALERT_VIEW_TITLE message:REGISTER_ERROR_ALERT_VIEW_BODY delegate:nil cancelButtonTitle:REGISTER_ERROR_ALERT_VIEW_DISMISS otherButtonTitles:nil, nil];
|
||||
|
||||
|
@ -173,22 +154,30 @@
|
|||
_challengeButton.enabled = NO;
|
||||
[_challengeActivityIndicator startAnimating];
|
||||
|
||||
HttpRequest *verifyRequest = [HttpRequest httpRequestToVerifyAccessToPhoneNumberWithChallenge:_challengeTextField.text];
|
||||
TOCFuture *futureDone = [HttpManager asyncOkResponseFromMasterServer:verifyRequest
|
||||
unlessCancelled:nil
|
||||
andErrorHandler:Environment.errorNoter];
|
||||
|
||||
[futureDone catchDo:^(id error) {
|
||||
[[RPServerRequestsManager sharedInstance] performRequest:[RPAPICall verifyVerificationCode:_challengeTextField.text] success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
|
||||
[PushManager.sharedManager registrationWithSuccess:^{
|
||||
[futureChallengeAcceptedSource trySetResult:@YES];
|
||||
[Environment setRegistered:YES];
|
||||
[registered trySetResult:@YES];
|
||||
[Environment.getCurrent.phoneDirectoryManager forceUpdate];
|
||||
[self dismissView];
|
||||
} failure:^{
|
||||
_challengeButton.enabled = YES;
|
||||
[_challengeActivityIndicator stopAnimating];
|
||||
}];
|
||||
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
NSString *alertTitle = NSLocalizedString(@"REGISTRATION_ERROR", @"");
|
||||
|
||||
if ([error isKindOfClass:HttpResponse.class]) {
|
||||
HttpResponse* badResponse = error;
|
||||
if (badResponse.getStatusCode == 401) {
|
||||
NSHTTPURLResponse* badResponse = (NSHTTPURLResponse*)task.response;
|
||||
if (badResponse.statusCode == 401) {
|
||||
SignalAlertView(alertTitle, REGISTER_CHALLENGE_ALERT_VIEW_BODY);
|
||||
} else if (badResponse.getStatusCode == 401){
|
||||
} else if (badResponse.statusCode == 401){
|
||||
SignalAlertView(alertTitle, NSLocalizedString(@"REGISTER_RATE_LIMITING_BODY", @""));
|
||||
} else {
|
||||
NSString *alertBodyString = [NSString stringWithFormat:@"%@ %lu", NSLocalizedString(@"SERVER_CODE", @""),(unsigned long)badResponse.getStatusCode];
|
||||
NSString *alertBodyString = [NSString stringWithFormat:@"%@ %lu", NSLocalizedString(@"SERVER_CODE", @""),(unsigned long)badResponse.statusCode];
|
||||
SignalAlertView (alertTitle, alertBodyString);
|
||||
}
|
||||
} else{
|
||||
|
@ -199,22 +188,6 @@
|
|||
_challengeButton.enabled = YES;
|
||||
[_challengeActivityIndicator stopAnimating];
|
||||
}];
|
||||
|
||||
[futureDone thenDo:^(id result) {
|
||||
[futureChallengeAcceptedSource trySetResult:@YES];
|
||||
}];
|
||||
|
||||
[futureChallengeAcceptedSource.future thenDo:^(id value) {
|
||||
[PushManager.sharedManager registrationWithSuccess:^{
|
||||
[Environment setRegistered:YES];
|
||||
[registered trySetResult:@YES];
|
||||
[Environment.getCurrent.phoneDirectoryManager forceUpdate];
|
||||
[self dismissView];
|
||||
} failure:^{
|
||||
_challengeButton.enabled = YES;
|
||||
[_challengeActivityIndicator stopAnimating];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)showViewNumber:(NSInteger)viewNumber {
|
||||
|
@ -275,29 +248,17 @@
|
|||
|
||||
- (void) initiateVoiceVerification{
|
||||
[self stopVoiceVerificationCountdownTimer];
|
||||
TOCUntilOperation callStarter = ^TOCFuture *(TOCCancelToken* internalUntilCancelledToken) {
|
||||
HttpRequest* voiceVerifyReq = [HttpRequest httpRequestToStartRegistrationOfPhoneNumberWithVoice];
|
||||
|
||||
[self.voiceChallengeTextLabel setText:NSLocalizedString(@"REGISTER_CALL_CALLING", @"")];
|
||||
return [HttpManager asyncOkResponseFromMasterServer:voiceVerifyReq
|
||||
unlessCancelled:internalUntilCancelledToken
|
||||
andErrorHandler:Environment.errorNoter];
|
||||
};
|
||||
TOCFuture *futureVoiceVerificationStarted = [TOCFuture futureFromUntilOperation:[TOCFuture operationTry:callStarter]
|
||||
withOperationTimeout:SERVER_TIMEOUT_SECONDS
|
||||
until:life.token];
|
||||
[futureVoiceVerificationStarted catchDo:^(id errorId) {
|
||||
HttpResponse* error = (HttpResponse*)errorId;
|
||||
[self.voiceChallengeTextLabel setText:error.getStatusText];
|
||||
}];
|
||||
[self.voiceChallengeTextLabel setText:NSLocalizedString(@"REGISTER_CALL_CALLING", @"")];
|
||||
|
||||
[futureVoiceVerificationStarted finallyTry:^(id _id) {
|
||||
[[RPServerRequestsManager sharedInstance] performRequest:[RPAPICall requestVerificationCodeWithVoice] success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
|
||||
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, VOICE_VERIFICATION_COOLDOWN_SECONDS * NSEC_PER_SEC);
|
||||
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
|
||||
[self.voiceChallengeTextLabel setText:NSLocalizedString(@"REGISTER_CALL_RECALL", @"")];
|
||||
});
|
||||
|
||||
return _id;
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
[self.voiceChallengeTextLabel setText:error.description];
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue