From fdac92a9ea5c6d95c32c0f14717d5a70fae47ad7 Mon Sep 17 00:00:00 2001 From: Jenna Vassar Date: Thu, 11 Jun 2026 15:03:24 -0700 Subject: [PATCH] Rename the custom recovery passphrase well-known to match the merged schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The merged element-enterprise#261 well-known schema advertises the feature under custom_recovery_passphrase (no _settings/_requirements suffix), so the parser previously looking for custom_recovery_passphrase_settings would never activate the flow. Update the @SerialName and drop the narrow "Requirements" suffix from the type — the block is now general, extensible feature settings — to mirror the .pkl CustomRecoveryPassphrase class. Bumps the enterprise submodule to the matching consumer change. Co-Authored-By: Claude Opus 4.8 (1M context) --- enterprise | 2 +- ...rements.kt => CustomRecoveryPassphrase.kt} | 8 ++--- .../wellknown/api/ElementWellKnown.kt | 2 +- .../impl/InternalElementWellKnown.kt | 8 ++--- .../libraries/wellknown/impl/Mapper.kt | 10 +++--- ...est.kt => CustomRecoveryPassphraseTest.kt} | 10 +++--- .../DefaultSessionWellknownRetrieverTest.kt | 32 +++++++++---------- .../features/wellknown/test/Fixtures.kt | 10 +++--- 8 files changed, 41 insertions(+), 41 deletions(-) rename libraries/wellknown/api/src/main/kotlin/io/element/android/libraries/wellknown/api/{CustomRecoveryPassphraseRequirements.kt => CustomRecoveryPassphrase.kt} (67%) rename libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/api/{CustomRecoveryPassphraseRequirementsTest.kt => CustomRecoveryPassphraseTest.kt} (55%) diff --git a/enterprise b/enterprise index 11248b7ba4..cc23736aca 160000 --- a/enterprise +++ b/enterprise @@ -1 +1 @@ -Subproject commit 11248b7ba47a0e8ba32be9d094c22a3e4defe94b +Subproject commit cc23736aca2428dfeed246fdbb608fd2da4869b9 diff --git a/libraries/wellknown/api/src/main/kotlin/io/element/android/libraries/wellknown/api/CustomRecoveryPassphraseRequirements.kt b/libraries/wellknown/api/src/main/kotlin/io/element/android/libraries/wellknown/api/CustomRecoveryPassphrase.kt similarity index 67% rename from libraries/wellknown/api/src/main/kotlin/io/element/android/libraries/wellknown/api/CustomRecoveryPassphraseRequirements.kt rename to libraries/wellknown/api/src/main/kotlin/io/element/android/libraries/wellknown/api/CustomRecoveryPassphrase.kt index dc6241b0a9..c7bc602dde 100644 --- a/libraries/wellknown/api/src/main/kotlin/io/element/android/libraries/wellknown/api/CustomRecoveryPassphraseRequirements.kt +++ b/libraries/wellknown/api/src/main/kotlin/io/element/android/libraries/wellknown/api/CustomRecoveryPassphrase.kt @@ -8,11 +8,11 @@ package io.element.android.libraries.wellknown.api /** - * Server-driven requirements for a user-chosen recovery passphrase. Today the only rule - * is a minimum character count; additional rules can be added here as the well-known - * schema (`custom_recovery_passphrase_settings`) grows. + * Server-driven settings for a user-chosen recovery passphrase, advertised under the well-known + * `custom_recovery_passphrase` key. Today the only rule is a minimum character count; additional + * settings can be added here as the schema grows. */ -data class CustomRecoveryPassphraseRequirements( +data class CustomRecoveryPassphrase( val minCharacterCount: Int, ) { /** True when [input] meets every active rule. */ diff --git a/libraries/wellknown/api/src/main/kotlin/io/element/android/libraries/wellknown/api/ElementWellKnown.kt b/libraries/wellknown/api/src/main/kotlin/io/element/android/libraries/wellknown/api/ElementWellKnown.kt index ac050ba94a..8f2c07ab68 100644 --- a/libraries/wellknown/api/src/main/kotlin/io/element/android/libraries/wellknown/api/ElementWellKnown.kt +++ b/libraries/wellknown/api/src/main/kotlin/io/element/android/libraries/wellknown/api/ElementWellKnown.kt @@ -15,5 +15,5 @@ data class ElementWellKnown( val brandColor: String?, val notificationSound: String?, val identityProviderAppScheme: String?, - val customRecoveryPassphraseRequirements: CustomRecoveryPassphraseRequirements?, + val customRecoveryPassphrase: CustomRecoveryPassphrase?, ) diff --git a/libraries/wellknown/impl/src/main/kotlin/io/element/android/libraries/wellknown/impl/InternalElementWellKnown.kt b/libraries/wellknown/impl/src/main/kotlin/io/element/android/libraries/wellknown/impl/InternalElementWellKnown.kt index 803e498eda..cd0f39c77f 100644 --- a/libraries/wellknown/impl/src/main/kotlin/io/element/android/libraries/wellknown/impl/InternalElementWellKnown.kt +++ b/libraries/wellknown/impl/src/main/kotlin/io/element/android/libraries/wellknown/impl/InternalElementWellKnown.kt @@ -21,7 +21,7 @@ import kotlinx.serialization.Serializable * "brand_color": "#FF0000", * "notification_sound": "ring.flac", * "idp_app_scheme": "io.element.app", - * "custom_recovery_passphrase_settings": { + * "custom_recovery_passphrase": { * "min_character_count": 8 * } * } @@ -42,12 +42,12 @@ data class InternalElementWellKnown( val notificationSound: String? = null, @SerialName("idp_app_scheme") val identityProviderAppScheme: String? = null, - @SerialName("custom_recovery_passphrase_settings") - val customRecoveryPassphraseRequirements: InternalCustomRecoveryPassphraseRequirements? = null, + @SerialName("custom_recovery_passphrase") + val customRecoveryPassphrase: InternalCustomRecoveryPassphrase? = null, ) @Serializable -data class InternalCustomRecoveryPassphraseRequirements( +data class InternalCustomRecoveryPassphrase( @SerialName("min_character_count") val minCharacterCount: Int? = null, ) diff --git a/libraries/wellknown/impl/src/main/kotlin/io/element/android/libraries/wellknown/impl/Mapper.kt b/libraries/wellknown/impl/src/main/kotlin/io/element/android/libraries/wellknown/impl/Mapper.kt index 2353017be8..c8760881d4 100644 --- a/libraries/wellknown/impl/src/main/kotlin/io/element/android/libraries/wellknown/impl/Mapper.kt +++ b/libraries/wellknown/impl/src/main/kotlin/io/element/android/libraries/wellknown/impl/Mapper.kt @@ -9,7 +9,7 @@ package io.element.android.libraries.wellknown.impl import io.element.android.libraries.core.log.logger.LoggerTag -import io.element.android.libraries.wellknown.api.CustomRecoveryPassphraseRequirements +import io.element.android.libraries.wellknown.api.CustomRecoveryPassphrase import io.element.android.libraries.wellknown.api.ElementWellKnown import timber.log.Timber @@ -29,20 +29,20 @@ internal fun InternalElementWellKnown.map() = ElementWellKnown( brandColor = brandColor, notificationSound = notificationSound, identityProviderAppScheme = identityProviderAppScheme, - customRecoveryPassphraseRequirements = customRecoveryPassphraseRequirements?.toPublic(), + customRecoveryPassphrase = customRecoveryPassphrase?.toPublic(), ) -private fun InternalCustomRecoveryPassphraseRequirements.toPublic(): CustomRecoveryPassphraseRequirements { +private fun InternalCustomRecoveryPassphrase.toPublic(): CustomRecoveryPassphrase { // Whenever the homeserver advertises the settings block we run the custom passphrase flow, flooring // the minimum at 1 so the passphrase can never be empty even if the server omits min_character_count // or advertises a non-positive value. The operator owns any stronger minimum. val min = (minCharacterCount ?: MINIMUM_PASSPHRASE_CHARACTER_COUNT).coerceAtLeast(MINIMUM_PASSPHRASE_CHARACTER_COUNT) if (min != minCharacterCount) { Timber.tag(loggerTag.value).w( - "custom_recovery_passphrase_settings.min_character_count was %s; flooring to %d", + "custom_recovery_passphrase.min_character_count was %s; flooring to %d", minCharacterCount, min, ) } - return CustomRecoveryPassphraseRequirements(minCharacterCount = min) + return CustomRecoveryPassphrase(minCharacterCount = min) } diff --git a/libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/api/CustomRecoveryPassphraseRequirementsTest.kt b/libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/api/CustomRecoveryPassphraseTest.kt similarity index 55% rename from libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/api/CustomRecoveryPassphraseRequirementsTest.kt rename to libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/api/CustomRecoveryPassphraseTest.kt index c8f10fe2ca..d4e7ac112e 100644 --- a/libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/api/CustomRecoveryPassphraseRequirementsTest.kt +++ b/libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/api/CustomRecoveryPassphraseTest.kt @@ -10,24 +10,24 @@ package io.element.android.libraries.wellknown.api import com.google.common.truth.Truth.assertThat import org.junit.Test -class CustomRecoveryPassphraseRequirementsTest { +class CustomRecoveryPassphraseTest { @Test fun `empty input never satisfies a positive minimum`() { - assertThat(CustomRecoveryPassphraseRequirements(minCharacterCount = 1).isSatisfiedBy("")).isFalse() + assertThat(CustomRecoveryPassphrase(minCharacterCount = 1).isSatisfiedBy("")).isFalse() } @Test fun `input shorter than minimum is not satisfied`() { - assertThat(CustomRecoveryPassphraseRequirements(minCharacterCount = 8).isSatisfiedBy("abc")).isFalse() + assertThat(CustomRecoveryPassphrase(minCharacterCount = 8).isSatisfiedBy("abc")).isFalse() } @Test fun `input exactly at minimum is satisfied`() { - assertThat(CustomRecoveryPassphraseRequirements(minCharacterCount = 8).isSatisfiedBy("abcdefgh")).isTrue() + assertThat(CustomRecoveryPassphrase(minCharacterCount = 8).isSatisfiedBy("abcdefgh")).isTrue() } @Test fun `input longer than minimum is satisfied`() { - assertThat(CustomRecoveryPassphraseRequirements(minCharacterCount = 4).isSatisfiedBy("abcdefgh")).isTrue() + assertThat(CustomRecoveryPassphrase(minCharacterCount = 4).isSatisfiedBy("abcdefgh")).isTrue() } } diff --git a/libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/impl/DefaultSessionWellknownRetrieverTest.kt b/libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/impl/DefaultSessionWellknownRetrieverTest.kt index bdd25aa80b..a64d156f6e 100644 --- a/libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/impl/DefaultSessionWellknownRetrieverTest.kt +++ b/libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/impl/DefaultSessionWellknownRetrieverTest.kt @@ -19,7 +19,7 @@ import io.element.android.libraries.cachestore.api.CacheStore import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.sessionstorage.test.InMemoryCacheStore -import io.element.android.libraries.wellknown.api.CustomRecoveryPassphraseRequirements +import io.element.android.libraries.wellknown.api.CustomRecoveryPassphrase import io.element.android.libraries.wellknown.api.ElementWellKnown import io.element.android.libraries.wellknown.api.WellknownRetrieverResult import io.element.android.services.toolbox.api.systemclock.SystemClock @@ -52,7 +52,7 @@ class DefaultSessionWellknownRetrieverTest { brandColor = null, notificationSound = null, identityProviderAppScheme = null, - customRecoveryPassphraseRequirements = null, + customRecoveryPassphrase = null, ) ) ) @@ -78,7 +78,7 @@ class DefaultSessionWellknownRetrieverTest { brandColor = "#FF0000", notificationSound = "a_notification_sound.flac", identityProviderAppScheme = "an_app_scheme", - customRecoveryPassphraseRequirements = null, + customRecoveryPassphrase = null, ) ) ) @@ -108,19 +108,19 @@ class DefaultSessionWellknownRetrieverTest { brandColor = null, notificationSound = null, identityProviderAppScheme = null, - customRecoveryPassphraseRequirements = null, + customRecoveryPassphrase = null, ) ) ) } @Test - fun `get element wellknown with custom recovery passphrase requirements`() = runTest { + fun `get element wellknown with custom recovery passphrase settings`() = runTest { val sut = createDefaultSessionWellknownRetriever( getUrlLambda = { Result.success( """{ - "custom_recovery_passphrase_settings": { + "custom_recovery_passphrase": { "min_character_count": 8 } }""".trimIndent().toByteArray() @@ -130,19 +130,19 @@ class DefaultSessionWellknownRetrieverTest { assertThat(sut.getElementWellKnown()).isEqualTo( WellknownRetrieverResult.Success( anElementWellKnown( - customRecoveryPassphraseRequirements = CustomRecoveryPassphraseRequirements(minCharacterCount = 8) + customRecoveryPassphrase = CustomRecoveryPassphrase(minCharacterCount = 8) ) ) ) } @Test - fun `get element wellknown with custom recovery passphrase requirements missing min character count floors to 1`() = runTest { + fun `get element wellknown with custom recovery passphrase settings missing min character count floors to 1`() = runTest { val sut = createDefaultSessionWellknownRetriever( getUrlLambda = { Result.success( """{ - "custom_recovery_passphrase_settings": {} + "custom_recovery_passphrase": {} }""".trimIndent().toByteArray() ) }, @@ -150,7 +150,7 @@ class DefaultSessionWellknownRetrieverTest { assertThat(sut.getElementWellKnown()).isEqualTo( WellknownRetrieverResult.Success( anElementWellKnown( - customRecoveryPassphraseRequirements = CustomRecoveryPassphraseRequirements(minCharacterCount = 1) + customRecoveryPassphrase = CustomRecoveryPassphrase(minCharacterCount = 1) ) ) ) @@ -162,7 +162,7 @@ class DefaultSessionWellknownRetrieverTest { getUrlLambda = { Result.success( """{ - "custom_recovery_passphrase_settings": { + "custom_recovery_passphrase": { "min_character_count": 0 } }""".trimIndent().toByteArray() @@ -172,7 +172,7 @@ class DefaultSessionWellknownRetrieverTest { assertThat(sut.getElementWellKnown()).isEqualTo( WellknownRetrieverResult.Success( anElementWellKnown( - customRecoveryPassphraseRequirements = CustomRecoveryPassphraseRequirements(minCharacterCount = 1) + customRecoveryPassphrase = CustomRecoveryPassphrase(minCharacterCount = 1) ) ) ) @@ -184,7 +184,7 @@ class DefaultSessionWellknownRetrieverTest { getUrlLambda = { Result.success( """{ - "custom_recovery_passphrase_settings": { + "custom_recovery_passphrase": { "min_character_count": -5 } }""".trimIndent().toByteArray() @@ -194,7 +194,7 @@ class DefaultSessionWellknownRetrieverTest { assertThat(sut.getElementWellKnown()).isEqualTo( WellknownRetrieverResult.Success( anElementWellKnown( - customRecoveryPassphraseRequirements = CustomRecoveryPassphraseRequirements(minCharacterCount = 1) + customRecoveryPassphrase = CustomRecoveryPassphrase(minCharacterCount = 1) ) ) ) @@ -247,7 +247,7 @@ class DefaultSessionWellknownRetrieverTest { brandColor = "#FF0000", notificationSound = "a_notification_sound.flac", identityProviderAppScheme = "an_app_scheme", - customRecoveryPassphraseRequirements = null, + customRecoveryPassphrase = null, ) ) ) @@ -301,7 +301,7 @@ class DefaultSessionWellknownRetrieverTest { brandColor = "#FF0000", notificationSound = "a_notification_sound.flac", identityProviderAppScheme = "an_app_scheme", - customRecoveryPassphraseRequirements = null, + customRecoveryPassphrase = null, ) ) ) diff --git a/libraries/wellknown/test/src/main/kotlin/io/element/android/features/wellknown/test/Fixtures.kt b/libraries/wellknown/test/src/main/kotlin/io/element/android/features/wellknown/test/Fixtures.kt index 1ed69207ba..51b06f7226 100644 --- a/libraries/wellknown/test/src/main/kotlin/io/element/android/features/wellknown/test/Fixtures.kt +++ b/libraries/wellknown/test/src/main/kotlin/io/element/android/features/wellknown/test/Fixtures.kt @@ -8,7 +8,7 @@ package io.element.android.features.wellknown.test -import io.element.android.libraries.wellknown.api.CustomRecoveryPassphraseRequirements +import io.element.android.libraries.wellknown.api.CustomRecoveryPassphrase import io.element.android.libraries.wellknown.api.ElementWellKnown fun anElementWellKnown( @@ -18,7 +18,7 @@ fun anElementWellKnown( brandColor: String? = null, notificationSound: String? = null, identityProviderAppScheme: String? = null, - customRecoveryPassphraseRequirements: CustomRecoveryPassphraseRequirements? = null, + customRecoveryPassphrase: CustomRecoveryPassphrase? = null, ) = ElementWellKnown( registrationHelperUrl = registrationHelperUrl, enforceElementPro = enforceElementPro, @@ -26,11 +26,11 @@ fun anElementWellKnown( brandColor = brandColor, notificationSound = notificationSound, identityProviderAppScheme = identityProviderAppScheme, - customRecoveryPassphraseRequirements = customRecoveryPassphraseRequirements, + customRecoveryPassphrase = customRecoveryPassphrase, ) -fun aCustomRecoveryPassphraseRequirements( +fun aCustomRecoveryPassphrase( minCharacterCount: Int = 8, -) = CustomRecoveryPassphraseRequirements( +) = CustomRecoveryPassphrase( minCharacterCount = minCharacterCount, )