Rename the custom recovery passphrase well-known to match the merged schema
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) <noreply@anthropic.com>
This commit is contained in:
+1
-1
Submodule enterprise updated: 11248b7ba4...cc23736aca
+4
-4
@@ -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. */
|
||||
+1
-1
@@ -15,5 +15,5 @@ data class ElementWellKnown(
|
||||
val brandColor: String?,
|
||||
val notificationSound: String?,
|
||||
val identityProviderAppScheme: String?,
|
||||
val customRecoveryPassphraseRequirements: CustomRecoveryPassphraseRequirements?,
|
||||
val customRecoveryPassphrase: CustomRecoveryPassphrase?,
|
||||
)
|
||||
|
||||
+4
-4
@@ -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,
|
||||
)
|
||||
|
||||
+5
-5
@@ -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)
|
||||
}
|
||||
|
||||
+5
-5
@@ -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()
|
||||
}
|
||||
}
|
||||
+16
-16
@@ -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,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
+5
-5
@@ -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,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user