diff --git a/Riot/Modules/MatrixKit/Controllers/MXKAuthenticationViewController.m b/Riot/Modules/MatrixKit/Controllers/MXKAuthenticationViewController.m index a1d570d56..5add8bef2 100644 --- a/Riot/Modules/MatrixKit/Controllers/MXKAuthenticationViewController.m +++ b/Riot/Modules/MatrixKit/Controllers/MXKAuthenticationViewController.m @@ -30,6 +30,8 @@ #import "MXKSwiftHeader.h" +#import "GeneratedInterface-Swift.h" + @interface MXKAuthenticationViewController () { /** @@ -1626,7 +1628,7 @@ - (void)updateRESTClient { - NSString *homeserverURL = _homeServerTextField.text; + NSString *homeserverURL = [HomeserverAddress sanitized:_homeServerTextField.text]; if (homeserverURL.length) { diff --git a/RiotNSE/target.yml b/RiotNSE/target.yml index 897f39cd6..2fb7d9764 100644 --- a/RiotNSE/target.yml +++ b/RiotNSE/target.yml @@ -64,6 +64,7 @@ targets: - path: ../Riot/Modules/MatrixKit excludes: - "**/MXKAuthenticationRecaptchaWebView.*" + - "**/MXKAuthenticationViewController.*" - path: ../Riot/Modules/Analytics - path: ../Riot/Managers/UserSessions - path: ../Riot/Managers/AppInfo/ diff --git a/RiotShareExtension/target.yml b/RiotShareExtension/target.yml index 4073472a5..b7412db37 100644 --- a/RiotShareExtension/target.yml +++ b/RiotShareExtension/target.yml @@ -72,6 +72,7 @@ targets: - path: ../Riot/Modules/MatrixKit excludes: - "**/MXKAuthenticationRecaptchaWebView.*" + - "**/MXKAuthenticationViewController.*" - path: ../Riot/Modules/Analytics - path: ../Riot/Managers/UserSessions excludes: diff --git a/RiotSwiftUI/Modules/Authentication/Common/AuthenticationModels.swift b/RiotSwiftUI/Modules/Authentication/Common/AuthenticationModels.swift index 831783517..1e78da544 100644 --- a/RiotSwiftUI/Modules/Authentication/Common/AuthenticationModels.swift +++ b/RiotSwiftUI/Modules/Authentication/Common/AuthenticationModels.swift @@ -78,10 +78,23 @@ enum LoginError: String, Error { case resetPasswordNotStarted } -struct HomeserverAddress { - /// Ensures the address contains a scheme, otherwise makes it `https`. +@objcMembers +class HomeserverAddress: NSObject { + /// Sanitizes a user entered homeserver address with the following rules + /// - Trim any whitespace. + /// - Lowercase the address. + /// - Ensure the address contains a scheme, otherwise make it `https`. + /// - Remove any trailing slashes. static func sanitized(_ address: String) -> String { - !address.contains("://") ? "https://\(address.lowercased())" : address.lowercased() + var address = address.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() + + if !address.contains("://") { + address = "https://\(address)" + } + + address = address.trimmingCharacters(in: CharacterSet(charactersIn: "/")) + + return address } } diff --git a/RiotTests/Modules/Authentication/AuthenticationServiceTests.swift b/RiotTests/Modules/Authentication/AuthenticationServiceTests.swift index ace25dabe..db499be20 100644 --- a/RiotTests/Modules/Authentication/AuthenticationServiceTests.swift +++ b/RiotTests/Modules/Authentication/AuthenticationServiceTests.swift @@ -349,4 +349,27 @@ import XCTest XCTAssertFalse(forgotPasswordString.contains(password), "The password must not be included in any strings.") XCTAssertFalse(changePasswordString.contains(password), "The password must not be included in any strings.") } + + func testHomeserverAddressSanitization() { + let basicAddress = "matrix.org" + let httpAddress = "http://localhost" + let trailingSlashAddress = "https://matrix.example.com/" + let whitespaceAddress = " https://matrix.example.com/ " + let validAddress = "https://matrix.example.com" + let validAddressWithPort = "https://matrix.example.com:8484" + + let sanitizedBasicAddress = HomeserverAddress.sanitized(basicAddress) + let sanitizedHTTPAddress = HomeserverAddress.sanitized(httpAddress) + let sanitizedTrailingSlashAddress = HomeserverAddress.sanitized(trailingSlashAddress) + let sanitizedWhitespaceAddress = HomeserverAddress.sanitized(whitespaceAddress) + let sanitizedValidAddress = HomeserverAddress.sanitized(validAddress) + let sanitizedValidAddressWithPort = HomeserverAddress.sanitized(validAddressWithPort) + + XCTAssertEqual(sanitizedBasicAddress, "https://matrix.org") + XCTAssertEqual(sanitizedHTTPAddress, "http://localhost") + XCTAssertEqual(sanitizedTrailingSlashAddress, "https://matrix.example.com") + XCTAssertEqual(sanitizedWhitespaceAddress, "https://matrix.example.com") + XCTAssertEqual(sanitizedValidAddress, validAddress) + XCTAssertEqual(sanitizedValidAddressWithPort, validAddressWithPort) + } } diff --git a/SiriIntents/target.yml b/SiriIntents/target.yml index 0ac6d86f7..2cb4c9fbb 100644 --- a/SiriIntents/target.yml +++ b/SiriIntents/target.yml @@ -53,6 +53,7 @@ targets: - path: ../Riot/Modules/MatrixKit excludes: - "**/MXKAuthenticationRecaptchaWebView.*" + - "**/MXKAuthenticationViewController.*" - path: ../Riot/Modules/Analytics - path: ../Riot/Managers/UserSessions - path: ../Riot/Managers/AppInfo/ diff --git a/changelog.d/995.bugfix b/changelog.d/995.bugfix new file mode 100644 index 000000000..9b2fe4b9f --- /dev/null +++ b/changelog.d/995.bugfix @@ -0,0 +1 @@ +Authentication: Trim whitespace and trailing slashes from the entered homeserver address.