Skip to content

Commit

Permalink
Relink flow
Browse files Browse the repository at this point in the history
  • Loading branch information
tillh-stripe committed Jan 27, 2025
1 parent 4ac8f33 commit 044eb9c
Show file tree
Hide file tree
Showing 11 changed files with 707 additions and 450 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.stripe.android.financialconnections.domain

import com.stripe.android.financialconnections.FinancialConnectionsSheet
import com.stripe.android.financialconnections.di.APPLICATION_ID
import com.stripe.android.financialconnections.model.FinancialConnectionsAuthorizationSession
import com.stripe.android.financialconnections.repository.FinancialConnectionsManifestRepository
import javax.inject.Inject
import javax.inject.Named

internal class RepairAuthorizationSession @Inject constructor(
private val repository: FinancialConnectionsManifestRepository,
private val configuration: FinancialConnectionsSheet.Configuration,
@Named(APPLICATION_ID) private val applicationId: String,
) {

suspend operator fun invoke(
coreAuthorization: String
): FinancialConnectionsAuthorizationSession {
return repository.repairAuthorizationSession(
clientSecret = configuration.financialConnectionsSessionClientSecret,
coreAuthorization = coreAuthorization,
applicationId = applicationId,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.stripe.android.financialconnections.presentation.Async
import com.stripe.android.financialconnections.presentation.Async.Uninitialized
import com.stripe.android.financialconnections.presentation.FinancialConnectionsViewModel
import com.stripe.android.financialconnections.repository.AccountUpdateRequiredContentRepository
import com.stripe.android.financialconnections.repository.CoreAuthorizationPendingNetworkingRepairRepository
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
Expand All @@ -33,6 +34,7 @@ internal class AccountUpdateRequiredViewModel @AssistedInject constructor(
@Assisted initialState: AccountUpdateRequiredState,
nativeAuthFlowCoordinator: NativeAuthFlowCoordinator,
private val updateRequiredContentRepository: AccountUpdateRequiredContentRepository,
private val pendingRepairRepository: CoreAuthorizationPendingNetworkingRepairRepository,
private val navigationManager: NavigationManager,
private val eventTracker: FinancialConnectionsAnalyticsTracker,
private val updateLocalManifest: UpdateLocalManifest,
Expand Down Expand Up @@ -60,7 +62,11 @@ internal class AccountUpdateRequiredViewModel @AssistedInject constructor(
val referrer = state.referrer
when (val type = requireNotNull(state.payload()?.type)) {
is Type.Repair -> {
handleUnsupportedRepairAction(referrer)
if (type.authorization != null) {
openBankAuthRepair(type.institution, type.authorization, referrer)
} else {
handleUnsupportedRepairAction(referrer)
}
}
is Type.Supportability -> {
openPartnerAuth(type.institution, referrer)
Expand All @@ -80,6 +86,25 @@ internal class AccountUpdateRequiredViewModel @AssistedInject constructor(
navigationManager.tryNavigateTo(InstitutionPicker(referrer))
}

private fun openBankAuthRepair(
institution: FinancialConnectionsInstitution?,
authorization: String,
referrer: Pane,
) {
if (institution != null) {
updateLocalManifest {
it.copy(activeInstitution = institution)
}
} else {
// TODO: Is this required?
// Fall back to the institution picker
navigationManager.tryNavigateTo(InstitutionPicker(referrer))
}

pendingRepairRepository.set(authorization)
navigationManager.tryNavigateTo(Destination.BankAuthRepair(referrer))
}

private fun openPartnerAuth(
institution: FinancialConnectionsInstitution?,
referrer: Pane,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ internal fun BankAuthRepairScreen() {

SharedPartnerAuth(
state = state.value,
onContinueClick = { /*TODO*/ },
onCancelClick = { /*TODO*/ },
onClickableTextClick = { /*TODO*/ },
onWebAuthFlowFinished = { /*TODO*/ },
onViewEffectLaunched = { /*TODO*/ },
onContinueClick = viewModel::onLaunchAuthClick,
onCancelClick = viewModel::onCancelClick,
onClickableTextClick = viewModel::onClickableTextClick,
onWebAuthFlowFinished = viewModel::onWebAuthFlowFinished,
onViewEffectLaunched = viewModel::onViewEffectLaunched,
inModal = false
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,88 @@ import android.os.Parcelable
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.stripe.android.core.Logger
import com.stripe.android.financialconnections.analytics.FinancialConnectionsAnalyticsTracker
import com.stripe.android.financialconnections.browser.BrowserManager
import com.stripe.android.financialconnections.di.APPLICATION_ID
import com.stripe.android.financialconnections.di.FinancialConnectionsSheetNativeComponent
import com.stripe.android.financialconnections.domain.CancelAuthorizationSession
import com.stripe.android.financialconnections.domain.CompleteAuthorizationSession
import com.stripe.android.financialconnections.domain.GetOrFetchSync
import com.stripe.android.financialconnections.domain.HandleError
import com.stripe.android.financialconnections.domain.NativeAuthFlowCoordinator
import com.stripe.android.financialconnections.domain.PollAuthorizationSessionOAuthResults
import com.stripe.android.financialconnections.domain.PostAuthSessionEvent
import com.stripe.android.financialconnections.domain.PostAuthorizationSession
import com.stripe.android.financialconnections.domain.RepairAuthorizationSession
import com.stripe.android.financialconnections.domain.RetrieveAuthorizationSession
import com.stripe.android.financialconnections.domain.UpdateLocalManifest
import com.stripe.android.financialconnections.features.notice.PresentSheet
import com.stripe.android.financialconnections.features.partnerauth.SharedPartnerAuthState
import com.stripe.android.financialconnections.features.partnerauth.SharedPartnerAuthState.Payload
import com.stripe.android.financialconnections.features.partnerauth.SharedPartnerAuthViewModel
import com.stripe.android.financialconnections.model.FinancialConnectionsSessionManifest.Pane
import com.stripe.android.financialconnections.navigation.topappbar.TopAppBarStateUpdate
import com.stripe.android.financialconnections.presentation.FinancialConnectionsViewModel
import com.stripe.android.financialconnections.utils.error
import com.stripe.android.financialconnections.model.SynchronizeSessionResponse
import com.stripe.android.financialconnections.navigation.NavigationManager
import com.stripe.android.financialconnections.repository.CoreAuthorizationPendingNetworkingRepairRepository
import com.stripe.android.financialconnections.utils.UriUtils
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.parcelize.Parcelize
import javax.inject.Named

internal class BankAuthRepairViewModel @AssistedInject constructor(
completeAuthorizationSession: CompleteAuthorizationSession,
createAuthorizationSession: PostAuthorizationSession,
cancelAuthorizationSession: CancelAuthorizationSession,
retrieveAuthorizationSession: RetrieveAuthorizationSession,
eventTracker: FinancialConnectionsAnalyticsTracker,
@Named(APPLICATION_ID) applicationId: String,
uriUtils: UriUtils,
postAuthSessionEvent: PostAuthSessionEvent,
getOrFetchSync: GetOrFetchSync,
browserManager: BrowserManager,
handleError: HandleError,
navigationManager: NavigationManager,
pollAuthorizationSessionOAuthResults: PollAuthorizationSessionOAuthResults,
logger: Logger,
presentSheet: PresentSheet,
@Assisted initialState: SharedPartnerAuthState,
nativeAuthFlowCoordinator: NativeAuthFlowCoordinator,
) : FinancialConnectionsViewModel<SharedPartnerAuthState>(initialState, nativeAuthFlowCoordinator) {
private val pendingRepairRepository: CoreAuthorizationPendingNetworkingRepairRepository,
private val repairAuthSession: RepairAuthorizationSession,
private val updateLocalManifest: UpdateLocalManifest,
) : SharedPartnerAuthViewModel(
completeAuthorizationSession,
createAuthorizationSession,
cancelAuthorizationSession,
retrieveAuthorizationSession,
eventTracker,
applicationId,
uriUtils,
postAuthSessionEvent,
getOrFetchSync,
browserManager,
handleError,
navigationManager,
pollAuthorizationSessionOAuthResults,
logger,
presentSheet,
initialState,
nativeAuthFlowCoordinator,
) {

override fun updateTopAppBar(state: SharedPartnerAuthState): TopAppBarStateUpdate {
return TopAppBarStateUpdate(
pane = Pane.BANK_AUTH_REPAIR,
allowBackNavigation = state.canNavigateBack,
error = state.payload.error,
override suspend fun fetchPayload(sync: SynchronizeSessionResponse): Payload {
val authorization = requireNotNull(pendingRepairRepository.get()?.coreAuthorization)
val activeInstitution = requireNotNull(sync.manifest.activeInstitution)

val authSession = repairAuthSession(authorization)

return Payload(
isStripeDirect = sync.manifest.isStripeDirect ?: false,
institution = activeInstitution,
authSession = authSession,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ internal class LinkAccountPickerViewModel @AssistedInject constructor(
generic = genericContent,
type = Repair(
authorization = authorization?.let { payload.partnerToCoreAuths?.getValue(it) },
institution = institution,
),
)
PARTNER_AUTH -> UpdateRequired(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,15 @@ internal data class NoticeSheetState(
sealed interface Type : Parcelable {

@Parcelize
data class Repair(val authorization: String?) : Type
data class Repair(
val authorization: String?,
val institution: FinancialConnectionsInstitution?,
) : Type

@Parcelize
data class Supportability(val institution: FinancialConnectionsInstitution?) : Type
data class Supportability(
val institution: FinancialConnectionsInstitution?,
) : Type
}
}
}
Expand Down
Loading

0 comments on commit 044eb9c

Please sign in to comment.