Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FC] Prepares integrity on first sync call #9818

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions example/dependencies/dependencies.txt
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,13 @@
| +--- project :stripe-ui-core (*)
| +--- project :payments-model (*)
| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.21 (*)
| +--- project :stripe-attestation
| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.21 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 (*)
| | \--- com.google.android.play:integrity:1.4.0
| | +--- com.google.android.gms:play-services-basement:18.4.0 (*)
| | +--- com.google.android.gms:play-services-tasks:18.2.0 (*)
| | \--- com.google.android.play:core-common:2.0.4
| +--- androidx.activity:activity-ktx:1.8.2 (*)
| +--- androidx.annotation:annotation:1.9.0 (*)
| +--- androidx.appcompat:appcompat:1.7.0 (*)
Expand Down
17 changes: 12 additions & 5 deletions financial-connections-example/dependencies/dependencies.txt
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,17 @@
| | +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3 (*)
| | \--- org.jetbrains.kotlin:kotlin-parcelize-runtime:2.0.21 (*)
| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.21 (*)
| +--- project :stripe-attestation
| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.21 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 (*)
| | \--- com.google.android.play:integrity:1.4.0
| | +--- com.google.android.gms:play-services-basement:18.4.0
| | | +--- androidx.collection:collection:1.0.0 -> 1.4.0 (*)
| | | +--- androidx.core:core:1.2.0 -> 1.13.1 (*)
| | | \--- androidx.fragment:fragment:1.1.0 -> 1.8.4 (*)
| | +--- com.google.android.gms:play-services-tasks:18.2.0
| | | \--- com.google.android.gms:play-services-basement:18.4.0 (*)
| | \--- com.google.android.play:core-common:2.0.4
| +--- androidx.activity:activity-ktx:1.8.2 (*)
| +--- androidx.annotation:annotation:1.9.0 (*)
| +--- androidx.appcompat:appcompat:1.7.0 (*)
Expand Down Expand Up @@ -847,11 +858,7 @@
| +--- org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.3 -> 1.9.0
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0 (*)
| | +--- com.google.android.gms:play-services-tasks:16.0.1 -> 18.2.0
| | | \--- com.google.android.gms:play-services-basement:18.4.0
| | | +--- androidx.collection:collection:1.0.0 -> 1.4.0 (*)
| | | +--- androidx.core:core:1.2.0 -> 1.13.1 (*)
| | | \--- androidx.fragment:fragment:1.1.0 -> 1.8.4 (*)
| | +--- com.google.android.gms:play-services-tasks:16.0.1 -> 18.2.0 (*)
| | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 -> 2.0.21 (*)
| +--- com.google.android.material:material:1.12.0 (*)
| +--- com.google.android.gms:play-services-wallet:19.4.0
Expand Down
1 change: 1 addition & 0 deletions financial-connections/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ dependencies {
api project(":stripe-core")
api project(":stripe-ui-core")
api project(":payments-model")
implementation project(":stripe-attestation")

implementation libs.androidx.activity
implementation libs.androidx.annotation
Expand Down
11 changes: 11 additions & 0 deletions financial-connections/dependencies/dependencies.txt
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,17 @@
| +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3 (*)
| \--- org.jetbrains.kotlin:kotlin-parcelize-runtime:2.0.21 (*)
+--- org.jetbrains.kotlin:kotlin-stdlib:2.0.21 (*)
+--- project :stripe-attestation
| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.21 (*)
| +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 (*)
| \--- com.google.android.play:integrity:1.4.0
| +--- com.google.android.gms:play-services-basement:18.4.0
| | +--- androidx.collection:collection:1.0.0 -> 1.4.0 (*)
| | +--- androidx.core:core:1.2.0 -> 1.13.1 (*)
| | \--- androidx.fragment:fragment:1.1.0 -> 1.5.4 (*)
| +--- com.google.android.gms:play-services-tasks:18.2.0
| | \--- com.google.android.gms:play-services-basement:18.4.0 (*)
| \--- com.google.android.play:core-common:2.0.4
+--- androidx.activity:activity-ktx:1.8.2 (*)
+--- androidx.annotation:annotation:1.9.0 (*)
+--- androidx.appcompat:appcompat:1.7.0 (*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.stripe.android.financialconnections.FinancialConnectionsSheetViewEffe
import com.stripe.android.financialconnections.FinancialConnectionsSheetViewEffect.OpenAuthFlowWithUrl
import com.stripe.android.financialconnections.FinancialConnectionsSheetViewEffect.OpenNativeAuthFlow
import com.stripe.android.financialconnections.FinancialConnectionsSheetViewModel.Companion.QUERY_PARAM_PAYMENT_METHOD
import com.stripe.android.financialconnections.analytics.FinancialConnectionsAnalyticsEvent
import com.stripe.android.financialconnections.analytics.FinancialConnectionsAnalyticsTracker
import com.stripe.android.financialconnections.analytics.FinancialConnectionsEvent.ErrorCode
import com.stripe.android.financialconnections.analytics.FinancialConnectionsEvent.Metadata
Expand Down Expand Up @@ -58,6 +59,7 @@ import com.stripe.android.financialconnections.navigation.topappbar.TopAppBarSta
import com.stripe.android.financialconnections.presentation.FinancialConnectionsViewModel
import com.stripe.android.financialconnections.ui.FinancialConnectionsSheetNativeActivity
import com.stripe.android.financialconnections.utils.parcelable
import com.stripe.attestation.IntegrityRequestManager
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
Expand All @@ -68,6 +70,7 @@ internal class FinancialConnectionsSheetViewModel @Inject constructor(
@Named(APPLICATION_ID) private val applicationId: String,
savedStateHandle: SavedStateHandle,
private val getOrFetchSync: GetOrFetchSync,
private val integrityRequestManager: IntegrityRequestManager,
private val fetchFinancialConnectionsSession: FetchFinancialConnectionsSession,
private val fetchFinancialConnectionsSessionForToken: FetchFinancialConnectionsSessionForToken,
private val logger: Logger,
Expand All @@ -86,7 +89,9 @@ internal class FinancialConnectionsSheetViewModel @Inject constructor(
if (initialState.initialArgs.isValid()) {
eventReporter.onPresented(initialState.initialArgs.configuration)
// avoid re-fetching manifest if already exists (this will happen on process recreations)
if (initialState.manifest == null) fetchManifest()
if (initialState.manifest == null) {
initAuthFlow()
}
} else {
val result = Failed(
IllegalStateException("Invalid configuration provided when instantiating activity")
Expand All @@ -108,9 +113,10 @@ internal class FinancialConnectionsSheetViewModel @Inject constructor(
* Fetches the [FinancialConnectionsSessionManifest] from the Stripe API to get the hosted auth flow URL
* as well as the success and cancel callback URLs to verify.
*/
private fun fetchManifest() {
private fun initAuthFlow() {
viewModelScope.launch {
kotlin.runCatching {
prepareStandardRequestManager()
getOrFetchSync(refetchCondition = Always)
}.onFailure {
finishWithResult(stateFlow.value, Failed(it))
Expand All @@ -120,6 +126,20 @@ internal class FinancialConnectionsSheetViewModel @Inject constructor(
}
}

private suspend fun prepareStandardRequestManager(): Boolean {
val result = integrityRequestManager.prepare()
result.onFailure {
analyticsTracker.track(
FinancialConnectionsAnalyticsEvent.Error(
extraMessage = "Failed to warm up the IntegrityStandardRequestManager",
pane = Pane.CONSENT,
exception = it
)
)
}
return result.isSuccess
}

/**
* Builds the ChromeCustomTab intent to launch the hosted auth flow and launches it.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package com.stripe.android.financialconnections.di

import android.app.Application
import com.stripe.android.core.Logger
import com.stripe.attestation.BuildConfig
import com.stripe.attestation.IntegrityRequestManager
import com.stripe.attestation.IntegrityStandardRequestManager
import com.stripe.attestation.RealStandardIntegrityManagerFactory
import dagger.BindsInstance
import dagger.Component
import dagger.Module
import dagger.Provides
import javax.inject.Singleton

/**
Expand Down Expand Up @@ -32,11 +38,24 @@ internal object FinancialConnectionsSingletonSharedComponentHolder {
@Component(modules = [FinancialConnectionsSingletonSharedModule::class])
internal interface FinancialConnectionsSingletonSharedComponent {

fun providesIntegrityRequestManager(): IntegrityRequestManager

@Component.Factory
interface Factory {
fun create(@BindsInstance application: Application): FinancialConnectionsSingletonSharedComponent
}
}

@Module
internal class FinancialConnectionsSingletonSharedModule
internal class FinancialConnectionsSingletonSharedModule {

@Provides
@Singleton
fun providesIntegrityStandardRequestManager(
context: Application
): IntegrityRequestManager = IntegrityStandardRequestManager(
cloudProjectNumber = 527113280969, // stripe-financial-connections
logError = { message, error -> Logger.getInstance(BuildConfig.DEBUG).error(message, error) },
factory = RealStandardIntegrityManagerFactory(context)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,7 @@ class FinancialConnectionsSheetViewModelTest {
browserManager = browserManager,
savedStateHandle = SavedStateHandle(),
nativeAuthFlowCoordinator = mock(),
integrityRequestManager = mock(),
logger = Logger.noop()
)
}
Expand Down
7 changes: 7 additions & 0 deletions paymentsheet-example/dependencies/dependencies.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,13 @@
| +--- project :stripe-ui-core (*)
| +--- project :payments-model (*)
| +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.21 (*)
| +--- project :stripe-attestation
| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.21 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 (*)
| | \--- com.google.android.play:integrity:1.4.0
| | +--- com.google.android.gms:play-services-basement:18.4.0 (*)
| | +--- com.google.android.gms:play-services-tasks:18.2.0 (*)
| | \--- com.google.android.play:core-common:2.0.4
| +--- androidx.activity:activity-ktx:1.8.2 (*)
| +--- androidx.annotation:annotation:1.9.0 (*)
| +--- androidx.appcompat:appcompat:1.7.0 (*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ class IntegrityStandardRequestManager(
private var integrityTokenProvider: StandardIntegrityTokenProvider? = null

override suspend fun prepare(): Result<Unit> = runCatching {
if (integrityTokenProvider != null) {
return Result.success(Unit)
}

val finishedTask: Task<StandardIntegrityTokenProvider> = standardIntegrityManager
.prepareIntegrityToken(
PrepareIntegrityTokenRequest.builder()
Expand Down
Loading