diff --git a/app/src/main/java/com/android/trisolarispms/data/api/ApiClient.kt b/app/src/main/java/com/android/trisolarispms/data/api/ApiClient.kt index 4dc0978..f64a725 100644 --- a/app/src/main/java/com/android/trisolarispms/data/api/ApiClient.kt +++ b/app/src/main/java/com/android/trisolarispms/data/api/ApiClient.kt @@ -1,6 +1,7 @@ package com.android.trisolarispms.data.api import com.google.firebase.auth.FirebaseAuth +import okhttp3.Authenticator import okhttp3.Interceptor import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor @@ -18,7 +19,7 @@ object ApiClient { val authInterceptor = Interceptor { chain -> val original = chain.request() val token = try { - kotlinx.coroutines.runBlocking { tokenProvider.token() } + kotlinx.coroutines.runBlocking { tokenProvider.token(forceRefresh = false) } } catch (e: Exception) { null } @@ -32,12 +33,28 @@ object ApiClient { chain.proceed(request) } + val authenticator = Authenticator { _, response -> + if (response.code != 401) return@Authenticator null + if (response.request.header("X-Auth-Retry") == "true") return@Authenticator null + val newToken = try { + kotlinx.coroutines.runBlocking { tokenProvider.token(forceRefresh = true) } + } catch (e: Exception) { + null + } + if (newToken.isNullOrBlank()) return@Authenticator null + response.request.newBuilder() + .header("Authorization", "Bearer $newToken") + .header("X-Auth-Retry", "true") + .build() + } + val logging = HttpLoggingInterceptor().apply { level = if (enableLogging) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE } val client = OkHttpClient.Builder() .addInterceptor(authInterceptor) + .authenticator(authenticator) .addInterceptor(logging) .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) diff --git a/app/src/main/java/com/android/trisolarispms/data/api/AuthTokenProvider.kt b/app/src/main/java/com/android/trisolarispms/data/api/AuthTokenProvider.kt index cc311f8..d3f773a 100644 --- a/app/src/main/java/com/android/trisolarispms/data/api/AuthTokenProvider.kt +++ b/app/src/main/java/com/android/trisolarispms/data/api/AuthTokenProvider.kt @@ -1,5 +1,5 @@ package com.android.trisolarispms.data.api interface AuthTokenProvider { - suspend fun token(): String? + suspend fun token(forceRefresh: Boolean = false): String? } diff --git a/app/src/main/java/com/android/trisolarispms/data/api/FirebaseAuthTokenProvider.kt b/app/src/main/java/com/android/trisolarispms/data/api/FirebaseAuthTokenProvider.kt index 2664895..9b75dd5 100644 --- a/app/src/main/java/com/android/trisolarispms/data/api/FirebaseAuthTokenProvider.kt +++ b/app/src/main/java/com/android/trisolarispms/data/api/FirebaseAuthTokenProvider.kt @@ -6,8 +6,8 @@ import kotlinx.coroutines.tasks.await class FirebaseAuthTokenProvider( private val auth: FirebaseAuth ) : AuthTokenProvider { - override suspend fun token(): String? { + override suspend fun token(forceRefresh: Boolean): String? { val user = auth.currentUser ?: return null - return user.getIdToken(false).await().token + return user.getIdToken(forceRefresh).await().token } }