Skip to content

Commit

Permalink
Merge pull request #96 from CrisisCleanup/code-link-login
Browse files Browse the repository at this point in the history
Code link login
  • Loading branch information
hueachilles authored Dec 11, 2023
2 parents a049ad1 + cbe4ff9 commit 9cb451d
Show file tree
Hide file tree
Showing 53 changed files with 1,661 additions and 236 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ debug.properties
release.properties
prod.properties
earlybird.properties
aussie.properties

_ignore*.kt
core/database/schemas/com.crisiscleanup.core.database.TestCrisisCleanupDatabase
Expand Down
14 changes: 11 additions & 3 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ plugins {

android {
defaultConfig {
val buildVersion = 166
val buildVersion = 170
applicationId = "com.crisiscleanup"
versionCode = buildVersion
versionName = "0.8.${buildVersion - 155}"
versionName = "0.9.${buildVersion - 168}"

// Custom test runner to set up Hilt dependency graph
testInstrumentationRunner = "com.crisiscleanup.core.testing.CrisisCleanupTestRunner"
Expand Down Expand Up @@ -69,6 +69,11 @@ android {
buildConfigField("Boolean", "IS_PROD_BUILD", "true")
buildConfigField("Boolean", "IS_EARLYBIRD_BUILD", "true")
}

val aussie by getting {
buildConfigField("Boolean", "IS_PROD_BUILD", "true")
buildConfigField("Boolean", "IS_EARLYBIRD_BUILD", "false")
}
}

packaging {
Expand All @@ -91,7 +96,10 @@ secrets {
androidComponents {
beforeVariants { variantBuilder ->
// Unnecessary variants
if (variantBuilder.name == "prodDebug" || variantBuilder.name == "earlybirdDebug") {
if (variantBuilder.name == "prodDebug" ||
variantBuilder.name == "earlybirdDebug" ||
variantBuilder.name == "aussieDebug"
) {
variantBuilder.enable = false
}
}
Expand Down
48 changes: 48 additions & 0 deletions app/src/aussie/res/drawable/ic_launcher_foreground.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="256"
android:viewportHeight="256">
<group android:scaleX="0.67"
android:scaleY="0.67"
android:translateX="42.24"
android:translateY="42.24">
<path
android:pathData="M99,59C132.14,59 159,85.86 159,119C159,132.47 154.56,144.91 147.06,154.92L99,232L50.94,154.93C43.44,144.92 39,132.48 39,119C39,85.86 65.86,59 99,59Z"
android:strokeWidth="1"
android:fillColor="#454545"
android:fillAlpha="0.5325612"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M99,59C132.14,59 159,85.86 159,119C159,132.47 154.56,144.91 147.06,154.92L99,232L50.94,154.93C43.44,144.92 39,132.48 39,119C39,85.86 65.86,59 99,59Z"
android:strokeWidth="1"
android:fillColor="#FECE09"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M89,98.5C96.7,98.5 103.38,102.85 106.73,109.23L98.03,114.2C96.42,110.83 92.98,108.5 89,108.5C83.48,108.5 79,112.98 79,118.5C79,124.02 83.48,128.5 89,128.5C92.98,128.5 96.42,126.17 98.03,122.8L106.73,127.77C103.38,134.15 96.7,138.5 89,138.5C77.95,138.5 69,129.55 69,118.5C69,107.45 77.95,98.5 89,98.5Z"
android:strokeWidth="1"
android:fillColor="#F79820"
android:fillType="nonZero"
android:strokeColor="#00000000"/>
<path
android:pathData="M136.5,98.5C144.2,98.5 150.88,102.85 154.23,109.23L145.53,114.2C143.92,110.83 140.48,108.5 136.5,108.5C130.98,108.5 126.5,112.98 126.5,118.5C126.5,124.02 130.98,128.5 136.5,128.5C140.48,128.5 143.92,126.17 145.53,122.8L154.23,127.77C150.88,134.15 144.2,138.5 136.5,138.5C125.45,138.5 116.5,129.55 116.5,118.5C116.5,107.45 125.45,98.5 136.5,98.5Z"
android:strokeWidth="1"
android:fillColor="#F79820"
android:fillType="nonZero"
android:strokeColor="#00000000"/>
<path
android:pathData="M76.62,153.3C86.38,162.13 99.31,167.5 113.5,167.5C125.53,167.5 136.66,163.64 145.72,157.08L135.33,173.74C128.51,176.18 121.16,177.5 113.5,177.5C96.55,177.5 81.11,171.01 69.54,160.38L76.62,153.3Z"
android:strokeWidth="1"
android:fillColor="#F79820"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M136.23,215L141.82,199.53L162.24,199.53L167.48,215L175.14,215L156.41,163.36L148.5,163.36L129.05,215L136.23,215ZM159.99,193.84L143.82,193.84L152.15,171.02L159.99,193.84ZM202.32,216.37C211.04,216.37 216.97,213.25 220.11,207.02C221.82,203.6 222.68,198.71 222.68,192.36L222.68,192.36L222.68,163.36L215.57,163.36L215.57,195.28C215.57,199 215,201.97 213.85,204.17C211.72,208.23 207.69,210.25 201.76,210.25C196.81,210.25 193.3,208.38 191.21,204.63C189.8,202.14 189.1,199.03 189.1,195.28L189.1,195.28L189.1,163.36L182,163.36L182,192.36C182,198.71 182.86,203.6 184.57,207.02C187.68,213.25 193.6,216.37 202.32,216.37Z"
android:strokeWidth="1"
android:fillColor="#000000"
android:fillType="nonZero"
android:strokeColor="#00000000"/>
</group>
</vector>
4 changes: 0 additions & 4 deletions app/src/demo/res/mipmap-anydpi-v26/ic_launcher.xml

This file was deleted.

4 changes: 0 additions & 4 deletions app/src/demoDebug/res/mipmap-anydpi-v26/ic_launcher.xml

This file was deleted.

4 changes: 0 additions & 4 deletions app/src/earlybird/res/mipmap-anydpi-v26/ic_launcher.xml

This file was deleted.

7 changes: 5 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@

<activity
android:name=".MainActivity"
android:exported="true">
android:exported="true"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand All @@ -50,8 +51,10 @@

<data android:host="${APP_LINK_TLD}" />

<data android:pathPrefix="/o/callback" />
<data android:pathPrefix="/l" />
<data android:pathPrefix="/password/reset" />
<data android:pathPrefix="/invitation_token" />
<data android:pathPrefix="/mobile_app_user_invite" />
</intent-filter>
</activity>
</application>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ class ExternalIntentProcessor @Inject constructor(
}

private fun processMainIntent(url: Uri, urlPath: String): Boolean {
if (urlPath.startsWith("/o/callback")) {
url.getQueryParameter("code")?.let { code ->
if (urlPath.startsWith("/l/")) {
val code = urlPath.replace("/l/", "")
if (code.isNotBlank()) {
authEventBus.onEmailLoginLink(code)
}
} else if (urlPath.startsWith("/password/reset/")) {
Expand Down
24 changes: 20 additions & 4 deletions app/src/main/java/com/crisiscleanup/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.crisiscleanup

import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
Expand Down Expand Up @@ -160,14 +161,22 @@ class MainActivity : ComponentActivity() {

intent?.let {
if (!intentProcessor.processMainIntent(it)) {
it.data?.let { dataUri ->
// TODO Open to browser or WebView. Do no loop back here.
logger.logDebug("App link not processed $dataUri")
}
logUnprocessedExternalUri(it)
}
}
}

override fun onNewIntent(intent: Intent?) {
var isConsumed = false
intent?.let {
isConsumed = intentProcessor.processMainIntent(it)
}
if (!isConsumed) {
logUnprocessedExternalUri(intent)
super.onNewIntent(intent)
}
}

override fun onResume() {
super.onResume()
lazyStats.get().isTrackingEnabled = true
Expand Down Expand Up @@ -202,6 +211,13 @@ class MainActivity : ComponentActivity() {
trimMemoryEventManager.onTrimMemory(level)
super.onTrimMemory(level)
}

private fun logUnprocessedExternalUri(intent: Intent?) {
intent?.data?.let { dataUri ->
// TODO Open to browser or WebView. Do no loop back here.
logger.logDebug("App link not processed $dataUri")
}
}
}

/**
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/java/com/crisiscleanup/MainActivityViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import com.crisiscleanup.core.data.IncidentSelector
import com.crisiscleanup.core.data.repository.AccountDataRefresher
import com.crisiscleanup.core.data.repository.AccountDataRepository
import com.crisiscleanup.core.data.repository.AppDataManagementRepository
import com.crisiscleanup.core.data.repository.ClearAppDataStep.*
import com.crisiscleanup.core.data.repository.IncidentsRepository
import com.crisiscleanup.core.data.repository.LocalAppMetricsRepository
import com.crisiscleanup.core.data.repository.LocalAppPreferencesRepository
Expand Down Expand Up @@ -165,8 +164,8 @@ class MainActivityViewModel @Inject constructor(
return null
}

// TODO Build route to auth/forgot-password rather than switches through the hierarchy
val showPasswordReset = authEventBus.showResetPassword
val showMagicLinkLogin = authEventBus.showMagicLinkLogin

val isSwitchingToProduction: StateFlow<Boolean>
val productionSwitchMessage: StateFlow<String>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import com.crisiscleanup.core.appnav.RouteConstant
import com.crisiscleanup.core.appnav.RouteConstant.authGraphRoutePattern
import com.crisiscleanup.feature.authentication.navigation.authGraph
import com.crisiscleanup.feature.authentication.navigation.emailLoginLinkScreen
import com.crisiscleanup.feature.authentication.navigation.forgotPasswordScreen
import com.crisiscleanup.feature.authentication.navigation.loginWithEmailScreen
import com.crisiscleanup.feature.authentication.navigation.loginWithPhoneScreen
import com.crisiscleanup.feature.authentication.navigation.magicLinkLoginScreen
import com.crisiscleanup.feature.authentication.navigation.navigateToEmailLoginLink
import com.crisiscleanup.feature.authentication.navigation.navigateToForgotPassword
import com.crisiscleanup.feature.authentication.navigation.navigateToLoginWithEmail
import com.crisiscleanup.feature.authentication.navigation.navigateToLoginWithPhone
import com.crisiscleanup.feature.authentication.navigation.resetPasswordScreen

@Composable
fun CrisisCleanupAuthNavHost(
Expand All @@ -21,10 +25,12 @@ fun CrisisCleanupAuthNavHost(
closeAuthentication: () -> Unit,
onBack: () -> Unit,
modifier: Modifier = Modifier,
startDestination: String = RouteConstant.authGraphRoutePattern,
startDestination: String = authGraphRoutePattern,
) {
val navToLoginWithEmail =
remember(navController) { { navController.navigateToLoginWithEmail() } }
val navToLoginWithPhone =
remember(navController) { { navController.navigateToLoginWithPhone() } }
val navToForgotPassword =
remember(navController) { { navController.navigateToForgotPassword() } }
val navToEmailMagicLink =
Expand All @@ -51,9 +57,22 @@ fun CrisisCleanupAuthNavHost(
)
},
)
loginWithPhoneScreen(
onBack = onBack,
closeAuthentication = closeAuthentication,
)
resetPasswordScreen(
onBack = onBack,
closeResetPassword = navToLoginWithEmail,
)
magicLinkLoginScreen(
onBack = onBack,
closeAuthentication = closeAuthentication,
)
},
enableBackHandler = enableBackHandler,
openLoginWithEmail = navToLoginWithEmail,
openLoginWithPhone = navToLoginWithPhone,
closeAuthentication = closeAuthentication,
)
}
Expand Down
20 changes: 16 additions & 4 deletions app/src/main/java/com/crisiscleanup/ui/CrisisCleanupApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import androidx.compose.animation.slideIn
import androidx.compose.animation.slideOut
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
Expand Down Expand Up @@ -73,6 +72,8 @@ import com.crisiscleanup.core.designsystem.icon.Icon.ImageVectorIcon
import com.crisiscleanup.core.ui.AppLayoutArea
import com.crisiscleanup.core.ui.LocalAppLayout
import com.crisiscleanup.core.ui.rememberIsKeyboardOpen
import com.crisiscleanup.feature.authentication.navigation.navigateToMagicLinkLogin
import com.crisiscleanup.feature.authentication.navigation.navigateToPasswordReset
import com.crisiscleanup.feature.cases.ui.SelectIncidentDialog
import com.crisiscleanup.navigation.CrisisCleanupAuthNavHost
import com.crisiscleanup.navigation.CrisisCleanupNavHost
Expand Down Expand Up @@ -153,9 +154,22 @@ private fun LoadedContent(
val isAccountExpired by viewModel.isAccountExpired

val showPasswordReset by viewModel.showPasswordReset.collectAsStateWithLifecycle(false)
val showMagicLinkLogin by viewModel.showMagicLinkLogin.collectAsStateWithLifecycle(false)
val isNotAuthenticatedState = authState !is AuthState.Authenticated
var openAuthentication by rememberSaveable { mutableStateOf(isNotAuthenticatedState) }
if (openAuthentication || isNotAuthenticatedState || showPasswordReset) {
if (openAuthentication ||
isNotAuthenticatedState ||
showPasswordReset ||
showMagicLinkLogin
) {
LaunchedEffect(showPasswordReset, showMagicLinkLogin) {
if (showPasswordReset) {
appState.navController.navigateToPasswordReset()
} else if (showMagicLinkLogin) {
appState.navController.navigateToMagicLinkLogin()
}
}

val toggleAuthentication = remember(authState) {
{ open: Boolean -> openAuthentication = open }
}
Expand Down Expand Up @@ -209,7 +223,6 @@ private fun LoadedContent(

@OptIn(
ExperimentalComposeUiApi::class,
ExperimentalLayoutApi::class,
)
@Composable
private fun AuthenticateContent(
Expand Down Expand Up @@ -246,7 +259,6 @@ private fun AuthenticateContent(
}

@OptIn(
ExperimentalLayoutApi::class,
ExperimentalComposeUiApi::class,
)
@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum class NiaFlavor(val dimension: FlavorDimension, val applicationIdSuffix: St
demo(FlavorDimension.contentType, ".demo"),
prod(FlavorDimension.contentType, ".prod"),
earlybird(FlavorDimension.contentType, ".earlybird"),
aussie(FlavorDimension.contentType, ".aussie"),
}

fun configureFlavors(
Expand Down
24 changes: 23 additions & 1 deletion build_sign_prod_release_bundle.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,36 @@ APP_OUT=$DIR/app/build/outputs
if [[ -z "$DIST_DIR" ]]; then
DIST_DIR=$DIR/app/build
fi

DIST_AAB=$DIST_DIR/app-prod-release.aab
MAPPING_FILE_NAME=release-aab-mapping.txt
MAPPING_FILE_NAME=prod-release-aab-mapping.txt
cp $APP_OUT/bundle/prodRelease/app-prod-release.aab $DIST_AAB
cp $APP_OUT/mapping/prodRelease/mapping.txt $DIST_DIR/$MAPPING_FILE_NAME

# Sign app bundle
jarsigner -verbose -storepass $CRISIS_CLEANUP_ANDROID_KEYSTORE_PW -keystore $CRISIS_CLEANUP_ANDROID_KEYSTORE_PATH $DIST_AAB $CRISIS_CLEANUP_ANDROID_KEYSTORE_KEY_ALIAS -keypass $CRISIS_CLEANUP_ANDROID_KEYSTORE_KEY_PW

# Most likely successful
if [[ -f "$DIST_AAB" && -f "$DIST_DIR/$MAPPING_FILE_NAME" ]]; then
GREEN='\033[0;32m'
NC='\033[0m'
dirPathLength=${#DIR}
bundleRelativePath=${DIST_AAB:dirPathLength}
echo -e "\n${GREEN}Signed bundle at${NC} .$bundleRelativePath. Mapping $MAPPING_FILE_NAME is copied to same area.\n"
else
messageExit "Something went wrong during build/signing"
fi

$GRADLEW bundleAussieRelease

DIST_AAB=$DIST_DIR/app-aussie-release.aab
MAPPING_FILE_NAME=aussie-release-aab-mapping.txt
cp $APP_OUT/bundle/aussieRelease/app-aussie-release.aab $DIST_AAB
cp $APP_OUT/mapping/aussieRelease/mapping.txt $DIST_DIR/$MAPPING_FILE_NAME

# Sign app bundle
jarsigner -verbose -storepass $CRISIS_CLEANUP_ANDROID_KEYSTORE_PW -keystore $CRISIS_CLEANUP_ANDROID_KEYSTORE_PATH $DIST_AAB $CRISIS_CLEANUP_ANDROID_KEYSTORE_KEY_ALIAS -keypass $CRISIS_CLEANUP_ANDROID_KEYSTORE_KEY_PW

# Most likely successful
if [[ -f "$DIST_AAB" && -f "$DIST_DIR/$MAPPING_FILE_NAME" ]]; then
GREEN='\033[0;32m'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface AddressSearchRepository {
center: LatLng? = null,
southwest: LatLng? = null,
northeast: LatLng? = null,
maxResults: Int = 8,
maxResults: Int = 10,
): List<KeySearchAddress>

suspend fun getPlaceAddress(placeId: String): LocationAddress?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ object RouteConstant {

const val authRoute = "auth_route"
const val loginWithEmailRoute = "$authRoute/login_with_email"
const val loginWithPhoneRoute = "$authRoute/login_with_phone"
const val forgotPasswordRoute = "forgot_password_route"
const val emailLoginLinkRoute = "email_login_link_route"
// const val resetPasswordRoute = "reset_password_route"
const val resetPasswordRoute = "$authRoute/reset_password_route"
const val magicLinkLoginRoute = "$authRoute/magic_link_login"

// This cannot be used as the navHost startDestination
const val casesRoute = "cases_route"
Expand Down
Loading

0 comments on commit 9cb451d

Please sign in to comment.