Skip to content

Commit

Permalink
Implement quicksy password reset via SMS after iCloud restore
Browse files Browse the repository at this point in the history
  • Loading branch information
tmolitor-stud-tu committed Aug 28, 2024
1 parent b22f251 commit 58bb0d4
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 20 deletions.
20 changes: 18 additions & 2 deletions Monal/Classes/ActiveChatsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#import "XMPPIQ.h"
#import "MLIQProcessor.h"
#import "UIColor+Theme.h"
#import "Quicksy_Country.h"
#import <Monal-Swift.h>

#define prependToViewQueue(firstArg, ...) metamacro_if_eq(0, metamacro_argcount(__VA_ARGS__))([self prependToViewQueue:firstArg withId:MLViewIDUnspecified andFile:(char*)__FILE__ andLine:__LINE__ andFunc:(char*)__func__])(_prependToViewQueue(firstArg, __VA_ARGS__))
Expand Down Expand Up @@ -654,7 +655,7 @@ -(void) segueToIntroScreensIfNeeded

prependToViewQueue(MLViewIDWelcomeLoginView, (^(PMKResolver resolve) {
#ifdef IS_QUICKSY
if([[DataLayer sharedInstance] enabledAccountCnts].intValue == 0)
if([[[DataLayer sharedInstance] accountList] count] == 0)
{
DDLogDebug(@"Showing account registration view...");
UIViewController* view = [[SwiftuiInterface new] makeAccountRegistration:@{}];
Expand Down Expand Up @@ -713,6 +714,19 @@ -(void) segueToIntroScreensIfNeeded
NSArray* needingMigration = [[DataLayer sharedInstance] accountListNeedingPasswordMigration];
if(needingMigration.count > 0)
{
#ifdef IS_QUICKSY
DDLogDebug(@"Showing account registration view to do password migration...");
UIViewController* view = [[SwiftuiInterface new] makeAccountRegistration:@{}];
if(UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad)
view.modalPresentationStyle = UIModalPresentationFullScreen;
else
view.ml_disposeCallback = ^{
[self sheetDismissed];
};
[self dismissCompleteViewChainWithAnimation:NO andCompletion:^{
[self presentViewController:view animated:NO completion:^{resolve(nil);}];
}];
#else
DDLogDebug(@"Showing password migration view...");
UIViewController* passwordMigration = [[SwiftuiInterface new] makePasswordMigration:needingMigration];
passwordMigration.ml_disposeCallback = ^{
Expand All @@ -721,6 +735,7 @@ -(void) segueToIntroScreensIfNeeded
[self dismissCompleteViewChainWithAnimation:NO andCompletion:^{
[self presentViewController:passwordMigration animated:YES completion:^{resolve(nil);}];
}];
#endif
}
else
resolve(nil);
Expand All @@ -737,7 +752,8 @@ -(void) syncContacts
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError* _Nullable error) {
if(granted)
{
NSString* countryCode = [[HelperTools defaultsDB] objectForKey:@"Quicksy_countryCode"];
Quicksy_Country* country = [[HelperTools defaultsDB] objectForKey:@"Quicksy_country"];
NSString* countryCode = country.code;
NSCharacterSet* allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:@"+0123456789"] invertedSet];
NSMutableDictionary* numbers = [NSMutableDictionary new];

Expand Down
2 changes: 2 additions & 0 deletions Monal/Classes/HelperTools.m
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#import "MLContactSoftwareVersionInfo.h"
#import "IPC.h"
#import "MLDelayableTimer.h"
#import "Quicksy_Country.h"

@import UserNotifications;
@import CoreImage;
Expand Down Expand Up @@ -324,6 +325,7 @@ -(void) swizzled_setObject:(id) value forKey:(NSString*) defaultName
if(
[value isKindOfClass:[NSString class]] ||
[value isKindOfClass:[NSNumber class]] ||
[value isKindOfClass:[NSDate class]] ||
[value isKindOfClass:[NSURL class]] ||
[value isKindOfClass:[NSDictionary class]] ||
[value isKindOfClass:[NSMutableDictionary class]] ||
Expand Down
1 change: 0 additions & 1 deletion Monal/Classes/MLXMPPManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,6 @@ -(void) sendChatState:(BOOL) isTyping toContact:(MLContact*) contact

#pragma mark - login/register

//this will NOT set plain_activated to YES, only using the advanced account creation ui can do this
-(NSNumber*) login:(NSString*) jid password:(NSString*) password
{
//check if it is a JID
Expand Down
48 changes: 33 additions & 15 deletions Monal/Classes/Quicksy_RegisterAccount.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class Quicksy_State: ObservableObject {
@defaultsDB("Quicksy_phoneNumber")
var phoneNumber: String?

@defaultsDB("Quicksy_countryCode")
var countryCode: String?
@defaultsDB("Quicksy_country")
var country: Quicksy_Country?
}

struct Quicksy_RegisterAccount: View {
Expand Down Expand Up @@ -77,8 +77,7 @@ struct Quicksy_RegisterAccount: View {

init(delegate: SheetDismisserProtocol) {
self.delegate = delegate
self.state.phoneNumber = nil
var countries = COUNTRY_CODES
var countries = COUNTRY_CODES as! [Quicksy_Country]
countries.sort {
country2name($0) < country2name($1)
}
Expand All @@ -92,6 +91,7 @@ struct Quicksy_RegisterAccount: View {
}.done { data, response in
DDLogDebug("Got sendSMSRequest success: \(String(describing:response))\n\(String(describing:data))")
state.phoneNumber = number
state.country = selectedCountry //used to add a country code to phonebook entries not having any
}.catch { error in
DDLogError("Catched sendSMSRequest error: \(String(describing:error))")
if let response = error as? PMKHTTPError {
Expand All @@ -101,22 +101,31 @@ struct Quicksy_RegisterAccount: View {
}

private func createAccount() {
state.countryCode = selectedCountry!.code //used to add a country code to phonebook entries not having any
let password = HelperTools.generateRandomPassword()
if let number = state.phoneNumber {
if let number = state.phoneNumber, let _ = state.country {
showPromisingLoadingOverlay(overlay, headline:NSLocalizedString("Registering account...", comment: ""), description: "") {
sendRegisterRequest(number:number, pin:pin, password:password)
}.done { result in
DDLogDebug("Got sendRegisterRequest success: \(String(describing:result))")
startLoginTimeout()
showLoadingOverlay(overlay, headline:NSLocalizedString("Logging in", comment: ""))
self.errorObserverEnabled = true
self.newAccountNo = MLXMPPManager.sharedInstance().login("\(number)@quicksy.im", password: password)
if(self.newAccountNo == nil) {
currentTimeout = nil // <- disable timeout on error
errorObserverEnabled = false
showLoginErrorAlert(errorMessage:NSLocalizedString("Account already configured!", comment: ""))
self.newAccountNo = nil
//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.newAccountNo = newAccountID
var accountDict = DataLayer.sharedInstance().details(forAccount:newAccountID) as! [String:AnyObject]
accountDict["needs_password_migration"] = NSNumber(value:false)
accountDict["enabled"] = NSNumber(value:true)
DDLogDebug("Updating account in DB: enabled=\(String(describing:accountDict["enabled"])), needs_password_migration=\(String(describing:accountDict["needs_password_migration"])), password.count=\(password.count)")
DataLayer.sharedInstance().updateAccoun(with:accountDict)
MLXMPPManager.sharedInstance().updatePassword(password, forAccount:newAccountID)
DDLogDebug("Connecting successfully recovered and enabled account...")
MLXMPPManager.sharedInstance().connectAccount(newAccountID)
} else {
self.newAccountNo = MLXMPPManager.sharedInstance().login("\(number)@quicksy.im", password: password)
if(self.newAccountNo == nil) {
unreachable("Account already configured? This should never happen!")
}
}
}.catch { error in
DDLogError("Catched sendRegisterRequest error: \(String(describing:error))")
Expand Down Expand Up @@ -191,7 +200,7 @@ struct Quicksy_RegisterAccount: View {
/// Ensure the ZStack takes the entire area
Color.clear

if state.phoneNumber == nil {
if state.phoneNumber == nil || state.country == nil {
VStack(alignment: .leading) {
Text("Verify your phone number")
.font(.title)
Expand Down Expand Up @@ -287,13 +296,20 @@ struct Quicksy_RegisterAccount: View {
DDLogInfo("Localization: current locale localized string for regionCode: \(String(describing:Locale.current.localizedString(forRegionCode:regionCode)))")
DDLogInfo("Localization: en_US localized string for regionCode: \(String(describing:Locale(identifier: "en_US").localizedString(forRegionCode:regionCode)))")
for country in countries {
if country.alpha2 == regionCode || country.name == Locale.current.localizedString(forRegionCode:regionCode) || country.name == Locale(identifier: "en_US").localizedString(forRegionCode:regionCode) {
if let previousCountry = state.country {
//check alpha2 code and country name explicitly to still match even when changing other properties
if previousCountry.alpha2 == country.alpha2 || previousCountry.name == country.name {
selectedCountry = country
break
}
} else if country.alpha2 == regionCode || country.name == Locale.current.localizedString(forRegionCode:regionCode) || country.name == Locale(identifier: "en_US").localizedString(forRegionCode:regionCode) {
selectedCountry = country
break
}
}
phoneNumberFocused = true
}
} else if let number = state.phoneNumber {
} else if let number = state.phoneNumber, let _ = state.country {
VStack(alignment: .leading) {
Text("Verify your phone number")
.font(.title)
Expand Down Expand Up @@ -389,6 +405,8 @@ struct Quicksy_RegisterAccount: View {
.onAppear {
pinFocused = true
}
} else {
unreachable("quicksy registration out of ui options!")
}
}
.alert(isPresented: $showAlert) {
Expand Down
3 changes: 3 additions & 0 deletions Monal/Classes/SwiftHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ public typealias monal_id_block_t = @convention(block) (AnyObject?) -> Void;
public typealias monal_id_returning_void_block_t = @convention(block) () -> AnyObject?;
public typealias monal_id_returning_id_block_t = @convention(block) (AnyObject?) -> AnyObject?;

extension MLContact : Identifiable {} //make MLContact be usable in swiftui ForEach clauses etc.
extension Quicksy_Country : Identifiable {} //make Quicksy_Country be usable in swiftui ForEach clauses etc.

//see https://stackoverflow.com/a/40629365/3528174
extension String: Error {}

Expand Down
2 changes: 0 additions & 2 deletions Monal/Classes/SwiftuiHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import FLAnimatedImage
import OrderedCollections
import CropViewController

extension MLContact : Identifiable {} //make MLContact be usable in swiftui ForEach clauses

let monalGreen = Color(UIColor(red:128.0/255, green:203.0/255, blue:182.0/255, alpha:1.0));
let monalDarkGreen = Color(UIColor(red:20.0/255, green:138.0/255, blue:103.0/255, alpha:1.0));

Expand Down

0 comments on commit 58bb0d4

Please sign in to comment.