From f58b83b24116fde6527565704388c9a9ba60b09a Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 3 Sep 2019 16:35:18 +0200 Subject: [PATCH] Privacy: Settings: Allow adding 3pids when no IS #2659 And display an error if an IS is required --- CHANGES.rst | 1 + Riot/Assets/en.lproj/Vector.strings | 2 + Riot/Generated/Strings.swift | 8 + .../Modules/Settings/SettingsViewController.m | 241 ++++++++++-------- 4 files changed, 150 insertions(+), 102 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 4e035a9a2..57054ab84 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -16,6 +16,7 @@ Improvements: * Privacy: Support identity server v2 API authentication (#2603). * Privacy: Use the hashed v2 lookup API for 3PIDs (#2652). * Privacy: Prompt to accept identity server policies on firt use (#2602). + * Privacy: Settings: Allow adding 3pids when no IS (#2659). Changes in 0.9.2 (2019-08-08) =============================================== diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index b1a3fe8df..cc32d5c5a 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -92,6 +92,8 @@ "auth_missing_email_or_phone" = "Missing email address or phone number"; "auth_email_in_use" = "This email address is already in use"; "auth_phone_in_use" = "This phone number is already in use"; +"auth_email_is_required" = "No identity server is configured so you cannot add an email address in order to reset your password in the future."; +"auth_phone_is_required" = "No identity server is configured so you cannot add a phone number in order to reset your password in the future."; "auth_untrusted_id_server" = "The identity server is not trusted"; "auth_password_dont_match" = "Passwords don't match"; "auth_username_in_use" = "Username in use"; diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index 4513e74a7..567e01982 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -54,6 +54,10 @@ internal enum VectorL10n { internal static var authEmailInUse: String { return VectorL10n.tr("Vector", "auth_email_in_use") } + /// No identity server is configured so you cannot add an email address in order to reset your password in the future. + internal static var authEmailIsRequired: String { + return VectorL10n.tr("Vector", "auth_email_is_required") + } /// Failed to send email: This email address was not found internal static var authEmailNotFound: String { return VectorL10n.tr("Vector", "auth_email_not_found") @@ -162,6 +166,10 @@ internal enum VectorL10n { internal static var authPhoneInUse: String { return VectorL10n.tr("Vector", "auth_phone_in_use") } + /// No identity server is configured so you cannot add a phone number in order to reset your password in the future. + internal static var authPhoneIsRequired: String { + return VectorL10n.tr("Vector", "auth_phone_is_required") + } /// Phone number internal static var authPhonePlaceholder: String { return VectorL10n.tr("Vector", "auth_phone_placeholder") diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 0f77f9a4f..1833eb093 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -1241,25 +1241,13 @@ SingleImagePickerPresenterDelegate> userSettingsSurnameIndex = -1; userSettingsNightModeSepIndex = -1; userSettingsNightModeIndex = -1; - - if (self.mainSession.matrixRestClient.identityServer.length) - { - userSettingsEmailStartIndex = 3; - userSettingsNewEmailIndex = userSettingsEmailStartIndex + account.linkedEmails.count; - userSettingsPhoneStartIndex = userSettingsNewEmailIndex + 1; - userSettingsNewPhoneIndex = userSettingsPhoneStartIndex + account.linkedPhoneNumbers.count; - - count = userSettingsNewPhoneIndex + 1; - } - else - { - userSettingsEmailStartIndex = -1; - userSettingsNewEmailIndex = -1; - userSettingsPhoneStartIndex = -1; - userSettingsNewPhoneIndex = -1; - - count = userSettingsChangePasswordIndex + 1; - } + + userSettingsEmailStartIndex = 3; + userSettingsNewEmailIndex = userSettingsEmailStartIndex + account.linkedEmails.count; + userSettingsPhoneStartIndex = userSettingsNewEmailIndex + 1; + userSettingsNewPhoneIndex = userSettingsPhoneStartIndex + account.linkedPhoneNumbers.count; + + count = userSettingsNewPhoneIndex + 1; } else if (section == SETTINGS_SECTION_NOTIFICATIONS_SETTINGS_INDEX) { @@ -3613,51 +3601,59 @@ SingleImagePickerPresenterDelegate> MXSession* session = [AppDelegate theDelegate].mxSessions[0]; - MXK3PID *new3PID = [[MXK3PID alloc] initWithMedium:kMX3PIDMediumEmail andAddress:newEmailTextField.text]; - [new3PID requestValidationTokenWithMatrixRestClient:session.matrixRestClient isDuringRegistration:NO nextLink:nil success:^{ + [self checkIdentityServerRequirement:session.matrixRestClient forMedium:kMX3PIDMediumEmail success:^{ - [self showValidationEmailDialogWithMessage:[NSBundle mxk_localizedStringForKey:@"account_email_validation_message"] for3PID:new3PID]; + MXK3PID *new3PID = [[MXK3PID alloc] initWithMedium:kMX3PIDMediumEmail andAddress:newEmailTextField.text]; + [new3PID requestValidationTokenWithMatrixRestClient:session.matrixRestClient isDuringRegistration:NO nextLink:nil success:^{ + + [self showValidationEmailDialogWithMessage:[NSBundle mxk_localizedStringForKey:@"account_email_validation_message"] for3PID:new3PID]; + + } failure:^(NSError *error) { + + [self stopActivityIndicator]; + + NSLog(@"[SettingsViewController] Failed to request email token"); + + // Translate the potential MX error. + MXError *mxError = [[MXError alloc] initWithNSError:error]; + if (mxError && ([mxError.errcode isEqualToString:kMXErrCodeStringThreePIDInUse] || [mxError.errcode isEqualToString:kMXErrCodeStringServerNotTrusted])) + { + NSMutableDictionary *userInfo; + if (error.userInfo) + { + userInfo = [NSMutableDictionary dictionaryWithDictionary:error.userInfo]; + } + else + { + userInfo = [NSMutableDictionary dictionary]; + } + + userInfo[NSLocalizedFailureReasonErrorKey] = nil; + + if ([mxError.errcode isEqualToString:kMXErrCodeStringThreePIDInUse]) + { + userInfo[NSLocalizedDescriptionKey] = NSLocalizedStringFromTable(@"auth_email_in_use", @"Vector", nil); + userInfo[@"error"] = NSLocalizedStringFromTable(@"auth_email_in_use", @"Vector", nil); + } + else + { + userInfo[NSLocalizedDescriptionKey] = NSLocalizedStringFromTable(@"auth_untrusted_id_server", @"Vector", nil); + userInfo[@"error"] = NSLocalizedStringFromTable(@"auth_untrusted_id_server", @"Vector", nil); + } + + error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; + } + + // Notify user + NSString *myUserId = session.myUser.userId; // TODO: Hanlde multi-account + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil]; + + }]; } failure:^(NSError *error) { - - [self stopActivityIndicator]; - - NSLog(@"[SettingsViewController] Failed to request email token"); - - // Translate the potential MX error. - MXError *mxError = [[MXError alloc] initWithNSError:error]; - if (mxError && ([mxError.errcode isEqualToString:kMXErrCodeStringThreePIDInUse] || [mxError.errcode isEqualToString:kMXErrCodeStringServerNotTrusted])) - { - NSMutableDictionary *userInfo; - if (error.userInfo) - { - userInfo = [NSMutableDictionary dictionaryWithDictionary:error.userInfo]; - } - else - { - userInfo = [NSMutableDictionary dictionary]; - } - - userInfo[NSLocalizedFailureReasonErrorKey] = nil; - - if ([mxError.errcode isEqualToString:kMXErrCodeStringThreePIDInUse]) - { - userInfo[NSLocalizedDescriptionKey] = NSLocalizedStringFromTable(@"auth_email_in_use", @"Vector", nil); - userInfo[@"error"] = NSLocalizedStringFromTable(@"auth_email_in_use", @"Vector", nil); - } - else - { - userInfo[NSLocalizedDescriptionKey] = NSLocalizedStringFromTable(@"auth_untrusted_id_server", @"Vector", nil); - userInfo[@"error"] = NSLocalizedStringFromTable(@"auth_untrusted_id_server", @"Vector", nil); - } - - error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; - } - // Notify user NSString *myUserId = session.myUser.userId; // TODO: Hanlde multi-account [[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil]; - }]; } @@ -3714,56 +3710,97 @@ SingleImagePickerPresenterDelegate> { msisdn = [e164 substringFromIndex:2]; } - - MXK3PID *new3PID = [[MXK3PID alloc] initWithMedium:kMX3PIDMediumMSISDN andAddress:msisdn]; - - [new3PID requestValidationTokenWithMatrixRestClient:session.matrixRestClient isDuringRegistration:NO nextLink:nil success:^{ - - [self showValidationMsisdnDialogWithMessage:[NSBundle mxk_localizedStringForKey:@"account_msisdn_validation_message"] for3PID:new3PID]; - + + [self checkIdentityServerRequirement:session.matrixRestClient forMedium:kMX3PIDMediumMSISDN success:^{ + + MXK3PID *new3PID = [[MXK3PID alloc] initWithMedium:kMX3PIDMediumMSISDN andAddress:msisdn]; + + [new3PID requestValidationTokenWithMatrixRestClient:session.matrixRestClient isDuringRegistration:NO nextLink:nil success:^{ + + [self showValidationMsisdnDialogWithMessage:[NSBundle mxk_localizedStringForKey:@"account_msisdn_validation_message"] for3PID:new3PID]; + + } failure:^(NSError *error) { + + [self stopActivityIndicator]; + + NSLog(@"[SettingsViewController] Failed to request msisdn token"); + + // Translate the potential MX error. + MXError *mxError = [[MXError alloc] initWithNSError:error]; + if (mxError && ([mxError.errcode isEqualToString:kMXErrCodeStringThreePIDInUse] || [mxError.errcode isEqualToString:kMXErrCodeStringServerNotTrusted])) + { + NSMutableDictionary *userInfo; + if (error.userInfo) + { + userInfo = [NSMutableDictionary dictionaryWithDictionary:error.userInfo]; + } + else + { + userInfo = [NSMutableDictionary dictionary]; + } + + userInfo[NSLocalizedFailureReasonErrorKey] = nil; + + if ([mxError.errcode isEqualToString:kMXErrCodeStringThreePIDInUse]) + { + userInfo[NSLocalizedDescriptionKey] = NSLocalizedStringFromTable(@"auth_phone_in_use", @"Vector", nil); + userInfo[@"error"] = NSLocalizedStringFromTable(@"auth_phone_in_use", @"Vector", nil); + } + else + { + userInfo[NSLocalizedDescriptionKey] = NSLocalizedStringFromTable(@"auth_untrusted_id_server", @"Vector", nil); + userInfo[@"error"] = NSLocalizedStringFromTable(@"auth_untrusted_id_server", @"Vector", nil); + } + + error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; + } + + // Notify user + NSString *myUserId = session.myUser.userId; + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil]; + + }]; + } failure:^(NSError *error) { - - [self stopActivityIndicator]; - - NSLog(@"[SettingsViewController] Failed to request msisdn token"); - - // Translate the potential MX error. - MXError *mxError = [[MXError alloc] initWithNSError:error]; - if (mxError && ([mxError.errcode isEqualToString:kMXErrCodeStringThreePIDInUse] || [mxError.errcode isEqualToString:kMXErrCodeStringServerNotTrusted])) - { - NSMutableDictionary *userInfo; - if (error.userInfo) - { - userInfo = [NSMutableDictionary dictionaryWithDictionary:error.userInfo]; - } - else - { - userInfo = [NSMutableDictionary dictionary]; - } - - userInfo[NSLocalizedFailureReasonErrorKey] = nil; - - if ([mxError.errcode isEqualToString:kMXErrCodeStringThreePIDInUse]) - { - userInfo[NSLocalizedDescriptionKey] = NSLocalizedStringFromTable(@"auth_phone_in_use", @"Vector", nil); - userInfo[@"error"] = NSLocalizedStringFromTable(@"auth_phone_in_use", @"Vector", nil); - } - else - { - userInfo[NSLocalizedDescriptionKey] = NSLocalizedStringFromTable(@"auth_untrusted_id_server", @"Vector", nil); - userInfo[@"error"] = NSLocalizedStringFromTable(@"auth_untrusted_id_server", @"Vector", nil); - } - - error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; - } - // Notify user - NSString *myUserId = session.myUser.userId; + NSString *myUserId = session.myUser.userId; // TODO: Hanlde multi-account [[NSNotificationCenter defaultCenter] postNotificationName:kMXKErrorNotification object:error userInfo:myUserId ? @{kMXKErrorUserIdKey: myUserId} : nil]; - }]; } +- (void)checkIdentityServerRequirement:(MXRestClient*)mxRestClient forMedium:(NSString*)medium success:(void (^)(void))success failure:(void (^)(NSError *))failure +{ + [mxRestClient supportedMatrixVersions:^(MXMatrixVersions *matrixVersions) { + + NSLog(@"[SettingsViewController] checkIdentityServerRequirement: %@", matrixVersions.doesServerRequireIdentityServerParam ? @"YES": @"NO"); + + if (matrixVersions.doesServerRequireIdentityServerParam + && !mxRestClient.credentials.identityServer) + { + NSString *message; + if ([medium isEqualToString:kMX3PIDMediumMSISDN]) + { + message = [NSBundle mxk_localizedStringForKey:@"auth_phone_is_required"]; + } + else + { + [NSBundle mxk_localizedStringForKey:@"auth_email_is_required"]; + } + + failure([NSError errorWithDomain:MXKAuthErrorDomain + code:0 + userInfo:@{ + NSLocalizedDescriptionKey:message + }]); + } + else + { + success(); + } + + } failure:failure]; +} + - (void)updateSaveButtonStatus { if ([AppDelegate theDelegate].mxSessions.count > 0)