diff --git a/CHANGELOG.md b/CHANGELOG.md
index a75848bb4..dd0a5d68e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file.
- Add the ability to run garbage collection on the internal Git repository
- Introduce crash reporting backed by Sentry
- TOTP field now shows the remaining time for which it is valid
+- Allow customizing the timeout for decrypted password screen
### Fixed
diff --git a/app/src/main/java/app/passwordstore/ui/crypto/BasePgpActivity.kt b/app/src/main/java/app/passwordstore/ui/crypto/BasePgpActivity.kt
index c769e3342..f2778e2d0 100644
--- a/app/src/main/java/app/passwordstore/ui/crypto/BasePgpActivity.kt
+++ b/app/src/main/java/app/passwordstore/ui/crypto/BasePgpActivity.kt
@@ -22,6 +22,7 @@ import app.passwordstore.util.extensions.getString
import app.passwordstore.util.extensions.snackbar
import app.passwordstore.util.extensions.unsafeLazy
import app.passwordstore.util.services.ClipboardService
+import app.passwordstore.util.settings.Constants
import app.passwordstore.util.settings.PreferenceKeys
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
@@ -87,7 +88,9 @@ open class BasePgpActivity : AppCompatActivity() {
fun copyPasswordToClipboard(password: String?) {
copyTextToClipboard(password)
- val clearAfter = settings.getString(PreferenceKeys.GENERAL_SHOW_TIME)?.toIntOrNull() ?: 45
+ val clearAfter =
+ settings.getString(PreferenceKeys.GENERAL_SHOW_TIME)?.toIntOrNull()
+ ?: Constants.DEFAULT_DECRYPTION_TIMEOUT
if (clearAfter != 0) {
val service =
diff --git a/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt b/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt
index fa37f501e..dfe9f8bcd 100644
--- a/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt
+++ b/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt
@@ -16,9 +16,11 @@ import app.passwordstore.data.passfile.PasswordEntry
import app.passwordstore.data.password.FieldItem
import app.passwordstore.databinding.DecryptLayoutBinding
import app.passwordstore.ui.adapters.FieldItemAdapter
+import app.passwordstore.util.extensions.getString
import app.passwordstore.util.extensions.isErr
import app.passwordstore.util.extensions.unsafeLazy
import app.passwordstore.util.extensions.viewBinding
+import app.passwordstore.util.settings.Constants
import app.passwordstore.util.settings.PreferenceKeys
import com.github.michaelbull.result.runCatching
import com.github.michaelbull.result.unwrapError
@@ -91,13 +93,18 @@ class DecryptActivity : BasePgpActivity() {
}
/**
- * Automatically finishes the activity 60 seconds after decryption succeeded to prevent
- * information leaks from stale activities.
+ * Automatically finishes the activity after [PreferenceKeys.GENERAL_SHOW_TIME] seconds decryption
+ * succeeded to prevent information leaks from stale activities.
*/
private fun startAutoDismissTimer() {
lifecycleScope.launch {
- delay(60.seconds)
- finish()
+ val timeout =
+ settings.getString(PreferenceKeys.GENERAL_SHOW_TIME)?.toIntOrNull()
+ ?: Constants.DEFAULT_DECRYPTION_TIMEOUT
+ if (timeout != 0) {
+ delay(timeout.seconds)
+ finish()
+ }
}
}
diff --git a/app/src/main/java/app/passwordstore/util/settings/Constants.kt b/app/src/main/java/app/passwordstore/util/settings/Constants.kt
new file mode 100644
index 000000000..d843500f9
--- /dev/null
+++ b/app/src/main/java/app/passwordstore/util/settings/Constants.kt
@@ -0,0 +1,5 @@
+package app.passwordstore.util.settings
+
+object Constants {
+ const val DEFAULT_DECRYPTION_TIMEOUT = 60
+}
diff --git a/detekt-baselines/app.xml b/detekt-baselines/app.xml
index a82c325e3..cbbe4a172 100644
--- a/detekt-baselines/app.xml
+++ b/detekt-baselines/app.xml
@@ -35,7 +35,6 @@
LongMethod:RepositorySettings.kt$RepositorySettings$override fun provideSettings(builder: PreferenceScreen.Builder)
LoopWithTooManyJumpStatements:AutofillMatcher.kt$AutofillMatcher.Companion$for ((key, value) in prefs.all) { if (!key.startsWith(PREFERENCE_PREFIX_MATCHES)) continue // We know that preferences starting with `PREFERENCE_PREFIX_MATCHES` were // created with `putStringSet`. @Suppress("UNCHECKED_CAST") val oldMatches = value as? Set<String> if (oldMatches == null) { logcat(WARN) { "Failed to read matches for $key" } continue } // Delete all matches for file locations that are going to be overwritten, then // transfer matches over to the files at their new locations. val newMatches = oldMatches .asSequence() .minus(deletePathList) .minus(oldNewPathMap.values) .map { match -> val newPath = oldNewPathMap[match] ?: return@map match logcat { "Updating match for $key: $match --> $newPath" } newPath } .toSet() if (newMatches != oldMatches) prefs.edit { putStringSet(key, newMatches) } }
LoopWithTooManyJumpStatements:ErrorMessages.kt$ErrorMessages$while (cause.cause != null) { if (cause is GitException) break val nextCause = cause.cause!! if (nextCause is RemoteException) break cause = nextCause }
- MagicNumber:BasePgpActivity.kt$BasePgpActivity$45
MagicNumber:ClipboardService.kt$ClipboardService$1000
MagicNumber:ClipboardService.kt$ClipboardService$1000L
MagicNumber:ClipboardService.kt$ClipboardService$45
diff --git a/detekt-baselines/crypto-pgpainless.xml b/detekt-baselines/crypto-pgpainless.xml
index 5f6cad27d..0276df1b1 100644
--- a/detekt-baselines/crypto-pgpainless.xml
+++ b/detekt-baselines/crypto-pgpainless.xml
@@ -10,6 +10,5 @@
MagicNumber:GpgIdentifier.kt$GpgIdentifier.KeyId$8
NestedBlockDepth:GpgIdentifier.kt$GpgIdentifier.Companion$private fun splitUserId(userId: String): String?
ReturnCount:GpgIdentifier.kt$GpgIdentifier.Companion$public fun fromString(identifier: String): GpgIdentifier?
- ReturnCount:KeyUtils.kt$KeyUtils$public fun tryParseKeyring(key: PGPKey): PGPKeyRing?