session-ios/Signal/src/phone/signaling/SignalUtil.m

112 lines
5.0 KiB
Objective-C

#import "SignalUtil.h"
#import "Constraints.h"
#import "Environment.h"
#import "PreferencesUtil.h"
#import "Util.h"
#import "SGNKeychainUtil.h"
#define CLAIMED_INTEROP_VERSION_IN_INITIATE_SIGNAL 1
/**
*
* Augments HttpRequest with utility methods related to interacting with signaling servers.
*
*/
@implementation HttpRequest(SignalUtil)
-(NSNumber*) tryGetSessionId {
if (![self.location hasPrefix:@"/session/"]) return nil;
NSString* sessionIdText = [self.location substringFromIndex:@"/session/".length];
sessionIdText = [sessionIdText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSNumber* sessionIdNumber = [sessionIdText tryParseAsDecimalNumber];
if ([sessionIdNumber hasLongLongValue]) return sessionIdNumber;
return nil;
}
-(bool) isKeepAlive {
return [self.method isEqualToString:@"GET"] && [self.location hasPrefix:@"/keepalive"];
}
-(bool) isRingingForSession:(int64_t)targetSessionId {
return [self.method isEqualToString:@"RING"] && [@(targetSessionId) isEqualToNumber:[self tryGetSessionId]];
}
-(bool) isHangupForSession:(int64_t)targetSessionId {
return [self.method isEqualToString:@"DELETE"] && [@(targetSessionId) isEqualToNumber:[self tryGetSessionId]];
}
-(bool) isBusyForSession:(int64_t)targetSessionId {
return [self.method isEqualToString:@"BUSY"] && [@(targetSessionId) isEqualToNumber:[self tryGetSessionId]];
}
+(HttpRequest*) httpRequestToOpenPortWithSessionId:(int64_t)sessionId {
return [HttpRequest httpRequestUnauthenticatedWithMethod:@"GET"
andLocation:[NSString stringWithFormat:@"/open/%lld", sessionId]];
}
+(HttpRequest*) httpRequestToRingWithSessionId:(int64_t)sessionId {
return [HttpRequest httpRequestWithOtpAuthenticationAndMethod:@"RING"
andLocation:[NSString stringWithFormat:@"/session/%lld", sessionId]];
}
+(HttpRequest*) httpRequestToSignalBusyWithSessionId:(int64_t)sessionId {
return [HttpRequest httpRequestWithOtpAuthenticationAndMethod:@"BUSY"
andLocation:[NSString stringWithFormat:@"/session/%lld", sessionId]];
}
+(HttpRequest*) httpRequestToInitiateToRemoteNumber:(PhoneNumber*)remoteNumber {
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];
return [HttpRequest httpRequestWithOtpAuthenticationAndMethod:@"GET"
andLocation:[NSString stringWithFormat:@"/session%@/%@",
interopVersionInsert,
formattedRemoteNumber]];
}
+(HttpRequest*) httpRequestToStartRegistrationOfPhoneNumber {
return [HttpRequest httpRequestWithBasicAuthenticationAndMethod:@"GET"
andLocation:@"/users/verification"];
}
+(HttpRequest*) httpRequestToStartRegistrationOfPhoneNumberWithVoice {
return [HttpRequest httpRequestWithBasicAuthenticationAndMethod:@"GET"
andLocation:@"/users/verification/voice"];
}
+(HttpRequest*) httpRequestToVerifyAccessToPhoneNumberWithChallenge:(NSString*)challenge {
require(challenge != nil);
PhoneNumber* localPhoneNumber = [SGNKeychainUtil localNumber];
NSString* query = [NSString stringWithFormat:@"/users/verification/%@", [localPhoneNumber toE164]];
[SGNKeychainUtil generateSignaling];
NSData* signalingCipherKey = [SGNKeychainUtil signalingCipherKey];
NSData* signalingMacKey = [SGNKeychainUtil signalingMacKey];
NSData* signalingExtraKeyData = [SGNKeychainUtil signalingCipherKey];
NSString* encodedSignalingKey = [[@[signalingCipherKey, signalingMacKey, signalingExtraKeyData] concatDatas] encodedAsBase64];
NSString* body = [@{@"key" : encodedSignalingKey, @"challenge" : challenge} encodedAsJson];
return [HttpRequest httpRequestWithBasicAuthenticationAndMethod:@"PUT"
andLocation:query
andOptionalBody:body];
}
+(HttpRequest*) httpRequestToRegisterForApnSignalingWithDeviceToken:(NSData*)deviceToken {
require(deviceToken != nil);
NSString* query = [NSString stringWithFormat:@"/apn/%@", [deviceToken encodedAsHexString]];
return [HttpRequest httpRequestWithBasicAuthenticationAndMethod:@"PUT"
andLocation:query];
}
+(HttpRequest*) httpRequestForPhoneNumberDirectoryFilter {
return [HttpRequest httpRequestWithOtpAuthenticationAndMethod:@"GET"
andLocation:@"/users/directory"];
}
@end