Support msisdn registration

This commit is contained in:
giomfo 2017-03-05 18:21:37 +01:00
parent f63a0c490a
commit bdb7ef1ae2
4 changed files with 456 additions and 112 deletions

View file

@ -294,7 +294,7 @@
AuthInputsView *authInputsview = (AuthInputsView*)self.authInputsView;
// Show the 3rd party ids screen if it is not shown yet
if (authInputsview.isThirdPartyIdentifiersSupported && authInputsview.isThirdPartyIdentifiersHidden)
if (authInputsview.areThirdPartyIdentifiersSupported && authInputsview.isThirdPartyIdentifiersHidden)
{
[self dismissKeyboard];
@ -320,6 +320,9 @@
[self.authenticationActivityIndicator stopAnimating];
// Show the supported 3rd party ids which may be added to the account
// Retrieve the MCC from the SIM card information (Note: the phone book country code is not defined yet)
authInputsview.isoCountryCode = [MXKAppSettings standardAppSettings].phonebookCountryCode;
authInputsview.delegate = self;
authInputsview.thirdPartyIdentifiersHidden = NO;
[self updateRegistrationScreenWithThirdPartyIdentifiersHidden:NO];
@ -419,6 +422,35 @@
}
}
- (void)onSuccessfulLogin:(MXCredentials*)credentials
{
// Check whether a third party identifiers has not been used
if ([self.authInputsView isKindOfClass:AuthInputsView.class])
{
AuthInputsView *authInputsview = (AuthInputsView*)self.authInputsView;
if (authInputsview.isThirdPartyIdentifierPending)
{
// Alert user
if (alert)
{
[alert dismiss:NO];
}
alert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"warning", @"Vector", nil) message:NSLocalizedStringFromTable(@"auth_add_email_and_phone_warning", @"Vector", nil) style:MXKAlertStyleAlert];
[alert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] style:MXKAlertActionStyleCancel handler:^(MXKAlert *alert)
{
[super onSuccessfulLogin:credentials];
}];
[alert showInViewController:self];
return;
}
}
[super onSuccessfulLogin:credentials];
}
- (void)updateForgotPwdButtonVisibility
{
self.forgotPasswordButton.hidden = (self.authType != MXKAuthenticationTypeLogin);
@ -598,4 +630,18 @@
}
}
#pragma mark - MXKAuthInputsViewDelegate
- (void)authInputsView:(MXKAuthInputsView *)authInputsView presentViewController:(UIViewController*)viewControllerToPresent
{
[self dismissKeyboard];
[self presentViewController:viewControllerToPresent animated:YES completion:nil];
}
- (void)authInputsViewDidCancelOperation:(MXKAuthInputsView *)authInputsView
{
[self cancel];
}
@end

View file

@ -53,7 +53,17 @@
/**
Tell whether some third-party identifiers may be added during the account registration.
*/
@property (nonatomic, readonly) BOOL isThirdPartyIdentifiersSupported;
@property (nonatomic, readonly) BOOL areThirdPartyIdentifiersSupported;
/**
Tell whether at least one third-party identifier is required to create a new account.
*/
@property (nonatomic, readonly) BOOL isThirdPartyIdentifierRequired;
/**
Tell whether all the supported third-party identifiers are required to create a new account.
*/
@property (nonatomic, readonly) BOOL areAllThirdPartyIdentifiersRequired;
/**
Update the registration inputs layout by hidding the third-party identifiers fields (YES by default).
@ -61,6 +71,11 @@
*/
@property (nonatomic, getter=isThirdPartyIdentifiersHidden) BOOL thirdPartyIdentifiersHidden;
/**
Tell whether a second third-party identifier is waiting for being added to the new account.
*/
@property (nonatomic, readonly) BOOL isThirdPartyIdentifierPending;
/**
The current selected country code
*/

View file

@ -34,6 +34,7 @@
The current msisdn validation
*/
MXK3PID *submittedMSISDN;
UINavigationController *phoneNumberPickerNavigationController;
CountryPickerViewController *phoneNumberCountryPicker;
NBPhoneNumber *newPhoneNumber;
@ -43,6 +44,11 @@
NSDictionary *externalRegistrationParameters;
}
/**
The current view container displayed at last position.
*/
@property (nonatomic) UIView *currentLastContainer;
@end
@implementation AuthInputsView
@ -72,6 +78,7 @@
self.messageLabel.numberOfLines = 0;
_thirdPartyIdentifiersHidden = YES;
_isThirdPartyIdentifierPending = NO;
}
- (void)destroy
@ -86,18 +93,10 @@
{
[super layoutSubviews];
CGRect lastItemFrame;
if (self.recaptchaWebView.isHidden)
if (_currentLastContainer)
{
lastItemFrame = self.repeatPasswordContainer.frame;
self.currentLastContainer = _currentLastContainer;
}
else
{
lastItemFrame = self.recaptchaWebView.frame;
}
self.viewHeightConstraint.constant = lastItemFrame.origin.y + lastItemFrame.size.height;
}
#pragma mark -
@ -140,8 +139,7 @@
self.userLoginContainer.hidden = NO;
self.passwordContainer.hidden = NO;
CGRect frame = self.passwordContainer.frame;
self.viewHeightConstraint.constant = frame.origin.y + frame.size.height;
self.currentLastContainer = self.passwordContainer;
}
else
{
@ -226,35 +224,54 @@
}
else
{
if (self.isEmailIdentityFlowRequired && !self.emailTextField.text.length)
// Check email field
if (self.isEmailIdentityFlowSupported && !self.emailTextField.text.length)
{
NSLog(@"[AuthInputsView] Missing email");
errorMsg = NSLocalizedStringFromTable(@"auth_missing_email", @"Vector", nil);
}
else if (self.isMSISDNFlowRequired && !self.phoneTextField.text.length)
{
NSLog(@"[AuthInputsView] Missing phone");
errorMsg = NSLocalizedStringFromTable(@"auth_missing_phone", @"Vector", nil);
}
else
{
if (self.emailTextField.text.length)
if (self.areAllThirdPartyIdentifiersRequired)
{
// Check validity of the non empty email
if (![MXTools isEmailAddress:self.emailTextField.text])
NSLog(@"[AuthInputsView] Missing email");
errorMsg = NSLocalizedStringFromTable(@"auth_missing_email", @"Vector", nil);
}
else if (self.isMSISDNFlowSupported && !self.phoneTextField.text.length && self.isThirdPartyIdentifierRequired)
{
NSLog(@"[AuthInputsView] Missing email or phone number");
errorMsg = NSLocalizedStringFromTable(@"auth_missing_email_or_phone", @"Vector", nil);
}
}
if (!errorMsg)
{
// Check phone field
if (self.isMSISDNFlowSupported && !self.phoneTextField.text.length)
{
if (self.areAllThirdPartyIdentifiersRequired)
{
NSLog(@"[AuthInputsView] Invalid email");
errorMsg = NSLocalizedStringFromTable(@"auth_invalid_email", @"Vector", nil);
NSLog(@"[AuthInputsView] Missing phone");
errorMsg = NSLocalizedStringFromTable(@"auth_missing_phone", @"Vector", nil);
}
}
if (!errorMsg && newPhoneNumber)
if (!errorMsg)
{
// Check validity of the non empty phone
if (![[NBPhoneNumberUtil sharedInstance] isValidNumber:newPhoneNumber])
// Check email/phone validity
if (self.emailTextField.text.length)
{
NSLog(@"[AuthInputsView] Invalid phone number");
errorMsg = NSLocalizedStringFromTable(@"auth_invalid_phone", @"Vector", nil);
// Check validity of the non empty email
if (![MXTools isEmailAddress:self.emailTextField.text])
{
NSLog(@"[AuthInputsView] Invalid email");
errorMsg = NSLocalizedStringFromTable(@"auth_invalid_email", @"Vector", nil);
}
}
if (!errorMsg && newPhoneNumber)
{
// Check validity of the non empty phone
if (![[NBPhoneNumberUtil sharedInstance] isValidNumber:newPhoneNumber])
{
NSLog(@"[AuthInputsView] Invalid phone number");
errorMsg = NSLocalizedStringFromTable(@"auth_invalid_phone", @"Vector", nil);
}
}
}
}
@ -347,9 +364,11 @@
}
else if (type == MXKAuthenticationTypeRegister)
{
// Check whether an email has been set, and if it is not handled yet
if (!self.emailContainer.isHidden && self.emailTextField.text.length && !self.isEmailIdentityFlowCompleted)
// Check whether a phone number has been set, and if it is not handled yet
if (newPhoneNumber && !self.isMSISDNFlowCompleted)
{
NSLog(@"[AuthInputsView] Prepare msisdn stage");
// Retrieve the REST client from delegate
MXRestClient *restClient;
@ -360,6 +379,65 @@
if (restClient)
{
// Check whether a second 3pid is available
_isThirdPartyIdentifierPending = (!self.emailContainer.isHidden && self.emailTextField.text.length && !self.isEmailIdentityFlowCompleted);
// Launch msisdn validation
NSString *e164 = [[NBPhoneNumberUtil sharedInstance] format:newPhoneNumber numberFormat:NBEPhoneNumberFormatE164 error:nil];
NSString *msisdn;
if ([e164 hasPrefix:@"+"])
{
msisdn = [e164 substringFromIndex:1];
}
else if ([e164 hasPrefix:@"00"])
{
msisdn = [e164 substringFromIndex:2];
}
submittedMSISDN = [[MXK3PID alloc] initWithMedium:kMX3PIDMediumMSISDN andAddress:msisdn];
[submittedMSISDN requestValidationTokenWithMatrixRestClient:restClient
nextLink:nil
success:^{
[self showValidationMSISDNDialogToPrepareParameters:callback];
} failure:^(NSError *error) {
NSLog(@"[AuthInputsView] Failed to request msisdn token");
// Ignore connection cancellation error
if (([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled))
{
return;
}
callback(nil);
}];
// Async response
return;
}
NSLog(@"[AuthInputsView] Authentication failed during the msisdn stage");
}
// Check whether an email has been set, and if it is not handled yet
else if (!self.emailContainer.isHidden && self.emailTextField.text.length && !self.isEmailIdentityFlowCompleted)
{
NSLog(@"[AuthInputsView] Prepare email identity stage");
// Retrieve the REST client from delegate
MXRestClient *restClient;
if (self.delegate && [self.delegate respondsToSelector:@selector(authInputsViewEmailValidationRestClient:)])
{
restClient = [self.delegate authInputsViewEmailValidationRestClient:self];
}
if (restClient)
{
// Check whether a second 3pid is available
_isThirdPartyIdentifierPending = (newPhoneNumber && !self.isMSISDNFlowCompleted);
// Launch email validation
submittedEmail = [[MXK3PID alloc] initWithMedium:kMX3PIDMediumEmail andAddress:self.emailTextField.text];
@ -381,6 +459,7 @@
@"auth": @{@"session":currentSession.session, @"threepid_creds": @{@"client_secret": submittedEmail.clientSecret, @"id_server": identServerURL.host, @"sid": submittedEmail.sid}, @"type": kMXLoginFlowTypeEmailIdentity},
@"username": self.userLoginTextField.text,
@"password": self.passWordTextField.text,
@"bind_msisdn": [NSNumber numberWithBool:self.isMSISDNFlowCompleted],
@"bind_email": @(YES)
};
@ -408,13 +487,12 @@
// Async response
return;
}
else if (self.isEmailIdentityFlowRequired)
{
NSLog(@"[AuthInputsView] Authentication failed during the email identity stage");
}
NSLog(@"[AuthInputsView] Authentication failed during the email identity stage");
}
else if (self.isRecaptchaFlowRequired)
{
NSLog(@"[AuthInputsView] Prepare reCaptcha stage");
[self displayRecaptchaForm:^(NSString *response) {
if (response.length)
@ -423,6 +501,7 @@
@"auth": @{@"session":currentSession.session, @"response": response, @"type": kMXLoginFlowTypeRecaptcha},
@"username": self.userLoginTextField.text,
@"password": self.passWordTextField.text,
@"bind_msisdn": [NSNumber numberWithBool:self.isMSISDNFlowCompleted],
@"bind_email": [NSNumber numberWithBool:self.isEmailIdentityFlowCompleted]
};
@ -445,6 +524,7 @@
@"auth": @{@"session":currentSession.session, @"type": kMXLoginFlowTypeDummy},
@"username": self.userLoginTextField.text,
@"password": self.passWordTextField.text,
@"bind_msisdn": @(NO),
@"bind_email": @(NO)
};
}
@ -470,9 +550,20 @@
{
currentSession.completed = completedStages;
// Check the supported use case
if ([completedStages indexOfObject:kMXLoginFlowTypeEmailIdentity] != NSNotFound && self.isRecaptchaFlowRequired)
// Check the supported use cases
if ([completedStages indexOfObject:kMXLoginFlowTypeMSISDN] != NSNotFound && self.isThirdPartyIdentifierPending)
{
NSLog(@"[AuthInputsView] Prepare a new third-party stage");
// Here an email address is available, we add it to the authentication session.
[self prepareParameters:callback];
return;
}
else if ([completedStages indexOfObject:kMXLoginFlowTypeEmailIdentity] != NSNotFound && self.isRecaptchaFlowRequired)
{
NSLog(@"[AuthInputsView] Display reCaptcha stage");
[self displayRecaptchaForm:^(NSString *response) {
if (response.length)
@ -493,6 +584,7 @@
@"auth": @{@"session": currentSession.session, @"response": response, @"type": kMXLoginFlowTypeRecaptcha},
@"username": self.userLoginTextField.text,
@"password": self.passWordTextField.text,
@"bind_msisdn": [NSNumber numberWithBool:self.isMSISDNFlowCompleted],
@"bind_email": @(YES)
};
}
@ -622,11 +714,22 @@
[self.userLoginTextField resignFirstResponder];
[self.passWordTextField resignFirstResponder];
[self.emailTextField resignFirstResponder];
[self.phoneTextField resignFirstResponder];
[self.repeatPasswordTextField resignFirstResponder];
[super dismissKeyboard];
}
- (void)dismissCountryPicker
{
[phoneNumberCountryPicker withdrawViewControllerAnimated:YES completion:nil];
[phoneNumberCountryPicker destroy];
phoneNumberCountryPicker = nil;
[phoneNumberPickerNavigationController dismissViewControllerAnimated:YES completion:nil];
phoneNumberPickerNavigationController = nil;
}
- (NSString*)userId
{
return self.userLoginTextField.text;
@ -637,19 +740,98 @@
return self.passWordTextField.text;
}
- (void)setCurrentLastContainer:(UIView*)currentLastContainer
{
_currentLastContainer = currentLastContainer;
CGRect frame = _currentLastContainer.frame;
self.viewHeightConstraint.constant = frame.origin.y + frame.size.height;
}
#pragma mark -
- (BOOL)isThirdPartyIdentifiersSupported
- (BOOL)areThirdPartyIdentifiersSupported
{
return (self.isEmailIdentityFlowSupported || self.isMSISDNFlowSupported);
}
- (BOOL)isThirdPartyIdentifierRequired
{
// Check first whether some 3pids are supported
if (!self.areThirdPartyIdentifiersSupported)
{
return NO;
}
// Check whether an account may be created without third-party identifiers.
for (MXLoginFlow *loginFlow in currentSession.flows)
{
if ([loginFlow.stages indexOfObject:kMXLoginFlowTypeDummy] != NSNotFound || [loginFlow.type isEqualToString:kMXLoginFlowTypeDummy])
{
// The dummy flow is supported, the 3pid are then optional.
return NO;
}
if ((loginFlow.stages.count == 1 && [loginFlow.stages[0] isEqualToString:kMXLoginFlowTypeRecaptcha]) || [loginFlow.type isEqualToString:kMXLoginFlowTypeRecaptcha])
{
// The recaptcha flow is supported alone, the 3pids are then optional.
return NO;
}
if ((loginFlow.stages.count == 1 && [loginFlow.stages[0] isEqualToString:kMXLoginFlowTypePassword]) || [loginFlow.type isEqualToString:kMXLoginFlowTypePassword])
{
// The password flow is supported alone, the 3pids are then optional.
return NO;
}
}
return YES;
}
- (BOOL)areAllThirdPartyIdentifiersRequired
{
// Check first whether some 3pids are required
if (!self.isThirdPartyIdentifierRequired)
{
return NO;
}
BOOL isEmailIdentityFlowSupported = self.isEmailIdentityFlowSupported;
BOOL isMSISDNFlowSupported = self.isMSISDNFlowSupported;
for (MXLoginFlow *loginFlow in currentSession.flows)
{
if (isEmailIdentityFlowSupported)
{
if ([loginFlow.stages indexOfObject:kMXLoginFlowTypeEmailIdentity] == NSNotFound)
{
return NO;
}
else if (isMSISDNFlowSupported)
{
if ([loginFlow.stages indexOfObject:kMXLoginFlowTypeMSISDN] == NSNotFound)
{
return NO;
}
}
}
else if (isMSISDNFlowSupported)
{
if ([loginFlow.stages indexOfObject:kMXLoginFlowTypeMSISDN] == NSNotFound)
{
return NO;
}
}
}
return YES;
}
- (void)setThirdPartyIdentifiersHidden:(BOOL)thirdPartyIdentifiersHidden
{
[self hideInputsContainer];
CGFloat viewHeight = 0;
UIView *lastViewContainer;
if (thirdPartyIdentifiersHidden)
{
@ -661,13 +843,13 @@
self.passwordContainer.hidden = NO;
self.repeatPasswordContainer.hidden = NO;
viewHeight = 150;
lastViewContainer = self.repeatPasswordContainer;
}
else
{
if (self.isEmailIdentityFlowSupported)
{
if (self.isEmailIdentityFlowRequired)
if (self.isThirdPartyIdentifierRequired)
{
self.emailTextField.placeholder = NSLocalizedStringFromTable(@"auth_email_placeholder", @"Vector", nil);
}
@ -681,12 +863,12 @@
self.messageLabel.hidden = NO;
self.messageLabel.text = NSLocalizedStringFromTable(@"auth_add_email_message", @"Vector", nil);
viewHeight = 50;
lastViewContainer = self.emailContainer;
}
if (self.isMSISDNFlowSupported)
{
if (self.isMSISDNFlowRequired)
if (self.isThirdPartyIdentifierRequired)
{
self.phoneTextField.placeholder = NSLocalizedStringFromTable(@"auth_phone_placeholder", @"Vector", nil);
}
@ -703,17 +885,22 @@
self.phoneContainerTopConstraint.constant = 50;
self.messageLabel.text = NSLocalizedStringFromTable(@"auth_add_email_msisdn_message", @"Vector", nil);
viewHeight = 100;
if (self.areAllThirdPartyIdentifiersRequired)
{
self.messageLabel.text = NSLocalizedStringFromTable(@"auth_add_email_and_phone_message", @"Vector", nil);
}
else
{
self.messageLabel.text = NSLocalizedStringFromTable(@"auth_add_email_phone_message", @"Vector", nil);
}
}
else
{
self.messageLabel.hidden = NO;
self.messageLabel.text = NSLocalizedStringFromTable(@"auth_add_phone_message", @"Vector", nil);
viewHeight = 50;
}
lastViewContainer = self.phoneContainer;
}
if (!self.messageLabel.isHidden)
@ -722,15 +909,14 @@
CGRect frame = self.messageLabel.frame;
CGFloat offset = frame.origin.x + frame.size.height;
CGFloat offset = frame.origin.y + frame.size.height;
self.emailContainerTopConstraint.constant = offset;
self.phoneContainerTopConstraint.constant += offset;
viewHeight += offset;
}
}
self.viewHeightConstraint.constant = viewHeight;
self.currentLastContainer = lastViewContainer;
_thirdPartyIdentifiersHidden = thirdPartyIdentifiersHidden;
}
@ -743,7 +929,13 @@
phoneNumberCountryPicker.delegate = self;
phoneNumberCountryPicker.showCountryCallingCode = YES;
[self.delegate authInputsView:self presentViewController:phoneNumberCountryPicker];
phoneNumberPickerNavigationController = [[UINavigationController alloc] init];
[phoneNumberPickerNavigationController pushViewController:phoneNumberCountryPicker animated:NO];
UIBarButtonItem *leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back_icon"] style:UIBarButtonItemStylePlain target:self action:@selector(dismissCountryPicker)];
phoneNumberCountryPicker.navigationItem.leftBarButtonItem = leftBarButtonItem;
[self.delegate authInputsView:self presentViewController:phoneNumberPickerNavigationController];
}
}
@ -780,8 +972,7 @@
newPhoneNumber = [[NBPhoneNumberUtil sharedInstance] parse:self.phoneTextField.text defaultRegion:isoCountryCode error:nil];
[self formatNewPhoneNumber];
[countryPickerViewController withdrawViewControllerAnimated:YES completion:nil];
phoneNumberCountryPicker = nil;
[self dismissCountryPicker];
}
#pragma mark - UITextField delegate
@ -844,6 +1035,8 @@
// Hide other items
self.messageLabel.hidden = YES;
self.recaptchaWebView.hidden = YES;
_currentLastContainer = nil;
}
- (void)formatNewPhoneNumber
@ -889,8 +1082,7 @@
self.messageLabel.text = NSLocalizedStringFromTable(@"auth_recaptcha_message", @"Vector", nil);
self.recaptchaWebView.hidden = NO;
CGRect frame = self.recaptchaWebView.frame;
self.viewHeightConstraint.constant = frame.origin.y + frame.size.height;
self.currentLastContainer = self.recaptchaWebView;
[self.recaptchaWebView openRecaptchaWidgetWithSiteKey:siteKey fromHomeServer:restClient.homeserver callback:callback];
@ -1013,6 +1205,133 @@
return nil;
}
- (void)showValidationMSISDNDialogToPrepareParameters:(void (^)(NSDictionary *parameters))callback
{
__weak typeof(self) weakSelf = self;
if (inputsAlert)
{
[inputsAlert dismiss:NO];
}
inputsAlert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"auth_msisdn_validation_title", @"Vector", nil)
message:NSLocalizedStringFromTable(@"auth_msisdn_validation_message", @"Vector", nil)
style:MXKAlertStyleAlert];
inputsAlert.cancelButtonIndex = [inputsAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"abort"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert){
if (weakSelf)
{
typeof(self) self = weakSelf;
self->inputsAlert = nil;
if (self.delegate && [self.delegate respondsToSelector:@selector(authInputsViewDidCancelOperation:)])
{
[self.delegate authInputsViewDidCancelOperation:self];
}
}
}];
[inputsAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.secureTextEntry = NO;
textField.placeholder = nil;
textField.keyboardType = UIKeyboardTypeDecimalPad;
}];
[inputsAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"submit"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) {
UITextField *textField = [alert textFieldAtIndex:0];
NSString *smsCode = textField.text;
if (weakSelf)
{
typeof(self) self = weakSelf;
self->inputsAlert = nil;
if (smsCode.length)
{
[self->submittedMSISDN submitValidationToken:smsCode success:^{
// Retrieve the REST client from delegate
MXRestClient *restClient;
if (self.delegate && [self.delegate respondsToSelector:@selector(authInputsViewEmailValidationRestClient:)])
{
restClient = [self.delegate authInputsViewEmailValidationRestClient:self];
}
NSURL *identServerURL = [NSURL URLWithString:restClient.identityServer];
NSDictionary *parameters;
parameters = @{
@"auth": @{@"session":self->currentSession.session, @"threepid_creds": @{@"client_secret": self->submittedMSISDN.clientSecret, @"id_server": identServerURL.host, @"sid": self->submittedMSISDN.sid}, @"type": kMXLoginFlowTypeMSISDN},
@"username": self.userLoginTextField.text,
@"password": self.passWordTextField.text,
@"bind_msisdn": @(YES),
@"bind_email": [NSNumber numberWithBool:self.isEmailIdentityFlowCompleted]
};
callback(parameters);
} failure:^(NSError *error) {
NSLog(@"[AuthInputsView] Failed to submit the sms token");
// Ignore connection cancellation error
if (([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled))
{
return;
}
// Alert user
NSString *title = [error.userInfo valueForKey:NSLocalizedFailureReasonErrorKey];
NSString *msg = [error.userInfo valueForKey:NSLocalizedDescriptionKey];
if (!title)
{
if (msg)
{
title = msg;
msg = nil;
}
else
{
title = [NSBundle mxk_localizedStringForKey:@"error"];
}
}
self->inputsAlert = [[MXKAlert alloc] initWithTitle:title message:msg style:MXKAlertStyleAlert];
self->inputsAlert.cancelButtonIndex = [self->inputsAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->inputsAlert = nil;
// Ask again for the token
[self showValidationMSISDNDialogToPrepareParameters:callback];
}
}];
self->inputsAlert.mxkAccessibilityIdentifier = @"AuthInputsViewErrorAlert";
[self.delegate authInputsView:self presentMXKAlert:self->inputsAlert];
}];
}
else
{
// Ask again for the token
[self showValidationMSISDNDialogToPrepareParameters:callback];
}
}
}];
inputsAlert.mxkAccessibilityIdentifier = @"AuthInputsViewMsisdnValidationAlert";
[self.delegate authInputsView:self presentMXKAlert:inputsAlert];
}
- (BOOL)isPasswordBasedFlowSupported
{
if (currentSession)
@ -1045,24 +1364,6 @@
return NO;
}
- (BOOL)isEmailIdentityFlowRequired
{
if (currentSession && currentSession.flows)
{
for (MXLoginFlow *loginFlow in currentSession.flows)
{
if ([loginFlow.stages indexOfObject:kMXLoginFlowTypeEmailIdentity] == NSNotFound && ![loginFlow.type isEqualToString:kMXLoginFlowTypeEmailIdentity])
{
return NO;
}
}
return YES;
}
return NO;
}
- (BOOL)isEmailIdentityFlowCompleted
{
if (currentSession && currentSession.completed)
@ -1092,24 +1393,6 @@
return NO;
}
- (BOOL)isMSISDNFlowRequired
{
if (currentSession && currentSession.flows)
{
for (MXLoginFlow *loginFlow in currentSession.flows)
{
if ([loginFlow.stages indexOfObject:kMXLoginFlowTypeMSISDN] == NSNotFound && ![loginFlow.type isEqualToString:kMXLoginFlowTypeMSISDN])
{
return NO;
}
}
return YES;
}
return NO;
}
- (BOOL)isMSISDNFlowCompleted
{
if (currentSession && currentSession.completed)
@ -1123,7 +1406,6 @@
return NO;
}
- (BOOL)isRecaptchaFlowRequired
{
if (currentSession && currentSession.flows)

View file

@ -127,13 +127,14 @@
<constraints>
<constraint firstAttribute="width" constant="44" id="Jm3-K6-0hG"/>
</constraints>
<inset key="imageEdgeInsets" minX="0.0" minY="5" maxX="0.0" maxY="0.0"/>
<state key="normal" image="shrink_icon.png"/>
<connections>
<action selector="selectPhoneNumberCountry:" destination="x74-04-ezp" eventType="touchUpInside" id="nvG-sc-8Wn"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="FR" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="u0g-Z1-e7a">
<rect key="frame" x="13" y="14.5" width="30" height="21"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="u0g-Z1-e7a">
<rect key="frame" x="13" y="18" width="30" height="0.0"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="dTe-UY-tRF"/>
</constraints>
@ -141,23 +142,23 @@
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="584" translatesAutoresizingMaskIntoConstraints="NO" id="CLw-uO-q5T">
<rect key="frame" x="60" y="14.5" width="42" height="21"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="584" translatesAutoresizingMaskIntoConstraints="NO" id="CLw-uO-q5T">
<rect key="frame" x="60" y="18" width="10" height="0.0"/>
<color key="tintColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="10" id="G1u-di-SRu"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="34" placeholder="Email address" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="4Md-Fk-tj9">
<rect key="frame" x="110" y="18" width="472" height="21"/>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Email address" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="4Md-Fk-tj9">
<rect key="frame" x="78" y="18" width="504" height="21"/>
<accessibility key="accessibilityConfiguration" identifier="AuthInputsViewEmailTextField"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="Atb-T3-6eG"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="phonePad" returnKeyType="done"/>
<connections>
<action selector="textFieldDidChange:" destination="x74-04-ezp" eventType="editingChanged" id="kR9-TL-ZDM"/>
@ -177,17 +178,17 @@
<constraints>
<constraint firstItem="4Md-Fk-tj9" firstAttribute="leading" secondItem="CLw-uO-q5T" secondAttribute="trailing" constant="8" id="195-Hm-3Ue"/>
<constraint firstItem="5r3-Tj-ARd" firstAttribute="top" secondItem="IB7-1E-eeL" secondAttribute="top" id="4gX-WV-3yS"/>
<constraint firstItem="CLw-uO-q5T" firstAttribute="centerY" secondItem="IB7-1E-eeL" secondAttribute="centerY" id="ArE-5L-euR"/>
<constraint firstItem="CLw-uO-q5T" firstAttribute="top" secondItem="IB7-1E-eeL" secondAttribute="top" constant="18" id="BOi-aC-RFk"/>
<constraint firstItem="4Md-Fk-tj9" firstAttribute="top" secondItem="IB7-1E-eeL" secondAttribute="top" constant="18" id="Bac-nE-XY1"/>
<constraint firstItem="0Uh-dj-10x" firstAttribute="leading" secondItem="IB7-1E-eeL" secondAttribute="leading" constant="10" id="CGT-Ho-HOv"/>
<constraint firstItem="5r3-Tj-ARd" firstAttribute="leading" secondItem="IB7-1E-eeL" secondAttribute="leading" constant="8" id="KyO-Vy-ERT"/>
<constraint firstItem="u0g-Z1-e7a" firstAttribute="leading" secondItem="5r3-Tj-ARd" secondAttribute="leading" constant="5" id="LwH-ff-U1C"/>
<constraint firstAttribute="trailing" secondItem="0Uh-dj-10x" secondAttribute="trailing" constant="10" id="NYe-mf-ZBP"/>
<constraint firstAttribute="bottom" secondItem="0Uh-dj-10x" secondAttribute="bottom" id="NhZ-6E-PKC"/>
<constraint firstItem="u0g-Z1-e7a" firstAttribute="top" secondItem="IB7-1E-eeL" secondAttribute="top" constant="18" id="NtT-EB-z6J"/>
<constraint firstAttribute="height" constant="50" id="Q5U-nJ-HaM"/>
<constraint firstItem="CLw-uO-q5T" firstAttribute="leading" secondItem="5r3-Tj-ARd" secondAttribute="trailing" constant="8" id="kBc-p5-eJM"/>
<constraint firstItem="5r3-Tj-ARd" firstAttribute="height" secondItem="IB7-1E-eeL" secondAttribute="height" id="nrv-aK-2kk"/>
<constraint firstItem="u0g-Z1-e7a" firstAttribute="centerY" secondItem="5r3-Tj-ARd" secondAttribute="centerY" id="r7G-3L-YQc"/>
<constraint firstAttribute="trailing" secondItem="4Md-Fk-tj9" secondAttribute="trailing" constant="18" id="wXN-hG-YNx"/>
</constraints>
</view>
@ -227,7 +228,7 @@
</constraints>
</view>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="68j-f9-JG4">
<rect key="frame" x="8" y="8" width="584" height="18"/>
<rect key="frame" x="10" y="8" width="580" height="18"/>
<accessibility key="accessibilityConfiguration" identifier="AuthInputsViewMessageLabel"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
@ -251,7 +252,7 @@
<constraint firstItem="rb1-L5-udI" firstAttribute="top" secondItem="x74-04-ezp" secondAttribute="top" constant="100" id="75U-tx-PsQ"/>
<constraint firstItem="UfH-jv-6w4" firstAttribute="leading" secondItem="x74-04-ezp" secondAttribute="leading" id="7Bk-GF-MZ0"/>
<constraint firstItem="IB7-1E-eeL" firstAttribute="leading" secondItem="x74-04-ezp" secondAttribute="leading" id="7Lr-fy-W8L"/>
<constraint firstAttribute="trailing" secondItem="68j-f9-JG4" secondAttribute="trailing" constant="8" id="8Aa-YT-MP5"/>
<constraint firstAttribute="trailing" secondItem="68j-f9-JG4" secondAttribute="trailing" constant="10" id="8Aa-YT-MP5"/>
<constraint firstAttribute="trailing" secondItem="UfH-jv-6w4" secondAttribute="trailing" id="8dz-wY-Kxx"/>
<constraint firstItem="whs-Ob-uzD" firstAttribute="centerX" secondItem="x74-04-ezp" secondAttribute="centerX" id="8lX-k1-85c"/>
<constraint firstItem="68j-f9-JG4" firstAttribute="top" secondItem="x74-04-ezp" secondAttribute="top" constant="8" id="BK1-XE-vz5"/>
@ -261,7 +262,7 @@
<constraint firstAttribute="trailing" secondItem="xOW-lo-QGC" secondAttribute="trailing" id="SNm-WQ-Piu"/>
<constraint firstItem="xOW-lo-QGC" firstAttribute="top" secondItem="x74-04-ezp" secondAttribute="top" id="WmX-gO-hPJ"/>
<constraint firstItem="rb1-L5-udI" firstAttribute="leading" secondItem="x74-04-ezp" secondAttribute="leading" id="XAJ-ST-sWV"/>
<constraint firstItem="68j-f9-JG4" firstAttribute="leading" secondItem="x74-04-ezp" secondAttribute="leading" constant="8" id="aYh-VJ-bss"/>
<constraint firstItem="68j-f9-JG4" firstAttribute="leading" secondItem="x74-04-ezp" secondAttribute="leading" constant="10" id="aYh-VJ-bss"/>
<constraint firstAttribute="trailing" secondItem="rb1-L5-udI" secondAttribute="trailing" id="c49-Cf-H9a"/>
<constraint firstItem="bXz-VI-5FS" firstAttribute="top" secondItem="x74-04-ezp" secondAttribute="top" id="enV-j0-cgR"/>
<constraint firstItem="whs-Ob-uzD" firstAttribute="top" secondItem="68j-f9-JG4" secondAttribute="bottom" id="g87-rp-bgb"/>