diff options
Diffstat (limited to 'app/src/main/java/dev/msfjarvis/aps/ui')
3 files changed, 36 insertions, 30 deletions
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillDecryptActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillDecryptActivity.kt index ab1f402d..7a36899b 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillDecryptActivity.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillDecryptActivity.kt @@ -16,6 +16,7 @@ import androidx.activity.result.IntentSenderRequest import androidx.activity.result.contract.ActivityResultContracts.StartIntentSenderForResult import androidx.annotation.RequiresApi import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope import com.github.ajalt.timberkt.d import com.github.ajalt.timberkt.e import com.github.androidpasswordstore.autofillparser.AutofillAction @@ -24,7 +25,8 @@ import com.github.michaelbull.result.getOrElse import com.github.michaelbull.result.onFailure import com.github.michaelbull.result.onSuccess import com.github.michaelbull.result.runCatching -import dev.msfjarvis.aps.data.password.PasswordEntry +import dagger.hilt.android.AndroidEntryPoint +import dev.msfjarvis.aps.injection.password.PasswordEntryFactory import dev.msfjarvis.aps.util.autofill.AutofillPreferences import dev.msfjarvis.aps.util.autofill.AutofillResponseBuilder import dev.msfjarvis.aps.util.autofill.DirectoryStructure @@ -33,6 +35,7 @@ import java.io.ByteArrayOutputStream import java.io.File import java.io.InputStream import java.io.OutputStream +import javax.inject.Inject import kotlin.coroutines.Continuation import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException @@ -49,6 +52,7 @@ import org.openintents.openpgp.IOpenPgpService2 import org.openintents.openpgp.OpenPgpError @RequiresApi(Build.VERSION_CODES.O) +@AndroidEntryPoint class AutofillDecryptActivity : AppCompatActivity(), CoroutineScope { companion object { @@ -77,6 +81,8 @@ class AutofillDecryptActivity : AppCompatActivity(), CoroutineScope { } } + @Inject lateinit var passwordEntryFactory: PasswordEntryFactory + private val decryptInteractionRequiredAction = registerForActivityResult(StartIntentSenderForResult()) { result -> if (continueAfterUserInteraction != null) { @@ -183,7 +189,8 @@ class AutofillDecryptActivity : AppCompatActivity(), CoroutineScope { runCatching { val entry = withContext(Dispatchers.IO) { - @Suppress("BlockingMethodInNonBlockingContext") (PasswordEntry(decryptedOutput)) + @Suppress("BlockingMethodInNonBlockingContext") + passwordEntryFactory.create(lifecycleScope, decryptedOutput.toByteArray()) } AutofillPreferences.credentialsFromStoreEntry(this, file, entry, directoryStructure) } diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/crypto/DecryptActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/crypto/DecryptActivity.kt index fe688b40..f50410d4 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/crypto/DecryptActivity.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/crypto/DecryptActivity.kt @@ -16,28 +16,34 @@ import androidx.lifecycle.lifecycleScope import com.github.ajalt.timberkt.e import com.github.michaelbull.result.onFailure import com.github.michaelbull.result.runCatching +import dagger.hilt.android.AndroidEntryPoint import dev.msfjarvis.aps.R +import dev.msfjarvis.aps.data.passfile.PasswordEntry import dev.msfjarvis.aps.data.password.FieldItem -import dev.msfjarvis.aps.data.password.PasswordEntry import dev.msfjarvis.aps.databinding.DecryptLayoutBinding +import dev.msfjarvis.aps.injection.password.PasswordEntryFactory import dev.msfjarvis.aps.ui.adapters.FieldItemAdapter import dev.msfjarvis.aps.util.extensions.viewBinding import dev.msfjarvis.aps.util.settings.PreferenceKeys import java.io.ByteArrayOutputStream import java.io.File +import javax.inject.Inject import kotlin.time.ExperimentalTime import kotlin.time.seconds import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import me.msfjarvis.openpgpktx.util.OpenPgpApi import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection import org.openintents.openpgp.IOpenPgpService2 +@AndroidEntryPoint class DecryptActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound { private val binding by viewBinding(DecryptLayoutBinding::inflate) + @Inject lateinit var passwordEntryFactory: PasswordEntryFactory private val relativeParentPath by lazy(LazyThreadSafetyMode.NONE) { getParentPath(fullPath, repoPath) } private var passwordEntry: PasswordEntry? = null @@ -85,7 +91,7 @@ class DecryptActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound { passwordEntry?.let { entry -> if (menu != null) { menu.findItem(R.id.edit_password).isVisible = true - if (entry.password.isNotEmpty()) { + if (entry.password.isNullOrBlank()) { menu.findItem(R.id.share_password_as_plaintext).isVisible = true menu.findItem(R.id.copy_password).isVisible = true } @@ -136,7 +142,7 @@ class DecryptActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound { intent.putExtra("REPO_PATH", repoPath) intent.putExtra(PasswordCreationActivity.EXTRA_FILE_NAME, name) intent.putExtra(PasswordCreationActivity.EXTRA_PASSWORD, passwordEntry?.password) - intent.putExtra(PasswordCreationActivity.EXTRA_EXTRA_CONTENT, passwordEntry?.extraContent) + intent.putExtra(PasswordCreationActivity.EXTRA_EXTRA_CONTENT, passwordEntry?.extraContentWithoutAuthData) intent.putExtra(PasswordCreationActivity.EXTRA_EDITING, true) startActivity(intent) finish() @@ -172,7 +178,7 @@ class DecryptActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound { startAutoDismissTimer() runCatching { val showPassword = settings.getBoolean(PreferenceKeys.SHOW_PASSWORD, true) - val entry = PasswordEntry(outputStream) + val entry = passwordEntryFactory.create(lifecycleScope, outputStream.toByteArray()) val items = arrayListOf<FieldItem>() val adapter = FieldItemAdapter(emptyList(), showPassword) { text -> copyTextToClipboard(text) } @@ -183,37 +189,25 @@ class DecryptActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound { passwordEntry = entry invalidateOptionsMenu() - if (entry.password.isNotEmpty()) { - items.add(FieldItem.createPasswordField(entry.password)) + if (entry.password.isNullOrBlank()) { + items.add(FieldItem.createPasswordField(entry.password!!)) } if (entry.hasTotp()) { launch(Dispatchers.IO) { - // Calculate the actual remaining time for the first pass - // then return to the standard rotation. - val remainingTime = entry.totpPeriod - (System.currentTimeMillis() % entry.totpPeriod) withContext(Dispatchers.Main) { - val code = entry.calculateTotpCode() ?: "Error" + val code = entry.totp.value items.add(FieldItem.createOtpField(code)) } - delay(remainingTime.seconds) - repeat(Int.MAX_VALUE) { - val code = entry.calculateTotpCode() ?: "Error" - withContext(Dispatchers.Main) { adapter.updateOTPCode(code) } - delay(entry.totpPeriod.seconds) - } + entry.totp.collect { code -> withContext(Dispatchers.Main) { adapter.updateOTPCode(code) } } } } - if (!entry.username.isNullOrEmpty()) { - items.add(FieldItem.createUsernameField(entry.username)) + if (!entry.username.isNullOrBlank()) { + items.add(FieldItem.createUsernameField(entry.username!!)) } - if (entry.hasExtraContentWithoutAuthData()) { - entry.extraContentMap.forEach { (key, value) -> - items.add(FieldItem(key, value, FieldItem.ActionType.COPY)) - } - } + entry.extraContent.forEach { (key, value) -> items.add(FieldItem(key, value, FieldItem.ActionType.COPY)) } binding.recyclerView.adapter = adapter adapter.updateItems(items) diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/crypto/PasswordCreationActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/crypto/PasswordCreationActivity.kt index 7966628f..462dc388 100644 --- a/app/src/main/java/dev/msfjarvis/aps/ui/crypto/PasswordCreationActivity.kt +++ b/app/src/main/java/dev/msfjarvis/aps/ui/crypto/PasswordCreationActivity.kt @@ -28,10 +28,11 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import com.google.zxing.integration.android.IntentIntegrator import com.google.zxing.integration.android.IntentIntegrator.QR_CODE +import dagger.hilt.android.AndroidEntryPoint import dev.msfjarvis.aps.R -import dev.msfjarvis.aps.data.password.PasswordEntry import dev.msfjarvis.aps.data.repo.PasswordRepository import dev.msfjarvis.aps.databinding.PasswordCreationActivityBinding +import dev.msfjarvis.aps.injection.password.PasswordEntryFactory import dev.msfjarvis.aps.ui.dialogs.OtpImportDialogFragment import dev.msfjarvis.aps.ui.dialogs.PasswordGeneratorDialogFragment import dev.msfjarvis.aps.ui.dialogs.XkPasswordGeneratorDialogFragment @@ -49,15 +50,18 @@ import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.File import java.io.IOException +import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import me.msfjarvis.openpgpktx.util.OpenPgpApi import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection +@AndroidEntryPoint class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound { private val binding by viewBinding(PasswordCreationActivityBinding::inflate) + @Inject lateinit var passwordEntryFactory: PasswordEntryFactory private val suggestedName by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra(EXTRA_FILE_NAME) } private val suggestedPass by lazy(LazyThreadSafetyMode.NONE) { intent.getStringExtra(EXTRA_PASSWORD) } @@ -221,7 +225,8 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB } else { // User wants to disable username encryption, so we extract the // username from the encrypted extras and use it as the filename. - val entry = PasswordEntry("PASSWORD\n${extraContent.text}") + val entry = + passwordEntryFactory.create(lifecycleScope, "PASSWORD\n${extraContent.text}".encodeToByteArray()) val username = entry.username // username should not be null here by the logic in @@ -288,11 +293,11 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB private fun updateViewState() = with(binding) { // Use PasswordEntry to parse extras for username - val entry = PasswordEntry("PLACEHOLDER\n${extraContent.text}") + val entry = passwordEntryFactory.create(lifecycleScope, "PLACEHOLDER\n${extraContent.text}".encodeToByteArray()) encryptUsername.apply { if (visibility != View.VISIBLE) return@apply val hasUsernameInFileName = filename.text.toString().isNotBlank() - val hasUsernameInExtras = entry.hasUsername() + val hasUsernameInExtras = !entry.username.isNullOrBlank() isEnabled = hasUsernameInFileName xor hasUsernameInExtras isChecked = hasUsernameInExtras } @@ -430,7 +435,7 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB if (shouldGeneratePassword) { val directoryStructure = AutofillPreferences.directoryStructure(applicationContext) - val entry = PasswordEntry(content) + val entry = passwordEntryFactory.create(lifecycleScope, content.encodeToByteArray()) returnIntent.putExtra(RETURN_EXTRA_PASSWORD, entry.password) val username = entry.username ?: directoryStructure.getUsernameFor(file) returnIntent.putExtra(RETURN_EXTRA_USERNAME, username) |
