mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
e4ad169d71
// FREEBIE
209 lines
9.8 KiB
Objective-C
209 lines
9.8 KiB
Objective-C
//
|
|
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
#import "OWSLinkDeviceViewController.h"
|
|
#import "Cryptography.h"
|
|
#import "OWSDeviceProvisioningURLParser.h"
|
|
#import "OWSLinkedDevicesTableViewController.h"
|
|
#import "OWSProfileManager.h"
|
|
#import "Signal-Swift.h"
|
|
#import <SignalServiceKit/ECKeyPair+OWSPrivateKey.h>
|
|
#import <SignalServiceKit/OWSDeviceProvisioner.h>
|
|
#import <SignalServiceKit/OWSIdentityManager.h>
|
|
#import <SignalServiceKit/OWSReadReceiptManager.h>
|
|
#import <SignalServiceKit/TSAccountManager.h>
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
@interface OWSLinkDeviceViewController ()
|
|
|
|
@property (strong, nonatomic) IBOutlet UIView *qrScanningView;
|
|
@property (strong, nonatomic) IBOutlet UILabel *scanningInstructionsLabel;
|
|
@property (strong, nonatomic) OWSQRCodeScanningViewController *qrScanningController;
|
|
@property (nonatomic, readonly) OWSReadReceiptManager *readReceiptManager;
|
|
|
|
@end
|
|
|
|
@implementation OWSLinkDeviceViewController
|
|
|
|
- (void)viewDidLoad
|
|
{
|
|
[super viewDidLoad];
|
|
|
|
// HACK to get full width preview layer
|
|
CGRect oldFrame = self.qrScanningView.frame;
|
|
self.qrScanningView.frame = CGRectMake(
|
|
oldFrame.origin.x, oldFrame.origin.y, self.view.frame.size.width, self.view.frame.size.height / 2.0f - 32.0f);
|
|
// END HACK to get full width preview layer
|
|
|
|
self.scanningInstructionsLabel.text = NSLocalizedString(@"LINK_DEVICE_SCANNING_INSTRUCTIONS",
|
|
@"QR Scanning screen instructions, placed alongside a camera view for scanning QRCodes");
|
|
self.title
|
|
= NSLocalizedString(@"LINK_NEW_DEVICE_TITLE", "Navigation title when scanning QR code to add new device.");
|
|
}
|
|
|
|
- (OWSProfileManager *)profileManager
|
|
{
|
|
return [OWSProfileManager sharedManager];
|
|
}
|
|
|
|
- (OWSReadReceiptManager *)readReceiptManager
|
|
{
|
|
return [OWSReadReceiptManager sharedManager];
|
|
}
|
|
|
|
- (void)viewWillAppear:(BOOL)animated
|
|
{
|
|
[super viewWillAppear:animated];
|
|
}
|
|
|
|
- (void)viewDidAppear:(BOOL)animated
|
|
{
|
|
[super viewDidAppear:animated];
|
|
[self.qrScanningController startCapture];
|
|
}
|
|
|
|
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(nullable id)sender
|
|
{
|
|
if ([segue.identifier isEqualToString:@"embedDeviceQRScanner"]) {
|
|
OWSQRCodeScanningViewController *qrScanningController
|
|
= (OWSQRCodeScanningViewController *)segue.destinationViewController;
|
|
qrScanningController.scanDelegate = self;
|
|
self.qrScanningController = qrScanningController;
|
|
}
|
|
}
|
|
|
|
|
|
// pragma mark - OWSQRScannerDelegate
|
|
- (void)controller:(OWSQRCodeScanningViewController *)controller didDetectQRCodeWithString:(NSString *)string
|
|
{
|
|
OWSDeviceProvisioningURLParser *parser = [[OWSDeviceProvisioningURLParser alloc] initWithProvisioningURL:string];
|
|
if (!parser.isValid) {
|
|
DDLogError(@"Unable to parse provisioning params from QRCode: %@", string);
|
|
|
|
NSString* title = NSLocalizedString(@"LINK_DEVICE_INVALID_CODE_TITLE", @"report an invalid linking code");
|
|
NSString* body = NSLocalizedString(@"LINK_DEVICE_INVALID_CODE_BODY", @"report an invalid linking code");
|
|
|
|
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
|
|
message:body
|
|
preferredStyle:UIAlertControllerStyleAlert];
|
|
|
|
UIAlertAction *cancelAction =
|
|
[UIAlertAction actionWithTitle:CommonStrings.cancelButton
|
|
style:UIAlertActionStyleCancel
|
|
handler:^(UIAlertAction *action) {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[self.navigationController popViewControllerAnimated:YES];
|
|
});
|
|
}];
|
|
[alertController addAction:cancelAction];
|
|
|
|
UIAlertAction *proceedAction =
|
|
[UIAlertAction actionWithTitle:NSLocalizedString(@"LINK_DEVICE_RESTART", @"attempt another linking")
|
|
style:UIAlertActionStyleDefault
|
|
handler:^(UIAlertAction *action) {
|
|
[self.qrScanningController startCapture];
|
|
}];
|
|
[alertController addAction:proceedAction];
|
|
|
|
[self presentViewController:alertController animated:YES completion:nil];
|
|
} else {
|
|
NSString *title
|
|
= NSLocalizedString(@"LINK_DEVICE_PERMISSION_ALERT_TITLE", @"confirm the users intent to link a new device");
|
|
NSString *linkingDescription
|
|
= NSLocalizedString(@"LINK_DEVICE_PERMISSION_ALERT_BODY", @"confirm the users intent to link a new device");
|
|
|
|
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
|
|
message:linkingDescription
|
|
preferredStyle:UIAlertControllerStyleAlert];
|
|
|
|
UIAlertAction *cancelAction =
|
|
[UIAlertAction actionWithTitle:CommonStrings.cancelButton
|
|
style:UIAlertActionStyleCancel
|
|
handler:^(UIAlertAction *action) {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[self.navigationController popViewControllerAnimated:YES];
|
|
});
|
|
}];
|
|
[alertController addAction:cancelAction];
|
|
|
|
UIAlertAction *proceedAction =
|
|
[UIAlertAction actionWithTitle:NSLocalizedString(@"CONFIRM_LINK_NEW_DEVICE_ACTION", @"Button text")
|
|
style:UIAlertActionStyleDefault
|
|
handler:^(UIAlertAction *action) {
|
|
[self provisionWithParser:parser];
|
|
}];
|
|
[alertController addAction:proceedAction];
|
|
|
|
[self presentViewController:alertController animated:YES completion:nil];
|
|
}
|
|
}
|
|
|
|
- (void)provisionWithParser:(OWSDeviceProvisioningURLParser *)parser
|
|
{
|
|
ECKeyPair *_Nullable identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPair];
|
|
OWSAssert(identityKeyPair);
|
|
NSData *myPublicKey = identityKeyPair.publicKey;
|
|
NSData *myPrivateKey = identityKeyPair.ows_privateKey;
|
|
NSString *accountIdentifier = [TSAccountManager localNumber];
|
|
NSData *myProfileKeyData = self.profileManager.localProfileKey.keyData;
|
|
BOOL areReadReceiptsEnabled = self.readReceiptManager.areReadReceiptsEnabled;
|
|
|
|
OWSDeviceProvisioner *provisioner = [[OWSDeviceProvisioner alloc] initWithMyPublicKey:myPublicKey
|
|
myPrivateKey:myPrivateKey
|
|
theirPublicKey:parser.publicKey
|
|
theirEphemeralDeviceId:parser.ephemeralDeviceId
|
|
accountIdentifier:accountIdentifier
|
|
profileKey:myProfileKeyData
|
|
readReceiptsEnabled:areReadReceiptsEnabled];
|
|
|
|
[provisioner provisionWithSuccess:^{
|
|
DDLogInfo(@"Successfully provisioned device.");
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[self.linkedDevicesTableViewController expectMoreDevices];
|
|
[self.navigationController popToViewController:self.linkedDevicesTableViewController animated:YES];
|
|
});
|
|
}
|
|
failure:^(NSError *error) {
|
|
DDLogError(@"Failed to provision device with error: %@", error);
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[self presentViewController:[self retryAlertControllerWithError:error
|
|
retryBlock:^{
|
|
[self provisionWithParser:parser];
|
|
}]
|
|
animated:YES
|
|
completion:nil];
|
|
});
|
|
}];
|
|
}
|
|
|
|
- (UIAlertController *)retryAlertControllerWithError:(NSError *)error retryBlock:(void (^)())retryBlock
|
|
{
|
|
NSString *title = NSLocalizedString(@"LINKING_DEVICE_FAILED_TITLE", @"Alert Title");
|
|
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
|
|
message:error.localizedDescription
|
|
preferredStyle:UIAlertControllerStyleAlert];
|
|
|
|
UIAlertAction *retryAction = [UIAlertAction actionWithTitle:[CommonStrings retryButton]
|
|
style:UIAlertActionStyleDefault
|
|
handler:^(UIAlertAction *action) {
|
|
retryBlock();
|
|
}];
|
|
[alertController addAction:retryAction];
|
|
|
|
UIAlertAction *cancelAction =
|
|
[UIAlertAction actionWithTitle:CommonStrings.cancelButton
|
|
style:UIAlertActionStyleCancel
|
|
handler:^(UIAlertAction *action) {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[self dismissViewControllerAnimated:YES completion:nil];
|
|
});
|
|
}];
|
|
[alertController addAction:cancelAction];
|
|
return alertController;
|
|
}
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|