diff --git a/app/k9mail/build.gradle.kts b/app/k9mail/build.gradle.kts
index 88d056375ee4eb81a67b93335fecfc42357e58c8..3711999c61638617349f9e560b981443dff9d867 100644
--- a/app/k9mail/build.gradle.kts
+++ b/app/k9mail/build.gradle.kts
@@ -126,10 +126,23 @@ android {
"\"dj0yJmk9dUNqYXZhYWxOYkdRJmQ9WVdrOU1YQnZVRFZoY1ZrbWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PWIw\"",
)
buildConfigField("String", "OAUTH_MICROSOFT_CLIENT_ID", "\"${getProperty("MICROSOFT_CLIENT_ID")}\"")
+
+ buildConfigField(
+ "String",
+ "MICROSOFT_REDIRECT_URI_SUFFIX_COMMUNITY",
+ "\"${getProperty("MICROSOFT_REDIRECT_URI_SUFFIX_COMMUNITY")}\"",
+ )
+
+ buildConfigField(
+ "String",
+ "MICROSOFT_REDIRECT_URI_SUFFIX_OFFICIAL",
+ "\"${getProperty("MICROSOFT_REDIRECT_URI_SUFFIX_OFFICIAL")}\"",
+ )
+
buildConfigField(
"String",
- "OAUTH_MICROSOFT_REDIRECT_URI",
- "\"msauth://foundation.e.mail/${getProperty("MICROSOFT_REDIRECT_URI_SUFFIX")}\"",
+ "MICROSOFT_REDIRECT_URI_SUFFIX_TEST",
+ "\"${getProperty("MICROSOFT_REDIRECT_URI_SUFFIX_TEST")}\"",
)
manifestPlaceholders["appAuthRedirectScheme"] = "foundation.e.mail"
@@ -157,11 +170,25 @@ android {
"OAUTH_AOL_CLIENT_ID",
"\"dj0yJmk9cHYydkJkTUxHcXlYJmQ9WVdrOWVHZHhVVXN4VVV3bWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PTdm\"",
)
+
buildConfigField("String", "OAUTH_MICROSOFT_CLIENT_ID", "\"${getProperty("MICROSOFT_CLIENT_ID")}\"")
+
+ buildConfigField(
+ "String",
+ "MICROSOFT_REDIRECT_URI_SUFFIX_COMMUNITY",
+ "\"${getProperty("MICROSOFT_REDIRECT_URI_SUFFIX_COMMUNITY")}\"",
+ )
+
+ buildConfigField(
+ "String",
+ "MICROSOFT_REDIRECT_URI_SUFFIX_OFFICIAL",
+ "\"${getProperty("MICROSOFT_REDIRECT_URI_SUFFIX_OFFICIAL")}\"",
+ )
+
buildConfigField(
"String",
- "OAUTH_MICROSOFT_REDIRECT_URI",
- "\"msauth://foundation.e.mail/${getProperty("MICROSOFT_REDIRECT_URI_SUFFIX")}\"",
+ "MICROSOFT_REDIRECT_URI_SUFFIX_TEST",
+ "\"${getProperty("MICROSOFT_REDIRECT_URI_SUFFIX_TEST")}\"",
)
manifestPlaceholders["appAuthRedirectScheme"] = "foundation.e.mail.debug"
diff --git a/app/k9mail/src/main/java/com/fsck/k9/auth/AppOAuthConfigurationFactory.kt b/app/k9mail/src/main/java/com/fsck/k9/auth/AppOAuthConfigurationFactory.kt
index 0116365aeb0bac16d12bc0ed9f51105996460e02..89654a5a10f01c11b34613a6ede099d4bbca3d4c 100644
--- a/app/k9mail/src/main/java/com/fsck/k9/auth/AppOAuthConfigurationFactory.kt
+++ b/app/k9mail/src/main/java/com/fsck/k9/auth/AppOAuthConfigurationFactory.kt
@@ -52,7 +52,7 @@ class AppOAuthConfigurationFactory : OAuthConfigurationFactory {
),
authorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
tokenEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/token",
- redirectUri = BuildConfig.OAUTH_MICROSOFT_REDIRECT_URI,
+ redirectUri = MicrosoftRedirectUriGenerator.generate(),
)
}
diff --git a/app/k9mail/src/main/java/com/fsck/k9/auth/MicrosoftRedirectUriGenerator.kt b/app/k9mail/src/main/java/com/fsck/k9/auth/MicrosoftRedirectUriGenerator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..88b165fb97bf67ff5eb82ec70484a885b01c9704
--- /dev/null
+++ b/app/k9mail/src/main/java/com/fsck/k9/auth/MicrosoftRedirectUriGenerator.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 e Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.fsck.k9.auth
+
+import com.fsck.k9.BuildConfig
+import com.fsck.k9.auth.ReleaseType.Community
+import com.fsck.k9.auth.ReleaseType.Official
+import com.fsck.k9.auth.ReleaseType.Test
+import com.fsck.k9.auth.ReleaseType.Unavailable
+
+object MicrosoftRedirectUriGenerator {
+ fun generate(): String {
+ val releaseType = ReleaseTypeHelper.getReleaseType()
+ val redirectUriSuffix = when (releaseType) {
+ Community -> BuildConfig.MICROSOFT_REDIRECT_URI_SUFFIX_COMMUNITY
+ Official -> BuildConfig.MICROSOFT_REDIRECT_URI_SUFFIX_OFFICIAL
+ Test, Unavailable -> BuildConfig.MICROSOFT_REDIRECT_URI_SUFFIX_TEST
+ }
+
+ // For debug build (foundation.e.mail.debug), update the hash of your debug keystore in Microsoft Azure portal,
+ // and based on that, set the redirectUriSuffix as it is a combination of both
+ // the applicationId and signature hash of the keystore.
+
+ return "msauth://${BuildConfig.APPLICATION_ID}/$redirectUriSuffix"
+ }
+}
diff --git a/app/k9mail/src/main/java/com/fsck/k9/auth/ReleaseTypeHelper.kt b/app/k9mail/src/main/java/com/fsck/k9/auth/ReleaseTypeHelper.kt
new file mode 100644
index 0000000000000000000000000000000000000000..00c95854383b9f3d13d3344cae8f68515e165a1f
--- /dev/null
+++ b/app/k9mail/src/main/java/com/fsck/k9/auth/ReleaseTypeHelper.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 e Foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.fsck.k9.auth
+
+import android.annotation.SuppressLint
+import com.fsck.k9.auth.ReleaseType.Community
+import com.fsck.k9.auth.ReleaseType.Official
+import com.fsck.k9.auth.ReleaseType.Test
+import com.fsck.k9.auth.ReleaseType.Unavailable
+import com.fsck.k9.logging.Timber
+
+object ReleaseTypeHelper {
+
+ private const val KEY_SYSTEM_PROPERTY_RELEASE_TYPE = "ro.lineage.releasetype"
+
+ fun getReleaseType(): ReleaseType {
+ val property = getSystemProperty(KEY_SYSTEM_PROPERTY_RELEASE_TYPE)
+
+ return when (property) {
+ Community.value -> Community
+ Official.value -> Official
+ Test.value -> Test
+ else -> Unavailable
+ }
+ }
+}
+
+enum class ReleaseType(val value: String) {
+ Community("community"),
+ Official("official"),
+ Test("test"),
+ Unavailable("")
+}
+
+@SuppressLint("PrivateApi")
+private fun getSystemProperty(key: String): String {
+ return try {
+ Class.forName("android.os.SystemProperties")
+ .getMethod("get", String::class.java)
+ .invoke(null, key) as String
+ } catch (e: Exception) {
+ Timber.e("Unable to determine system property for $key", e)
+ Unavailable.value
+ }
+}