Rework account attributes; persist manual message fetch; add "unrestricted UD" setting.
This commit is contained in:
parent
12c8eaf060
commit
1d40cbfb41
|
@ -154,6 +154,7 @@
|
|||
3491D9A121022DB7001EF5A1 /* CDSSigningCertificateTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 3491D9A021022DB7001EF5A1 /* CDSSigningCertificateTest.m */; };
|
||||
3496744D2076768700080B5F /* OWSMessageBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3496744C2076768700080B5F /* OWSMessageBubbleView.m */; };
|
||||
3496744F2076ACD000080B5F /* LongTextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3496744E2076ACCE00080B5F /* LongTextViewController.swift */; };
|
||||
349EA07C2162AEA800F7B17F /* OWS111UDAttributesMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349EA07B2162AEA700F7B17F /* OWS111UDAttributesMigration.swift */; };
|
||||
34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */; };
|
||||
34A910601FFEB114000C4745 /* OWSBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A9105F1FFEB114000C4745 /* OWSBackup.m */; };
|
||||
34ABB2C42090C59700C727A6 /* OWSResaveCollectionDBMigration.m in Sources */ = {isa = PBXBuildFile; fileRef = 34ABB2C22090C59600C727A6 /* OWSResaveCollectionDBMigration.m */; };
|
||||
|
@ -789,6 +790,7 @@
|
|||
3496744B2076768600080B5F /* OWSMessageBubbleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageBubbleView.h; sourceTree = "<group>"; };
|
||||
3496744C2076768700080B5F /* OWSMessageBubbleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSMessageBubbleView.m; sourceTree = "<group>"; };
|
||||
3496744E2076ACCE00080B5F /* LongTextViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LongTextViewController.swift; sourceTree = "<group>"; };
|
||||
349EA07B2162AEA700F7B17F /* OWS111UDAttributesMigration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWS111UDAttributesMigration.swift; sourceTree = "<group>"; };
|
||||
34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWS2FARegistrationViewController.m; sourceTree = "<group>"; };
|
||||
34A55F3620485464002CC6DE /* OWS2FARegistrationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWS2FARegistrationViewController.h; sourceTree = "<group>"; };
|
||||
34A9105E1FFEB113000C4745 /* OWSBackup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackup.h; sourceTree = "<group>"; };
|
||||
|
@ -1625,6 +1627,8 @@
|
|||
4598198D204E2F28009414F2 /* OWS108CallLoggingPreference.m */,
|
||||
34D5872E208E2C4100D2255A /* OWS109OutgoingMessageState.h */,
|
||||
34D5872D208E2C4100D2255A /* OWS109OutgoingMessageState.m */,
|
||||
4C858A552130CBEC001B45D3 /* OWS110SortIdMigration.swift */,
|
||||
349EA07B2162AEA700F7B17F /* OWS111UDAttributesMigration.swift */,
|
||||
346129931FD1E30000532771 /* OWSDatabaseMigration.h */,
|
||||
346129941FD1E30000532771 /* OWSDatabaseMigration.m */,
|
||||
346129E51FD5C0C600532771 /* OWSDatabaseMigrationRunner.h */,
|
||||
|
@ -3254,6 +3258,7 @@
|
|||
34AC0A1E211B39EA00997B47 /* ThreadViewHelper.m in Sources */,
|
||||
34641E182088D7E900E2EDE5 /* OWSScreenLock.swift in Sources */,
|
||||
346129721FD1D74C00532771 /* SignalKeyingStorage.m in Sources */,
|
||||
349EA07C2162AEA800F7B17F /* OWS111UDAttributesMigration.swift in Sources */,
|
||||
34480B561FD0A7A400BC14EF /* DebugLogger.m in Sources */,
|
||||
459B775C207BA46C0071D0AB /* OWSQuotedReplyModel.m in Sources */,
|
||||
34ABB2C42090C59700C727A6 /* OWSResaveCollectionDBMigration.m in Sources */,
|
||||
|
|
|
@ -14,8 +14,6 @@ import SignalServiceKit
|
|||
public class AccountManager: NSObject {
|
||||
|
||||
let textSecureAccountManager: TSAccountManager
|
||||
let networkManager: TSNetworkManager
|
||||
let preferences: OWSPreferences
|
||||
|
||||
var pushManager: PushManager {
|
||||
// dependency injection hack since PushManager has *alot* of dependencies, and would induce a cycle.
|
||||
|
@ -23,16 +21,24 @@ public class AccountManager: NSObject {
|
|||
}
|
||||
|
||||
@objc
|
||||
public required init(textSecureAccountManager: TSAccountManager, preferences: OWSPreferences) {
|
||||
self.networkManager = textSecureAccountManager.networkManager
|
||||
public required init(textSecureAccountManager: TSAccountManager) {
|
||||
self.textSecureAccountManager = textSecureAccountManager
|
||||
self.preferences = preferences
|
||||
|
||||
super.init()
|
||||
|
||||
SwiftSingletons.register(self)
|
||||
}
|
||||
|
||||
// MARK: - Singletons
|
||||
|
||||
private var networkManager: TSNetworkManager {
|
||||
return SSKEnvironment.shared.networkManager
|
||||
}
|
||||
|
||||
private var preferences: OWSPreferences {
|
||||
return Environment.shared.preferences
|
||||
}
|
||||
|
||||
// MARK: registration
|
||||
|
||||
@objc func register(verificationCode: String,
|
||||
|
@ -108,9 +114,17 @@ public class AccountManager: NSObject {
|
|||
}
|
||||
|
||||
func registerForManualMessageFetching() -> Promise<Void> {
|
||||
return Promise { fulfill, reject in
|
||||
self.textSecureAccountManager.registerForManualMessageFetching(success: fulfill, failure: reject)
|
||||
}
|
||||
TSAccountManager.sharedInstance().setIsManualMessageFetchEnabled(true)
|
||||
|
||||
// Try to update the account attributes to reflect this change.
|
||||
let request = OWSRequestFactory.updateAttributesRequest()
|
||||
let promise: Promise<Void> = self.networkManager.makePromise(request: request)
|
||||
.then(execute: { (_, _) in
|
||||
Logger.info("updated server with account attributes to enableManualFetching")
|
||||
}).catch(execute: { (error) in
|
||||
Logger.error("failed to update server with account attributes with error: \(error)")
|
||||
})
|
||||
return promise
|
||||
}
|
||||
|
||||
// MARK: Turn Server
|
||||
|
@ -136,5 +150,4 @@ public class AccountManager: NSObject {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -63,8 +63,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
OWSAssertDebug(SSKEnvironment.shared.networkManager);
|
||||
OWSAssertDebug(SSKEnvironment.shared.contactsUpdater);
|
||||
|
||||
_accountManager = [[AccountManager alloc] initWithTextSecureAccountManager:[TSAccountManager sharedInstance]
|
||||
preferences:Environment.shared.preferences];
|
||||
_accountManager = [[AccountManager alloc] initWithTextSecureAccountManager:[TSAccountManager sharedInstance]];
|
||||
|
||||
_notificationsManager = [NotificationsManager new];
|
||||
SSKEnvironment.shared.notificationsManager = self.notificationsManager;
|
||||
|
|
|
@ -128,7 +128,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}
|
||||
}
|
||||
|
||||
#pragma mark Upgrading to 2.1.3 - Adding VOIP flag on TS Server
|
||||
#pragma mark - Update Account Attributes
|
||||
|
||||
+ (void)blockingAttributesUpdate
|
||||
{
|
||||
|
@ -139,7 +139,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
__block BOOL success;
|
||||
|
||||
TSRequest *request = [OWSRequestFactory updateAttributesRequestWithManualMessageFetching:NO];
|
||||
TSRequest *request = [OWSRequestFactory updateAttributesRequest];
|
||||
[[TSNetworkManager sharedManager] makeRequest:request
|
||||
success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
success = YES;
|
||||
|
|
|
@ -25,7 +25,7 @@ static NSString *const OWS103EnableVideoCallingMigrationId = @"103";
|
|||
OWSLogWarn(@"running migration...");
|
||||
if ([TSAccountManager isRegistered]) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
TSRequest *request = [OWSRequestFactory updateAttributesRequestWithManualMessageFetching:NO];
|
||||
TSRequest *request = [OWSRequestFactory updateAttributesRequest];
|
||||
[[TSNetworkManager sharedManager] makeRequest:request
|
||||
success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
OWSLogInfo(@"successfully ran");
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class OWS111UDAttributesMigration: OWSDatabaseMigration {
|
||||
|
||||
// MARK: - Singletons
|
||||
|
||||
private var networkManager: TSNetworkManager {
|
||||
return SSKEnvironment.shared.networkManager
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
// increment a similar constant for each migration.
|
||||
@objc
|
||||
class func migrationId() -> String {
|
||||
return "111"
|
||||
}
|
||||
|
||||
override public func runUp(completion: @escaping OWSDatabaseMigrationCompletion) {
|
||||
Logger.debug("")
|
||||
BenchAsync(title: "UD Attributes Migration") { completeBenchmark in
|
||||
self.doMigration {
|
||||
completeBenchmark()
|
||||
completion()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func doMigration(completion: @escaping OWSDatabaseMigrationCompletion) {
|
||||
let request = OWSRequestFactory.updateAttributesRequest()
|
||||
self.networkManager.makePromise(request: request).then(execute: { (_, _) in
|
||||
self.dbReadWriteConnection().readWrite { transaction in
|
||||
self.save(with: transaction)
|
||||
}
|
||||
})
|
||||
.always {
|
||||
completion()
|
||||
}.retainUntilComplete()
|
||||
}
|
||||
}
|
|
@ -45,6 +45,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[[OWS107LegacySounds alloc] initWithPrimaryStorage:primaryStorage],
|
||||
[[OWS108CallLoggingPreference alloc] initWithPrimaryStorage:primaryStorage],
|
||||
[[OWS109OutgoingMessageState alloc] initWithPrimaryStorage:primaryStorage]
|
||||
[[OWS111UDAttributesMigration alloc] initWithPrimaryStorage:primaryStorage],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -91,9 +91,6 @@ extern NSString *const kNSNotificationName_LocalNumberDidChange;
|
|||
success:(void (^)(void))successBlock
|
||||
failure:(void (^)(NSError *error))failureBlock;
|
||||
|
||||
- (void)registerForManualMessageFetchingWithSuccess:(void (^)(void))successBlock
|
||||
failure:(void (^)(NSError *error))failureBlock;
|
||||
|
||||
// Called once registration is complete - meaning the following have succeeded:
|
||||
// - obtained signal server credentials
|
||||
// - uploaded pre-keys
|
||||
|
@ -137,6 +134,11 @@ extern NSString *const kNSNotificationName_LocalNumberDidChange;
|
|||
- (NSString *)reregisterationPhoneNumber;
|
||||
- (BOOL)isReregistering;
|
||||
|
||||
#pragma mark - Manual Message Fetch
|
||||
|
||||
- (BOOL)isManualMessageFetchEnabled;
|
||||
- (void)setIsManualMessageFetchEnabled:(BOOL)value;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#import "OWSRequestFactory.h"
|
||||
#import "TSNetworkManager.h"
|
||||
#import "TSPreKeyManager.h"
|
||||
#import "TSVerifyCodeRequest.h"
|
||||
#import "YapDatabaseConnection+OWS.h"
|
||||
#import "YapDatabaseTransaction+OWS.h"
|
||||
#import <SignalCoreKit/NSData+OWS.h>
|
||||
|
@ -34,6 +33,7 @@ NSString *const TSAccountManager_LocalRegistrationIdKey = @"TSStorageLocalRegist
|
|||
NSString *const TSAccountManager_UserAccountCollection = @"TSStorageUserAccountCollection";
|
||||
NSString *const TSAccountManager_ServerAuthToken = @"TSStorageServerAuthToken";
|
||||
NSString *const TSAccountManager_ServerSignalingKey = @"TSStorageServerSignalingKey";
|
||||
NSString *const TSAccountManager_ManualMessageFetchKey = @"TSAccountManager_ManualMessageFetchKey";
|
||||
|
||||
@interface TSAccountManager ()
|
||||
|
||||
|
@ -327,21 +327,6 @@ NSString *const TSAccountManager_ServerSignalingKey = @"TSStorageServerSignaling
|
|||
[self registerWithPhoneNumber:number success:successBlock failure:failureBlock smsVerification:NO];
|
||||
}
|
||||
|
||||
- (void)registerForManualMessageFetchingWithSuccess:(void (^)(void))successBlock
|
||||
failure:(void (^)(NSError *error))failureBlock
|
||||
{
|
||||
TSRequest *request = [OWSRequestFactory updateAttributesRequestWithManualMessageFetching:YES];
|
||||
[self.networkManager makeRequest:request
|
||||
success:^(NSURLSessionDataTask *_Nonnull task, id _Nonnull responseObject) {
|
||||
OWSLogInfo(@"updated server with account attributes to enableManualFetching");
|
||||
successBlock();
|
||||
}
|
||||
failure:^(NSURLSessionDataTask *_Nonnull task, NSError *_Nonnull error) {
|
||||
OWSLogInfo(@"failed to updat server with account attributes with error: %@", error);
|
||||
failureBlock(error);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)verifyAccountWithCode:(NSString *)verificationCode
|
||||
pin:(nullable NSString *)pin
|
||||
success:(void (^)(void))successBlock
|
||||
|
@ -355,11 +340,11 @@ NSString *const TSAccountManager_ServerSignalingKey = @"TSStorageServerSignaling
|
|||
OWSAssertDebug(authToken);
|
||||
OWSAssertDebug(phoneNumber);
|
||||
|
||||
TSVerifyCodeRequest *request = [[TSVerifyCodeRequest alloc] initWithVerificationCode:verificationCode
|
||||
forNumber:phoneNumber
|
||||
pin:pin
|
||||
signalingKey:signalingKey
|
||||
authKey:authToken];
|
||||
TSRequest *request = [OWSRequestFactory verifyCodeRequestWithVerificationCode:verificationCode
|
||||
forNumber:phoneNumber
|
||||
pin:pin
|
||||
signalingKey:signalingKey
|
||||
authKey:authToken];
|
||||
|
||||
[self.networkManager makeRequest:request
|
||||
success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
|
@ -604,6 +589,20 @@ NSString *const TSAccountManager_ServerSignalingKey = @"TSStorageServerSignaling
|
|||
inCollection:TSAccountManager_UserAccountCollection];
|
||||
}
|
||||
|
||||
- (BOOL)isManualMessageFetchEnabled
|
||||
{
|
||||
return [self.dbConnection boolForKey:TSAccountManager_ManualMessageFetchKey
|
||||
inCollection:TSAccountManager_UserAccountCollection
|
||||
defaultValue:NO];
|
||||
}
|
||||
|
||||
- (void)setIsManualMessageFetchEnabled:(BOOL)value
|
||||
{
|
||||
[self.dbConnection setBool:value
|
||||
forKey:TSAccountManager_ManualMessageFetchKey
|
||||
inCollection:TSAccountManager_UserAccountCollection];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TSAttributes : NSObject
|
||||
|
||||
+ (NSDictionary *)attributesFromStorageWithManualMessageFetching:(BOOL)isEnabled pin:(nullable NSString *)pin;
|
||||
|
||||
+ (NSDictionary *)attributesWithSignalingKey:(NSString *)signalingKey
|
||||
serverAuthToken:(NSString *)authToken
|
||||
manualMessageFetching:(BOOL)isEnabled
|
||||
pin:(nullable NSString *)pin;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -1,45 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSAttributes.h"
|
||||
#import "TSAccountManager.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation TSAttributes
|
||||
|
||||
+ (NSDictionary *)attributesFromStorageWithManualMessageFetching:(BOOL)isEnabled pin:(nullable NSString *)pin
|
||||
{
|
||||
return [self attributesWithSignalingKey:TSAccountManager.signalingKey
|
||||
serverAuthToken:TSAccountManager.serverAuthToken
|
||||
manualMessageFetching:isEnabled
|
||||
pin:pin];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)attributesWithSignalingKey:(NSString *)signalingKey
|
||||
serverAuthToken:(NSString *)authToken
|
||||
manualMessageFetching:(BOOL)isEnabled
|
||||
pin:(nullable NSString *)pin
|
||||
{
|
||||
OWSAssertDebug(signalingKey.length > 0);
|
||||
OWSAssertDebug(authToken.length > 0);
|
||||
|
||||
NSMutableDictionary *result = [@{
|
||||
@"signalingKey" : signalingKey,
|
||||
@"AuthKey" : authToken,
|
||||
@"voice" : @(YES), // all Signal-iOS clients support voice
|
||||
@"video" : @(YES), // all Signal-iOS clients support WebRTC-based voice and video calls.
|
||||
@"fetchesMessages" :
|
||||
@(isEnabled), // devices that don't support push must tell the server they fetch messages manually
|
||||
@"registrationId" : [NSString stringWithFormat:@"%i", [TSAccountManager getOrGenerateRegistrationId]]
|
||||
} mutableCopy];
|
||||
if (pin.length > 0) {
|
||||
result[@"pin"] = pin;
|
||||
}
|
||||
return [result copy];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -26,10 +26,18 @@ public enum OWSUDError: Error {
|
|||
// No-op if this recipient id is already marked as _NOT_ a "UD recipient".
|
||||
@objc func removeUDRecipientId(_ recipientId: String)
|
||||
|
||||
// MARK: - Sender Certificate
|
||||
|
||||
// We use completion handlers instead of a promise so that message sending
|
||||
// logic can access the certificate data.
|
||||
@objc func ensureSenderCertificateObjC(success:@escaping (Data) -> Void,
|
||||
failure:@escaping (Error) -> Void)
|
||||
|
||||
// MARK: - Unrestricted Access
|
||||
|
||||
@objc func allowUnrestrictedAccess() -> Bool
|
||||
|
||||
@objc func setAllowUnrestrictedAccess(_ value: Bool)
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
@ -42,6 +50,7 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
|
|||
private let kUDRecipientModeCollection = "kUDRecipientModeCollection"
|
||||
private let kUDCollection = "kUDCollection"
|
||||
private let kUDCurrentSenderCertificateKey = "kUDCurrentSenderCertificateKey"
|
||||
private let kUDUnrestrictedAccessKey = "kUDUnrestrictedAccessKey"
|
||||
|
||||
@objc
|
||||
public required init(primaryStorage: OWSPrimaryStorage) {
|
||||
|
@ -166,4 +175,16 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
|
|||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Unrestricted Access
|
||||
|
||||
@objc
|
||||
public func allowUnrestrictedAccess() -> Bool {
|
||||
return dbConnection.bool(forKey: kUDUnrestrictedAccessKey, inCollection: kUDRecipientModeCollection, defaultValue: false)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func setAllowUnrestrictedAccess(_ value: Bool) {
|
||||
dbConnection.setBool(value, forKey: kUDUnrestrictedAccessKey, inCollection: kUDRecipientModeCollection)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ extension NetworkManagerError {
|
|||
}
|
||||
|
||||
extension TSNetworkManager {
|
||||
func makePromise(request: TSRequest) -> Promise<(task: URLSessionDataTask, responseObject: Any?)> {
|
||||
public func makePromise(request: TSRequest) -> Promise<(task: URLSessionDataTask, responseObject: Any?)> {
|
||||
let (promise, fulfill, reject) = Promise<(task: URLSessionDataTask, responseObject: Any?)>.pending()
|
||||
|
||||
self.makeRequest(request,
|
||||
|
|
|
@ -46,7 +46,7 @@ typedef NS_ENUM(NSUInteger, TSVerificationTransport) { TSVerificationTransportVo
|
|||
|
||||
+ (TSRequest *)registerForPushRequestWithPushIdentifier:(NSString *)identifier voipIdentifier:(NSString *)voipId;
|
||||
|
||||
+ (TSRequest *)updateAttributesRequestWithManualMessageFetching:(BOOL)enableManualMessageFetching;
|
||||
+ (TSRequest *)updateAttributesRequest;
|
||||
|
||||
+ (TSRequest *)unregisterAccountRequest;
|
||||
|
||||
|
@ -57,6 +57,12 @@ typedef NS_ENUM(NSUInteger, TSVerificationTransport) { TSVerificationTransportVo
|
|||
messages:(NSArray *)messages
|
||||
timeStamp:(uint64_t)timeStamp;
|
||||
|
||||
+ (TSRequest *)verifyCodeRequestWithVerificationCode:(NSString *)verificationCode
|
||||
forNumber:(NSString *)phoneNumber
|
||||
pin:(nullable NSString *)pin
|
||||
signalingKey:(NSString *)signalingKey
|
||||
authKey:(NSString *)authKey;
|
||||
|
||||
#pragma mark - Prekeys
|
||||
|
||||
+ (TSRequest *)availablePreKeysCountRequest;
|
||||
|
|
|
@ -5,13 +5,18 @@
|
|||
#import "OWSRequestFactory.h"
|
||||
#import "OWS2FAManager.h"
|
||||
#import "OWSDevice.h"
|
||||
#import "TSAttributes.h"
|
||||
#import "ProfileManagerProtocol.h"
|
||||
#import "SSKEnvironment.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSConstants.h"
|
||||
#import "TSRequest.h"
|
||||
#import <AxolotlKit/NSData+keyVersionByte.h>
|
||||
#import <AxolotlKit/SignedPreKeyRecord.h>
|
||||
#import <Curve25519Kit/Curve25519.h>
|
||||
#import <SignalCoreKit/Cryptography.h>
|
||||
#import <SignalCoreKit/NSData+OWS.h>
|
||||
#import <SignalMetadataKit/SignalMetadataKit-Swift.h>
|
||||
#import <SignalServiceKit/SignalServiceKit-Swift.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
@ -165,15 +170,20 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}];
|
||||
}
|
||||
|
||||
+ (TSRequest *)updateAttributesRequestWithManualMessageFetching:(BOOL)enableManualMessageFetching
|
||||
+ (TSRequest *)updateAttributesRequest
|
||||
{
|
||||
NSString *path = [textSecureAccountsAPI stringByAppendingString:textSecureAttributesAPI];
|
||||
|
||||
NSString *signalingKey = TSAccountManager.signalingKey;
|
||||
OWSAssertDebug(signalingKey.length > 0);
|
||||
NSString *authKey = TSAccountManager.serverAuthToken;
|
||||
OWSAssertDebug(authKey.length > 0);
|
||||
NSString *_Nullable pin = [OWS2FAManager.sharedManager pinCode];
|
||||
return [TSRequest
|
||||
requestWithUrl:[NSURL URLWithString:path]
|
||||
method:@"PUT"
|
||||
parameters:[TSAttributes attributesFromStorageWithManualMessageFetching:enableManualMessageFetching
|
||||
pin:pin]];
|
||||
|
||||
NSDictionary<NSString *, id> *accountAttributes =
|
||||
[self accountAttributesWithPin:pin signalingKey:signalingKey authKey:authKey];
|
||||
|
||||
return [TSRequest requestWithUrl:[NSURL URLWithString:path] method:@"PUT" parameters:accountAttributes];
|
||||
}
|
||||
|
||||
+ (TSRequest *)unregisterAccountRequest
|
||||
|
@ -205,6 +215,68 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}
|
||||
}
|
||||
|
||||
+ (TSRequest *)verifyCodeRequestWithVerificationCode:(NSString *)verificationCode
|
||||
forNumber:(NSString *)phoneNumber
|
||||
pin:(nullable NSString *)pin
|
||||
signalingKey:(NSString *)signalingKey
|
||||
authKey:(NSString *)authKey
|
||||
{
|
||||
OWSAssertDebug(verificationCode.length > 0);
|
||||
OWSAssertDebug(phoneNumber.length > 0);
|
||||
OWSAssertDebug(signalingKey.length > 0);
|
||||
OWSAssertDebug(authKey.length > 0);
|
||||
|
||||
NSString *path = [NSString stringWithFormat:@"%@/code/%@", textSecureAccountsAPI, verificationCode];
|
||||
|
||||
NSMutableDictionary<NSString *, id> *accountAttributes =
|
||||
[[self accountAttributesWithPin:pin signalingKey:signalingKey authKey:authKey] mutableCopy];
|
||||
[accountAttributes removeObjectForKey:@"AuthKey"];
|
||||
|
||||
TSRequest *request =
|
||||
[TSRequest requestWithUrl:[NSURL URLWithString:path] method:@"PUT" parameters:accountAttributes];
|
||||
// The "verify code" request handles auth differently.
|
||||
request.authUsername = phoneNumber;
|
||||
request.authPassword = authKey;
|
||||
return request;
|
||||
}
|
||||
|
||||
+ (NSDictionary<NSString *, id> *)accountAttributesWithPin:(nullable NSString *)pin
|
||||
signalingKey:(NSString *)signalingKey
|
||||
authKey:(NSString *)authKey
|
||||
{
|
||||
OWSAssertDebug(signalingKey.length > 0);
|
||||
OWSAssertDebug(authKey.length > 0);
|
||||
uint32_t registrationId = [TSAccountManager getOrGenerateRegistrationId];
|
||||
|
||||
BOOL isManualMessageFetchEnabled = TSAccountManager.sharedInstance.isManualMessageFetchEnabled;
|
||||
|
||||
OWSAES256Key *profileKey = [SSKEnvironment.shared.profileManager localProfileKey];
|
||||
NSError *error;
|
||||
SMKUDAccessKey *_Nullable udAccessKey = [[SMKUDAccessKey alloc] initWithProfileKey:profileKey.keyData error:&error];
|
||||
if (error || !udAccessKey) {
|
||||
OWSLogError(@"Could not determine UD access key: %@.", error);
|
||||
}
|
||||
BOOL allowUnrestrictedUD = [SSKEnvironment.shared.udManager allowUnrestrictedAccess] && udAccessKey != nil;
|
||||
|
||||
NSMutableDictionary *accountAttributes = [@{
|
||||
@"signalingKey" : signalingKey,
|
||||
@"AuthKey" : authKey,
|
||||
@"voice" : @(YES), // all Signal-iOS clients support voice
|
||||
@"video" : @(YES), // all Signal-iOS clients support WebRTC-based voice and video calls.
|
||||
@"fetchesMessages" : @(isManualMessageFetchEnabled), // devices that don't support push must tell the server
|
||||
// they fetch messages manually
|
||||
@"registrationId" : [NSString stringWithFormat:@"%i", registrationId],
|
||||
} mutableCopy];
|
||||
if (pin.length > 0) {
|
||||
accountAttributes[@"pin"] = pin;
|
||||
}
|
||||
if (udAccessKey.keyData.length > 0) {
|
||||
accountAttributes[@"unidentifiedAccessKey"] = udAccessKey.keyData.base64EncodedString;
|
||||
accountAttributes[@"unrestrictedUnidentifiedAccess"] = @(allowUnrestrictedUD);
|
||||
}
|
||||
return [accountAttributes copy];
|
||||
}
|
||||
|
||||
+ (TSRequest *)submitMessageRequestWithRecipient:(NSString *)recipientId
|
||||
messages:(NSArray *)messages
|
||||
timeStamp:(uint64_t)timeStamp
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSRequest.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TSVerifyCodeRequest : TSRequest
|
||||
|
||||
@property (nonatomic, readonly) NSString *numberToValidate;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
- (TSRequest *)initWithVerificationCode:(NSString *)verificationCode
|
||||
forNumber:(NSString *)phoneNumber
|
||||
pin:(nullable NSString *)pin
|
||||
signalingKey:(NSString *)signalingKey
|
||||
authKey:(NSString *)authKey;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSVerifyCodeRequest.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSAttributes.h"
|
||||
#import "TSConstants.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation TSVerifyCodeRequest
|
||||
|
||||
- (TSRequest *)initWithVerificationCode:(NSString *)verificationCode
|
||||
forNumber:(NSString *)phoneNumber
|
||||
pin:(nullable NSString *)pin
|
||||
signalingKey:(NSString *)signalingKey
|
||||
authKey:(NSString *)authKey
|
||||
{
|
||||
OWSAssertDebug(verificationCode.length > 0);
|
||||
OWSAssertDebug(phoneNumber.length > 0);
|
||||
OWSAssertDebug(signalingKey.length > 0);
|
||||
OWSAssertDebug(authKey.length > 0);
|
||||
|
||||
NSURL *url =
|
||||
[NSURL URLWithString:[NSString stringWithFormat:@"%@/code/%@", textSecureAccountsAPI, verificationCode]];
|
||||
NSDictionary *parameters =
|
||||
[TSAttributes attributesWithSignalingKey:signalingKey serverAuthToken:authKey manualMessageFetching:NO pin:pin];
|
||||
self = [super initWithURL:url method:@"PUT" parameters:parameters];
|
||||
|
||||
_numberToValidate = phoneNumber;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -9,7 +9,7 @@
|
|||
#import "OWSSignalService.h"
|
||||
#import "SSKEnvironment.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSVerifyCodeRequest.h"
|
||||
#import "TSRequest.h"
|
||||
#import <AFNetworking/AFNetworking.h>
|
||||
#import <SignalCoreKit/NSData+OWS.h>
|
||||
#import <SignalServiceKit/SignalServiceKit-Swift.h>
|
||||
|
@ -103,56 +103,43 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error);
|
|||
// session manager, so its safe to reconfigure it here.
|
||||
sessionManager.completionQueue = completionQueue;
|
||||
|
||||
if ([request isKindOfClass:[TSVerifyCodeRequest class]]) {
|
||||
// We plant the Authorization parameter ourselves, no need to double add.
|
||||
[sessionManager.requestSerializer
|
||||
setAuthorizationHeaderFieldWithUsername:((TSVerifyCodeRequest *)request).numberToValidate
|
||||
password:[request.parameters objectForKey:@"AuthKey"]];
|
||||
NSMutableDictionary *parameters = [request.parameters mutableCopy];
|
||||
[parameters removeObjectForKey:@"AuthKey"];
|
||||
[sessionManager PUT:request.URL.absoluteString parameters:parameters success:success failure:failure];
|
||||
if (request.shouldHaveAuthorizationHeaders) {
|
||||
[sessionManager.requestSerializer setAuthorizationHeaderFieldWithUsername:request.authUsername
|
||||
password:request.authPassword];
|
||||
}
|
||||
|
||||
// Honor the request's preferences about default cookie handling.
|
||||
//
|
||||
// Default is YES.
|
||||
sessionManager.requestSerializer.HTTPShouldHandleCookies = request.HTTPShouldHandleCookies;
|
||||
|
||||
// Honor the request's headers.
|
||||
for (NSString *headerField in request.allHTTPHeaderFields) {
|
||||
NSString *headerValue = request.allHTTPHeaderFields[headerField];
|
||||
[sessionManager.requestSerializer setValue:headerValue forHTTPHeaderField:headerField];
|
||||
}
|
||||
|
||||
if ([request.HTTPMethod isEqualToString:@"GET"]) {
|
||||
[sessionManager GET:request.URL.absoluteString
|
||||
parameters:request.parameters
|
||||
progress:nil
|
||||
success:success
|
||||
failure:failure];
|
||||
} else if ([request.HTTPMethod isEqualToString:@"POST"]) {
|
||||
[sessionManager POST:request.URL.absoluteString
|
||||
parameters:request.parameters
|
||||
progress:nil
|
||||
success:success
|
||||
failure:failure];
|
||||
} else if ([request.HTTPMethod isEqualToString:@"PUT"]) {
|
||||
[sessionManager PUT:request.URL.absoluteString parameters:request.parameters success:success failure:failure];
|
||||
} else if ([request.HTTPMethod isEqualToString:@"DELETE"]) {
|
||||
[sessionManager DELETE:request.URL.absoluteString
|
||||
parameters:request.parameters
|
||||
success:success
|
||||
failure:failure];
|
||||
} else {
|
||||
if (request.shouldHaveAuthorizationHeaders) {
|
||||
[sessionManager.requestSerializer setAuthorizationHeaderFieldWithUsername:request.authUsername
|
||||
password:request.authPassword];
|
||||
}
|
||||
|
||||
// Honor the request's preferences about default cookie handling.
|
||||
//
|
||||
// Default is YES.
|
||||
sessionManager.requestSerializer.HTTPShouldHandleCookies = request.HTTPShouldHandleCookies;
|
||||
|
||||
// Honor the request's headers.
|
||||
for (NSString *headerField in request.allHTTPHeaderFields) {
|
||||
NSString *headerValue = request.allHTTPHeaderFields[headerField];
|
||||
[sessionManager.requestSerializer setValue:headerValue forHTTPHeaderField:headerField];
|
||||
}
|
||||
|
||||
if ([request.HTTPMethod isEqualToString:@"GET"]) {
|
||||
[sessionManager GET:request.URL.absoluteString
|
||||
parameters:request.parameters
|
||||
progress:nil
|
||||
success:success
|
||||
failure:failure];
|
||||
} else if ([request.HTTPMethod isEqualToString:@"POST"]) {
|
||||
[sessionManager POST:request.URL.absoluteString
|
||||
parameters:request.parameters
|
||||
progress:nil
|
||||
success:success
|
||||
failure:failure];
|
||||
} else if ([request.HTTPMethod isEqualToString:@"PUT"]) {
|
||||
[sessionManager PUT:request.URL.absoluteString
|
||||
parameters:request.parameters
|
||||
success:success
|
||||
failure:failure];
|
||||
} else if ([request.HTTPMethod isEqualToString:@"DELETE"]) {
|
||||
[sessionManager DELETE:request.URL.absoluteString
|
||||
parameters:request.parameters
|
||||
success:success
|
||||
failure:failure];
|
||||
} else {
|
||||
OWSLogError(@"Trying to perform HTTP operation with unknown verb: %@", request.HTTPMethod);
|
||||
}
|
||||
OWSLogError(@"Trying to perform HTTP operation with unknown verb: %@", request.HTTPMethod);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,8 +191,14 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error);
|
|||
return ^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull networkError) {
|
||||
NSInteger statusCode = [task statusCode];
|
||||
|
||||
DDLogInfo(@"statusCode: %zd", statusCode);
|
||||
DDLogInfo(@"statusCode: %@", task.originalRequest.URL);
|
||||
DDLogInfo(@"allHTTPHeaderFields: %@", task.originalRequest.allHTTPHeaderFields);
|
||||
DDLogInfo(@"HTTPBody: %@", task.originalRequest.HTTPBody);
|
||||
DDLogInfo(@"parameters: %@", request.parameters);
|
||||
|
||||
#ifdef DEBUG
|
||||
[TSNetworkManager logCurlForTask:task];
|
||||
[TSNetworkManager logCurlForTask:task];
|
||||
#endif
|
||||
|
||||
[OutageDetection.sharedManager reportConnectionFailure];
|
||||
|
|
|
@ -43,6 +43,20 @@ public class OWSFakeUDManager: NSObject, OWSUDManager {
|
|||
}
|
||||
success(certificateData)
|
||||
}
|
||||
|
||||
// MARK: - Unrestricted Access
|
||||
|
||||
private var _allowUnrestrictedAccess = false
|
||||
|
||||
@objc
|
||||
public func allowUnrestrictedAccess() -> Bool {
|
||||
return _allowUnrestrictedAccess
|
||||
}
|
||||
|
||||
@objc
|
||||
public func setAllowUnrestrictedAccess(_ value: Bool) {
|
||||
_allowUnrestrictedAccess = value
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSAttributes.h"
|
||||
#import "SSKBaseTestObjC.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface TSAttributesTest : SSKBaseTestObjC
|
||||
|
||||
@end
|
||||
|
||||
@implementation TSAttributesTest
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testAttributesWithSignalingKey {
|
||||
|
||||
NSString *registrationId = [NSString stringWithFormat:@"%i", [TSAccountManager getOrGenerateRegistrationId]];
|
||||
NSDictionary *expected = @{
|
||||
@"AuthKey" : @"fake-server-auth-token",
|
||||
@"registrationId" : registrationId,
|
||||
@"signalingKey" : @"fake-signaling-key",
|
||||
@"video" : @1,
|
||||
@"voice" : @1
|
||||
};
|
||||
|
||||
NSDictionary *actual = [TSAttributes attributesWithSignalingKey:@"fake-signaling-key"
|
||||
serverAuthToken:@"fake-server-auth-token"
|
||||
manualMessageFetching:NO
|
||||
pin:nil];
|
||||
|
||||
XCTAssertEqualObjects(expected, actual);
|
||||
}
|
||||
|
||||
@end
|
Loading…
Reference in New Issue