diff --git a/appconfig/src/main/kotlin/io/element/android/appconfig/ApplicationConfig.kt b/appconfig/src/main/kotlin/io/element/android/appconfig/ApplicationConfig.kt index e1ae6896bb..2e2208814c 100644 --- a/appconfig/src/main/kotlin/io/element/android/appconfig/ApplicationConfig.kt +++ b/appconfig/src/main/kotlin/io/element/android/appconfig/ApplicationConfig.kt @@ -24,12 +24,12 @@ object ApplicationConfig { * Cannot be empty. * For Element, the value is "Element". */ - const val PRODUCTION_APPLICATION_NAME: String = "Element" + const val PRODUCTION_APPLICATION_NAME: String = "HealthChat" /** * Used in the strings to reference the Element Desktop client, for instance Element Web. * Cannot be empty. * For Element, the value is "Element". We use the same name for desktop and mobile for now. */ - const val DESKTOP_APPLICATION_NAME: String = "Element" + const val DESKTOP_APPLICATION_NAME: String = "HealthChat" } diff --git a/features/enterprise/impl-foss/src/main/kotlin/io/element/android/features/enterprise/impl/DefaultEnterpriseService.kt b/features/enterprise/impl-foss/src/main/kotlin/io/element/android/features/enterprise/impl/DefaultEnterpriseService.kt index e4e2611bc7..15db06e578 100644 --- a/features/enterprise/impl-foss/src/main/kotlin/io/element/android/features/enterprise/impl/DefaultEnterpriseService.kt +++ b/features/enterprise/impl-foss/src/main/kotlin/io/element/android/features/enterprise/impl/DefaultEnterpriseService.kt @@ -37,9 +37,9 @@ class DefaultEnterpriseService( ) : EnterpriseService { override suspend fun isEnterpriseUser(sessionId: SessionId) = false override suspend fun tweakMasUrl(url: String, urlContentFetcher: ClientUrlContentFetcher) = url - override fun accountProviderAllowList(): List = emptyList() - override fun canConnectToAnyAccountProvider(): Boolean = true - override suspend fun isAllowedToConnectToAccountProvider(accountProvider: AccountProvider) = true + override fun accountProviderAllowList(): List = listOf(healthChatAccountProvider) + override fun canConnectToAnyAccountProvider(): Boolean = false + override suspend fun isAllowedToConnectToAccountProvider(accountProvider: AccountProvider) = healthChatAccountProvider.matches(accountProvider) override suspend fun isElementProEnforced(serverName: String): Boolean = withContext(dispatchers.io) { val temporaryMatrixClient = temporaryMatrixClientFactory.create(serverName).getOrElse { return@withContext false } temporaryMatrixClient.use { client -> @@ -77,6 +77,11 @@ class DefaultEnterpriseService( override fun getNoisyNotificationChannelId(sessionId: SessionId): String? = null } +/** + * HealthChat is locked to its own homeserver: this is the only account provider users can sign in to. + */ +private val healthChatAccountProvider = AccountProvider.Generic(serverName = "matrix.healthchat.ch") + /** * A minimal version of the enterprise config that only contains the fields we need to check if Element Pro is enforced. */ diff --git a/features/enterprise/impl-foss/src/test/kotlin/io/element/android/features/enterprise/impl/DefaultEnterpriseServiceTest.kt b/features/enterprise/impl-foss/src/test/kotlin/io/element/android/features/enterprise/impl/DefaultEnterpriseServiceTest.kt index 8119b8f53e..02e8de0ce5 100644 --- a/features/enterprise/impl-foss/src/test/kotlin/io/element/android/features/enterprise/impl/DefaultEnterpriseServiceTest.kt +++ b/features/enterprise/impl-foss/src/test/kotlin/io/element/android/features/enterprise/impl/DefaultEnterpriseServiceTest.kt @@ -14,6 +14,7 @@ import io.element.android.compound.colors.SemanticColorsLightDark import io.element.android.features.enterprise.api.BugReportUrl import io.element.android.libraries.androidutils.json.JsonProvider import io.element.android.libraries.core.uri.ensureProtocol +import io.element.android.libraries.matrix.api.accountprovider.AccountProvider import io.element.android.libraries.matrix.test.A_HOMESERVER_URL import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.FakeTemporaryMatrixClient @@ -29,21 +30,24 @@ import org.junit.Test class DefaultEnterpriseServiceTest { @Test - fun accountProviderAllowList() = runTest { + fun `accountProviderAllowList contains the HealthChat homeserver only`() = runTest { val defaultEnterpriseService = createDefaultEnterpriseService() - assertThat(defaultEnterpriseService.accountProviderAllowList()).isEmpty() + assertThat(defaultEnterpriseService.accountProviderAllowList()) + .containsExactly(AccountProvider.Generic(serverName = "matrix.healthchat.ch")) } @Test - fun `canConnectToAnyAccountProvider is always true`() = runTest { + fun `canConnectToAnyAccountProvider is always false`() = runTest { val defaultEnterpriseService = createDefaultEnterpriseService() - assertThat(defaultEnterpriseService.canConnectToAnyAccountProvider()).isTrue() + assertThat(defaultEnterpriseService.canConnectToAnyAccountProvider()).isFalse() } @Test - fun `isAllowedToConnectToAccountProvider is true for all account providers`() = runTest { + fun `isAllowedToConnectToAccountProvider is true for the HealthChat homeserver only`() = runTest { val defaultEnterpriseService = createDefaultEnterpriseService() - assertThat(defaultEnterpriseService.isAllowedToConnectToAccountProvider(anAccountProviderGeneric())).isTrue() + assertThat(defaultEnterpriseService.isAllowedToConnectToAccountProvider(AccountProvider.Generic("matrix.healthchat.ch"))).isTrue() + assertThat(defaultEnterpriseService.isAllowedToConnectToAccountProvider(AccountProvider.Generic("https://matrix.healthchat.ch/"))).isTrue() + assertThat(defaultEnterpriseService.isAllowedToConnectToAccountProvider(anAccountProviderGeneric())).isFalse() } @Test diff --git a/plugins/src/main/kotlin/config/BuildTimeConfig.kt b/plugins/src/main/kotlin/config/BuildTimeConfig.kt index 4160efeb78..51dae48e88 100644 --- a/plugins/src/main/kotlin/config/BuildTimeConfig.kt +++ b/plugins/src/main/kotlin/config/BuildTimeConfig.kt @@ -9,16 +9,24 @@ package config object BuildTimeConfig { - const val APPLICATION_ID = "io.element.android.x" - const val APPLICATION_NAME = "Element X" - val METADATA_HOST_REVERSED: String? = null - val OAUTH_CLIENT_URL_PATH: String? = "apps/android" - val URL_WEBSITE: String? = null - val URL_LOGO: String? = null + const val APPLICATION_ID = "ch.healthchat.element" + const val APPLICATION_NAME = "HealthChat" + + // OIDC redirect scheme base. MAS requires the custom scheme to be the + // reverse-DNS of the CLIENT_URI (URL_WEBSITE) host, or an extension of it. + val METADATA_HOST_REVERSED: String? = "ch.healthchat.element" + // No path is appended to the OIDC client_uri: MAS validates the redirect + // scheme against the apex host, so the client URI must stay https://healthchat.ch. + val OAUTH_CLIENT_URL_PATH: String? = null + // Must stay the apex host: the OIDC client_uri host must reverse-match + // METADATA_HOST_REVERSED, and logo/tos/policy URIs must be on this host + // or a subdomain of it. + val URL_WEBSITE: String? = "https://healthchat.ch" + val URL_LOGO: String? = "https://www.healthchat.ch/favicon.ico" val URL_COPYRIGHT: String? = null - val URL_ACCEPTABLE_USE: String? = null - val URL_PRIVACY: String? = null - val URL_POLICY: String? = null + val URL_ACCEPTABLE_USE: String? = "https://www.healthchat.ch/datenschutz" + val URL_PRIVACY: String? = "https://www.healthchat.ch/datenschutz" + val URL_POLICY: String? = "https://www.healthchat.ch/datenschutz" val SERVICES_MAPTILER_BASE_URL: String? = null val SERVICES_MAPTILER_APIKEY: String? = null val SERVICES_MAPTILER_LIGHT_MAPID: String? = null