From adf83cd315c4c0b73193b7e4006965624f7d7669 Mon Sep 17 00:00:00 2001 From: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com> Date: Mon, 1 Dec 2025 09:12:14 -0500 Subject: [PATCH] [PM-28157] Revert "Add string extension to prefix URIs with www" (#6192) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Álison Fernandes --- .../credentials/manager/OriginManagerImpl.kt | 9 +-- .../credentials/manager/OriginManagerTest.kt | 58 ------------------ .../ui/platform/base/util/StringExtensions.kt | 28 --------- .../base/util/StringExtensionsTest.kt | 61 ------------------- 4 files changed, 1 insertion(+), 155 deletions(-) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/data/credentials/manager/OriginManagerImpl.kt b/app/src/main/kotlin/com/x8bit/bitwarden/data/credentials/manager/OriginManagerImpl.kt index def2f8e013..7db20e9516 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/data/credentials/manager/OriginManagerImpl.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/data/credentials/manager/OriginManagerImpl.kt @@ -3,7 +3,6 @@ package com.x8bit.bitwarden.data.credentials.manager import androidx.credentials.provider.CallingAppInfo import com.bitwarden.network.service.DigitalAssetLinkService import com.bitwarden.ui.platform.base.util.prefixHttpsIfNecessary -import com.bitwarden.ui.platform.base.util.prefixWwwIfNecessary import com.x8bit.bitwarden.data.credentials.model.ValidateOriginResult import com.x8bit.bitwarden.data.credentials.repository.PrivilegedAppRepository import com.x8bit.bitwarden.data.platform.manager.AssetManager @@ -41,13 +40,7 @@ class OriginManagerImpl( ): ValidateOriginResult { return digitalAssetLinkService .checkDigitalAssetLinksRelations( - sourceWebSite = relyingPartyId - // The DAL API does not allow redirects, so we add `www.` to prevent redirects - // when it is absent from the `relyingPartyId`. This ensures that relying - // parties storing their `assetlinks.json` at the `www.` subdomain do not fail - // verification checks. - .prefixWwwIfNecessary() - .prefixHttpsIfNecessary(), + sourceWebSite = relyingPartyId.prefixHttpsIfNecessary(), targetPackageName = callingAppInfo.packageName, targetCertificateFingerprint = callingAppInfo .getSignatureFingerprintAsHexString() diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/data/credentials/manager/OriginManagerTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/data/credentials/manager/OriginManagerTest.kt index 1420342c24..9cbe70d40d 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/data/credentials/manager/OriginManagerTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/data/credentials/manager/OriginManagerTest.kt @@ -242,64 +242,6 @@ class OriginManagerTest { ), ) } - - @Test - fun `validateOrigin should prefix www to rpId without www before checking asset links`() = - runTest { - coEvery { - mockDigitalAssetLinkService.checkDigitalAssetLinksRelations( - sourceWebSite = "https://www.example.com", - targetPackageName = DEFAULT_PACKAGE_NAME, - targetCertificateFingerprint = DEFAULT_CERT_FINGERPRINT, - relations = listOf("delegate_permission/common.handle_all_urls"), - ) - } returns DEFAULT_ASSET_LINKS_CHECK_RESPONSE.asSuccess() - - val result = originManager.validateOrigin( - relyingPartyId = "example.com", - callingAppInfo = mockNonPrivilegedAppInfo, - ) - - assertEquals(ValidateOriginResult.Success(null), result) - } - - @Test - fun `validateOrigin should preserve existing www prefix when present`() = runTest { - coEvery { - mockDigitalAssetLinkService.checkDigitalAssetLinksRelations( - sourceWebSite = "https://www.example.com", - targetPackageName = DEFAULT_PACKAGE_NAME, - targetCertificateFingerprint = DEFAULT_CERT_FINGERPRINT, - relations = listOf("delegate_permission/common.handle_all_urls"), - ) - } returns DEFAULT_ASSET_LINKS_CHECK_RESPONSE.asSuccess() - - val result = originManager.validateOrigin( - relyingPartyId = "www.example.com", - callingAppInfo = mockNonPrivilegedAppInfo, - ) - - assertEquals(ValidateOriginResult.Success(null), result) - } - - @Test - fun `validateOrigin should handle rpId with https scheme correctly`() = runTest { - coEvery { - mockDigitalAssetLinkService.checkDigitalAssetLinksRelations( - sourceWebSite = "https://www.example.com", - targetPackageName = DEFAULT_PACKAGE_NAME, - targetCertificateFingerprint = DEFAULT_CERT_FINGERPRINT, - relations = listOf("delegate_permission/common.handle_all_urls"), - ) - } returns DEFAULT_ASSET_LINKS_CHECK_RESPONSE.asSuccess() - - val result = originManager.validateOrigin( - relyingPartyId = "https://example.com", - callingAppInfo = mockNonPrivilegedAppInfo, - ) - - assertEquals(ValidateOriginResult.Success(null), result) - } } private const val DEFAULT_PACKAGE_NAME = "com.x8bit.bitwarden" diff --git a/ui/src/main/kotlin/com/bitwarden/ui/platform/base/util/StringExtensions.kt b/ui/src/main/kotlin/com/bitwarden/ui/platform/base/util/StringExtensions.kt index 3871d44f7f..00ff9947e9 100644 --- a/ui/src/main/kotlin/com/bitwarden/ui/platform/base/util/StringExtensions.kt +++ b/ui/src/main/kotlin/com/bitwarden/ui/platform/base/util/StringExtensions.kt @@ -239,34 +239,6 @@ fun String.prefixHttpsIfNecessaryOrNull(): String? = fun String.prefixHttpsIfNecessary(): String = prefixHttpsIfNecessaryOrNull() ?: this -/** - * If the given [String] is a valid URI, "www." will be prepended (or inserted after the scheme - * if present) if it is not already present. Otherwise `null` will be returned. - * - * Examples: - * - "example.com" -> "www.example.com" - * - "www.example.com" -> "www.example.com" - * - "https://example.com" -> "https://www.example.com" - * - "https://www.example.com" -> "https://www.example.com" - */ -fun String.prefixWwwIfNecessaryOrNull(): String? = - when { - this.isBlank() || !this.isValidUri() -> null - this.startsWith("www.") -> this - this.startsWith("http://") || this.startsWith("https://") -> { - if ("://www." in this) this else this.replaceFirst("://", "://www.") - } - - else -> "www.$this" - } - -/** - * If the given [String] is a valid URI, "www." will be prepended (or inserted after the scheme - * if present) if it is not already present. Otherwise the original [String] will be returned. - */ -fun String.prefixWwwIfNecessary(): String = - prefixWwwIfNecessaryOrNull() ?: this - /** * Checks if a string is using base32 digits. */ diff --git a/ui/src/test/kotlin/com/bitwarden/ui/platform/base/util/StringExtensionsTest.kt b/ui/src/test/kotlin/com/bitwarden/ui/platform/base/util/StringExtensionsTest.kt index 5d4ad58c0c..3a9de66085 100644 --- a/ui/src/test/kotlin/com/bitwarden/ui/platform/base/util/StringExtensionsTest.kt +++ b/ui/src/test/kotlin/com/bitwarden/ui/platform/base/util/StringExtensionsTest.kt @@ -281,65 +281,4 @@ class StringExtensionsTest { fun `orZeroWidthSpace returns the original value for a non-blank string`() { assertEquals("test", "test".orZeroWidthSpace()) } - - @Suppress("MaxLineLength") - @Test - fun `prefixWwwIfNecessaryOrNull should prefix www when URI is valid and no scheme and no www`() { - val uri = "example.com" - val expected = "www.$uri" - val actual = uri.prefixWwwIfNecessaryOrNull() - - assertEquals(expected, actual) - } - - @Test - fun `prefixWwwIfNecessaryOrNull should return URI unchanged when starts with www`() { - val uri = "www.example.com" - val actual = uri.prefixWwwIfNecessaryOrNull() - assertEquals(uri, actual) - } - - @Test - fun `prefixWwwIfNecessaryOrNull should prefix www when scheme is http and no www`() { - val uri = "http://example.com" - val expected = "http://www.example.com" - val actual = uri.prefixWwwIfNecessaryOrNull() - assertEquals(expected, actual) - } - - @Test - fun `prefixWwwIfNecessaryOrNull should prefix www when scheme is https and no www`() { - val uri = "https://example.com" - val expected = "https://www.example.com" - val actual = uri.prefixWwwIfNecessaryOrNull() - assertEquals(expected, actual) - } - - @Suppress("MaxLineLength") - @Test - fun `prefixWwwIfNecessaryOrNull should return URI unchanged when scheme is http and www is present`() { - val uri = "http://www.example.com" - val actual = uri.prefixWwwIfNecessaryOrNull() - assertEquals(uri, actual) - } - - @Suppress("MaxLineLength") - @Test - fun `prefixWwwIfNecessaryOrNull should return URI unchanged when scheme is https and www is present`() { - val uri = "https://www.example.com" - val actual = uri.prefixWwwIfNecessaryOrNull() - assertEquals(uri, actual) - } - - @Test - fun `prefixWwwIfNecessaryOrNull should return null when URI is empty string`() { - val uri = "" - assertNull(uri.prefixWwwIfNecessaryOrNull()) - } - - @Test - fun `prefixWwwIfNecessaryOrNull should return null when URI is invalid`() { - val invalidUri = "invalid uri" - assertNull(invalidUri.prefixWwwIfNecessaryOrNull()) - } }