diff options
| author | Jon Petersson <jon.petersson@kvadrat.se> | 2024-05-13 13:41:50 +0200 |
|---|---|---|
| committer | Emīls <emils@mullvad.net> | 2024-05-13 17:42:20 +0200 |
| commit | 9d4c27f7caec0741bb682ea81c70fadd094ceb8e (patch) | |
| tree | fef18d937173bed178e2aa2ea8bc1dbaa8ebffb4 /ios/MullvadVPN | |
| parent | 2378efb3314ec5548a1c7c9b8629a4773650e056 (diff) | |
| download | mullvadvpn-9d4c27f7caec0741bb682ea81c70fadd094ceb8e.tar.xz mullvadvpn-9d4c27f7caec0741bb682ea81c70fadd094ceb8e.zip | |
Fix user input string validation
Diffstat (limited to 'ios/MullvadVPN')
7 files changed, 38 insertions, 15 deletions
diff --git a/ios/MullvadVPN/Coordinators/CustomLists/CustomListCellConfiguration.swift b/ios/MullvadVPN/Coordinators/CustomLists/CustomListCellConfiguration.swift index 10f2c3ef7c..372a7b4e07 100644 --- a/ios/MullvadVPN/Coordinators/CustomLists/CustomListCellConfiguration.swift +++ b/ios/MullvadVPN/Coordinators/CustomLists/CustomListCellConfiguration.swift @@ -7,6 +7,7 @@ // import Combine +import MullvadTypes import UIKit struct CustomListCellConfiguration { @@ -75,7 +76,7 @@ struct CustomListCellConfiguration { contentConfiguration.setPlaceholder(type: .required) contentConfiguration.textFieldProperties = .withSmartFeaturesDisabled() contentConfiguration.inputText = subject.value.name - contentConfiguration.maxLength = 30 + contentConfiguration.maxLength = NameInputFormatter.maxLength contentConfiguration.editingEvents.onChange = subject.bindTextAction(to: \.name) cell.accessibilityIdentifier = AccessibilityIdentifier.customListEditNameFieldCell diff --git a/ios/MullvadVPN/Coordinators/CustomLists/CustomListDataSourceConfiguration.swift b/ios/MullvadVPN/Coordinators/CustomLists/CustomListDataSourceConfiguration.swift index 77bbefd8bc..b5598abf3e 100644 --- a/ios/MullvadVPN/Coordinators/CustomLists/CustomListDataSourceConfiguration.swift +++ b/ios/MullvadVPN/Coordinators/CustomLists/CustomListDataSourceConfiguration.swift @@ -92,7 +92,12 @@ extension CustomListDataSourceConfiguration: UITableViewDelegate { let errorsInSection = itemsWithErrors.filter { itemsInSection.contains($0) }.compactMap { item in switch item { case .name: - CustomListFieldValidationError.name + Array(validationErrors).filter { error in + if case .name = error { + return true + } + return false + } case .addLocations, .editLocations, .deleteList: nil } @@ -102,7 +107,7 @@ extension CustomListDataSourceConfiguration: UITableViewDelegate { case .name: let view = SettingsFieldValidationErrorContentView( configuration: SettingsFieldValidationErrorConfiguration( - errors: errorsInSection.settingsFieldValidationErrors + errors: errorsInSection.flatMap { $0.settingsFieldValidationErrors } ) ) return view diff --git a/ios/MullvadVPN/Coordinators/CustomLists/CustomListValidationError.swift b/ios/MullvadVPN/Coordinators/CustomLists/CustomListValidationError.swift index 100cff15a6..35880b0371 100644 --- a/ios/MullvadVPN/Coordinators/CustomLists/CustomListValidationError.swift +++ b/ios/MullvadVPN/Coordinators/CustomLists/CustomListValidationError.swift @@ -7,19 +7,15 @@ // import Foundation +import MullvadSettings -enum CustomListFieldValidationError: LocalizedError { - case name +enum CustomListFieldValidationError: LocalizedError, Hashable { + case name(CustomRelayListError) var errorDescription: String? { switch self { - case .name: - NSLocalizedString( - "CUSTOM_LISTS_VALIDATION_ERROR_EMPTY_FIELD", - tableName: "CutstomLists", - value: "A custom list with this name exists, please choose a unique name.", - comment: "" - ) + case let .name(error): + error.errorDescription } } } diff --git a/ios/MullvadVPN/Coordinators/CustomLists/CustomListViewController.swift b/ios/MullvadVPN/Coordinators/CustomLists/CustomListViewController.swift index baf4e8949a..6e4fe54ac5 100644 --- a/ios/MullvadVPN/Coordinators/CustomLists/CustomListViewController.swift +++ b/ios/MullvadVPN/Coordinators/CustomLists/CustomListViewController.swift @@ -154,8 +154,10 @@ class CustomListViewController: UIViewController { try interactor.save(viewModel: subject.value) delegate?.customListDidSave(subject.value.customList) } catch { - validationErrors.insert(.name) - dataSourceConfiguration?.set(validationErrors: validationErrors) + if let error = error as? CustomRelayListError { + validationErrors.insert(.name(error)) + dataSourceConfiguration?.set(validationErrors: validationErrors) + } } } diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/MethodSettings/MethodSettingsCellConfiguration.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/MethodSettings/MethodSettingsCellConfiguration.swift index 979a0ad9c3..9378efef74 100644 --- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/MethodSettings/MethodSettingsCellConfiguration.swift +++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/MethodSettings/MethodSettingsCellConfiguration.swift @@ -7,6 +7,7 @@ // import Combine +import MullvadTypes import UIKit class MethodSettingsCellConfiguration { @@ -109,6 +110,7 @@ class MethodSettingsCellConfiguration { contentConfiguration.setPlaceholder(type: .required) contentConfiguration.textFieldProperties = .withSmartFeaturesDisabled() contentConfiguration.inputText = subject.value.name + contentConfiguration.maxLength = NameInputFormatter.maxLength contentConfiguration.editingEvents.onChange = subject.bindTextAction(to: \.name) cell.accessibilityIdentifier = .accessMethodNameTextField diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Models/AccessMethodValidationError.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Models/AccessMethodValidationError.swift index 6bd2bd3274..60d247e626 100644 --- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Models/AccessMethodValidationError.swift +++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Models/AccessMethodValidationError.swift @@ -7,6 +7,7 @@ // import Foundation +import MullvadTypes /// Access method validation error that holds an array of individual per-field validation errors. struct AccessMethodValidationError: LocalizedError, Equatable { @@ -57,6 +58,9 @@ struct AccessMethodFieldValidationError: LocalizedError, Equatable { /// Invalid port number, i.e zero. case invalidPort + + /// The name input is too long. + case nameTooLong } /// Kind of validation error. @@ -91,6 +95,16 @@ struct AccessMethodFieldValidationError: LocalizedError, Equatable { value: "Please enter a valid port.", comment: "" ) + case .nameTooLong: + String( + format: NSLocalizedString( + "VALIDATION_ERRORS_NAME_TOO_LONG", + tableName: "APIAccess", + value: "Name should be no longer than %i characters.", + comment: "" + ), + NameInputFormatter.maxLength + ) } } } diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Models/AccessMethodViewModel+Persistent.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Models/AccessMethodViewModel+Persistent.swift index 3a1d938e05..0d8182b5af 100644 --- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Models/AccessMethodViewModel+Persistent.swift +++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Models/AccessMethodViewModel+Persistent.swift @@ -66,10 +66,13 @@ extension AccessMethodViewModel { } private func validateName() throws -> String { + // Context doesn't matter for name field errors. if name.isEmpty { - // Context doesn't matter for name field. let fieldError = AccessMethodFieldValidationError(kind: .emptyValue, field: .name, context: .shadowsocks) throw AccessMethodValidationError(fieldErrors: [fieldError]) + } else if name.count > NameInputFormatter.maxLength { + let fieldError = AccessMethodFieldValidationError(kind: .nameTooLong, field: .name, context: .shadowsocks) + throw AccessMethodValidationError(fieldErrors: [fieldError]) } return name |
