ChatSecure-iOS/ChatSecure/Classes/View Controllers/OTRNewBuddyViewController.m

302 lines
10 KiB
Objective-C

//
// OTRNewBuddyViewController.m
// Off the Record
//
// Created by David on 3/4/13.
// Copyright (c) 2013 Chris Ballinger. All rights reserved.
//
#import "OTRNewBuddyViewController.h"
#import "OTRInLineTextEditTableViewCell.h"
#import "OTRProtocolManager.h"
@import QuartzCore;
@import OTRAssets;
#import "OTRXMPPManager.h"
#import "OTRDatabaseManager.h"
#import "OTRAccount.h"
#import "OTRBuddy.h"
#import "OTRXMPPAccount.h"
#import "OTRXMPPBuddy.h"
@import QRCodeReaderViewController;
@import XMPPFramework;
#import "NSURL+ChatSecure.h"
#import "ChatSecureCoreCompat-Swift.h"
@interface OTRNewBuddyViewController () <QRCodeReaderDelegate>
@property (nonatomic) BOOL isXMPPaccount;
@end
@implementation OTRNewBuddyViewController
-(id)initWithAccountId:(NSString *)accountId {
if (self = [super init]) {
[[OTRDatabaseManager sharedInstance].uiConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
self.account = [OTRAccount fetchObjectWithUniqueID:accountId transaction:transaction];
}];
}
return self;
}
-(void)setAccount:(OTRAccount *)account
{
self.isXMPPaccount = [[account protocolClass] isSubclassOfClass:[OTRXMPPManager class]];
_account = account;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section == 0) {
return self.account.username;
}
return @"";
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = ADD_BUDDY_STRING();
//self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelButtonPressed:)];
UIBarButtonItem *qrButton = [[UIBarButtonItem alloc] initWithTitle:QR_CODE_STRING() style:UIBarButtonItemStylePlain target:self action:@selector(qrButtonPressed:)];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(doneButtonPressed:)];
self.navigationItem.rightBarButtonItems = @[doneButton, qrButton];
self.accountNameTextField = [[UITextField alloc] initWithFrame:CGRectZero];
self.accountNameTextField.placeholder = XMPP_USERNAME_EXAMPLE_STRING();
if (self.isXMPPaccount) {
self.displayNameTextField = [[UITextField alloc] initWithFrame:CGRectZero];
self.displayNameTextField.placeholder = OPTIONAL_STRING();
self.accountNameTextField.delegate= self.displayNameTextField.delegate = self;
self.displayNameTextField.autocapitalizationType = self.accountNameTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;
self.displayNameTextField.autocorrectionType = self.accountNameTextField.autocorrectionType = UITextAutocorrectionTypeNo;
}
if (self.storyboard == nil) {
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
}
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.scrollEnabled = NO;
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
if (self.storyboard == nil) {
[self.view addSubview:self.tableView];
}
[self.accountNameTextField becomeFirstResponder];
// Do any additional setup after loading the view.
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.isXMPPaccount) {
return 2;
}
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * cellType = @"Cell";
UITextField * textField = nil;
NSString * cellText = nil;
if (indexPath.row == 0) {
textField = self.accountNameTextField;
cellText = USERNAME_STRING();
}
else if(indexPath.row == 1) {
textField = self.displayNameTextField;
cellText = NAME_STRING();
}
OTRInLineTextEditTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellType];
if (!cell) {
cell = [[OTRInLineTextEditTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellType];
}
cell.textLabel.text = cellText;
[cell layoutIfNeeded];
cell.textField = textField;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
-(BOOL)checkFields
{
if ([[self.accountNameTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]) {
return YES;
}
else
{
return NO;
}
}
-(void)updateReturnButtons:(UITextField *)textField;
{
if ([self checkFields] && [[self.accountNameTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] &&[[self.displayNameTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]) {
textField.returnKeyType = UIReturnKeyDone;
}
else if ([textField isEqual:self.accountNameTextField]) {
textField.returnKeyType = UIReturnKeyNext;
}
else if ([textField isEqual:self.displayNameTextField] && ![self checkFields])
{
textField.returnKeyType = UIReturnKeyNext;
}
else
{
textField.returnKeyType = UIReturnKeyDone;
}
}
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
[self updateReturnButtons:textField];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField.returnKeyType == UIReturnKeyDone ) {
[textField resignFirstResponder];
[self doneButtonPressed:textField];
}
else{
[textField resignFirstResponder];
if ([textField isEqual:self.accountNameTextField]) {
[self.displayNameTextField becomeFirstResponder];
}
else{
[self.accountNameTextField becomeFirstResponder];
}
}
return NO;
}
-(void)cancelButtonPressed:(id)sender
{
[self dismissViewController];
}
-(IBAction)doneButtonPressed:(id)sender
{
if ([self checkFields]) {
NSString * newBuddyAccountName = [[self.accountNameTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] lowercaseString];
NSString * newBuddyDisplayName = [self.displayNameTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
XMPPJID *jid = [XMPPJID jidWithString:newBuddyAccountName];
if (!jid) { return; }
OTRXMPPManager *manager = (OTRXMPPManager *)[[OTRProtocolManager sharedInstance] protocolForAccount:self.account];
OTRXMPPBuddy *buddy = [manager addToRosterWithJID:jid displayName:newBuddyDisplayName];
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(controller:didAddBuddy:)]) {
[self.delegate controller:self didAddBuddy:buddy];
}
[self dismissViewController];
}
else
{
[UIView animateWithDuration:.3 animations:^{
self.accountNameTextField.backgroundColor = [UIColor colorWithRed: 0.734 green: 0.124 blue: 0.124 alpha: .8];
} completion:^(BOOL finished) {
[UIView animateWithDuration:.3 animations:^{
self.accountNameTextField.backgroundColor = [UIColor clearColor];
} completion:NULL];
}];
}
}
- (void)dismissViewController {
if (self.delegate == nil || ([self.delegate respondsToSelector:@selector(shouldDismissViewController:)] && [self.delegate shouldDismissViewController:self])) {
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
}
- (void) qrButtonPressed:(id)sender {
if (![QRCodeReader supportsMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]]) {
return;
}
QRCodeReaderViewController *reader = [[QRCodeReaderViewController alloc] init];
reader.modalPresentationStyle = UIModalPresentationFormSheet;
reader.delegate = self;
[self presentViewController:reader animated:YES completion:NULL];
}
- (void)populateFromQRResult:(NSString *)result
{
NSURL *resultURL = [NSURL URLWithString:result];
if ([result containsString:@"xmpp:"]) {
XMPPURI *uri = [[XMPPURI alloc] initWithURIString:result];
NSString *jid = uri.jid.full;
if (jid.length) {
self.accountNameTextField.text = jid;
}
} else if ([resultURL otr_isInviteLink]) {
NSURL *url = [NSURL URLWithString:result];
__block XMPPJID *jid = nil;
__block NSString *fingerprint = nil;
NSString *otr = [OTRAccount fingerprintStringTypeForFingerprintType:OTRFingerprintTypeOTR];
[url otr_decodeShareLink:^(XMPPJID * _Nullable inJid, NSArray<NSURLQueryItem*> * _Nullable queryItems) {
jid = inJid;
[queryItems enumerateObjectsUsingBlock:^(NSURLQueryItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj.name isEqualToString:otr]) {
fingerprint = obj.value;
fingerprint = [fingerprint stringByReplacingOccurrencesOfString:@" " withString:@""];
*stop = YES;
}
}];
}];
NSString *username = jid.bare;
if (username.length) {
self.accountNameTextField.text = username;
}
// add the OTR fingerprint to the trusted store
NSData *fprintData = [fingerprint dataFromHex];
if (fprintData) {
OTRFingerprint *otrFingerprint = [[OTRFingerprint alloc] initWithUsername:username accountName:self.account.username protocol:self.account.protocolTypeString fingerprint:fprintData trustLevel:OTRTrustLevelTrustedUser];
[OTRProtocolManager.encryptionManager.otrKit saveFingerprint:otrFingerprint];
}
} else {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:Unrecognized_Invite_Format() message:nil preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alert animated:YES completion:nil];
}
}
#pragma mark - QRCodeReader Delegate Methods
- (void)reader:(QRCodeReaderViewController *)reader didScanResult:(NSString *)result
{
[self dismissViewControllerAnimated:YES completion:^{
[self populateFromQRResult:result];
}];
}
- (void)readerDidCancel:(QRCodeReaderViewController *)reader
{
[reader dismissViewControllerAnimated:YES completion:NULL];
}
@end