Create DeviceLinkingMessage

This commit is contained in:
Niels Andriesse 2019-09-24 14:20:22 +10:00
parent 395d167f56
commit 0bb6721768
18 changed files with 105 additions and 46 deletions

View File

@ -576,7 +576,7 @@
B891105C2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; };
B891105E2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; };
B891105F2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; };
B89841E322B7579F00B1BDC6 /* NewConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */; };
B89841E322B7579F00B1BDC6 /* NewConversationVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89841E222B7579F00B1BDC6 /* NewConversationVC.swift */; };
B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; };
B9EB5ABD1884C002007CBB57 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EB5ABC1884C002007CBB57 /* MessageUI.framework */; };
BFF3FB9730634F37D25903F4 /* Pods_Signal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D17BB5C25D615AB49813100C /* Pods_Signal.framework */; };
@ -1382,7 +1382,7 @@
B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceLinkingModal.swift; sourceTree = "<group>"; };
B885D5F52334A32100EE0D8E /* UIView+Constraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Constraint.swift"; sourceTree = "<group>"; };
B891105B2320872800F15FCC /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationViewController.swift; sourceTree = "<group>"; };
B89841E222B7579F00B1BDC6 /* NewConversationVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationVC.swift; sourceTree = "<group>"; };
B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = "<group>"; };
B90418E5183E9DD40038554A /* DateUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DateUtil.m; sourceTree = "<group>"; };
B97940251832BD2400BD66CB /* UIUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIUtil.h; sourceTree = "<group>"; };
@ -2646,7 +2646,7 @@
B8162F0222891AD600D46544 /* FriendRequestView.swift */,
B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */,
24A830A12293CD0100F4CAC0 /* LokiP2PServer.swift */,
B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */,
B89841E222B7579F00B1BDC6 /* NewConversationVC.swift */,
B8258491230FA5DA001B41CB /* ScanQRCodeViewController.h */,
B8258492230FA5E9001B41CB /* ScanQRCodeViewController.m */,
);
@ -3859,7 +3859,7 @@
45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */,
34B3F8771E8DF1700035BE1A /* ContactsPicker.swift in Sources */,
45C0DC1B1E68FE9000E04C47 /* UIApplication+OWS.swift in Sources */,
B89841E322B7579F00B1BDC6 /* NewConversationViewController.swift in Sources */,
B89841E322B7579F00B1BDC6 /* NewConversationVC.swift in Sources */,
45FBC5C81DF8575700E9B410 /* CallKitCallManager.swift in Sources */,
4539B5861F79348F007141FF /* PushRegistrationManager.swift in Sources */,
45FBC5D11DF8592E00E9B410 /* SignalCall.swift in Sources */,

View File

@ -28,7 +28,7 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BF1AA1A1F4180E0BF6CA9FD699844BF7"
BlueprintIdentifier = "51E5126436E74C817013DE9DE3C88131"
BuildableName = "SignalServiceKit.framework"
BlueprintName = "SignalServiceKit"
ReferencedContainer = "container:Pods/Pods.xcodeproj">
@ -41,6 +41,22 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "NO">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D221A088169C9E5E00537ABF"
BuildableName = "Loki Messenger.app"
BlueprintName = "Signal"
ReferencedContainer = "container:Signal.xcodeproj">
</BuildableReference>
</MacroExpansion>
<EnvironmentVariables>
<EnvironmentVariable
key = "runningTests_dontStartApp"
value = "YES"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<Testables>
<TestableReference
skipped = "NO">
@ -113,24 +129,6 @@
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D221A088169C9E5E00537ABF"
BuildableName = "Loki Messenger.app"
BlueprintName = "Signal"
ReferencedContainer = "container:Signal.xcodeproj">
</BuildableReference>
</MacroExpansion>
<EnvironmentVariables>
<EnvironmentVariable
key = "runningTests_dontStartApp"
value = "YES"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@ -144,6 +142,7 @@
debugDocumentVersioning = "YES"
stopOnEveryThreadSanitizerIssue = "YES"
stopOnEveryUBSanitizerIssue = "YES"
migratedStopOnEveryIssue = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
showNonLocalizedStrings = "YES">
@ -179,8 +178,6 @@
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "App Store Release"

View File

@ -1,6 +1,6 @@
@objc(LKNewConversationViewController)
final class NewConversationViewController : OWSViewController, OWSQRScannerDelegate {
@objc(LKNewConversationVC)
final class NewConversationVC : OWSViewController, OWSQRScannerDelegate {
// MARK: Components
private lazy var publicKeyTextField: UITextField = {

View File

@ -315,8 +315,8 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
}
case .link:
seed = self.seed
let hexEncodedPublicKey = masterHexEncodedPublicKeyTextField.text!.trimmingCharacters(in: CharacterSet.whitespaces)
if !ECKeyPair.isValidHexEncodedPublicKey(candidate: hexEncodedPublicKey) {
let masterHexEncodedPublicKey = masterHexEncodedPublicKeyTextField.text!.trimmingCharacters(in: CharacterSet.whitespaces)
if !ECKeyPair.isValidHexEncodedPublicKey(candidate: masterHexEncodedPublicKey) {
errorLabel2Spacer.isHidden = false
return errorLabel2.text = NSLocalizedString("Invalid public key", comment: "")
}
@ -337,15 +337,18 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
case .link: Analytics.shared.track("Device Linked")
}
if mode == .link {
let masterHexEncodedPublicKey = masterHexEncodedPublicKeyTextField.text!.trimmingCharacters(in: CharacterSet.whitespaces)
let deviceLinkingModal = DeviceLinkingModal(mode: .slave, delegate: self)
deviceLinkingModal.modalPresentationStyle = .overFullScreen
present(deviceLinkingModal, animated: true, completion: nil)
let thread = TSContactThread.getOrCreateThread(contactId: masterHexEncodedPublicKey)
ThreadUtil.enqueueDeviceLinkingMessage(in: thread)
} else {
onboardingController.pushDisplayNameVC(from: self)
}
}
func handleDeviceLinked() {
func handleDeviceLinkingRequestAuthorized() {
TSAccountManager.sharedInstance().didRegister()
UserDefaults.standard.set(true, forKey: "didUpdateForMainnet")
onboardingController.verificationDidComplete(fromView: self)

View File

@ -122,8 +122,8 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
@objc private func authorizeDeviceLink() {
let deviceLink = self.deviceLink!
let session = DeviceLinkingSession.current!
session.authorizeDeviceLink(deviceLink)
session.stopListeningForLinkingRequests()
// TODO: Send device link authorized message
dismiss(animated: true, completion: nil)
}
}

View File

@ -2,5 +2,6 @@
@objc(LKDeviceLinkingModalDelegate)
protocol DeviceLinkingModalDelegate {
func handleDeviceLinked()
/// Provides an opportunity for the slave device to update its UI after the master device has authorized the device linking request.
func handleDeviceLinkingRequestAuthorized()
}

View File

@ -91,6 +91,7 @@
#import <SignalServiceKit/OWSDispatch.h>
#import <SignalServiceKit/OWSEndSessionMessage.h>
#import <SignalServiceKit/LKEphemeralMessage.h>
#import <SignalServiceKit/LKDeviceLinkingMessage.h>
#import <SignalServiceKit/OWSError.h>
#import <SignalServiceKit/OWSFileSystem.h>
#import <SignalServiceKit/LKFriendRequestMessage.h>

View File

@ -4348,7 +4348,7 @@ typedef enum : NSUInteger {
// Update the thread's friend request status
[self.thread saveFriendRequestStatus:LKThreadFriendRequestStatusFriends withTransaction:nil];
// Send a friend request accepted message
[ThreadUtil enqueueAcceptFriendRequestMessageInThread:self.thread];
[ThreadUtil enqueueFriendRequestAcceptanceMessageInThread:self.thread];
}
- (void)declineFriendRequest:(TSIncomingMessage *)friendRequest

View File

@ -835,8 +835,8 @@ typedef NS_ENUM(NSInteger, HomeViewControllerSection) {
- (void)showNewConversationView
{
LKNewConversationViewController *viewController = [LKNewConversationViewController new];
OWSNavigationController *navigationController = [[OWSNavigationController alloc] initWithRootViewController:viewController];
LKNewConversationVC *newConversationVC = [LKNewConversationVC new];
OWSNavigationController *navigationController = [[OWSNavigationController alloc] initWithRootViewController:newConversationVC];
[self.navigationController presentViewController:navigationController animated:YES completion:nil];
/**

View File

@ -4,6 +4,7 @@
import UIKit
import PromiseKit
import Contacts
@objc
public class OnboardingPermissionsViewController: OnboardingBaseViewController {

View File

@ -44,7 +44,8 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Durable Message Enqueue
+ (TSOutgoingMessage *)enqueueAcceptFriendRequestMessageInThread:(TSThread *)thread;
+ (TSOutgoingMessage *)enqueueFriendRequestAcceptanceMessageInThread:(TSThread *)thread;
+ (TSOutgoingMessage *)enqueueDeviceLinkingMessageInThread:(TSThread *)thread;
+ (TSOutgoingMessage *)enqueueMessageWithText:(NSString *)fullMessageText
inThread:(TSThread *)thread

View File

@ -85,13 +85,22 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess
#pragma mark - Durable Message Enqueue
+ (LKEphemeralMessage *)enqueueAcceptFriendRequestMessageInThread:(TSThread *)thread
+ (LKEphemeralMessage *)enqueueFriendRequestAcceptanceMessageInThread:(TSThread *)thread
{
LKEphemeralMessage *emptyMessage = [[LKEphemeralMessage alloc] initInThread:thread];
LKEphemeralMessage *message = [[LKEphemeralMessage alloc] initInThread:thread];
[self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self.messageSenderJobQueue addMessage:emptyMessage transaction:transaction];
[self.messageSenderJobQueue addMessage:message transaction:transaction];
}];
return emptyMessage;
return message;
}
+ (LKDeviceLinkingMessage *)enqueueDeviceLinkingMessageInThread:(TSThread *)thread
{
LKDeviceLinkingMessage *message = [[LKDeviceLinkingMessage alloc] initInThread:thread];
[self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self.messageSenderJobQueue addMessage:message transaction:transaction];
}];
return message;
}
+ (TSOutgoingMessage *)enqueueMessageWithText:(NSString *)fullMessageText

View File

@ -36,10 +36,6 @@ public final class DeviceLinkingSession : NSObject {
isListeningForLinkingRequests = false
}
public func authorizeDeviceLink(_ deviceLink: DeviceLink) {
// TODO: Send a device link authorized message
}
// MARK: Private API
private func isValidLinkingRequest(_ deviceLink: DeviceLink) -> Bool {
// When requesting a device link, the slave device signs the master device's public key. When authorizing

View File

@ -0,0 +1,8 @@
#import "TSOutgoingMessage.h"
NS_SWIFT_NAME(DeviceLinkingMessage)
@interface LKDeviceLinkingMessage : TSOutgoingMessage
- (instancetype)initInThread:(TSThread *)thread;
@end

View File

@ -0,0 +1,40 @@
#import "LKDeviceLinkingMessage.h"
#import "OWSIdentityManager.h"
#import "SignalRecipient.h"
#import <SignalCoreKit/NSData+OWS.h>
#import <SignalCoreKit/NSDate+OWS.h>
#import <SignalServiceKit/SignalServiceKit-Swift.h>
@implementation LKDeviceLinkingMessage
- (instancetype)initInThread:(nullable TSThread *)thread {
return [self initOutgoingMessageWithTimestamp:NSDate.ows_millisecondTimeStamp inThread:thread messageBody:@"" attachmentIds:[NSMutableArray<NSString *> new]
expiresInSeconds:0 expireStartedAt:0 isVoiceMessage:NO groupMetaMessage:TSGroupMetaMessageUnspecified quotedMessage:nil contactShare:nil linkPreview:nil];
}
- (SSKProtoContentBuilder *)contentBuilder:(SignalRecipient *)recipient {
SSKProtoContentBuilder *contentBuilder = [super contentBuilder:recipient];
// When authorizing a device link, the master device signs the slave device's public key. When requesting
// a device link, the slave device signs the master device's public key.
SSKProtoLokiDeviceLinkingMessageBuilder *deviceLinkingMessageBuilder = [SSKProtoLokiDeviceLinkingMessage builder];
NSString *masterHexEncodedPublicKey = recipient.recipientId;
NSData *masterPublicKey = [NSData dataFromHexString:masterHexEncodedPublicKey];
[deviceLinkingMessageBuilder setMasterHexEncodedPublicKey:masterHexEncodedPublicKey];
ECKeyPair *slaveKeyPair = OWSIdentityManager.sharedManager.identityKeyPair;
NSString *slaveHexEncodedPublicKey = slaveKeyPair.hexEncodedPublicKey;
[deviceLinkingMessageBuilder setSlaveHexEncodedPublicKey:slaveHexEncodedPublicKey];
NSData *slaveSignature = [Ed25519 sign:masterPublicKey withKeyPair:slaveKeyPair error:nil];
[deviceLinkingMessageBuilder setSlaveSignature:slaveSignature];
NSError *error;
SSKProtoLokiDeviceLinkingMessage *deviceLinkingMessage = [deviceLinkingMessageBuilder buildAndReturnError:&error];
if (error || deviceLinkingMessage == nil) {
OWSFailDebug(@"Failed to build device linking message for: %@ due to error: %@", masterHexEncodedPublicKey, error);
}
[contentBuilder setLokiDeviceLinkingMessage:deviceLinkingMessage];
return contentBuilder;
}
- (BOOL)shouldSyncTranscript { return NO; }
- (BOOL)shouldBeSaved { return NO; }
@end

View File

@ -1103,12 +1103,12 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
[ProtoUtils addLocalProfileKeyIfNecessary:self.thread recipientId:recipientId dataMessageBuilder:builder];
// Loki: Set display name if needed
id<ProfileManagerProtocol> profileManager = SSKEnvironment.shared.profileManager;
NSString *displayName = profileManager.localProfileName;
if (displayName != nil) {
SSKProtoDataMessageLokiProfileBuilder *profileBuilder = [SSKProtoDataMessageLokiProfile builder];
[profileBuilder setDisplayName:displayName];
SSKProtoDataMessageLokiProfile *profile = [profileBuilder buildAndReturnError:nil];
[builder setProfile:profile];
}

View File

@ -20,6 +20,7 @@
#import "OWSDisappearingMessagesConfiguration.h"
#import "OWSDisappearingMessagesJob.h"
#import "LKEphemeralMessage.h"
#import "LKDeviceLinkingMessage.h"
#import "OWSIdentityManager.h"
#import "OWSIncomingMessageFinder.h"
#import "OWSIncomingSentMessageTranscript.h"
@ -1546,7 +1547,7 @@ NS_ASSUME_NONNULL_BEGIN
if (existingFriendRequestMessage != nil && existingFriendRequestMessage.isFriendRequest) {
[existingFriendRequestMessage saveFriendRequestStatus:LKMessageFriendRequestStatusAccepted withTransaction:transaction];
}
// The two lines below are equivalent to calling [ThreadUtil enqueueAcceptFriendRequestMessageInThread:thread]
// The two lines below are equivalent to calling [ThreadUtil enqueueFriendRequestAcceptanceMessageInThread:thread]
LKEphemeralMessage *backgroundMessage = [[LKEphemeralMessage alloc] initInThread:thread];
[self.messageSenderJobQueue addMessage:backgroundMessage transaction:transaction];
} else if (!thread.isContactFriend) {

View File

@ -1,6 +1,7 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import Contacts
@objc(OWSFakeContactsManager)
public class FakeContactsManager: NSObject, ContactsManagerProtocol {