Use GENERAL_SHOW_TIME for decryption screen timeout (#2107)

* feat(app): use `GENERAL_SHOW_TIME` for decryption screen as well

Signed-off-by: Aditya Wasan <adityawasan55@gmail.com>

* feat: update timeout to 60 seconds

Signed-off-by: Aditya Wasan <adityawasan55@gmail.com>

* refactor(app): use constant instead of using a magic number

Signed-off-by: Aditya Wasan <adityawasan55@gmail.com>

* Add changelog entry

Signed-off-by: Aditya Wasan <adityawasan55@gmail.com>
Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Aditya Wasan 2022-09-07 17:49:08 -04:00 committed by GitHub
parent e5f02a3aca
commit 244fd92f8b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 21 additions and 7 deletions

View file

@ -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 - Add the ability to run garbage collection on the internal Git repository
- Introduce crash reporting backed by Sentry - Introduce crash reporting backed by Sentry
- TOTP field now shows the remaining time for which it is valid - TOTP field now shows the remaining time for which it is valid
- Allow customizing the timeout for decrypted password screen
### Fixed ### Fixed

View file

@ -22,6 +22,7 @@ import app.passwordstore.util.extensions.getString
import app.passwordstore.util.extensions.snackbar import app.passwordstore.util.extensions.snackbar
import app.passwordstore.util.extensions.unsafeLazy import app.passwordstore.util.extensions.unsafeLazy
import app.passwordstore.util.services.ClipboardService import app.passwordstore.util.services.ClipboardService
import app.passwordstore.util.settings.Constants
import app.passwordstore.util.settings.PreferenceKeys import app.passwordstore.util.settings.PreferenceKeys
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@ -87,7 +88,9 @@ open class BasePgpActivity : AppCompatActivity() {
fun copyPasswordToClipboard(password: String?) { fun copyPasswordToClipboard(password: String?) {
copyTextToClipboard(password) 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) { if (clearAfter != 0) {
val service = val service =

View file

@ -16,9 +16,11 @@ import app.passwordstore.data.passfile.PasswordEntry
import app.passwordstore.data.password.FieldItem import app.passwordstore.data.password.FieldItem
import app.passwordstore.databinding.DecryptLayoutBinding import app.passwordstore.databinding.DecryptLayoutBinding
import app.passwordstore.ui.adapters.FieldItemAdapter import app.passwordstore.ui.adapters.FieldItemAdapter
import app.passwordstore.util.extensions.getString
import app.passwordstore.util.extensions.isErr import app.passwordstore.util.extensions.isErr
import app.passwordstore.util.extensions.unsafeLazy import app.passwordstore.util.extensions.unsafeLazy
import app.passwordstore.util.extensions.viewBinding import app.passwordstore.util.extensions.viewBinding
import app.passwordstore.util.settings.Constants
import app.passwordstore.util.settings.PreferenceKeys import app.passwordstore.util.settings.PreferenceKeys
import com.github.michaelbull.result.runCatching import com.github.michaelbull.result.runCatching
import com.github.michaelbull.result.unwrapError import com.github.michaelbull.result.unwrapError
@ -91,13 +93,18 @@ class DecryptActivity : BasePgpActivity() {
} }
/** /**
* Automatically finishes the activity 60 seconds after decryption succeeded to prevent * Automatically finishes the activity after [PreferenceKeys.GENERAL_SHOW_TIME] seconds decryption
* information leaks from stale activities. * succeeded to prevent information leaks from stale activities.
*/ */
private fun startAutoDismissTimer() { private fun startAutoDismissTimer() {
lifecycleScope.launch { lifecycleScope.launch {
delay(60.seconds) val timeout =
finish() settings.getString(PreferenceKeys.GENERAL_SHOW_TIME)?.toIntOrNull()
?: Constants.DEFAULT_DECRYPTION_TIMEOUT
if (timeout != 0) {
delay(timeout.seconds)
finish()
}
} }
} }

View file

@ -0,0 +1,5 @@
package app.passwordstore.util.settings
object Constants {
const val DEFAULT_DECRYPTION_TIMEOUT = 60
}

View file

@ -35,7 +35,6 @@
<ID>LongMethod:RepositorySettings.kt$RepositorySettings$override fun provideSettings(builder: PreferenceScreen.Builder)</ID> <ID>LongMethod:RepositorySettings.kt$RepositorySettings$override fun provideSettings(builder: PreferenceScreen.Builder)</ID>
<ID>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&lt;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) } }</ID> <ID>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&lt;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) } }</ID>
<ID>LoopWithTooManyJumpStatements:ErrorMessages.kt$ErrorMessages$while (cause.cause != null) { if (cause is GitException) break val nextCause = cause.cause!! if (nextCause is RemoteException) break cause = nextCause }</ID> <ID>LoopWithTooManyJumpStatements:ErrorMessages.kt$ErrorMessages$while (cause.cause != null) { if (cause is GitException) break val nextCause = cause.cause!! if (nextCause is RemoteException) break cause = nextCause }</ID>
<ID>MagicNumber:BasePgpActivity.kt$BasePgpActivity$45</ID>
<ID>MagicNumber:ClipboardService.kt$ClipboardService$1000</ID> <ID>MagicNumber:ClipboardService.kt$ClipboardService$1000</ID>
<ID>MagicNumber:ClipboardService.kt$ClipboardService$1000L</ID> <ID>MagicNumber:ClipboardService.kt$ClipboardService$1000L</ID>
<ID>MagicNumber:ClipboardService.kt$ClipboardService$45</ID> <ID>MagicNumber:ClipboardService.kt$ClipboardService$45</ID>

View file

@ -10,6 +10,5 @@
<ID>MagicNumber:GpgIdentifier.kt$GpgIdentifier.KeyId$8</ID> <ID>MagicNumber:GpgIdentifier.kt$GpgIdentifier.KeyId$8</ID>
<ID>NestedBlockDepth:GpgIdentifier.kt$GpgIdentifier.Companion$private fun splitUserId(userId: String): String?</ID> <ID>NestedBlockDepth:GpgIdentifier.kt$GpgIdentifier.Companion$private fun splitUserId(userId: String): String?</ID>
<ID>ReturnCount:GpgIdentifier.kt$GpgIdentifier.Companion$public fun fromString(identifier: String): GpgIdentifier?</ID> <ID>ReturnCount:GpgIdentifier.kt$GpgIdentifier.Companion$public fun fromString(identifier: String): GpgIdentifier?</ID>
<ID>ReturnCount:KeyUtils.kt$KeyUtils$public fun tryParseKeyring(key: PGPKey): PGPKeyRing?</ID>
</CurrentIssues> </CurrentIssues>
</SmellBaseline> </SmellBaseline>