diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index e9295cc9e..84b0affc6 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -255,6 +255,10 @@ "password_validation_error_contain_number" = "Contain a number."; "password_validation_error_contain_symbol" = "Contain a symbol."; +// MARK: Password policy errors +"password_policy_too_short_pwd_error" = "Too short password"; +"password_policy_weak_pwd_error" = "This password is too weak. It must contain at least 8 characters, with at least one character of each type: uppercase, lowercase, digit and special character."; +"password_policy_pwd_in_dict_error" = "This password has been found in a dictionary, and is not allowed."; // MARK: Legacy Authentication "auth_login" = "Log in"; diff --git a/Riot/Categories/MXError.swift b/Riot/Categories/MXError.swift new file mode 100644 index 000000000..2c237b93a --- /dev/null +++ b/Riot/Categories/MXError.swift @@ -0,0 +1,60 @@ +// +// Copyright 2022 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import MatrixSDK + +extension MXError { + /// Returns custom localized message from errcode parameter of MXError. + func authenticationErrorMessage() -> String { + let message: String + switch self.errcode { + case kMXErrCodeStringForbidden: + message = VectorL10n.loginErrorForbidden + case kMXErrCodeStringUnknownToken: + message = VectorL10n.loginErrorUnknownToken + case kMXErrCodeStringBadJSON: + message = VectorL10n.loginErrorBadJson + case kMXErrCodeStringNotJSON: + message = VectorL10n.loginErrorBadJson + case kMXErrCodeStringLimitExceeded: + message = VectorL10n.loginErrorLimitExceeded + case kMXErrCodeStringUserInUse: + message = VectorL10n.loginErrorUserInUse + case kMXErrCodeStringLoginEmailURLNotYet: + message = VectorL10n.loginErrorLoginEmailNotYet + case kMXErrCodeStringThreePIDInUse: + message = VectorL10n.authEmailInUse + case kMXErrCodeStringPasswordTooShort: + message = VectorL10n.passwordPolicyTooShortPwdError + case kMXErrCodeStringPasswordNoDigit: + message = VectorL10n.passwordPolicyWeakPwdError + case kMXErrCodeStringPasswordNoLowercase: + message = VectorL10n.passwordPolicyWeakPwdError + case kMXErrCodeStringPasswordNoUppercase: + message = VectorL10n.passwordPolicyWeakPwdError + case kMXErrCodeStringPasswordNoSymbol: + message = VectorL10n.passwordPolicyWeakPwdError + case kMXErrCodeStringWeakPassword: + message = VectorL10n.passwordPolicyWeakPwdError + case kMXErrCodeStringPasswordInDictionary: + message = VectorL10n.passwordPolicyPwdInDictError + default: + message = self.error + } + + return message + } +} diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index f773146b2..bb83aa012 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -4603,6 +4603,18 @@ public class VectorL10n: NSObject { public static var or: String { return VectorL10n.tr("Vector", "or") } + /// This password has been found in a dictionary, and is not allowed. + public static var passwordPolicyPwdInDictError: String { + return VectorL10n.tr("Vector", "password_policy_pwd_in_dict_error") + } + /// Too short password + public static var passwordPolicyTooShortPwdError: String { + return VectorL10n.tr("Vector", "password_policy_too_short_pwd_error") + } + /// This password is too weak. It must contain at least 8 characters, with at least one character of each type: uppercase, lowercase, digit and special character. + public static var passwordPolicyWeakPwdError: String { + return VectorL10n.tr("Vector", "password_policy_weak_pwd_error") + } /// Contain a lower-case letter. public static var passwordValidationErrorContainLowercaseLetter: String { return VectorL10n.tr("Vector", "password_validation_error_contain_lowercase_letter") diff --git a/RiotSwiftUI/Modules/Authentication/ChoosePassword/Coordinator/AuthenticationChoosePasswordCoordinator.swift b/RiotSwiftUI/Modules/Authentication/ChoosePassword/Coordinator/AuthenticationChoosePasswordCoordinator.swift index df3f7d793..b151f9f03 100644 --- a/RiotSwiftUI/Modules/Authentication/ChoosePassword/Coordinator/AuthenticationChoosePasswordCoordinator.swift +++ b/RiotSwiftUI/Modules/Authentication/ChoosePassword/Coordinator/AuthenticationChoosePasswordCoordinator.swift @@ -138,7 +138,8 @@ final class AuthenticationChoosePasswordCoordinator: Coordinator, Presentable { if mxError.errcode == kMXErrCodeStringUnauthorized { authenticationChoosePasswordViewModel.displayError(.emailNotVerified) } else { - authenticationChoosePasswordViewModel.displayError(.mxError(mxError.error)) + let message = mxError.authenticationErrorMessage() + authenticationChoosePasswordViewModel.displayError(.mxError(message)) } return diff --git a/RiotSwiftUI/Modules/Authentication/ForgotPassword/Coordinator/AuthenticationForgotPasswordCoordinator.swift b/RiotSwiftUI/Modules/Authentication/ForgotPassword/Coordinator/AuthenticationForgotPasswordCoordinator.swift index deea1e803..0ac3c1b73 100644 --- a/RiotSwiftUI/Modules/Authentication/ForgotPassword/Coordinator/AuthenticationForgotPasswordCoordinator.swift +++ b/RiotSwiftUI/Modules/Authentication/ForgotPassword/Coordinator/AuthenticationForgotPasswordCoordinator.swift @@ -164,7 +164,8 @@ final class AuthenticationForgotPasswordCoordinator: Coordinator, Presentable { /// Processes an error to either update the flow or display it to the user. @MainActor private func handleError(_ error: Error) { if let mxError = MXError(nsError: error as NSError) { - authenticationForgotPasswordViewModel.displayError(.mxError(mxError.error)) + let message = mxError.authenticationErrorMessage() + authenticationForgotPasswordViewModel.displayError(.mxError(message)) return } diff --git a/RiotSwiftUI/Modules/Authentication/Login/Coordinator/AuthenticationLoginCoordinator.swift b/RiotSwiftUI/Modules/Authentication/Login/Coordinator/AuthenticationLoginCoordinator.swift index 2c6a7e3f9..a1b899ad6 100644 --- a/RiotSwiftUI/Modules/Authentication/Login/Coordinator/AuthenticationLoginCoordinator.swift +++ b/RiotSwiftUI/Modules/Authentication/Login/Coordinator/AuthenticationLoginCoordinator.swift @@ -180,7 +180,8 @@ final class AuthenticationLoginCoordinator: Coordinator, Presentable { /// Processes an error to either update the flow or display it to the user. @MainActor private func handleError(_ error: Error) { if let mxError = MXError(nsError: error as NSError) { - authenticationLoginViewModel.displayError(.mxError(mxError.error)) + let message = mxError.authenticationErrorMessage() + authenticationLoginViewModel.displayError(.mxError(message)) return } diff --git a/RiotSwiftUI/Modules/Authentication/ReCaptcha/Coordinator/AuthenticationReCaptchaCoordinator.swift b/RiotSwiftUI/Modules/Authentication/ReCaptcha/Coordinator/AuthenticationReCaptchaCoordinator.swift index efeafb184..3f3df2be1 100644 --- a/RiotSwiftUI/Modules/Authentication/ReCaptcha/Coordinator/AuthenticationReCaptchaCoordinator.swift +++ b/RiotSwiftUI/Modules/Authentication/ReCaptcha/Coordinator/AuthenticationReCaptchaCoordinator.swift @@ -130,7 +130,8 @@ final class AuthenticationReCaptchaCoordinator: Coordinator, Presentable { /// Processes an error to either update the flow or display it to the user. @MainActor private func handleError(_ error: Error) { if let mxError = MXError(nsError: error as NSError) { - authenticationReCaptchaViewModel.displayError(.mxError(mxError.error)) + let message = mxError.authenticationErrorMessage() + authenticationReCaptchaViewModel.displayError(.mxError(message)) return } diff --git a/RiotSwiftUI/Modules/Authentication/Registration/Coordinator/AuthenticationRegistrationCoordinator.swift b/RiotSwiftUI/Modules/Authentication/Registration/Coordinator/AuthenticationRegistrationCoordinator.swift index 72fa8f441..6845def00 100644 --- a/RiotSwiftUI/Modules/Authentication/Registration/Coordinator/AuthenticationRegistrationCoordinator.swift +++ b/RiotSwiftUI/Modules/Authentication/Registration/Coordinator/AuthenticationRegistrationCoordinator.swift @@ -230,7 +230,8 @@ final class AuthenticationRegistrationCoordinator: Coordinator, Presentable { /// Processes an error to either update the flow or display it to the user. @MainActor private func handleError(_ error: Error) { if let mxError = MXError(nsError: error as NSError) { - authenticationRegistrationViewModel.displayError(.mxError(mxError.error)) + let message = mxError.authenticationErrorMessage() + authenticationRegistrationViewModel.displayError(.mxError(message)) return } diff --git a/RiotSwiftUI/Modules/Authentication/SoftLogout/Coordinator/AuthenticationSoftLogoutCoordinator.swift b/RiotSwiftUI/Modules/Authentication/SoftLogout/Coordinator/AuthenticationSoftLogoutCoordinator.swift index a76ce9a0b..1d4d294b5 100644 --- a/RiotSwiftUI/Modules/Authentication/SoftLogout/Coordinator/AuthenticationSoftLogoutCoordinator.swift +++ b/RiotSwiftUI/Modules/Authentication/SoftLogout/Coordinator/AuthenticationSoftLogoutCoordinator.swift @@ -210,7 +210,8 @@ final class AuthenticationSoftLogoutCoordinator: Coordinator, Presentable { /// Processes an error to either update the flow or display it to the user. @MainActor private func handleError(_ error: Error) { if let mxError = MXError(nsError: error as NSError) { - authenticationSoftLogoutViewModel.displayError(.mxError(mxError.error)) + let message = mxError.authenticationErrorMessage() + authenticationSoftLogoutViewModel.displayError(.mxError(message)) return } diff --git a/RiotSwiftUI/Modules/Authentication/Terms/Coordinator/AuthenticationTermsCoordinator.swift b/RiotSwiftUI/Modules/Authentication/Terms/Coordinator/AuthenticationTermsCoordinator.swift index 5baeb2d3f..d212bd965 100644 --- a/RiotSwiftUI/Modules/Authentication/Terms/Coordinator/AuthenticationTermsCoordinator.swift +++ b/RiotSwiftUI/Modules/Authentication/Terms/Coordinator/AuthenticationTermsCoordinator.swift @@ -149,7 +149,8 @@ final class AuthenticationTermsCoordinator: Coordinator, Presentable { /// Processes an error to either update the flow or display it to the user. @MainActor private func handleError(_ error: Error) { if let mxError = MXError(nsError: error as NSError) { - authenticationTermsViewModel.displayError(.mxError(mxError.error)) + let message = mxError.authenticationErrorMessage() + authenticationTermsViewModel.displayError(.mxError(message)) return } diff --git a/RiotSwiftUI/Modules/Authentication/VerifyEmail/Coordinator/AuthenticationVerifyEmailCoordinator.swift b/RiotSwiftUI/Modules/Authentication/VerifyEmail/Coordinator/AuthenticationVerifyEmailCoordinator.swift index 920884048..30752d8d0 100644 --- a/RiotSwiftUI/Modules/Authentication/VerifyEmail/Coordinator/AuthenticationVerifyEmailCoordinator.swift +++ b/RiotSwiftUI/Modules/Authentication/VerifyEmail/Coordinator/AuthenticationVerifyEmailCoordinator.swift @@ -190,7 +190,8 @@ final class AuthenticationVerifyEmailCoordinator: Coordinator, Presentable { /// Processes an error to either update the flow or display it to the user. @MainActor private func handleError(_ error: Error) { if let mxError = MXError(nsError: error as NSError) { - authenticationVerifyEmailViewModel.displayError(.mxError(mxError.error)) + let message = mxError.authenticationErrorMessage() + authenticationVerifyEmailViewModel.displayError(.mxError(message)) return } diff --git a/RiotSwiftUI/Modules/Authentication/VerifyMsisdn/Coordinator/AuthenticationVerifyMsisdnCoordinator.swift b/RiotSwiftUI/Modules/Authentication/VerifyMsisdn/Coordinator/AuthenticationVerifyMsisdnCoordinator.swift index 0d7b42dc4..492eefc2e 100644 --- a/RiotSwiftUI/Modules/Authentication/VerifyMsisdn/Coordinator/AuthenticationVerifyMsisdnCoordinator.swift +++ b/RiotSwiftUI/Modules/Authentication/VerifyMsisdn/Coordinator/AuthenticationVerifyMsisdnCoordinator.swift @@ -204,7 +204,8 @@ final class AuthenticationVerifyMsisdnCoordinator: Coordinator, Presentable { /// Processes an error to either update the flow or display it to the user. @MainActor private func handleError(_ error: Error) { if let mxError = MXError(nsError: error as NSError) { - authenticationVerifyMsisdnViewModel.displayError(.mxError(mxError.error)) + let message = mxError.authenticationErrorMessage() + authenticationVerifyMsisdnViewModel.displayError(.mxError(message)) return } diff --git a/RiotSwiftUI/Modules/Settings/ChangePassword/Coordinator/ChangePasswordCoordinator.swift b/RiotSwiftUI/Modules/Settings/ChangePassword/Coordinator/ChangePasswordCoordinator.swift index bd3f6fc29..ef6f8a16d 100644 --- a/RiotSwiftUI/Modules/Settings/ChangePassword/Coordinator/ChangePasswordCoordinator.swift +++ b/RiotSwiftUI/Modules/Settings/ChangePassword/Coordinator/ChangePasswordCoordinator.swift @@ -127,7 +127,8 @@ final class ChangePasswordCoordinator: Coordinator, Presentable { /// Processes an error to either update the flow or display it to the user. @MainActor private func handleError(_ error: Error) { if let mxError = MXError(nsError: error as NSError) { - changePasswordViewModel.displayError(.mxError(mxError.error)) + let message = mxError.authenticationErrorMessage() + changePasswordViewModel.displayError(.mxError(message)) return } diff --git a/changelog.d/pr-X.change b/changelog.d/pr-X.change new file mode 100644 index 000000000..a6e9d77b6 --- /dev/null +++ b/changelog.d/pr-X.change @@ -0,0 +1 @@ +Add localization for authentication errors.