From 0a908b62b451dfbf23e1783233983947e30bbc19 Mon Sep 17 00:00:00 2001 From: Thilo Molitor Date: Mon, 9 Oct 2023 03:17:40 +0200 Subject: [PATCH] Implement omemo-key support in xmpp: urls opened by monal --- Monal/Classes/ActiveChatsViewController.h | 2 +- Monal/Classes/ActiveChatsViewController.m | 19 +-- Monal/Classes/AddContactMenu.swift | 58 ++++++--- Monal/Classes/MLQRCodeScanner.swift | 143 +++++----------------- Monal/Classes/MonalAppDelegate.m | 61 ++++----- Monal/Classes/OmemoKeys.swift | 23 ++-- Monal/Classes/SwiftuiHelpers.swift | 4 +- 7 files changed, 120 insertions(+), 190 deletions(-) diff --git a/Monal/Classes/ActiveChatsViewController.h b/Monal/Classes/ActiveChatsViewController.h index 59f2088c28..107a96829f 100644 --- a/Monal/Classes/ActiveChatsViewController.h +++ b/Monal/Classes/ActiveChatsViewController.h @@ -38,7 +38,7 @@ NS_ASSUME_NONNULL_BEGIN -(void) showPrivacySettings; -(void) showDetails; -(void) showRegisterWithUsername:(NSString*) username onHost:(NSString*) host withToken:(NSString* _Nullable) token usingCompletion:(monal_id_block_t _Nullable) callback; --(void) showAddContactWithJid:(NSString*) jid andPreauthToken:(NSString* _Nullable) preauthToken; +-(void) showAddContactWithJid:(NSString*) jid preauthToken:(NSString* _Nullable) preauthToken prefillAccount:(xmpp* _Nullable) account andOmemoFingerprints:(NSDictionary* _Nullable) fingerprints; @end diff --git a/Monal/Classes/ActiveChatsViewController.m b/Monal/Classes/ActiveChatsViewController.m index 5e7c61b01d..d22bfd502e 100755 --- a/Monal/Classes/ActiveChatsViewController.m +++ b/Monal/Classes/ActiveChatsViewController.m @@ -428,17 +428,20 @@ -(void) viewDidAppear:(BOOL) animated -(void) didReceiveMemoryWarning { [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. } --(void) showAddContactWithJid:(NSString*) jid andPreauthToken:(NSString* _Nullable) preauthToken +-(void) showAddContactWithJid:(NSString*) jid preauthToken:(NSString* _Nullable) preauthToken prefillAccount:(xmpp* _Nullable) account andOmemoFingerprints:(NSDictionary* _Nullable) fingerprints { - UIViewController* addContactMenuView = [[SwiftuiInterface new] makeAddContactViewForJid:jid andPreauthToken:preauthToken withDismisser:^(MLContact* _Nonnull newContact) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self presentChatWithContact:newContact]; - }); - }]; - [self presentViewController:addContactMenuView animated:YES completion:^{}]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self dismissCompleteViewChainWithAnimation:NO andCompletion:^{ + UIViewController* addContactMenuView = [[SwiftuiInterface new] makeAddContactViewForJid:jid preauthToken:preauthToken prefillAccount:account andOmemoFingerprints:fingerprints withDismisser:^(MLContact* _Nonnull newContact) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self presentChatWithContact:newContact]; + }); + }]; + [self presentViewController:addContactMenuView animated:NO completion:^{}]; + }]; + }); } -(void) segueToIntroScreensIfNeeded diff --git a/Monal/Classes/AddContactMenu.swift b/Monal/Classes/AddContactMenu.swift index fad6c1dae1..de86a3d5a5 100644 --- a/Monal/Classes/AddContactMenu.swift +++ b/Monal/Classes/AddContactMenu.swift @@ -15,7 +15,7 @@ struct AddContactMenu: View { @State private var connectedAccounts: [xmpp] @State private var selectedAccount: Int - @State private var scannedFingerprints: Dictionary? = nil + @State private var scannedFingerprints: [NSNumber:Data]? = nil @State private var importScannedFingerprints: Bool = false @State private var toAdd: String = "" @@ -23,7 +23,7 @@ struct AddContactMenu: View { @State private var showAlert = false // note: dismissLabel is not accessed but defined at the .alert() section @State private var alertPrompt = AlertPrompt(dismissLabel: Text("Close")) - @State private var invitationResult: Dictionary? = nil + @State private var invitationResult: [String:AnyObject]? = nil @ObservedObject private var overlay = LoadingOverlayState() @@ -34,16 +34,27 @@ struct AddContactMenu: View { private let dismissWithNewContact: (MLContact) -> () private let preauthToken: String? - init(delegate: SheetDismisserProtocol, dismissWithNewContact: @escaping (MLContact) -> (), prefillJid: String = "", preauthToken:String? = nil) { + init(delegate: SheetDismisserProtocol, dismissWithNewContact: @escaping (MLContact) -> (), prefillJid: String = "", preauthToken:String? = nil, prefillAccount:xmpp? = nil, omemoFingerprints: [NSNumber:Data]? = nil) { self.delegate = delegate self.dismissWithNewContact = dismissWithNewContact //self.toAdd = State(wrappedValue: prefillJid) self.toAdd = prefillJid self.preauthToken = preauthToken + //only display omemo ui part if there are any fingerprints (the checks below test for nil, not for 0) + if omemoFingerprints?.count ?? 0 > 0 { + self.scannedFingerprints = omemoFingerprints + } let connectedAccounts = MLXMPPManager.sharedInstance().connectedXMPP as! [xmpp] self.connectedAccounts = connectedAccounts self.selectedAccount = connectedAccounts.first != nil ? 0 : -1; + if let prefillAccount = prefillAccount { + for index in connectedAccounts.indices { + if connectedAccounts[index].accountNo.isEqual(to:prefillAccount.accountNo) { + self.selectedAccount = index + } + } + } } // FIXME duplicate code from WelcomeLogIn.swift, maybe move to SwiftuiHelpers @@ -84,11 +95,33 @@ struct AddContactMenu: View { return toAddEmpty || toAddInvalid ? Color(UIColor.systemGray) : Color(UIColor.systemBlue) } + func trustFingerprints(_ fingerprints:[NSNumber:Data]?, for jid:String, on account:xmpp) { + //we don't untrust other devices not included in here, because conversations only exports its own fingerprint + if let fingerprints = fingerprints { + for (deviceId, fingerprint) in fingerprints { + let address = SignalAddress.init(name:jid, deviceId:deviceId.int32Value) + let knownDevices = Array(account.omemo.knownDevices(forAddressName:jid)) + if !knownDevices.contains(deviceId) { + account.omemo.addIdentityManually(address, identityKey:fingerprint) + assert(account.omemo.getIdentityFor(address) == fingerprint, "The stored and created fingerprint should match") + } + //trust device/fingerprint if fingerprints match + let knownFingerprintHex = HelperTools.signalHexKey(with:account.omemo.getIdentityFor(address)) + let addedFingerprintHex = HelperTools.signalHexKey(with:fingerprint) + if knownFingerprintHex.uppercased() == addedFingerprintHex.uppercased() { + account.omemo.updateTrust(true, for:address) + } + } + } + } + func addJid(jid: String) { let account = self.connectedAccounts[selectedAccount] let contact = MLContact.createContact(fromJid: jid, andAccountNo: account.accountNo) if contact.isInRoster { self.newContact = contact + //import omemo fingerprints as manually trusted, if requested + trustFingerprints(self.importScannedFingerprints ? self.scannedFingerprints : [:], for:jid, on:account) if self.connectedAccounts.count > 1 { successAlert(title: Text("Already present"), message: Text("This contact is already in the contact list of the selected account")) } else { @@ -103,6 +136,8 @@ struct AddContactMenu: View { let contact = MLContact.createContact(fromJid: jid, andAccountNo: account.accountNo) self.newContact = contact MLXMPPManager.sharedInstance().add(contact, withPreauthToken:preauthToken) + //import omemo fingerprints as manually trusted, if requested + trustFingerprints(self.importScannedFingerprints ? self.scannedFingerprints : [:], for:jid, on:account) successAlert(title: Text("Permission Requested"), message: Text("The new contact will be added to your contacts list when the person you've added has approved your request.")) } else if(type == "muc") { showLoadingOverlay(overlay, headline: NSLocalizedString("Adding Group/Channel...", comment: "")) @@ -182,7 +217,7 @@ struct AddContactMenu: View { return } // use the canonized jid from now on (lowercased, resource removed etc.) - addJid(jid: jidComponents["user"]!) // check if user entry exists in components? + addJid(jid: jidComponents["user"]!) } }, label: { scannedFingerprints == nil ? Text("Add Group/Channel or Contact") : Text("Add scanned Group/Channel or Contact") @@ -251,7 +286,7 @@ struct AddContactMenu: View { DDLogVerbose("Trying to create invitation for: \(String(describing:splitJid["host"]!))") showLoadingOverlay(overlay, headline: NSLocalizedString("Creating invitation...", comment: "")) account.createInvitation(completion: { - let result = $0 as! Dictionary + let result = $0 as! [String:AnyObject] DispatchQueue.main.async { hideLoadingOverlay(overlay) DDLogVerbose("Got invitation result: \(String(describing:result))") @@ -275,16 +310,9 @@ struct AddContactMenu: View { }) .sheet(isPresented: $showQRCodeScanner) { NavigationView { - MLQRCodeScanner( - handleContact: { jid, fingerprints in - self.toAdd = jid - self.scannedFingerprints = fingerprints - self.importScannedFingerprints = true - self.showQRCodeScanner = false - }, handleClose: { - self.showQRCodeScanner = false - } - ) + MLQRCodeScanner(handleClose: { + self.showQRCodeScanner = false + }) .navigationTitle("QR-Code Scanner") .navigationBarTitleDisplayMode(.inline) .toolbar(content: { diff --git a/Monal/Classes/MLQRCodeScanner.swift b/Monal/Classes/MLQRCodeScanner.swift index 9a8171c404..d52f8c0a1d 100644 --- a/Monal/Classes/MLQRCodeScanner.swift +++ b/Monal/Classes/MLQRCodeScanner.swift @@ -10,6 +10,7 @@ import CocoaLumberjack import AVFoundation import UIKit import SwiftUI +import SafariServices @objc protocol MLLQRCodeScannerAccountLoginDelegate : AnyObject { @@ -17,11 +18,6 @@ import SwiftUI func closeQRCodeScanner() } -@objc protocol MLLQRCodeScannerContactDelegate : AnyObject -{ - func MLQRCodeContactScanned(jid: String, fingerprints: Dictionary) -} - struct XMPPLoginQRCode : Codable { let usedProtocol:String @@ -34,12 +30,9 @@ struct XMPPLoginQRCode : Codable } } -@available(macCatalyst 14.0, *) -@available(iOS 14.0, *) @objc class MLQRCodeScannerController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { @objc weak var loginDelegate : MLLQRCodeScannerAccountLoginDelegate? - @objc weak var contactDelegate : MLLQRCodeScannerContactDelegate? var videoPreviewLayer: AVCaptureVideoPreviewLayer!; var captureSession: AVCaptureSession!; @@ -166,40 +159,37 @@ struct XMPPLoginQRCode : Codable if let metadataObject = metadataObjects.first { guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return } - guard let qrCodeAsString = readableObject.stringValue - else - { - handleQRCodeError() - return + guard let qrCodeAsString = readableObject.stringValue else { + return handleQRCodeError() } AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate)) - if(qrCodeAsString.hasPrefix("xmpp:")) - { - handleNewContactRequest(contactString: qrCodeAsString) - return - } - else - { + //open https?:// urls in safari view controller just as they would if the qrcode was scanned using the camera app + if qrCodeAsString.hasPrefix("https://") || qrCodeAsString.hasPrefix("http://") { + if let url = URL(string:qrCodeAsString) { + let vc = SFSafariViewController(url:url, configuration:SFSafariViewController.Configuration()) + present(vc, animated: true) + } + //let our app delegate handle all xmpp: urls + } else if qrCodeAsString.hasPrefix("xmpp:") { + guard let url = URL(string:qrCodeAsString) else { + return handleQRCodeError() + } + return (UIApplication.shared.delegate as! MonalAppDelegate).handleXMPPURL(url) + //if none of the above: handle json provisioning qrcodes, see: https://github.com/iNPUTmice/Conversations/issues/3796 + } else { // check if we have a json object - // https://github.com/iNPUTmice/Conversations/issues/3796 - guard let qrCodeData = qrCodeAsString.data(using: .utf8) - else - { - handleQRCodeError() - return + guard let qrCodeData = qrCodeAsString.data(using:.utf8) else { + return handleQRCodeError() } let jsonDecoder = JSONDecoder() - do - { - let loginData = try jsonDecoder.decode(XMPPLoginQRCode.self, from: qrCodeData) - handleAccountLogin(loginData: loginData) - return - } catch - { + do { + let loginData = try jsonDecoder.decode(XMPPLoginQRCode.self, from:qrCodeData) + handleAccountLogin(loginData:loginData) + } catch { handleQRCodeError() - return } + return } } } @@ -236,70 +226,9 @@ struct XMPPLoginQRCode : Codable } else { - errorMsg(title: NSLocalizedString("Wrong menu", comment: "QR-Code-Scanner: account scan wrong menu"), msg: NSLocalizedString("The qrcode contains login credentials for a acount. Go to settings and rescan the qrcode", comment: "QR-Code-Scanner: account scan wrong menu"), startCaptureOnClose: true) - } - } - } - - func handleNewContactRequest(contactString: String) - { - let XMPP_PREFIX : String = "xmpp:" - let OMEMO_SID_PREFIX : String = "omemo-sid-" - - var omemoFingerprints = Dictionary() - var parsedJid : String - // parse contact string - if(contactString.hasPrefix(XMPP_PREFIX)) - { - let shortendContactString = contactString.suffix(contactString.count - XMPP_PREFIX.count) - let contactStringParts = shortendContactString.components(separatedBy: "?") - if(contactStringParts.count >= 1 && contactStringParts.count <= 2) - { - // check if contactStringParts[0] is a valid jid - let jidParts = contactStringParts[0].components(separatedBy: "@") - if(jidParts.count == 2 && jidParts[0].count > 0 && jidParts[1].count > 0) - { - parsedJid = contactStringParts[0] - // parse omemo fingerprints if present - if(contactStringParts.count == 2) - { - let omemoParts = contactStringParts[1].components(separatedBy: ";") - for omemoPart in omemoParts - { - let keyParts = omemoPart.components(separatedBy: "=") - if(keyParts.count == 2 && keyParts[0].hasPrefix(OMEMO_SID_PREFIX)) - { - let sidStr = keyParts[0].suffix(keyParts[0].count - OMEMO_SID_PREFIX.count) - // parse string sid to int - let sid = Int(sidStr) ?? -1 - if(sid > 0) - { - // valid sid - if(keyParts[1].count > 0) - { - // todo append - omemoFingerprints[sid] = keyParts[1] - } - } - } - } - } - // call handler - if(self.contactDelegate != nil) - { - self.navigationController?.popViewController(animated: true) - self.contactDelegate?.MLQRCodeContactScanned(jid: parsedJid, fingerprints: omemoFingerprints) - return - } - else - { - errorMsg(title: NSLocalizedString("Wrong menu", comment: "QR-Code-Scanner: jid scan wrong menu"), msg: NSLocalizedString("The qrcode contains a jid. Rescan the qrcode in the add user menu", comment: "QR-Code-Scanner: jid scan wrong menu"), startCaptureOnClose: true) - return - } - } + errorMsg(title: NSLocalizedString("Wrong menu", comment: "QR-Code-Scanner: account scan wrong menu"), msg: NSLocalizedString("The qrcode contains login credentials for an acount. Go to settings -> new account and rescan the qrcode", comment: "QR-Code-Scanner: account scan wrong menu"), startCaptureOnClose: true) } } - handleQRCodeError() } func handleQRCodeError() @@ -310,12 +239,10 @@ struct XMPPLoginQRCode : Codable struct MLQRCodeScanner : UIViewControllerRepresentable { let handleLogin: ((String, String) -> Void)? - let handleContact: ((String, Dictionary) -> Void)? let handleClose: (() -> Void) - class Coordinator: NSObject, MLLQRCodeScannerContactDelegate, MLLQRCodeScannerAccountLoginDelegate { + class Coordinator: NSObject, MLLQRCodeScannerAccountLoginDelegate { let handleLogin: ((String, String) -> Void)? - let handleContact: ((String, Dictionary) -> Void)? let handleClose: (() -> Void) func MLQRCodeAccountLoginScanned(jid: String, password: String) { @@ -324,19 +251,12 @@ struct MLQRCodeScanner : UIViewControllerRepresentable { } } - func MLQRCodeContactScanned(jid: String, fingerprints: Dictionary) { - if(self.handleContact != nil) { - self.handleContact!(jid, fingerprints) - } - } - func closeQRCodeScanner() { self.handleClose() } - init(handleLogin: ((String, String) -> Void)?, handleContact: ((String, Dictionary) -> Void)?, handleClose: @escaping () -> Void) { + init(handleLogin: ((String, String) -> Void)?, handleClose: @escaping () -> Void) { self.handleLogin = handleLogin - self.handleContact = handleContact self.handleClose = handleClose } } @@ -346,9 +266,6 @@ struct MLQRCodeScanner : UIViewControllerRepresentable { if(self.handleLogin != nil) { qrCodeScannerViewController.loginDelegate = context.coordinator } - if(self.handleContact != nil) { - qrCodeScannerViewController.contactDelegate = context.coordinator - } return qrCodeScannerViewController } @@ -356,18 +273,16 @@ struct MLQRCodeScanner : UIViewControllerRepresentable { } func makeCoordinator() -> MLQRCodeScanner.Coordinator { - Coordinator(handleLogin: self.handleLogin, handleContact: self.handleContact, handleClose: self.handleClose); + Coordinator(handleLogin: self.handleLogin, handleClose: self.handleClose); } - init(handleContact: @escaping (String, Dictionary) -> Void, handleClose: @escaping () -> Void) { - self.handleContact = handleContact + init(handleClose: @escaping () -> Void) { self.handleLogin = nil self.handleClose = handleClose } init(handleLogin: @escaping (String, String) -> Void, handleClose: @escaping () -> Void) { self.handleLogin = handleLogin - self.handleContact = nil self.handleClose = handleClose } } diff --git a/Monal/Classes/MonalAppDelegate.m b/Monal/Classes/MonalAppDelegate.m index 660d8f33ce..8dbe3cfe59 100644 --- a/Monal/Classes/MonalAppDelegate.m +++ b/Monal/Classes/MonalAppDelegate.m @@ -722,8 +722,9 @@ -(void) handleXMPPURL:(NSURL*) url BOOL isGroupJoin = NO; BOOL isIbr = NO; NSString* preauthToken = nil; - //someone had the really superior (NOT!) idea to split uri query parts by ';' instead of the standard '&' making all existing uri libs useless - //see: https://xmpp.org/extensions/xep-0147.html + NSMutableDictionary* omemoFingerprints = [NSMutableDictionary new]; + //someone had the really superior (NOT!) idea to split uri query parts by ';' instead of the standard '&' + //making all existing uri libs useless, see: https://xmpp.org/extensions/xep-0147.html //blame this author: Peter Saint-Andre NSArray* queryItems = [components.query componentsSeparatedByString:@";"]; for(NSString* item in queryItems) @@ -744,6 +745,12 @@ -(void) handleXMPPURL:(NSURL*) url isIbr = YES; if([name isEqualToString:@"preauth"]) preauthToken = [value copy]; + if([name hasPrefix:@"omemo-sid-"]) + { + NSNumber* sid = [NSNumber numberWithUnsignedInteger:(NSUInteger)[[name substringFromIndex:10] longLongValue]]; + NSData* fingerprint = [HelperTools signalIdentityWithHexKey:value]; + omemoFingerprints[sid] = fingerprint; + } } if(!jidParts[@"host"]) @@ -752,14 +759,21 @@ -(void) handleXMPPURL:(NSURL*) url return; } - if(isRegister || (isRoster && isIbr && registerNeeded)) + if(isRegister || (isRoster && registerNeeded)) { NSString* username = nilDefault(jidParts[@"node"], @""); NSString* host = jidParts[@"host"]; if(isRoster) - username = @""; //roster does not specify a predefined username for the new account, register does (optional) + { + //isRoster variant does not specify a predefined username for the new account, register does (but this is still optional) + username = @""; + //isRoster variant without ibr does not specify a host to register on, too + if(!isIbr) + host = @""; + } + //show register view and, if isRoster, add contact as usual after register (e.g. call this method again) weakify(self); [self.activeChats showRegisterWithUsername:username onHost:host withToken:preauthToken usingCompletion:^(NSNumber* accountNo) { strongify(self); @@ -776,32 +790,7 @@ -(void) handleXMPPURL:(NSURL*) url //add given jid to our roster if in roster mode (e.g. the jid is not the jid we just registered as like in register mode) if(account != nil && isRoster) //silence memory warning despite assertion above - { - MLContact* contact = [MLContact createContactFromJid:jid andAccountNo:account.accountNo]; - DDLogInfo(@"Adding contact to roster: %@", contact); - //will handle group joins and normal contacts transparently and even implement roster subscription pre-approval - [[MLXMPPManager sharedInstance] addContact:contact withPreauthToken:preauthToken]; - [[DataLayer sharedInstance] addActiveBuddies:jid forAccount:account.accountNo]; - [self openChatOfContact:contact]; - } - }]; - } - else if(isRoster && registerNeeded) - { - //show register view and after register add contact as usual (e.g. call this method again) - weakify(self); - [self.activeChats showRegisterWithUsername:@"" onHost:@"" withToken:nil usingCompletion:^(NSNumber* accountNo) { - strongify(self); - DDLogVerbose(@"Got accountNo for newly registered account: %@", accountNo); - xmpp* account = [[MLXMPPManager sharedInstance] getConnectedAccountForID:accountNo]; - DDLogInfo(@"Got newly registered account: %@", account); - - //this should never happen - MLAssert(account != nil, @"Can not use account after register!", (@{ - @"components": components, - })); - - [self handleXMPPURL:url]; + [self handleXMPPURL:url]; }]; } //I know this if is moot, but I wanted to preserve the different cases: @@ -812,19 +801,13 @@ -(void) handleXMPPURL:(NSURL*) url { if([MLXMPPManager sharedInstance].connectedXMPP.count == 1) { + //the add contacts ui will check if the contact is already present on the selected account xmpp* account = [[MLXMPPManager sharedInstance].connectedXMPP firstObject]; - MLContact* contact = [MLContact createContactFromJid:jid andAccountNo:account.accountNo]; - if(contact.isInRoster) - { - [[DataLayer sharedInstance] addActiveBuddies:jid forAccount:account.accountNo]; - [self openChatOfContact:contact]; - } - else - [self.activeChats showAddContactWithJid:jid andPreauthToken:preauthToken]; + [self.activeChats showAddContactWithJid:jid preauthToken:preauthToken prefillAccount:account andOmemoFingerprints:omemoFingerprints]; } else //the add contacts ui will check if the contact is already present on the selected account - [self.activeChats showAddContactWithJid:jid andPreauthToken:preauthToken]; + [self.activeChats showAddContactWithJid:jid preauthToken:preauthToken prefillAccount:nil andOmemoFingerprints:omemoFingerprints]; } else { diff --git a/Monal/Classes/OmemoKeys.swift b/Monal/Classes/OmemoKeys.swift index 4e97885f70..a56a0d5dc4 100644 --- a/Monal/Classes/OmemoKeys.swift +++ b/Monal/Classes/OmemoKeys.swift @@ -28,7 +28,7 @@ struct OmemoKeysEntry: View { self.contactJid = contactJid self.deviceId = deviceId self.isOwnDevice = isOwnDevice - self.address = SignalAddress.init(name: contactJid, deviceId: deviceId.int32Value) + self.address = SignalAddress.init(name: contactJid, deviceId: Int32(deviceId.int32Value)) self.fingerprint = account.omemo.getIdentityFor(self.address) self.trustLevel = account.omemo.getTrustLevel(self.address, identityKey: self.fingerprint) self.account = account @@ -291,8 +291,9 @@ struct OmemoKeys: View { } func resetTrustFromQR(scannedJid : String, scannedFingerprints : Dictionary) { - // untrust all devices from jid - self.account!.omemo.untrustAllDevices(from: scannedJid) + //don't untrust other devices not included in here, because conversations only exports its own fingerprint +// // untrust all devices from jid +// self.account!.omemo.untrustAllDevices(from: scannedJid) // trust all devices that were part of the qr code let knownDevices = Array(self.account!.omemo.knownDevices(forAddressName: scannedJid)) for (qrDeviceId, fingerprint) in scannedFingerprints { @@ -316,14 +317,14 @@ struct OmemoKeys: View { // workaround for the fact that NavigationLink inside a form forces a formatting we don't want if(self.selectedContact != nil) { // selectedContact is set to a value either when the user presses a QR code button or if there is only a single contact to choose from (-> user views a single account) NavigationLink(destination:LazyClosureView(OmemoQrCodeView(contact: self.selectedContact!)), isActive: $navigateToQRCodeView){}.hidden().disabled(true) // navigation happens as soon as our button sets navigateToQRCodeView to true... - NavigationLink(destination: LazyClosureView(MLQRCodeScanner( - handleContact: { jid, fingerprints in - // we scanned a contact but it was not in the contact list, show the alert... - self.scannedJid = jid - self.scannedFingerprints = fingerprints - showScannedContactMissmatchAlert = true - }, handleClose: {} - )), isActive: $navigateToQRCodeScanner){}.hidden().disabled(true) +// NavigationLink(destination: LazyClosureView(MLQRCodeScanner( +// handleContact: { jid, fingerprints in +// // we scanned a contact but it was not in the contact list, show the alert... +// self.scannedJid = jid +// self.scannedFingerprints = fingerprints +// showScannedContactMissmatchAlert = true +// }, handleClose: {} +// )), isActive: $navigateToQRCodeScanner){}.hidden().disabled(true) } List { let helpDescription = (self.ownKeys == true) ? diff --git a/Monal/Classes/SwiftuiHelpers.swift b/Monal/Classes/SwiftuiHelpers.swift index bff143e4bd..be0fbcb7e1 100644 --- a/Monal/Classes/SwiftuiHelpers.swift +++ b/Monal/Classes/SwiftuiHelpers.swift @@ -412,11 +412,11 @@ class SwiftuiInterface : NSObject { } @objc - func makeAddContactView(forJid jid:String, andPreauthToken preauthToken: String?, withDismisser dismisser: @escaping (MLContact) -> ()) -> UIViewController { + func makeAddContactView(forJid jid:String, preauthToken: String?, prefillAccount: xmpp?, andOmemoFingerprints omemoFingerprints: [NSNumber:Data]?, withDismisser dismisser: @escaping (MLContact) -> ()) -> UIViewController { let delegate = SheetDismisserProtocol() let host = UIHostingController(rootView:AnyView(EmptyView())) delegate.host = host - host.rootView = AnyView(AddTopLevelNavigation(withDelegate: delegate, to: AddContactMenu(delegate: delegate, dismissWithNewContact: dismisser, prefillJid: jid, preauthToken: preauthToken))) + host.rootView = AnyView(AddTopLevelNavigation(withDelegate: delegate, to: AddContactMenu(delegate: delegate, dismissWithNewContact: dismisser, prefillJid: jid, preauthToken: preauthToken, prefillAccount: prefillAccount, omemoFingerprints: omemoFingerprints))) return host }