From 500ff4eabad5e22377e774017cd16baeb89b1929 Mon Sep 17 00:00:00 2001 From: Sam Steele Date: Fri, 3 Jan 2025 07:32:01 -0500 Subject: [PATCH] Add a button to request a password reset from the login screen --- IRCCloud/Classes/LoginSplashViewController.h | 3 + IRCCloud/Classes/LoginSplashViewController.m | 71 +++++++++++++++----- IRCCloud/Classes/NetworkConnection.h | 3 +- IRCCloud/Classes/NetworkConnection.m | 6 +- IRCCloud/MainStoryboard.storyboard | 46 +++++++++++-- 5 files changed, 104 insertions(+), 25 deletions(-) diff --git a/IRCCloud/Classes/LoginSplashViewController.h b/IRCCloud/Classes/LoginSplashViewController.h index 763f0279..260b5932 100644 --- a/IRCCloud/Classes/LoginSplashViewController.h +++ b/IRCCloud/Classes/LoginSplashViewController.h @@ -50,6 +50,7 @@ IBOutlet UIControl *signupHint; IBOutlet UIControl *loginHint; IBOutlet UIControl *forgotPasswordHint; + IBOutlet UIControl *resetPasswordHint; IBOutlet UIControl *TOSHint; IBOutlet UIControl *enterpriseLearnMore; IBOutlet UIControl *forgotPasswordLogin; @@ -65,6 +66,7 @@ CGSize _kbSize; NSURL *_accessLink; BOOL _gotCredentialsFromPasswordManager; + BOOL _requestingReset; NSString *_authURL; } @property NSURL *accessLink; @@ -74,6 +76,7 @@ -(IBAction)loginHintPressed:(id)sender; -(IBAction)signupHintPressed:(id)sender; -(IBAction)forgotPasswordHintPressed:(id)sender; +-(IBAction)resetPasswordHintPressed:(id)sender; -(IBAction)TOSHintPressed:(id)sender; -(IBAction)nextButtonPressed:(id)sender; -(IBAction)enterpriseLearnMorePressed:(id)sender; diff --git a/IRCCloud/Classes/LoginSplashViewController.m b/IRCCloud/Classes/LoginSplashViewController.m index f5ac415c..c0fbe55f 100644 --- a/IRCCloud/Classes/LoginSplashViewController.m +++ b/IRCCloud/Classes/LoginSplashViewController.m @@ -92,6 +92,11 @@ - (void)viewDidLoad { [l sizeToFit]; } + for(UILabel *l in resetPasswordHint.subviews) { + l.font = sourceSansPro; + [l sizeToFit]; + } + for(UILabel *l in TOSHint.subviews) { l.font = sourceSansPro; [l sizeToFit]; @@ -410,6 +415,7 @@ -(IBAction)loginHintPressed:(id)sender { else enterpriseHint.alpha = 1; forgotPasswordHint.alpha = 1; + resetPasswordHint.alpha = 1; TOSHint.alpha = 0; forgotPasswordLogin.alpha = 0; forgotPasswordSignup.alpha = 0; @@ -432,6 +438,7 @@ -(IBAction)signupHintPressed:(id)sender { loginHint.alpha = 1; signupHint.alpha = 0; forgotPasswordHint.alpha = 0; + resetPasswordHint.alpha = 0; TOSHint.alpha = 1; forgotPasswordLogin.alpha = 0; forgotPasswordSignup.alpha = 0; @@ -451,6 +458,7 @@ -(IBAction)forgotPasswordHintPressed:(id)sender { password.alpha = 0; signupHint.alpha = 0; forgotPasswordHint.alpha = 0; + resetPasswordHint.alpha = 0; enterpriseHint.alpha = 0; forgotPasswordLogin.alpha = 1; @@ -462,6 +470,16 @@ -(IBAction)forgotPasswordHintPressed:(id)sender { if(sender) [UIView commitAnimations]; [self _updateFieldPositions]; + _requestingReset = NO; + [sendAccessLink setTitle:@"Request access link" forState:UIControlStateNormal]; + [enterEmailAddressHint setText:@"Just enter the email address you signed up with and we'll send you a link to log straight in."]; +} + +-(void)resetPasswordHintPressed:(id)sender { + [self forgotPasswordHintPressed:sender]; + _requestingReset = YES; + [sendAccessLink setTitle:@"Request password reset" forState:UIControlStateNormal]; + [enterEmailAddressHint setText:@"Just enter the email address you signed up with and we'll send you a link to reset your password."]; } -(void)_accessLinkRequestFailed { @@ -470,7 +488,7 @@ -(void)_accessLinkRequestFailed { self->loadingView.alpha = 0; [UIView commitAnimations]; [self->activity stopAnimating]; - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Request Failed" message:@"Unable to request an access link. Please try again later." preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Request Failed" message:self->_requestingReset?@"Unable to request a password reset. Please try again later.":@"Unable to request an access link. Please try again later." preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleCancel handler:nil]]; [self presentViewController:alert animated:YES completion:nil]; } @@ -481,28 +499,46 @@ -(IBAction)sendAccessLinkButtonPressed:(id)sender { loginView.alpha = 0; loadingView.alpha = 1; [UIView commitAnimations]; - [status setText:@"Requesting Access Link"]; + [status setText:self->_requestingReset?@"Requesting Password Reset":@"Requesting Access Link"]; UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, status.text); [activity startAnimating]; activity.hidden = NO; NSString *user = [username.text stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet]; [[NetworkConnection sharedInstance] requestAuthTokenWithHandler:^(IRCCloudJSONObject *result) { if([[result objectForKey:@"success"] intValue] == 1) { - [[NetworkConnection sharedInstance] requestPassword:user token:[result objectForKey:@"token"] handler:^(IRCCloudJSONObject *result) { - if([[result objectForKey:@"success"] intValue] == 1) { - [UIView beginAnimations:nil context:nil]; - self->loginView.alpha = 1; - self->loadingView.alpha = 0; - [UIView commitAnimations]; - [self->activity stopAnimating]; - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Email Sent" message:@"We've sent you an access link. Check your email and follow the instructions to sign in." preferredStyle:UIAlertControllerStyleAlert]; - [alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleCancel handler:nil]]; - [self presentViewController:alert animated:YES completion:nil]; - [self loginHintPressed:nil]; - } else { - [self _accessLinkRequestFailed]; - } - }]; + if(self->_requestingReset) { + [[NetworkConnection sharedInstance] requestPasswordReset:user token:[result objectForKey:@"token"] handler:^(IRCCloudJSONObject *result) { + if([[result objectForKey:@"success"] intValue] == 1) { + [UIView beginAnimations:nil context:nil]; + self->loginView.alpha = 1; + self->loadingView.alpha = 0; + [UIView commitAnimations]; + [self->activity stopAnimating]; + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Email Sent" message:@"We've sent you a password reset link. Check your email and follow the instructions to sign in." preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController:alert animated:YES completion:nil]; + [self loginHintPressed:nil]; + } else { + [self _accessLinkRequestFailed]; + } + }]; + } else { + [[NetworkConnection sharedInstance] requestAccessLink:user token:[result objectForKey:@"token"] handler:^(IRCCloudJSONObject *result) { + if([[result objectForKey:@"success"] intValue] == 1) { + [UIView beginAnimations:nil context:nil]; + self->loginView.alpha = 1; + self->loadingView.alpha = 0; + [UIView commitAnimations]; + [self->activity stopAnimating]; + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Email Sent" message:@"We've sent you an access link. Check your email and follow the instructions to sign in." preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController:alert animated:YES completion:nil]; + [self loginHintPressed:nil]; + } else { + [self _accessLinkRequestFailed]; + } + }]; + } } else { [self _accessLinkRequestFailed]; } @@ -660,6 +696,7 @@ -(IBAction)nextButtonPressed:(id)sender { self->username.alpha = 1; self->password.alpha = 1; self->forgotPasswordHint.alpha = 1; + self->resetPasswordHint.alpha = 1; } if(self->signupHint.enabled) self->signupHint.alpha = 1; diff --git a/IRCCloud/Classes/NetworkConnection.h b/IRCCloud/Classes/NetworkConnection.h index df16a068..91e70660 100644 --- a/IRCCloud/Classes/NetworkConnection.h +++ b/IRCCloud/Classes/NetworkConnection.h @@ -279,6 +279,7 @@ typedef void (^IRCCloudAPIResultHandler)(IRCCloudJSONObject *result); -(void)POSTheartbeat:(int)selectedBuffer cids:(NSArray *)cids bids:(NSArray *)bids lastSeenEids:(NSArray *)lastSeenEids handler:(IRCCloudAPIResultHandler)handler; -(void)registerAPNs:(NSData *)token fcm:(NSString *)fcm handler:(IRCCloudAPIResultHandler)handler; -(void)unregisterAPNs:(NSData *)token fcm:(NSString *)fcm session:(NSString *)session handler:(IRCCloudAPIResultHandler)handler; --(void)requestPassword:(NSString *)email token:(NSString *)token handler:(IRCCloudAPIResultHandler)handler; +-(void)requestAccessLink:(NSString *)email token:(NSString *)token handler:(IRCCloudAPIResultHandler)handler; +-(void)requestPasswordReset:(NSString *)email token:(NSString *)token handler:(IRCCloudAPIResultHandler)handler; -(void)finalizeUpload:(NSString *)uploadID filename:(NSString *)filename originalFilename:(NSString *)originalFilename avatar:(BOOL)avatar orgId:(int)orgId cid:(int)cid handler:(IRCCloudAPIResultHandler)handler; @end diff --git a/IRCCloud/Classes/NetworkConnection.m b/IRCCloud/Classes/NetworkConnection.m index 43c25b24..3e0a7a2f 100644 --- a/IRCCloud/Classes/NetworkConnection.m +++ b/IRCCloud/Classes/NetworkConnection.m @@ -1331,7 +1331,11 @@ -(void)signup:(NSString *)email password:(NSString *)password realname:(NSString [self _postRequest:@"/chat/signup" args:@{@"realname":realname, @"email":email, @"password":password, @"token":token} handler:handler]; } --(void)requestPassword:(NSString *)email token:(NSString *)token handler:(IRCCloudAPIResultHandler)handler { +-(void)requestPasswordReset:(NSString *)email token:(NSString *)token handler:(IRCCloudAPIResultHandler)handler { + return [self _postRequest:@"/chat/request-password-reset" args:@{@"email":email, @"mobile":@"1", @"token":token} handler:handler]; +} + +-(void)requestAccessLink:(NSString *)email token:(NSString *)token handler:(IRCCloudAPIResultHandler)handler { return [self _postRequest:@"/chat/request-access-link" args:@{@"email":email, @"mobile":@"1", @"token":token} handler:handler]; } diff --git a/IRCCloud/MainStoryboard.storyboard b/IRCCloud/MainStoryboard.storyboard index 4eb2011b..a326c19d 100644 --- a/IRCCloud/MainStoryboard.storyboard +++ b/IRCCloud/MainStoryboard.storyboard @@ -1,9 +1,9 @@ - + - + @@ -438,16 +438,16 @@ - + + + + + + + + + + + + + + + + + + + + + + @@ -564,6 +595,8 @@ + + @@ -663,6 +696,7 @@ +