Skip to content

Commit

Permalink
Rewrite the Change Password view in SwiftUI
Browse files Browse the repository at this point in the history
Use the Handler and MLPromise frameworks
And only display the old password if it was autogenerated
  • Loading branch information
lissine0 authored and tmolitor-stud-tu committed Jan 4, 2025
1 parent 7f985a0 commit 60f8015
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 269 deletions.
104 changes: 104 additions & 0 deletions Monal/Classes/ChangePassword.swift
Original file line number Diff line number Diff line change
@@ -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)
}
}
33 changes: 33 additions & 0 deletions Monal/Classes/MLIQProcessor.m
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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:@"/<type=error>"])
{
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#"];
Expand Down
25 changes: 0 additions & 25 deletions Monal/Classes/MLPasswordChangeTableViewController.h

This file was deleted.

200 changes: 0 additions & 200 deletions Monal/Classes/MLPasswordChangeTableViewController.m

This file was deleted.

3 changes: 2 additions & 1 deletion Monal/Classes/Quicksy_RegisterAccount.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
Loading

0 comments on commit 60f8015

Please sign in to comment.