diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt index fa126ae3a..93f11d03e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt @@ -1,6 +1,7 @@ package com.habitrpg.android.habitica.data.implementation import android.content.Context +import android.util.Log import com.google.gson.JsonSyntaxException import com.habitrpg.android.habitica.BuildConfig import com.habitrpg.android.habitica.HabiticaBaseApplication @@ -155,6 +156,14 @@ class ApiClientImpl( // Modify cache control for 4xx or 5xx range - effectively "do not cache", preventing caching of 4xx and 5xx responses if (response.code in 400..599) { when (response.code) { + 401 -> { + val path = response.request.url.encodedPath + if (!path.contains("user/auth/update-password")) { + // token has been revoked/rotated elsewhere + HabiticaBaseApplication.logout(context) + } + return@addNetworkInterceptor response + } 404 -> { // The server is returning a 404 error, which means the requested resource was not found. // In this case - we want to actually cache the response, and handle it in the app diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/AccountPreferenceFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/AccountPreferenceFragment.kt index 80eddc841..82b954ba2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/AccountPreferenceFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/AccountPreferenceFragment.kt @@ -271,6 +271,10 @@ class AccountPreferenceFragment : ) response?.apiToken?.let { viewModel.saveTokens(it, user?.id ?: "") + (activity as? SnackbarActivity)?.showSnackbar( + content = getString(R.string.password_changed), + displayType = HabiticaSnackbar.SnackbarDisplayType.SUCCESS, + ) sheet.dismiss() } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/ApiTokenBottomSheetFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/ApiTokenBottomSheetFragment.kt index 7b090c557..df8827953 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/ApiTokenBottomSheetFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/ApiTokenBottomSheetFragment.kt @@ -1,5 +1,7 @@ package com.habitrpg.android.habitica.ui.fragments.preferences +import android.content.ClipData +import android.content.ClipboardManager import android.content.res.Configuration import android.os.Bundle import android.view.LayoutInflater @@ -7,6 +9,7 @@ import android.view.View import android.view.ViewGroup import androidx.compose.ui.platform.ComposeView import androidx.core.content.ContextCompat +import androidx.core.content.ContextCompat.getSystemService import androidx.core.view.WindowInsetsControllerCompat import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.habitrpg.android.habitica.R @@ -61,6 +64,9 @@ class ApiTokenBottomSheetFragment : BottomSheetDialogFragment() { content = getString(R.string.copied_to_clipboard, copiedToken), displayType = HabiticaSnackbar.SnackbarDisplayType.SUCCESS, ) + val clipboard: ClipboardManager? = + context?.let { getSystemService(it, ClipboardManager::class.java) } + clipboard?.setPrimaryClip(ClipData.newPlainText("API Token", copiedToken)) dismiss() }) }