From 60f8015b85a8c77c9226c99b5d4ed8e24534255e Mon Sep 17 00:00:00 2001 From: lissine Date: Fri, 2 Aug 2024 01:21:55 +0100 Subject: [PATCH] Rewrite the Change Password view in SwiftUI Use the Handler and MLPromise frameworks And only display the old password if it was autogenerated --- Monal/Classes/ChangePassword.swift | 104 +++++++++ Monal/Classes/MLIQProcessor.m | 33 +++ .../MLPasswordChangeTableViewController.h | 25 --- .../MLPasswordChangeTableViewController.m | 200 ------------------ Monal/Classes/Quicksy_RegisterAccount.swift | 3 +- Monal/Classes/SwiftuiHelpers.swift | 9 +- Monal/Classes/XMPPEdit.m | 32 ++- Monal/Classes/xmpp.h | 2 +- Monal/Classes/xmpp.m | 33 ++- Monal/Monal.xcodeproj/project.pbxproj | 10 +- 10 files changed, 182 insertions(+), 269 deletions(-) create mode 100644 Monal/Classes/ChangePassword.swift delete mode 100644 Monal/Classes/MLPasswordChangeTableViewController.h delete mode 100644 Monal/Classes/MLPasswordChangeTableViewController.m diff --git a/Monal/Classes/ChangePassword.swift b/Monal/Classes/ChangePassword.swift new file mode 100644 index 0000000000..9e8b3e4fc3 --- /dev/null +++ b/Monal/Classes/ChangePassword.swift @@ -0,0 +1,104 @@ +// +// ChangePassword.swift +// Monal +// +// Created by lissine on 2/8/2024. +// Copyright © 2024 monal-im.org. All rights reserved. +// + +struct ChangePassword: View { + @Environment(\.dismiss) private var dismiss + + @State private var oldPass = "" + @State private var newPass = "" + + @State private var showAlert = false + @State private var alertPrompt = AlertPrompt(dismissLabel: Text("Close")) + + @StateObject private var overlay = LoadingOverlayState() + + let accountID: NSNumber + + private func errorAlert(title: Text, message: Text = Text("")) { + alertPrompt.title = title + alertPrompt.message = message + showAlert = true + alertPrompt.dismissCallback = nil + } + private func successAlert(title: Text, message: Text) { + alertPrompt.title = title + alertPrompt.message = message + showAlert = true + alertPrompt.dismissCallback = { + dismiss() + } + } + private func passwordChangeProcessing() { + guard let account = MLXMPPManager.sharedInstance().getEnabledAccount(forID: accountID) else { + errorAlert( + title: Text("Account Disabled"), + message: Text("Please enable your account before changing its password.") + ) + return + } + + guard MLXMPPManager.sharedInstance().isValidPassword(oldPass, forAccount: accountID) else { + errorAlert( + title: Text("Wrong Password!"), + message: Text("The current password is not correct.") + ) + return + } + + showPromisingLoadingOverlay(overlay, headlineView: Text("Changing Password"), descriptionView: Text("")) { + account.changePassword(newPass) + } + .done { _ in + successAlert(title: Text("Success"), message: Text("The password has been changed")) + } + .catch { error in + errorAlert(title: Text("Error"), message: Text(error.localizedDescription)) + } + + } + + var body: some View { + Form { + Section(header: Text("Enter your new password. Passwords may not be empty. They may also be governed by server or company policies.")) { +#if IS_QUICKSY + if HelperTools.defaultsDB().bool(forKey: "autogeneratedPassword") { + TextField(NSLocalizedString("Current Password", comment: ""), text: $oldPass) + .textInputAutocapitalization(.never) + .autocorrectionDisabled() + .onAppear { + oldPass = MLXMPPManager.sharedInstance().getPasswordForAccount(accountID) + } + } else { + SecureField(NSLocalizedString("Current Password", comment: ""), text: $oldPass) + } +#else + SecureField(NSLocalizedString("Current Password", comment: ""), text: $oldPass) +#endif + SecureField(NSLocalizedString("New Password", comment: ""), text: $newPass) + } + + Section { + Button(action: passwordChangeProcessing) { + Text("Change Password") + .frame(maxWidth: .infinity, alignment: .center) + } + .disabled(oldPass.isEmpty || newPass.isEmpty) + } + + } + .alert( + alertPrompt.title, + isPresented: $showAlert, + actions: { Button(NSLocalizedString("Close", comment: ""), action: alertPrompt.dismissCallback ?? {}) }, + message: { alertPrompt.message } + ) + .navigationTitle(Text("Change Password")) + .navigationBarTitleDisplayMode(NavigationBarItem.TitleDisplayMode.inline) + .addLoadingOverlay(overlay) + } +} diff --git a/Monal/Classes/MLIQProcessor.m b/Monal/Classes/MLIQProcessor.m index 604a1a59f2..0ece61df85 100644 --- a/Monal/Classes/MLIQProcessor.m +++ b/Monal/Classes/MLIQProcessor.m @@ -12,11 +12,13 @@ #import "MLHandler.h" #import "DataLayer.h" #import "MLImageManager.h" +#import "MLXMPPManager.h" #import "HelperTools.h" #import "MLNotificationQueue.h" #import "MLContactSoftwareVersionInfo.h" #import "MLOMEMO.h" +@import SAMKeychain; /** Validate and process any iq elements. @@ -732,6 +734,37 @@ +(BOOL) processRosterWithAccount:(xmpp*) account andIqNode:(XMPPIQ*) iqNode } $$ +$$class_handler(handlePasswordChangeInvalidation, $$ID(xmpp*, account), $$ID(NSString*, uuid), $$ID(MLPromise*, promise)) + NSString* jid = account.connectionProperties.identity.jid; + DDLogError(@"Could not change the password of '%@'", jid); + NSString* errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Could not change the password of '%@'. Please try again.", @""), jid]; + NSError* error = [NSError errorWithDomain:@"Monal" code:0 userInfo:@{NSLocalizedDescriptionKey: errorMessage}]; + [promise reject:error]; + [SAMKeychain deletePasswordForService:uuid account:jid]; +$$ + +$$class_handler(handlePasswordChange, $$ID(XMPPIQ*, iqNode), $$ID(xmpp*, account), $$ID(NSString*, uuid), $$ID(MLPromise*, promise)) + NSString* jid = account.connectionProperties.identity.jid; + if([iqNode check:@"/"]) + { + DDLogError(@"Changing the password of '%@' returned error: %@", jid, [iqNode findFirst:@"error"]); + NSString* errorMessage = [HelperTools extractXMPPError:iqNode withDescription:[NSString stringWithFormat:NSLocalizedString(@"Could not change the password of '%@'", @""), jid]]; + NSError* error = [NSError errorWithDomain:@"Monal" code:0 userInfo:@{NSLocalizedDescriptionKey: errorMessage}]; + [promise reject:error]; + } + else + { + NSString* newPass = [SAMKeychain passwordForService:uuid account:jid]; + [[MLXMPPManager sharedInstance] updatePassword:newPass forAccount: account.accountID]; +#if IS_QUICKSY + [[HelperTools defaultsDB] setBool:NO forKey:@"autogeneratedPassword"]; +#endif + DDLogInfo(@"Successfully changed the password of '%@'", jid); + [promise fulfill:nil]; + } + [SAMKeychain deletePasswordForService:uuid account:jid]; +$$ + $$class_handler(handleVersionResponse, $$ID(xmpp*, account), $$ID(XMPPIQ*, iqNode)) NSString* iqAppName = [iqNode findFirst:@"{jabber:iq:version}query/name#"]; NSString* iqAppVersion = [iqNode findFirst:@"{jabber:iq:version}query/version#"]; diff --git a/Monal/Classes/MLPasswordChangeTableViewController.h b/Monal/Classes/MLPasswordChangeTableViewController.h deleted file mode 100644 index ed5fe24ec2..0000000000 --- a/Monal/Classes/MLPasswordChangeTableViewController.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// MLPasswordChangeTableViewController.h -// Monal -// -// Created by Anurodh Pokharel on 5/22/19. -// Copyright © 2019 Monal.im. All rights reserved. -// - -#import -#import "MLConstants.h" -#import "xmpp.h" -#import "MLButtonCell.h" -#import "MLTextInputCell.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface MLPasswordChangeTableViewController : UITableViewController - -@property (nonatomic, strong) xmpp *xmppAccount; --(IBAction) changePress:(id)sender; - -@end - - -NS_ASSUME_NONNULL_END diff --git a/Monal/Classes/MLPasswordChangeTableViewController.m b/Monal/Classes/MLPasswordChangeTableViewController.m deleted file mode 100644 index 0460b2d31d..0000000000 --- a/Monal/Classes/MLPasswordChangeTableViewController.m +++ /dev/null @@ -1,200 +0,0 @@ -// -// MLPasswordChangeTableViewController.m -// Monal -// -// Created by Anurodh Pokharel on 5/22/19. -// Copyright © 2019 Monal.im. All rights reserved. -// - -#import "MLPasswordChangeTableViewController.h" -#import "MBProgressHUD.h" -#import "MLXMPPManager.h" - - -@interface MLPasswordChangeTableViewController () -@property (nonatomic, weak) MLTextInputCell* passwordOld; -@property (nonatomic, weak) MLTextInputCell* passwordNew; -@property (nonatomic, strong) MBProgressHUD* progress; -@end - -@implementation MLPasswordChangeTableViewController - --(void) closeView -{ - [self dismissViewControllerAnimated:YES completion:nil]; -} - --(IBAction) changePress:(id)sender -{ - if(!self.xmppAccount) - { - UIAlertController* messageAlert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"No connected accounts", @"") message:NSLocalizedString(@"Please make sure you are connected before changing your password.", @"") preferredStyle:UIAlertControllerStyleAlert]; - UIAlertAction* closeAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Close", @"") style:UIAlertActionStyleCancel handler:^(UIAlertAction* action __unused) {}]; - [messageAlert addAction:closeAction]; - - [self presentViewController:messageAlert animated:YES completion:nil]; - } - else - { - if([self.passwordNew getText].length > 0 && [self.passwordOld getText] > 0) - { - if([[MLXMPPManager sharedInstance] isValidPassword:[self.passwordOld getText] forAccount:self.xmppAccount.accountID] == NO) - { - UIAlertController* messageAlert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Invalid Password!", @"") message:NSLocalizedString(@"The current password is not correct.", @"") preferredStyle:UIAlertControllerStyleAlert]; - UIAlertAction* closeAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Close", @"") style:UIAlertActionStyleCancel handler:^(UIAlertAction* action __unused) {}]; - [messageAlert addAction:closeAction]; - - [self presentViewController:messageAlert animated:YES completion:nil]; - return; - } - - self.progress = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; - self.progress.label.text = NSLocalizedString(@"Changing Password", @""); - self.progress.mode = MBProgressHUDModeIndeterminate; - self.progress.removeFromSuperViewOnHide = YES; - self.progress.hidden = NO; - - [self.xmppAccount changePassword:[self.passwordNew getText] withCompletion:^(BOOL success, NSString* message) { - dispatch_async(dispatch_get_main_queue(), ^{ - self.progress.hidden = YES; - NSString* title = NSLocalizedString(@"Error", @""); - NSString* displayMessage = message; - if(success == YES) { - title = NSLocalizedString(@"Success", @""); - displayMessage = NSLocalizedString(@"The password has been changed", @""); - - [[MLXMPPManager sharedInstance] updatePassword:[self.passwordNew getText] forAccount:self.xmppAccount.accountID]; - } else { - if(displayMessage.length == 0) displayMessage = NSLocalizedString(@"Could not change the password", @""); - } - - UIAlertController* messageAlert = [UIAlertController alertControllerWithTitle:title message:displayMessage preferredStyle:UIAlertControllerStyleAlert]; - UIAlertAction* closeAction =[UIAlertAction actionWithTitle:NSLocalizedString(@"Close", @"") style:UIAlertActionStyleCancel handler:^(UIAlertAction* action __unused) { - - }]; - [messageAlert addAction:closeAction]; - - [self presentViewController:messageAlert animated:YES completion:nil]; - }); - }]; - } - else - { - UIAlertController *messageAlert =[UIAlertController alertControllerWithTitle:NSLocalizedString(@"Error", @"") message:NSLocalizedString(@"Password cannot be empty", @"") preferredStyle:UIAlertControllerStyleAlert]; - UIAlertAction* closeAction =[UIAlertAction actionWithTitle:NSLocalizedString(@"Close", @"") style:UIAlertActionStyleCancel handler:^(UIAlertAction* action __unused) { - - }]; - [messageAlert addAction:closeAction]; - - [self presentViewController:messageAlert animated:YES completion:nil]; - - } - - } -} - -#pragma mark - textfield delegate - -- (BOOL)textFieldShouldReturn:(UITextField *)textField -{ - [textField resignFirstResponder]; - - return YES; -} - - -- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField { - - return YES; -} - - -#pragma mark View life cycle - --(void) viewDidLoad -{ - [super viewDidLoad]; - self.navigationItem.title=NSLocalizedString(@"Change Password", @""); - [self.tableView registerNib:[UINib nibWithNibName:@"MLTextInputCell" - bundle:[NSBundle mainBundle]] - forCellReuseIdentifier:@"TextCell"]; -} - --(void) viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; - -} - -#pragma mark tableview datasource delegate - --(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView -{ - return 2; -} - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section -{ - if(section == 0) - return NSLocalizedString(@"Enter your new password. Passwords may not be empty. They may also be governed by server or company policies.",@ ""); - else - return nil; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - NSInteger toreturn = 0; - switch (section) { - case 0: - toreturn = 2; - break; - case 1: - toreturn = 1; - break; - - default: - break; - } - - return toreturn; -} - -- (UITableViewCell*) tableView:(UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath -{ - if(indexPath.section == 0) - { - MLTextInputCell* textCell = [tableView dequeueReusableCellWithIdentifier:@"TextCell"]; - if(indexPath.row == 0) - { -#ifdef IS_QUICKSY - [textCell initTextCell:[[MLXMPPManager sharedInstance] getPasswordForAccount:self.xmppAccount.accountID] andPlaceholder:NSLocalizedString(@"Current Password", @"") andDelegate:self]; -#else - [textCell initPasswordCell:[[MLXMPPManager sharedInstance] getPasswordForAccount:self.xmppAccount.accountID] andPlaceholder:NSLocalizedString(@"Current Password", @"") andDelegate:self]; -#endif - self.passwordOld = textCell; - } - else if(indexPath.row == 1) - { - [textCell initPasswordCell:nil andPlaceholder:NSLocalizedString(@"New Password", @"") andDelegate:self]; - self.passwordNew = textCell; - } - else - { - unreachable(); - } - return textCell; - } - else - return [tableView dequeueReusableCellWithIdentifier:@"addButton"]; -} - -#pragma mark tableview delegate -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - -} - - - - -@end diff --git a/Monal/Classes/Quicksy_RegisterAccount.swift b/Monal/Classes/Quicksy_RegisterAccount.swift index 726c5bf298..eb43de4474 100644 --- a/Monal/Classes/Quicksy_RegisterAccount.swift +++ b/Monal/Classes/Quicksy_RegisterAccount.swift @@ -110,7 +110,8 @@ struct Quicksy_RegisterAccount: View { startLoginTimeout() showLoadingOverlay(overlay, headline:NSLocalizedString("Logging in", comment: "")) self.errorObserverEnabled = true - //check if account is already configured and reset its password and its enabled and needs_password_migration states + HelperTools.defaultsDB().set(true, forKey: "autogeneratedPassword") + //check if account is already configured and reset its password and its enabled and needs_password_migration states if let newAccountID = DataLayer.sharedInstance().accountID(forUser:number, andDomain:"quicksy.im") { self.newAccountID = newAccountID var accountDict = DataLayer.sharedInstance().details(forAccount:newAccountID) as! [String:AnyObject] diff --git a/Monal/Classes/SwiftuiHelpers.swift b/Monal/Classes/SwiftuiHelpers.swift index e21e3a599c..92d1179ce6 100644 --- a/Monal/Classes/SwiftuiHelpers.swift +++ b/Monal/Classes/SwiftuiHelpers.swift @@ -743,7 +743,14 @@ class SwiftuiInterface : NSObject { } return host } - + + @objc + func makeChangePasswordView(for accountID: NSNumber) -> UIViewController { + let host = UIHostingController(rootView:AnyView(EmptyView())) + host.rootView = AnyView(ChangePassword(accountID: accountID)) + return host + } + @objc func makeAccountRegistration(_ registerData: [String:AnyObject]?) -> UIViewController { let delegate = SheetDismisserProtocol() diff --git a/Monal/Classes/XMPPEdit.m b/Monal/Classes/XMPPEdit.m index 7c89a94c81..8888c2619f 100644 --- a/Monal/Classes/XMPPEdit.m +++ b/Monal/Classes/XMPPEdit.m @@ -11,7 +11,6 @@ #import "MBProgressHUD.h" #import "MLButtonCell.h" #import "MLImageManager.h" -#import "MLPasswordChangeTableViewController.h" #import "MLSwitchCell.h" #import "MLOMEMO.h" #import "MLNotificationQueue.h" @@ -110,6 +109,7 @@ @interface XMPPEdit() @property (nonatomic) BOOL avatarChanged; @property (nonatomic) BOOL rosterNameChanged; @property (nonatomic) BOOL statusMessageChanged; +@property (nonatomic) BOOL passwordChanged; @property (nonatomic) BOOL detailsChanged; @property (nonatomic) BOOL plainActivated; @@ -409,6 +409,10 @@ -(IBAction) save:(id) sender { DDLogVerbose(@"Now setting password for account %@ in SAMKeychain...", self.accountID); [[MLXMPPManager sharedInstance] updatePassword:self.password forAccount:self.accountID]; +#if IS_QUICKSY + if (self.passwordChanged) + [[HelperTools defaultsDB] setBool:NO forKey:@"autogeneratedPassword"]; +#endif } if(self.enabled) { @@ -640,7 +644,10 @@ -(UITableViewCell*) tableView:(UITableView*) tableView cellForRowAtIndexPath:(NS { case SettingsChangePasswordRow: { #ifdef IS_QUICKSY - [thecell initTapCell:NSLocalizedString(@"Change/View Password", @"")]; + if([[HelperTools defaultsDB] boolForKey:@"autogeneratedPassword"]) + [thecell initTapCell:NSLocalizedString(@"Change/View Password", @"")]; + else + [thecell initTapCell:NSLocalizedString(@"Change Password", @"")]; #else [thecell initTapCell:NSLocalizedString(@"Change Password", @"")]; #endif @@ -828,9 +835,11 @@ -(void) tableView:(UITableView*) tableView didSelectRowAtIndexPath:(NSIndexPath* { switch(newIndexPath.row) { - case SettingsChangePasswordRow: - [self performSegueWithIdentifier:@"showPassChange" sender:self]; + case SettingsChangePasswordRow: { + UIViewController* changePasswordView = [[SwiftuiInterface new] makeChangePasswordViewFor:self.accountID]; + [self showDetailViewController:changePasswordView sender:self]; break; + } case SettingsOmemoKeysRow: { UIViewController* ownOmemoKeysView; xmpp* xmppAccount = [[MLXMPPManager sharedInstance] getEnabledAccountForID:self.accountID]; @@ -893,20 +902,6 @@ -(void) tableView:(UITableView*) tableView accessoryButtonTappedForRowWithIndexP } -#pragma mark - segeue - --(void) prepareForSegue:(UIStoryboardSegue*) segue sender:(id) sender -{ - if([segue.identifier isEqualToString:@"showPassChange"]) - { - if(self.jid && self.accountID) - { - MLPasswordChangeTableViewController* pwchange = (MLPasswordChangeTableViewController*)segue.destinationViewController; - pwchange.xmppAccount = [[MLXMPPManager sharedInstance] getEnabledAccountForID:self.accountID]; - } - } -} - #pragma mark - text input fielddelegate -(void) textFieldDidBeginEditing:(UITextField*) textField @@ -940,6 +935,7 @@ -(void) textFieldDidEndEditing:(UITextField*) textField case 3: { self.password = textField.text; self.detailsChanged = YES; + self.passwordChanged = YES; break; } case 4: { diff --git a/Monal/Classes/xmpp.h b/Monal/Classes/xmpp.h index 46c3ee4941..85499c4613 100644 --- a/Monal/Classes/xmpp.h +++ b/Monal/Classes/xmpp.h @@ -216,7 +216,7 @@ typedef void (^monal_iq_handler_t)(XMPPIQ* _Nullable); #pragma mark - account management --(void) changePassword:(NSString*) newPass withCompletion:(xmppCompletion _Nullable) completion; +-(AnyPromise*) changePassword:(NSString*) newPass; -(void) requestRegFormWithToken:(NSString* _Nullable) token andCompletion:(xmppDataCompletion) completion andErrorCompletion:(xmppCompletion) errorCompletion; -(void) registerUser:(NSString*) username withPassword:(NSString*) password captcha:(NSString* _Nullable) captcha andHiddenFields:(NSDictionary* _Nullable) hiddenFields withCompletion:(xmppCompletion _Nullable) completion; diff --git a/Monal/Classes/xmpp.m b/Monal/Classes/xmpp.m index c78dc6ca0a..7e26cafdfb 100644 --- a/Monal/Classes/xmpp.m +++ b/Monal/Classes/xmpp.m @@ -47,6 +47,7 @@ #import "AESGcm.h" @import AVFoundation; +@import SAMKeychain; #define STATE_VERSION 18 #define CONNECT_TIMEOUT 7.0 @@ -4634,24 +4635,22 @@ -(void) createInvitationWithCompletion:(monal_id_block_t) completion }]; } --(void) changePassword:(NSString *) newPass withCompletion:(xmppCompletion) completion +-(AnyPromise*) changePassword:(NSString*) newPass { - XMPPIQ* iq = [[XMPPIQ alloc] initWithType:kiqSetType]; - [iq setiqTo:self.connectionProperties.identity.domain]; - [iq changePasswordForUser:self.connectionProperties.identity.user newPassword:newPass]; - [self sendIq:iq withResponseHandler:^(XMPPIQ* response __unused) { - //dispatch completion handler outside of the receiveQueue - if(completion) - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - completion(YES, @""); - }); - } andErrorHandler:^(XMPPIQ* error) { - //dispatch completion handler outside of the receiveQueue - if(completion) - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - completion(NO, error ? [HelperTools extractXMPPError:error withDescription:NSLocalizedString(@"Could not change password", @"")] : NSLocalizedString(@"Could not change password: your account is currently not connected", @"")); - }); - }]; + MLPromise* promise = [MLPromise new]; + XMPPIQ* iqNode = [[XMPPIQ alloc] initWithType:kiqSetType]; + [iqNode setiqTo:self.connectionProperties.identity.domain]; + [iqNode changePasswordForUser:self.connectionProperties.identity.user newPassword:newPass]; + + //temporarily store the new password in the keychain. + //this way, we don't store the password in the db if the app is put + //in the background while awaiting the iq result. + NSString* uuid = [[NSUUID UUID] UUIDString]; + [SAMKeychain setAccessibilityType:kSecAttrAccessibleAfterFirstUnlock]; + [SAMKeychain setPassword:newPass forService:uuid account:self.connectionProperties.identity.jid]; + + [self sendIq:iqNode withHandler:$newHandlerWithInvalidation(MLIQProcessor, handlePasswordChange,handlePasswordChangeInvalidation, $ID(uuid), $ID(promise))]; + return [promise toAnyPromise]; } -(void) requestRegFormWithToken:(NSString* _Nullable) token andCompletion:(xmppDataCompletion) completion andErrorCompletion:(xmppCompletion) errorCompletion diff --git a/Monal/Monal.xcodeproj/project.pbxproj b/Monal/Monal.xcodeproj/project.pbxproj index cba3b987ea..807a8555f2 100644 --- a/Monal/Monal.xcodeproj/project.pbxproj +++ b/Monal/Monal.xcodeproj/project.pbxproj @@ -43,7 +43,6 @@ 26AA70152146BBB900598605 /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 26AA70142146BBB900598605 /* ShareViewController.m */; }; 26AA70182146BBB900598605 /* iosShare.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 26AA70162146BBB900598605 /* iosShare.storyboard */; }; 26AA701C2146BBB900598605 /* shareSheet.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 26AA70112146BBB800598605 /* shareSheet.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 26AAAADC2295742500200433 /* MLPasswordChangeTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 26AAAAD92295742400200433 /* MLPasswordChangeTableViewController.m */; }; 26AAE285179F7B0200271345 /* MLSettingCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 26AAE284179F7B0200271345 /* MLSettingCell.m */; }; 26B0CA8921AE2E3C0080B133 /* MLSoundsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 26B0CA8821AE2E3C0080B133 /* MLSoundsTableViewController.m */; }; 26B0CA8B21AE410E0080B133 /* AlertSounds in Resources */ = {isa = PBXBuildFile; fileRef = 26B0CA8A21AE410E0080B133 /* AlertSounds */; }; @@ -222,6 +221,7 @@ D02192F32C89BB3800202A59 /* BlockedUsers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02192F22C89BB3800202A59 /* BlockedUsers.swift */; }; D09B51F62C7F30DD008D725B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 26B2A4BA1B73061400272E63 /* Images.xcassets */; }; D0FA79B12C7E5C7400216D2A /* ServerDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FA79B02C7E5C7400216D2A /* ServerDetails.swift */; }; + D0FE3F542C5C56ED007AAD23 /* ChangePassword.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FE3F532C5C56ED007AAD23 /* ChangePassword.swift */; }; D7E74AF213445E39318BC648 /* Pods_MonalUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 29250DA62DD2322383585B2B /* Pods_MonalUITests.framework */; }; E89DD32525C6626400925F62 /* MLFileTransferDataCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E89DD32025C6626300925F62 /* MLFileTransferDataCell.m */; }; E89DD32625C6626400925F62 /* MLFileTransferVideoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E89DD32125C6626300925F62 /* MLFileTransferVideoCell.m */; }; @@ -415,8 +415,6 @@ 26AA70172146BBB900598605 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/iosShare.storyboard; sourceTree = ""; }; 26AA70192146BBB900598605 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 26AA70222146E2B900598605 /* shareSheet.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = shareSheet.entitlements; sourceTree = ""; }; - 26AAAAD82295742400200433 /* MLPasswordChangeTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MLPasswordChangeTableViewController.h; sourceTree = ""; }; - 26AAAAD92295742400200433 /* MLPasswordChangeTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MLPasswordChangeTableViewController.m; sourceTree = ""; }; 26AAE283179F7B0200271345 /* MLSettingCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MLSettingCell.h; sourceTree = ""; }; 26AAE284179F7B0200271345 /* MLSettingCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MLSettingCell.m; sourceTree = ""; }; 26ABE9FB494A9E7F3044C695 /* Pods-MonalUITests.appstore-quicksy.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonalUITests.appstore-quicksy.xcconfig"; path = "Target Support Files/Pods-MonalUITests/Pods-MonalUITests.appstore-quicksy.xcconfig"; sourceTree = ""; }; @@ -767,6 +765,7 @@ C1F5C7AB2777621B0001F295 /* ContactResources.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactResources.swift; sourceTree = ""; }; D02192F22C89BB3800202A59 /* BlockedUsers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsers.swift; sourceTree = ""; }; D0FA79B02C7E5C7400216D2A /* ServerDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerDetails.swift; sourceTree = ""; }; + D0FE3F532C5C56ED007AAD23 /* ChangePassword.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangePassword.swift; sourceTree = ""; }; D310A8387B2EB10761312F77 /* Pods-NotificaionService.appstore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificaionService.appstore.xcconfig"; path = "Target Support Files/Pods-NotificaionService/Pods-NotificaionService.appstore.xcconfig"; sourceTree = ""; }; D8D2595B2BE453296E59F1AF /* Pods-MonalUITests.appstore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonalUITests.appstore.xcconfig"; path = "Target Support Files/Pods-MonalUITests/Pods-MonalUITests.appstore.xcconfig"; sourceTree = ""; }; DC5DA2C9782510B3433FD50D /* Pods-monalxmpp.beta.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-monalxmpp.beta.xcconfig"; path = "Target Support Files/Pods-monalxmpp/Pods-monalxmpp.beta.xcconfig"; sourceTree = ""; }; @@ -1062,10 +1061,9 @@ 2636C43E177BD58C001CA71F /* XMPPEdit.m */, 262AEFE620AE756800498F82 /* MLMAMPrefTableViewController.h */, 262AEFE720AE756800498F82 /* MLMAMPrefTableViewController.m */, - 26AAAAD82295742400200433 /* MLPasswordChangeTableViewController.h */, - 26AAAAD92295742400200433 /* MLPasswordChangeTableViewController.m */, D0FA79B02C7E5C7400216D2A /* ServerDetails.swift */, D02192F22C89BB3800202A59 /* BlockedUsers.swift */, + D0FE3F532C5C56ED007AAD23 /* ChangePassword.swift */, ); name = Accounts; sourceTree = ""; @@ -2093,6 +2091,7 @@ 84E55E7D2964424E003E191A /* ActiveChatsViewController.m in Sources */, C1E8A7F72B8E47C300760220 /* EditGroupSubject.swift in Sources */, 263DFAC32187D0E00038E716 /* MLLinkCell.m in Sources */, + D0FE3F542C5C56ED007AAD23 /* ChangePassword.swift in Sources */, 3D65B78D27234B74005A30F4 /* ContactDetails.swift in Sources */, E89DD32525C6626400925F62 /* MLFileTransferDataCell.m in Sources */, E89DD32825C6626400925F62 /* MLFileTransferTextCell.m in Sources */, @@ -2137,7 +2136,6 @@ 3D5A91422842B4AE008CE57E /* MemberList.swift in Sources */, 849248492AD4CEC400986C1A /* ZoomableContainer.swift in Sources */, 2644D4921FF0064C00F46AB5 /* MLChatImageCell.m in Sources */, - 26AAAADC2295742500200433 /* MLPasswordChangeTableViewController.m in Sources */, 8441EFF92921B53500E851E9 /* BackgroundSettings.swift in Sources */, 841898AC2957DBAD00FEC77D /* RichAlert.swift in Sources */, 840E23CA28ADA56900A7FAC9 /* MLUploadQueueCell.m in Sources */,