diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 16a70c46c..74fa6ef7f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -27,6 +27,8 @@ android { vectorDrawables { useSupportLibrary = true } + + buildConfigField("String", "RECAPTCHA_API_SITE_KEY", "\"6LfaxOgpAAAAAI3Sj4rtB2oAFjkRJILiGEt-LUsc\"") } buildTypes { @@ -122,6 +124,7 @@ dependencies { // Others implementation(libs.kotlinx.serialization) + implementation(libs.recaptcha) // Test testImplementation(libs.junit) diff --git a/app/src/main/java/com/infomaniak/swisstransfer/di/ApplicationModule.kt b/app/src/main/java/com/infomaniak/swisstransfer/di/ApplicationModule.kt index 5c867609e..a244aca40 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/di/ApplicationModule.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/di/ApplicationModule.kt @@ -17,7 +17,10 @@ */ package com.infomaniak.swisstransfer.di +import android.app.Application import com.infomaniak.multiplatform_swisstransfer.SwissTransferInjection +import com.infomaniak.swisstransfer.ui.MainApplication +import com.infomaniak.swisstransfer.ui.utils.Recaptcha import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -30,10 +33,22 @@ import javax.inject.Singleton @InstallIn(SingletonComponent::class) object ApplicationModule { + @Provides + fun providesMainApplication(application: Application) = application as MainApplication + @Provides @Singleton fun providesSwissTransferInjection() = SwissTransferInjection() + @Provides + @Singleton + fun providesRecaptchaInjection( + application: MainApplication, + @IoDispatcher ioDispatcher: CoroutineDispatcher, + ): Recaptcha { + return Recaptcha(application, ioDispatcher) + } + @Provides @Singleton fun providesGlobalCoroutineScope(@DefaultDispatcher defaultDispatcher: CoroutineDispatcher): CoroutineScope { diff --git a/app/src/main/java/com/infomaniak/swisstransfer/di/CoroutinesDispatchersModule.kt b/app/src/main/java/com/infomaniak/swisstransfer/di/CoroutinesDispatchersModule.kt index 22debd640..248723a26 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/di/CoroutinesDispatchersModule.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/di/CoroutinesDispatchersModule.kt @@ -1,6 +1,6 @@ /* * Infomaniak SwissTransfer - Android - * Copyright (C) 2023-2024 Infomaniak Network SA + * Copyright (C) 2024 Infomaniak Network SA * * 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 diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/MainApplication.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/MainApplication.kt index e5f990138..3c1683914 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/MainApplication.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/MainApplication.kt @@ -20,6 +20,7 @@ package com.infomaniak.swisstransfer.ui import android.app.Application import com.infomaniak.multiplatform_swisstransfer.SwissTransferInjection import com.infomaniak.swisstransfer.BuildConfig +import com.infomaniak.swisstransfer.ui.utils.Recaptcha import dagger.hilt.android.HiltAndroidApp import io.sentry.SentryEvent import io.sentry.SentryOptions @@ -35,12 +36,18 @@ class MainApplication : Application() { @Inject lateinit var swissTransferInjection: SwissTransferInjection + @Inject + lateinit var recaptcha: Recaptcha + @Inject lateinit var globalCoroutineScope: CoroutineScope override fun onCreate() { super.onCreate() - globalCoroutineScope.launch { swissTransferInjection.loadDefaultAccount() } + globalCoroutineScope.launch { + swissTransferInjection.loadDefaultAccount() + recaptcha.initializeClient() + } SentryAndroid.init(this) { options: SentryAndroidOptions -> // register the callback as an option diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/Recaptcha.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/Recaptcha.kt new file mode 100644 index 000000000..c2f0ff2d9 --- /dev/null +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/Recaptcha.kt @@ -0,0 +1,53 @@ +/* + * Infomaniak SwissTransfer - Android + * Copyright (C) 2024 Infomaniak Network SA + * + * 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.infomaniak.swisstransfer.ui.utils + +import com.google.android.recaptcha.Recaptcha +import com.google.android.recaptcha.RecaptchaAction +import com.google.android.recaptcha.RecaptchaClient +import com.infomaniak.swisstransfer.BuildConfig +import com.infomaniak.swisstransfer.di.IoDispatcher +import com.infomaniak.swisstransfer.ui.MainApplication +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import javax.inject.Inject + +class Recaptcha @Inject constructor( + @ApplicationContext private val application: MainApplication, + @IoDispatcher private val ioDispatcher: CoroutineDispatcher, +) { + + private var client: RecaptchaClient? = null + + suspend fun initializeClient() { + runCatching { + client = Recaptcha.fetchClient(application, BuildConfig.RECAPTCHA_API_SITE_KEY) + }.onFailure { + // Handle errors + } + } + + fun fetchCode(callback: (String?) -> Unit) { + CoroutineScope(ioDispatcher).launch { + val code = client?.execute(RecaptchaAction.LOGIN)?.getOrNull() + callback(code) + } + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e94899bcf..3c6213494 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -18,6 +18,7 @@ serialization = "1.7.1" swisstransfer = "0.1.1" sentry = "4.12.0" sentry-android = "7.15.0" +recaptcha = "18.6.1" [libraries] androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } @@ -43,6 +44,7 @@ kotlinx-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization- navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation" } swisstransfer-core = { module = "com.github.Infomaniak.multiplatform-SwissTransfer:STCore", version.ref = "swisstransfer" } sentry-android = { module = "io.sentry:sentry-android", version.ref = "sentry-android" } +recaptcha = { module = "com.google.android.recaptcha:recaptcha", version.ref = "recaptcha" } # Tests androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } junit = { group = "junit", name = "junit", version.ref = "junit" }