summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/data/repo/PasswordRepository.kt57
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillDecryptActivity.kt44
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillDecryptActivityV2.kt24
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillFilterView.kt44
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillPublisherChangedActivity.kt39
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/crypto/DecryptActivity.kt54
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/crypto/GetKeyIdsActivity.kt18
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/crypto/PasswordCreationActivity.kt197
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/crypto/PasswordCreationActivityV2.kt161
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt33
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/folderselect/SelectFolderFragment.kt19
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitConfigActivity.kt23
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitServerConfigActivity.kt42
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/onboarding/fragments/CloneFragment.kt12
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt40
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordStore.kt9
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/proxy/ProxySelectorActivity.kt35
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/settings/RepositorySettings.kt6
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/ui/sshkeygen/SshKeyImportActivity.kt20
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillMatcher.kt10
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/extensions/Extensions.kt7
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt114
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt9
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt16
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt76
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt5
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt7
-rw-r--r--app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt5
-rw-r--r--app/src/nonFree/java/dev/msfjarvis/aps/autofill/oreo/ui/AutofillSmsActivity.kt4
-rw-r--r--autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategyDsl.kt45
-rw-r--r--autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FeatureAndTrustDetection.kt3
-rw-r--r--autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FormField.kt7
-rw-r--r--build-logic/kotlin-plugins/src/main/kotlin/com.github.android-password-store.kotlin-kapt.gradle.kts6
-rw-r--r--crypto-pgpainless/src/main/kotlin/dev/msfjarvis/aps/crypto/PGPKeyManager.kt12
34 files changed, 613 insertions, 590 deletions
diff --git a/app/src/main/java/dev/msfjarvis/aps/data/repo/PasswordRepository.kt b/app/src/main/java/dev/msfjarvis/aps/data/repo/PasswordRepository.kt
index 9bf1bce6..f675e80a 100644
--- a/app/src/main/java/dev/msfjarvis/aps/data/repo/PasswordRepository.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/data/repo/PasswordRepository.kt
@@ -42,10 +42,11 @@ object PasswordRepository {
private fun initializeRepository(repositoryDir: File) {
val builder = FileRepositoryBuilder()
repository =
- runCatching { builder.setGitDir(repositoryDir).build() }.getOrElse { e ->
- e.printStackTrace()
- null
- }
+ runCatching { builder.setGitDir(repositoryDir).build() }
+ .getOrElse { e ->
+ e.printStackTrace()
+ null
+ }
}
fun createRepository(repositoryDir: File) {
@@ -61,40 +62,40 @@ object PasswordRepository {
if (!remotes.contains(name)) {
runCatching {
- val uri = URIish(url)
- val refSpec = RefSpec("+refs/head/*:refs/remotes/$name/*")
+ val uri = URIish(url)
+ val refSpec = RefSpec("+refs/head/*:refs/remotes/$name/*")
- val remoteConfig = RemoteConfig(storedConfig, name)
- remoteConfig.addFetchRefSpec(refSpec)
- remoteConfig.addPushRefSpec(refSpec)
- remoteConfig.addURI(uri)
- remoteConfig.addPushURI(uri)
+ val remoteConfig = RemoteConfig(storedConfig, name)
+ remoteConfig.addFetchRefSpec(refSpec)
+ remoteConfig.addPushRefSpec(refSpec)
+ remoteConfig.addURI(uri)
+ remoteConfig.addPushURI(uri)
- remoteConfig.update(storedConfig)
+ remoteConfig.update(storedConfig)
- storedConfig.save()
- }
+ storedConfig.save()
+ }
.onFailure { e -> e.printStackTrace() }
} else if (replace) {
runCatching {
- val uri = URIish(url)
+ val uri = URIish(url)
- val remoteConfig = RemoteConfig(storedConfig, name)
- // remove the first and eventually the only uri
- if (remoteConfig.urIs.size > 0) {
- remoteConfig.removeURI(remoteConfig.urIs[0])
- }
- if (remoteConfig.pushURIs.size > 0) {
- remoteConfig.removePushURI(remoteConfig.pushURIs[0])
- }
+ val remoteConfig = RemoteConfig(storedConfig, name)
+ // remove the first and eventually the only uri
+ if (remoteConfig.urIs.size > 0) {
+ remoteConfig.removeURI(remoteConfig.urIs[0])
+ }
+ if (remoteConfig.pushURIs.size > 0) {
+ remoteConfig.removePushURI(remoteConfig.pushURIs[0])
+ }
- remoteConfig.addURI(uri)
- remoteConfig.addPushURI(uri)
+ remoteConfig.addURI(uri)
+ remoteConfig.addPushURI(uri)
- remoteConfig.update(storedConfig)
+ remoteConfig.update(storedConfig)
- storedConfig.save()
- }
+ storedConfig.save()
+ }
.onFailure { e -> e.printStackTrace() }
}
}
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 291c654f..bd3141a8 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
@@ -200,18 +200,18 @@ class AutofillDecryptActivity : AppCompatActivity() {
) {
OpenPgpApi.RESULT_CODE_SUCCESS -> {
runCatching {
- val entry =
- withContext(Dispatchers.IO) {
- @Suppress("BlockingMethodInNonBlockingContext")
- passwordEntryFactory.create(decryptedOutput.toByteArray())
- }
- AutofillPreferences.credentialsFromStoreEntry(
- this,
- file,
- entry,
- directoryStructure
- )
- }
+ val entry =
+ withContext(Dispatchers.IO) {
+ @Suppress("BlockingMethodInNonBlockingContext")
+ passwordEntryFactory.create(decryptedOutput.toByteArray())
+ }
+ AutofillPreferences.credentialsFromStoreEntry(
+ this,
+ file,
+ entry,
+ directoryStructure
+ )
+ }
.getOrElse { e ->
logcat(ERROR) { e.asLog("Failed to parse password entry") }
return null
@@ -221,17 +221,17 @@ class AutofillDecryptActivity : AppCompatActivity() {
val pendingIntent: PendingIntent =
result.getParcelableExtra(OpenPgpApi.RESULT_INTENT)!!
runCatching {
- val intentToResume =
- withContext(Dispatchers.Main) {
- suspendCoroutine<Intent> { cont ->
- continueAfterUserInteraction = cont
- decryptInteractionRequiredAction.launch(
- IntentSenderRequest.Builder(pendingIntent.intentSender).build()
- )
+ val intentToResume =
+ withContext(Dispatchers.Main) {
+ suspendCoroutine<Intent> { cont ->
+ continueAfterUserInteraction = cont
+ decryptInteractionRequiredAction.launch(
+ IntentSenderRequest.Builder(pendingIntent.intentSender).build()
+ )
+ }
}
- }
- decryptCredential(file, intentToResume)
- }
+ decryptCredential(file, intentToResume)
+ }
.getOrElse { e ->
logcat(ERROR) {
e.asLog("OpenPgpApi ACTION_DECRYPT_VERIFY failed with user interaction")
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillDecryptActivityV2.kt b/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillDecryptActivityV2.kt
index d7287605..af875e00 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillDecryptActivityV2.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillDecryptActivityV2.kt
@@ -150,25 +150,25 @@ class AutofillDecryptActivityV2 : AppCompatActivity() {
}
.onSuccess { encryptedInput ->
runCatching {
- withContext(Dispatchers.IO) {
- val outputStream = ByteArrayOutputStream()
- repository.decrypt(
- password,
- encryptedInput,
- outputStream,
- )
- outputStream
+ withContext(Dispatchers.IO) {
+ val outputStream = ByteArrayOutputStream()
+ repository.decrypt(
+ password,
+ encryptedInput,
+ outputStream,
+ )
+ outputStream
+ }
}
- }
.onFailure { e ->
logcat(ERROR) { e.asLog("Decryption failed") }
return null
}
.onSuccess { result ->
return runCatching {
- val entry = passwordEntryFactory.create(result.toByteArray())
- AutofillPreferences.credentialsFromStoreEntry(this, file, entry, directoryStructure)
- }
+ val entry = passwordEntryFactory.create(result.toByteArray())
+ AutofillPreferences.credentialsFromStoreEntry(this, file, entry, directoryStructure)
+ }
.getOrElse { e ->
logcat(ERROR) { e.asLog("Failed to parse password entry") }
return null
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillFilterView.kt b/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillFilterView.kt
index 573e5337..6bf238a1 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillFilterView.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillFilterView.kt
@@ -149,31 +149,31 @@ class AutofillFilterView : AppCompatActivity() {
::PasswordViewHolder,
lifecycleScope,
) { item ->
- val file = item.file.relativeTo(item.rootDir)
- val pathToIdentifier = directoryStructure.getPathToIdentifierFor(file)
- val identifier = directoryStructure.getIdentifierFor(file)
- val accountPart = directoryStructure.getAccountPartFor(file)
- check(identifier != null || accountPart != null) {
- "At least one of identifier and accountPart should always be non-null"
- }
- title.text =
- if (identifier != null) {
- buildSpannedString {
- if (pathToIdentifier != null) append("$pathToIdentifier/")
- bold { underline { append(identifier) } }
- }
- } else {
- accountPart
+ val file = item.file.relativeTo(item.rootDir)
+ val pathToIdentifier = directoryStructure.getPathToIdentifierFor(file)
+ val identifier = directoryStructure.getIdentifierFor(file)
+ val accountPart = directoryStructure.getAccountPartFor(file)
+ check(identifier != null || accountPart != null) {
+ "At least one of identifier and accountPart should always be non-null"
}
- subtitle.apply {
- if (identifier != null && accountPart != null) {
- text = accountPart
- visibility = View.VISIBLE
- } else {
- visibility = View.GONE
+ title.text =
+ if (identifier != null) {
+ buildSpannedString {
+ if (pathToIdentifier != null) append("$pathToIdentifier/")
+ bold { underline { append(identifier) } }
+ }
+ } else {
+ accountPart
+ }
+ subtitle.apply {
+ if (identifier != null && accountPart != null) {
+ text = accountPart
+ visibility = View.VISIBLE
+ } else {
+ visibility = View.GONE
+ }
}
}
- }
.onItemClicked { _, item -> decryptAndFill(item) }
layoutManager = LinearLayoutManager(context)
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillPublisherChangedActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillPublisherChangedActivity.kt
index 794fad8c..b0b5ea9c 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillPublisherChangedActivity.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/autofill/AutofillPublisherChangedActivity.kt
@@ -105,27 +105,28 @@ class AutofillPublisherChangedActivity : AppCompatActivity() {
private fun showPackageInfo() {
runCatching {
- with(binding) {
- val packageInfo = packageManager.getPackageInfo(appPackage, PackageManager.GET_META_DATA)
- val installTime = DateUtils.getRelativeTimeSpanString(packageInfo.firstInstallTime)
- warningAppInstallDate.text =
- getString(R.string.oreo_autofill_warning_publisher_install_time, installTime)
- val appInfo = packageManager.getApplicationInfo(appPackage, PackageManager.GET_META_DATA)
- warningAppName.text =
- getString(
- R.string.oreo_autofill_warning_publisher_app_name,
- packageManager.getApplicationLabel(appInfo)
- )
+ with(binding) {
+ val packageInfo = packageManager.getPackageInfo(appPackage, PackageManager.GET_META_DATA)
+ val installTime = DateUtils.getRelativeTimeSpanString(packageInfo.firstInstallTime)
+ warningAppInstallDate.text =
+ getString(R.string.oreo_autofill_warning_publisher_install_time, installTime)
+ val appInfo = packageManager.getApplicationInfo(appPackage, PackageManager.GET_META_DATA)
+ warningAppName.text =
+ getString(
+ R.string.oreo_autofill_warning_publisher_app_name,
+ packageManager.getApplicationLabel(appInfo)
+ )
- val currentHash = computeCertificatesHash(this@AutofillPublisherChangedActivity, appPackage)
- warningAppAdvancedInfo.text =
- getString(
- R.string.oreo_autofill_warning_publisher_advanced_info_template,
- appPackage,
- currentHash
- )
+ val currentHash =
+ computeCertificatesHash(this@AutofillPublisherChangedActivity, appPackage)
+ warningAppAdvancedInfo.text =
+ getString(
+ R.string.oreo_autofill_warning_publisher_advanced_info_template,
+ appPackage,
+ currentHash
+ )
+ }
}
- }
.onFailure { e ->
logcat(ERROR) { e.asLog("Failed to retrieve package info for $appPackage") }
finish()
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 77abde2a..af9a4ddd 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
@@ -178,42 +178,42 @@ class DecryptActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound {
OpenPgpApi.RESULT_CODE_SUCCESS -> {
startAutoDismissTimer()
runCatching {
- val showPassword = settings.getBoolean(PreferenceKeys.SHOW_PASSWORD, true)
- val entry = passwordEntryFactory.create(outputStream.toByteArray())
+ val showPassword = settings.getBoolean(PreferenceKeys.SHOW_PASSWORD, true)
+ val entry = passwordEntryFactory.create(outputStream.toByteArray())
- if (settings.getBoolean(PreferenceKeys.COPY_ON_DECRYPT, false)) {
- copyPasswordToClipboard(entry.password)
- }
+ if (settings.getBoolean(PreferenceKeys.COPY_ON_DECRYPT, false)) {
+ copyPasswordToClipboard(entry.password)
+ }
- passwordEntry = entry
- invalidateOptionsMenu()
+ passwordEntry = entry
+ invalidateOptionsMenu()
- val items = arrayListOf<FieldItem>()
- if (!entry.password.isNullOrBlank()) {
- items.add(FieldItem.createPasswordField(entry.password!!))
- }
+ val items = arrayListOf<FieldItem>()
+ if (!entry.password.isNullOrBlank()) {
+ items.add(FieldItem.createPasswordField(entry.password!!))
+ }
- if (entry.hasTotp()) {
- items.add(FieldItem.createOtpField(entry.totp.first()))
- }
+ if (entry.hasTotp()) {
+ items.add(FieldItem.createOtpField(entry.totp.first()))
+ }
- if (!entry.username.isNullOrBlank()) {
- items.add(FieldItem.createUsernameField(entry.username!!))
- }
+ if (!entry.username.isNullOrBlank()) {
+ items.add(FieldItem.createUsernameField(entry.username!!))
+ }
- entry.extraContent.forEach { (key, value) ->
- items.add(FieldItem(key, value, FieldItem.ActionType.COPY))
- }
+ entry.extraContent.forEach { (key, value) ->
+ items.add(FieldItem(key, value, FieldItem.ActionType.COPY))
+ }
- val adapter =
- FieldItemAdapter(items, showPassword) { text -> copyTextToClipboard(text) }
- binding.recyclerView.adapter = adapter
- binding.recyclerView.itemAnimator = null
+ val adapter =
+ FieldItemAdapter(items, showPassword) { text -> copyTextToClipboard(text) }
+ binding.recyclerView.adapter = adapter
+ binding.recyclerView.itemAnimator = null
- if (entry.hasTotp()) {
- entry.totp.onEach(adapter::updateOTPCode).launchIn(lifecycleScope)
+ if (entry.hasTotp()) {
+ entry.totp.onEach(adapter::updateOTPCode).launchIn(lifecycleScope)
+ }
}
- }
.onFailure { e -> logcat(ERROR) { e.asLog() } }
}
OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED -> {
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/crypto/GetKeyIdsActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/crypto/GetKeyIdsActivity.kt
index b24868c9..afd30270 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/crypto/GetKeyIdsActivity.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/crypto/GetKeyIdsActivity.kt
@@ -56,15 +56,15 @@ class GetKeyIdsActivity : BasePgpActivity() {
when (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
OpenPgpApi.RESULT_CODE_SUCCESS -> {
runCatching {
- val ids =
- result.getLongArrayExtra(OpenPgpApi.RESULT_KEY_IDS)?.map {
- OpenPgpUtils.convertKeyIdToHex(it)
- }
- ?: emptyList()
- val keyResult = Intent().putExtra(OpenPgpApi.EXTRA_KEY_IDS, ids.toTypedArray())
- setResult(RESULT_OK, keyResult)
- finish()
- }
+ val ids =
+ result.getLongArrayExtra(OpenPgpApi.RESULT_KEY_IDS)?.map {
+ OpenPgpUtils.convertKeyIdToHex(it)
+ }
+ ?: emptyList()
+ val keyResult = Intent().putExtra(OpenPgpApi.EXTRA_KEY_IDS, ids.toTypedArray())
+ setResult(RESULT_OK, keyResult)
+ finish()
+ }
.onFailure { e -> logcat(ERROR) { e.asLog() } }
}
OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED -> {
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 930da5cd..7a9ba54e 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
@@ -143,15 +143,15 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB
val reader = QRCodeReader()
runCatching {
- val result = reader.decode(binaryBitmap)
- val text = result.text
- val currentExtras = binding.extraContent.text.toString()
- if (currentExtras.isNotEmpty() && currentExtras.last() != '\n')
- binding.extraContent.append("\n$text")
- else binding.extraContent.append(text)
- snackbar(message = getString(R.string.otp_import_success))
- binding.otpImportButton.isVisible = false
- }
+ val result = reader.decode(binaryBitmap)
+ val text = result.text
+ val currentExtras = binding.extraContent.text.toString()
+ if (currentExtras.isNotEmpty() && currentExtras.last() != '\n')
+ binding.extraContent.append("\n$text")
+ else binding.extraContent.append(text)
+ snackbar(message = getString(R.string.otp_import_success))
+ binding.otpImportButton.isVisible = false
+ }
.onFailure { snackbar(message = getString(R.string.otp_import_failure)) }
}
@@ -411,22 +411,25 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB
File(repoRoot, directory.text.toString()).findTillRoot(".gpg-id", repoRoot)
?: File(repoRoot, ".gpg-id").apply { createNewFile() }
val gpgIdentifiers =
- gpgIdentifierFile.readLines().filter { it.isNotBlank() }.map { line ->
- GpgIdentifier.fromString(line)
- ?: run {
- // The line being empty means this is most likely an empty `.gpg-id`
- // file
- // we created. Skip the validation so we can make the user add a real
- // ID.
- if (line.isEmpty()) return@run
- if (line.removePrefix("0x").matches("[a-fA-F0-9]{8}".toRegex())) {
- snackbar(message = resources.getString(R.string.short_key_ids_unsupported))
- } else {
- snackbar(message = resources.getString(R.string.invalid_gpg_id))
+ gpgIdentifierFile
+ .readLines()
+ .filter { it.isNotBlank() }
+ .map { line ->
+ GpgIdentifier.fromString(line)
+ ?: run {
+ // The line being empty means this is most likely an empty `.gpg-id`
+ // file
+ // we created. Skip the validation so we can make the user add a real
+ // ID.
+ if (line.isEmpty()) return@run
+ if (line.removePrefix("0x").matches("[a-fA-F0-9]{8}".toRegex())) {
+ snackbar(message = resources.getString(R.string.short_key_ids_unsupported))
+ } else {
+ snackbar(message = resources.getString(R.string.invalid_gpg_id))
+ }
+ return@with
}
- return@with
- }
- }
+ }
if (gpgIdentifiers.isEmpty()) {
gpgKeySelectAction.launch(
Intent(this@PasswordCreationActivity, GetKeyIdsActivity::class.java)
@@ -480,86 +483,92 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB
when (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
OpenPgpApi.RESULT_CODE_SUCCESS -> {
runCatching {
- val file = File(path)
- // If we're not editing, this file should not already exist!
- // Additionally, if we were editing and the incoming and outgoing
- // filenames differ, it means we renamed. Ensure that the target
- // doesn't already exist to prevent an accidental overwrite.
- if ((!editing || (editing && suggestedName != file.nameWithoutExtension)) &&
- file.exists()
- ) {
- snackbar(message = getString(R.string.password_creation_duplicate_error))
- return@runCatching
- }
-
- if (!file.isInsideRepository()) {
- snackbar(message = getString(R.string.message_error_destination_outside_repo))
- return@runCatching
- }
+ val file = File(path)
+ // If we're not editing, this file should not already exist!
+ // Additionally, if we were editing and the incoming and outgoing
+ // filenames differ, it means we renamed. Ensure that the target
+ // doesn't already exist to prevent an accidental overwrite.
+ if ((!editing || (editing && suggestedName != file.nameWithoutExtension)) &&
+ file.exists()
+ ) {
+ snackbar(message = getString(R.string.password_creation_duplicate_error))
+ return@runCatching
+ }
- withContext(Dispatchers.IO) {
- file.outputStream().use { it.write(outputStream.toByteArray()) }
- }
+ if (!file.isInsideRepository()) {
+ snackbar(message = getString(R.string.message_error_destination_outside_repo))
+ return@runCatching
+ }
- // associate the new password name with the last name's timestamp in
- // history
- val preference = getSharedPreferences("recent_password_history", Context.MODE_PRIVATE)
- val oldFilePathHash = "$repoPath/${oldCategory?.trim('/')}/$oldFileName.gpg".base64()
- val timestamp = preference.getString(oldFilePathHash)
- if (timestamp != null) {
- preference.edit {
- remove(oldFilePathHash)
- putString(file.absolutePath.base64(), timestamp)
+ withContext(Dispatchers.IO) {
+ file.outputStream().use { it.write(outputStream.toByteArray()) }
}
- }
- val returnIntent = Intent()
- returnIntent.putExtra(RETURN_EXTRA_CREATED_FILE, path)
- returnIntent.putExtra(RETURN_EXTRA_NAME, editName)
- returnIntent.putExtra(
- RETURN_EXTRA_LONG_NAME,
- getLongName(fullPath, repoPath, editName)
- )
+ // associate the new password name with the last name's timestamp in
+ // history
+ val preference =
+ getSharedPreferences("recent_password_history", Context.MODE_PRIVATE)
+ val oldFilePathHash =
+ "$repoPath/${oldCategory?.trim('/')}/$oldFileName.gpg".base64()
+ val timestamp = preference.getString(oldFilePathHash)
+ if (timestamp != null) {
+ preference.edit {
+ remove(oldFilePathHash)
+ putString(file.absolutePath.base64(), timestamp)
+ }
+ }
- if (shouldGeneratePassword) {
- val directoryStructure = AutofillPreferences.directoryStructure(applicationContext)
- val entry = passwordEntryFactory.create(content.encodeToByteArray())
- returnIntent.putExtra(RETURN_EXTRA_PASSWORD, entry.password)
- val username = entry.username ?: directoryStructure.getUsernameFor(file)
- returnIntent.putExtra(RETURN_EXTRA_USERNAME, username)
- }
+ val returnIntent = Intent()
+ returnIntent.putExtra(RETURN_EXTRA_CREATED_FILE, path)
+ returnIntent.putExtra(RETURN_EXTRA_NAME, editName)
+ returnIntent.putExtra(
+ RETURN_EXTRA_LONG_NAME,
+ getLongName(fullPath, repoPath, editName)
+ )
- if (directoryInputLayout.isVisible &&
- directoryInputLayout.isEnabled &&
- oldFileName != null
- ) {
- val oldFile = File("$repoPath/${oldCategory?.trim('/')}/$oldFileName.gpg")
- if (oldFile.path != file.path && !oldFile.delete()) {
- setResult(RESULT_CANCELED)
- MaterialAlertDialogBuilder(this@PasswordCreationActivity)
- .setTitle(R.string.password_creation_file_fail_title)
- .setMessage(
- getString(R.string.password_creation_file_delete_fail_message, oldFileName)
- )
- .setCancelable(false)
- .setPositiveButton(android.R.string.ok) { _, _ -> finish() }
- .show()
- return@runCatching
+ if (shouldGeneratePassword) {
+ val directoryStructure =
+ AutofillPreferences.directoryStructure(applicationContext)
+ val entry = passwordEntryFactory.create(content.encodeToByteArray())
+ returnIntent.putExtra(RETURN_EXTRA_PASSWORD, entry.password)
+ val username = entry.username ?: directoryStructure.getUsernameFor(file)
+ returnIntent.putExtra(RETURN_EXTRA_USERNAME, username)
}
- }
- val commitMessageRes =
- if (editing) R.string.git_commit_edit_text else R.string.git_commit_add_text
- lifecycleScope.launch {
- commitChange(
- resources.getString(commitMessageRes, getLongName(fullPath, repoPath, editName))
- )
- .onSuccess {
- setResult(RESULT_OK, returnIntent)
- finish()
+ if (directoryInputLayout.isVisible &&
+ directoryInputLayout.isEnabled &&
+ oldFileName != null
+ ) {
+ val oldFile = File("$repoPath/${oldCategory?.trim('/')}/$oldFileName.gpg")
+ if (oldFile.path != file.path && !oldFile.delete()) {
+ setResult(RESULT_CANCELED)
+ MaterialAlertDialogBuilder(this@PasswordCreationActivity)
+ .setTitle(R.string.password_creation_file_fail_title)
+ .setMessage(
+ getString(R.string.password_creation_file_delete_fail_message, oldFileName)
+ )
+ .setCancelable(false)
+ .setPositiveButton(android.R.string.ok) { _, _ -> finish() }
+ .show()
+ return@runCatching
}
+ }
+
+ val commitMessageRes =
+ if (editing) R.string.git_commit_edit_text else R.string.git_commit_add_text
+ lifecycleScope.launch {
+ commitChange(
+ resources.getString(
+ commitMessageRes,
+ getLongName(fullPath, repoPath, editName)
+ )
+ )
+ .onSuccess {
+ setResult(RESULT_OK, returnIntent)
+ finish()
+ }
+ }
}
- }
.onFailure { e ->
if (e is IOException) {
logcat(ERROR) { e.asLog("Failed to write password file") }
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/crypto/PasswordCreationActivityV2.kt b/app/src/main/java/dev/msfjarvis/aps/ui/crypto/PasswordCreationActivityV2.kt
index a24fbc9e..a35891a5 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/crypto/PasswordCreationActivityV2.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/crypto/PasswordCreationActivityV2.kt
@@ -119,15 +119,15 @@ class PasswordCreationActivityV2 : BasePgpActivity() {
val reader = QRCodeReader()
runCatching {
- val result = reader.decode(binaryBitmap)
- val text = result.text
- val currentExtras = binding.extraContent.text.toString()
- if (currentExtras.isNotEmpty() && currentExtras.last() != '\n')
- binding.extraContent.append("\n$text")
- else binding.extraContent.append(text)
- snackbar(message = getString(R.string.otp_import_success))
- binding.otpImportButton.isVisible = false
- }
+ val result = reader.decode(binaryBitmap)
+ val text = result.text
+ val currentExtras = binding.extraContent.text.toString()
+ if (currentExtras.isNotEmpty() && currentExtras.last() != '\n')
+ binding.extraContent.append("\n$text")
+ else binding.extraContent.append(text)
+ snackbar(message = getString(R.string.otp_import_success))
+ binding.otpImportButton.isVisible = false
+ }
.onFailure { snackbar(message = getString(R.string.otp_import_failure)) }
}
@@ -357,86 +357,87 @@ class PasswordCreationActivityV2 : BasePgpActivity() {
lifecycleScope.launch(Dispatchers.Main) {
runCatching {
- val result =
- withContext(Dispatchers.IO) {
- val outputStream = ByteArrayOutputStream()
- repository.encrypt(content.byteInputStream(), outputStream)
- outputStream
+ val result =
+ withContext(Dispatchers.IO) {
+ val outputStream = ByteArrayOutputStream()
+ repository.encrypt(content.byteInputStream(), outputStream)
+ outputStream
+ }
+ val file = File(path)
+ // If we're not editing, this file should not already exist!
+ // Additionally, if we were editing and the incoming and outgoing
+ // filenames differ, it means we renamed. Ensure that the target
+ // doesn't already exist to prevent an accidental overwrite.
+ if ((!editing || (editing && suggestedName != file.nameWithoutExtension)) &&
+ file.exists()
+ ) {
+ snackbar(message = getString(R.string.password_creation_duplicate_error))
+ return@runCatching
}
- val file = File(path)
- // If we're not editing, this file should not already exist!
- // Additionally, if we were editing and the incoming and outgoing
- // filenames differ, it means we renamed. Ensure that the target
- // doesn't already exist to prevent an accidental overwrite.
- if ((!editing || (editing && suggestedName != file.nameWithoutExtension)) && file.exists()
- ) {
- snackbar(message = getString(R.string.password_creation_duplicate_error))
- return@runCatching
- }
-
- if (!file.isInsideRepository()) {
- snackbar(message = getString(R.string.message_error_destination_outside_repo))
- return@runCatching
- }
- withContext(Dispatchers.IO) { file.writeBytes(result.toByteArray()) }
-
- // associate the new password name with the last name's timestamp in
- // history
- val preference = getSharedPreferences("recent_password_history", Context.MODE_PRIVATE)
- val oldFilePathHash = "$repoPath/${oldCategory?.trim('/')}/$oldFileName.gpg".base64()
- val timestamp = preference.getString(oldFilePathHash)
- if (timestamp != null) {
- preference.edit {
- remove(oldFilePathHash)
- putString(file.absolutePath.base64(), timestamp)
+ if (!file.isInsideRepository()) {
+ snackbar(message = getString(R.string.message_error_destination_outside_repo))
+ return@runCatching
}
- }
- val returnIntent = Intent()
- returnIntent.putExtra(RETURN_EXTRA_CREATED_FILE, path)
- returnIntent.putExtra(RETURN_EXTRA_NAME, editName)
- returnIntent.putExtra(RETURN_EXTRA_LONG_NAME, getLongName(fullPath, repoPath, editName))
-
- if (shouldGeneratePassword) {
- val directoryStructure = AutofillPreferences.directoryStructure(applicationContext)
- val entry = passwordEntryFactory.create(content.encodeToByteArray())
- returnIntent.putExtra(RETURN_EXTRA_PASSWORD, entry.password)
- val username = entry.username ?: directoryStructure.getUsernameFor(file)
- returnIntent.putExtra(RETURN_EXTRA_USERNAME, username)
- }
+ withContext(Dispatchers.IO) { file.writeBytes(result.toByteArray()) }
+
+ // associate the new password name with the last name's timestamp in
+ // history
+ val preference = getSharedPreferences("recent_password_history", Context.MODE_PRIVATE)
+ val oldFilePathHash = "$repoPath/${oldCategory?.trim('/')}/$oldFileName.gpg".base64()
+ val timestamp = preference.getString(oldFilePathHash)
+ if (timestamp != null) {
+ preference.edit {
+ remove(oldFilePathHash)
+ putString(file.absolutePath.base64(), timestamp)
+ }
+ }
- if (directoryInputLayout.isVisible &&
- directoryInputLayout.isEnabled &&
- oldFileName != null
- ) {
- val oldFile = File("$repoPath/${oldCategory?.trim('/')}/$oldFileName.gpg")
- if (oldFile.path != file.path && !oldFile.delete()) {
- setResult(RESULT_CANCELED)
- MaterialAlertDialogBuilder(this@PasswordCreationActivityV2)
- .setTitle(R.string.password_creation_file_fail_title)
- .setMessage(
- getString(R.string.password_creation_file_delete_fail_message, oldFileName)
- )
- .setCancelable(false)
- .setPositiveButton(android.R.string.ok) { _, _ -> finish() }
- .show()
- return@runCatching
+ val returnIntent = Intent()
+ returnIntent.putExtra(RETURN_EXTRA_CREATED_FILE, path)
+ returnIntent.putExtra(RETURN_EXTRA_NAME, editName)
+ returnIntent.putExtra(RETURN_EXTRA_LONG_NAME, getLongName(fullPath, repoPath, editName))
+
+ if (shouldGeneratePassword) {
+ val directoryStructure = AutofillPreferences.directoryStructure(applicationContext)
+ val entry = passwordEntryFactory.create(content.encodeToByteArray())
+ returnIntent.putExtra(RETURN_EXTRA_PASSWORD, entry.password)
+ val username = entry.username ?: directoryStructure.getUsernameFor(file)
+ returnIntent.putExtra(RETURN_EXTRA_USERNAME, username)
}
- }
- val commitMessageRes =
- if (editing) R.string.git_commit_edit_text else R.string.git_commit_add_text
- lifecycleScope.launch {
- commitChange(
- resources.getString(commitMessageRes, getLongName(fullPath, repoPath, editName))
- )
- .onSuccess {
- setResult(RESULT_OK, returnIntent)
- finish()
+ if (directoryInputLayout.isVisible &&
+ directoryInputLayout.isEnabled &&
+ oldFileName != null
+ ) {
+ val oldFile = File("$repoPath/${oldCategory?.trim('/')}/$oldFileName.gpg")
+ if (oldFile.path != file.path && !oldFile.delete()) {
+ setResult(RESULT_CANCELED)
+ MaterialAlertDialogBuilder(this@PasswordCreationActivityV2)
+ .setTitle(R.string.password_creation_file_fail_title)
+ .setMessage(
+ getString(R.string.password_creation_file_delete_fail_message, oldFileName)
+ )
+ .setCancelable(false)
+ .setPositiveButton(android.R.string.ok) { _, _ -> finish() }
+ .show()
+ return@runCatching
}
+ }
+
+ val commitMessageRes =
+ if (editing) R.string.git_commit_edit_text else R.string.git_commit_add_text
+ lifecycleScope.launch {
+ commitChange(
+ resources.getString(commitMessageRes, getLongName(fullPath, repoPath, editName))
+ )
+ .onSuccess {
+ setResult(RESULT_OK, returnIntent)
+ finish()
+ }
+ }
}
- }
.onFailure { e ->
if (e is IOException) {
logcat(ERROR) { e.asLog("Failed to write password file") }
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt
index a21e9a6a..b0ddc8a7 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/dialogs/PasswordGeneratorDialogFragment.kt
@@ -48,8 +48,7 @@ class PasswordGeneratorDialogFragment : DialogFragment() {
val monoTypeface = Typeface.createFromAsset(callingActivity.assets, "fonts/sourcecodepro.ttf")
val prefs =
requireActivity()
- .applicationContext
- .getSharedPreferences("PasswordGenerator", Context.MODE_PRIVATE)
+ .applicationContext.getSharedPreferences("PasswordGenerator", Context.MODE_PRIVATE)
builder.setView(binding.root)
@@ -102,21 +101,21 @@ class PasswordGeneratorDialogFragment : DialogFragment() {
val passwordLength = getLength()
setPrefs(requireContext(), passwordOptions, passwordLength)
passwordField.text =
- runCatching { PasswordGenerator.generate(passwordOptions, passwordLength) }.getOrElse {
- exception ->
- val errorText =
- when (exception) {
- is MaxIterationsExceededException ->
- requireContext().getString(R.string.pwgen_max_iterations_exceeded)
- is NoCharactersIncludedException ->
- requireContext().getString(R.string.pwgen_no_chars_error)
- is PasswordLengthTooShortException ->
- requireContext().getString(R.string.pwgen_length_too_short_error)
- else -> requireContext().getString(R.string.pwgen_some_error_occurred)
- }
- Toast.makeText(requireActivity(), errorText, Toast.LENGTH_SHORT).show()
- ""
- }
+ runCatching { PasswordGenerator.generate(passwordOptions, passwordLength) }
+ .getOrElse { exception ->
+ val errorText =
+ when (exception) {
+ is MaxIterationsExceededException ->
+ requireContext().getString(R.string.pwgen_max_iterations_exceeded)
+ is NoCharactersIncludedException ->
+ requireContext().getString(R.string.pwgen_no_chars_error)
+ is PasswordLengthTooShortException ->
+ requireContext().getString(R.string.pwgen_length_too_short_error)
+ else -> requireContext().getString(R.string.pwgen_some_error_occurred)
+ }
+ Toast.makeText(requireActivity(), errorText, Toast.LENGTH_SHORT).show()
+ ""
+ }
}
private fun isChecked(@IdRes id: Int): Boolean {
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/folderselect/SelectFolderFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/folderselect/SelectFolderFragment.kt
index ae430485..54fd2892 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/folderselect/SelectFolderFragment.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/folderselect/SelectFolderFragment.kt
@@ -59,18 +59,17 @@ class SelectFolderFragment : Fragment(R.layout.password_recycler_view) {
override fun onAttach(context: Context) {
super.onAttach(context)
runCatching {
- listener =
- object : OnFragmentInteractionListener {
- override fun onFragmentInteraction(item: PasswordItem) {
- if (item.type == PasswordItem.TYPE_CATEGORY) {
- model.navigateTo(item.file, listMode = ListMode.DirectoriesOnly)
- (requireActivity() as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(
- true
- )
+ listener =
+ object : OnFragmentInteractionListener {
+ override fun onFragmentInteraction(item: PasswordItem) {
+ if (item.type == PasswordItem.TYPE_CATEGORY) {
+ model.navigateTo(item.file, listMode = ListMode.DirectoriesOnly)
+ (requireActivity() as AppCompatActivity)
+ .supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ }
}
}
- }
- }
+ }
.onFailure {
throw ClassCastException("$context must implement OnFragmentInteractionListener")
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitConfigActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitConfigActivity.kt
index 959d9325..03c92313 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitConfigActivity.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitConfigActivity.kt
@@ -88,9 +88,8 @@ class GitConfigActivity : BaseGitActivity() {
binding.gitAbortRebase.alpha = if (needsAbort) 1.0f else 0.5f
}
binding.gitLog.setOnClickListener {
- runCatching { startActivity(Intent(this, GitLogActivity::class.java)) }.onFailure { ex ->
- logcat(ERROR) { "Failed to start GitLogActivity\n${ex}" }
- }
+ runCatching { startActivity(Intent(this, GitLogActivity::class.java)) }
+ .onFailure { ex -> logcat(ERROR) { "Failed to start GitLogActivity\n${ex}" } }
}
binding.gitAbortRebase.setOnClickListener {
lifecycleScope.launch {
@@ -142,16 +141,16 @@ class GitConfigActivity : BaseGitActivity() {
*/
private fun headStatusMsg(repo: Repository): String {
return runCatching {
- val headRef = repo.getRef(Constants.HEAD)
- if (headRef.isSymbolic) {
- val branchName = headRef.target.name
- val shortBranchName = Repository.shortenRefName(branchName)
- getString(R.string.git_head_on_branch, shortBranchName)
- } else {
- val commitHash = headRef.objectId.abbreviate(8).name()
- getString(R.string.git_head_detached, commitHash)
+ val headRef = repo.getRef(Constants.HEAD)
+ if (headRef.isSymbolic) {
+ val branchName = headRef.target.name
+ val shortBranchName = Repository.shortenRefName(branchName)
+ getString(R.string.git_head_on_branch, shortBranchName)
+ } else {
+ val commitHash = headRef.objectId.abbreviate(8).name()
+ getString(R.string.git_head_detached, commitHash)
+ }
}
- }
.getOrElse { ex ->
logcat(ERROR) { "Error getting HEAD reference\n${ex}" }
getString(R.string.git_head_missing)
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitServerConfigActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitServerConfigActivity.kt
index 6b1f30ea..e713a54e 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitServerConfigActivity.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/git/config/GitServerConfigActivity.kt
@@ -240,24 +240,24 @@ class GitServerConfigActivity : BaseGitActivity() {
.setCancelable(false)
.setPositiveButton(R.string.dialog_delete) { dialog, _ ->
runCatching {
- lifecycleScope.launch {
- val snackbar =
- snackbar(
- message = getString(R.string.delete_directory_progress_text),
- length = Snackbar.LENGTH_INDEFINITE
- )
- withContext(Dispatchers.IO) { localDir.deleteRecursively() }
- snackbar.dismiss()
- launchGitOperation(GitOp.CLONE)
- .fold(
- success = {
- setResult(RESULT_OK)
- finish()
- },
- failure = { err -> promptOnErrorHandler(err) { finish() } }
- )
+ lifecycleScope.launch {
+ val snackbar =
+ snackbar(
+ message = getString(R.string.delete_directory_progress_text),
+ length = Snackbar.LENGTH_INDEFINITE
+ )
+ withContext(Dispatchers.IO) { localDir.deleteRecursively() }
+ snackbar.dismiss()
+ launchGitOperation(GitOp.CLONE)
+ .fold(
+ success = {
+ setResult(RESULT_OK)
+ finish()
+ },
+ failure = { err -> promptOnErrorHandler(err) { finish() } }
+ )
+ }
}
- }
.onFailure { e ->
e.printStackTrace()
MaterialAlertDialogBuilder(this).setMessage(e.message).show()
@@ -268,11 +268,11 @@ class GitServerConfigActivity : BaseGitActivity() {
.show()
} else {
runCatching {
- // Silently delete & replace the lone .git folder if it exists
- if (localDir.exists() && localDirFiles.size == 1 && localDirFiles[0].name == ".git") {
- localDir.deleteRecursively()
+ // Silently delete & replace the lone .git folder if it exists
+ if (localDir.exists() && localDirFiles.size == 1 && localDirFiles[0].name == ".git") {
+ localDir.deleteRecursively()
+ }
}
- }
.onFailure { e ->
logcat(ERROR) { e.asLog() }
MaterialAlertDialogBuilder(this).setMessage(e.message).show()
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/onboarding/fragments/CloneFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/onboarding/fragments/CloneFragment.kt
index 16c1a784..e3d1df85 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/onboarding/fragments/CloneFragment.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/onboarding/fragments/CloneFragment.kt
@@ -55,13 +55,13 @@ class CloneFragment : Fragment(R.layout.fragment_clone) {
private fun createRepository() {
val localDir = PasswordRepository.getRepositoryDirectory()
runCatching {
- check(localDir.exists() || localDir.mkdir()) { "Failed to create directory!" }
- PasswordRepository.createRepository(localDir)
- if (!PasswordRepository.isInitialized) {
- PasswordRepository.initialize()
+ check(localDir.exists() || localDir.mkdir()) { "Failed to create directory!" }
+ PasswordRepository.createRepository(localDir)
+ if (!PasswordRepository.isInitialized) {
+ PasswordRepository.initialize()
+ }
+ parentFragmentManager.performTransactionWithBackStack(KeySelectionFragment.newInstance())
}
- parentFragmentManager.performTransactionWithBackStack(KeySelectionFragment.newInstance())
- }
.onFailure { e ->
logcat(ERROR) { e.asLog() }
if (!localDir.delete()) {
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt b/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt
index 063f472c..0d0f9cfc 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordFragment.kt
@@ -293,32 +293,32 @@ class PasswordFragment : Fragment(R.layout.password_recycler_view) {
override fun onAttach(context: Context) {
super.onAttach(context)
runCatching {
- listener =
- object : OnFragmentInteractionListener {
- override fun onFragmentInteraction(item: PasswordItem) {
- if (settings.getString(PreferenceKeys.SORT_ORDER) ==
- PasswordSortOrder.RECENTLY_USED.name
- ) {
- // save the time when password was used
- val preferences =
- context.getSharedPreferences("recent_password_history", Context.MODE_PRIVATE)
- preferences.edit {
- putString(item.file.absolutePath.base64(), System.currentTimeMillis().toString())
+ listener =
+ object : OnFragmentInteractionListener {
+ override fun onFragmentInteraction(item: PasswordItem) {
+ if (settings.getString(PreferenceKeys.SORT_ORDER) ==
+ PasswordSortOrder.RECENTLY_USED.name
+ ) {
+ // save the time when password was used
+ val preferences =
+ context.getSharedPreferences("recent_password_history", Context.MODE_PRIVATE)
+ preferences.edit {
+ putString(item.file.absolutePath.base64(), System.currentTimeMillis().toString())
+ }
}
- }
- if (item.type == PasswordItem.TYPE_CATEGORY) {
- navigateTo(item.file)
- } else {
- if (requireArguments().getBoolean("matchWith", false)) {
- requireStore().matchPasswordWithApp(item)
+ if (item.type == PasswordItem.TYPE_CATEGORY) {
+ navigateTo(item.file)
} else {
- requireStore().decryptPassword(item)
+ if (requireArguments().getBoolean("matchWith", false)) {
+ requireStore().matchPasswordWithApp(item)
+ } else {
+ requireStore().decryptPassword(item)
+ }
}
}
}
- }
- }
+ }
.onFailure {
throw ClassCastException("$context must implement OnFragmentInteractionListener")
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordStore.kt b/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordStore.kt
index e4ec2359..84bef7bb 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordStore.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/passwords/PasswordStore.kt
@@ -292,9 +292,8 @@ class PasswordStore : BaseGitActivity() {
.setPositiveButton(resources.getString(R.string.dialog_ok), null)
when (id) {
R.id.user_pref -> {
- runCatching { startActivity(Intent(this, SettingsActivity::class.java)) }.onFailure { e ->
- e.printStackTrace()
- }
+ runCatching { startActivity(Intent(this, SettingsActivity::class.java)) }
+ .onFailure { e -> e.printStackTrace() }
}
R.id.git_push -> {
if (!PasswordRepository.isInitialized) {
@@ -618,9 +617,7 @@ class PasswordStore : BaseGitActivity() {
fun matchPasswordWithApp(item: PasswordItem) {
val path =
- item
- .file
- .absolutePath
+ item.file.absolutePath
.replace(PasswordRepository.getRepositoryDirectory().toString() + "/", "")
.replace(".gpg", "")
val data = Intent()
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/proxy/ProxySelectorActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/proxy/ProxySelectorActivity.kt
index 6fc63673..41cab040 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/proxy/ProxySelectorActivity.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/proxy/ProxySelectorActivity.kt
@@ -42,9 +42,10 @@ class ProxySelectorActivity : AppCompatActivity() {
with(binding) {
proxyHost.setText(proxyPrefs.getString(PreferenceKeys.PROXY_HOST))
proxyUser.setText(proxyPrefs.getString(PreferenceKeys.PROXY_USERNAME))
- proxyPrefs.getInt(PreferenceKeys.PROXY_PORT, -1).takeIf { it != -1 }?.let {
- proxyPort.setText("$it")
- }
+ proxyPrefs
+ .getInt(PreferenceKeys.PROXY_PORT, -1)
+ .takeIf { it != -1 }
+ ?.let { proxyPort.setText("$it") }
proxyPassword.setText(proxyPrefs.getString(PreferenceKeys.PROXY_PASSWORD))
save.setOnClickListener { saveSettings() }
proxyHost.doOnTextChanged { text, _, _, _ ->
@@ -70,18 +71,22 @@ class ProxySelectorActivity : AppCompatActivity() {
private fun saveSettings() {
proxyPrefs.edit {
- binding.proxyHost.text?.toString()?.takeIf { it.isNotEmpty() }.let {
- gitSettings.proxyHost = it
- }
- binding.proxyUser.text?.toString()?.takeIf { it.isNotEmpty() }.let {
- gitSettings.proxyUsername = it
- }
- binding.proxyPort.text?.toString()?.takeIf { it.isNotEmpty() }?.let {
- gitSettings.proxyPort = it.toInt()
- }
- binding.proxyPassword.text?.toString()?.takeIf { it.isNotEmpty() }.let {
- gitSettings.proxyPassword = it
- }
+ binding.proxyHost.text
+ ?.toString()
+ ?.takeIf { it.isNotEmpty() }
+ .let { gitSettings.proxyHost = it }
+ binding.proxyUser.text
+ ?.toString()
+ ?.takeIf { it.isNotEmpty() }
+ .let { gitSettings.proxyUsername = it }
+ binding.proxyPort.text
+ ?.toString()
+ ?.takeIf { it.isNotEmpty() }
+ ?.let { gitSettings.proxyPort = it.toInt() }
+ binding.proxyPassword.text
+ ?.toString()
+ ?.takeIf { it.isNotEmpty() }
+ .let { gitSettings.proxyPassword = it }
}
proxyUtils.setDefaultProxy()
Handler(Looper.getMainLooper()).postDelayed(500) { finish() }
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/settings/RepositorySettings.kt b/app/src/main/java/dev/msfjarvis/aps/ui/settings/RepositorySettings.kt
index 1c43127a..ffd0f851 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/settings/RepositorySettings.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/settings/RepositorySettings.kt
@@ -161,9 +161,9 @@ class RepositorySettings(private val activity: FragmentActivity) : SettingsProvi
.setCancelable(false)
.setPositiveButton(R.string.dialog_delete) { dialogInterface, _ ->
runCatching {
- PasswordRepository.getRepositoryDirectory().deleteRecursively()
- PasswordRepository.closeRepository()
- }
+ PasswordRepository.getRepositoryDirectory().deleteRecursively()
+ PasswordRepository.closeRepository()
+ }
.onFailure { it.message?.let { message -> activity.snackbar(message = message) } }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
diff --git a/app/src/main/java/dev/msfjarvis/aps/ui/sshkeygen/SshKeyImportActivity.kt b/app/src/main/java/dev/msfjarvis/aps/ui/sshkeygen/SshKeyImportActivity.kt
index af00e3df..446e0c32 100644
--- a/app/src/main/java/dev/msfjarvis/aps/ui/sshkeygen/SshKeyImportActivity.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/ui/sshkeygen/SshKeyImportActivity.kt
@@ -25,16 +25,16 @@ class SshKeyImportActivity : AppCompatActivity() {
return@registerForActivityResult
}
runCatching {
- SshKey.import(uri)
- Toast.makeText(
- this,
- resources.getString(R.string.ssh_key_success_dialog_title),
- Toast.LENGTH_LONG
- )
- .show()
- setResult(RESULT_OK)
- finish()
- }
+ SshKey.import(uri)
+ Toast.makeText(
+ this,
+ resources.getString(R.string.ssh_key_success_dialog_title),
+ Toast.LENGTH_LONG
+ )
+ .show()
+ setResult(RESULT_OK)
+ finish()
+ }
.onFailure { e ->
MaterialAlertDialogBuilder(this)
.setTitle(resources.getString(R.string.ssh_key_error_dialog_title))
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillMatcher.kt b/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillMatcher.kt
index 206074fa..42c1d693 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillMatcher.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/autofill/AutofillMatcher.kt
@@ -107,11 +107,13 @@ class AutofillMatcher {
val matchedFiles =
matchPreferences.getStringSet(matchesKey(formOrigin), emptySet())!!.map { File(it) }
return Ok(
- matchedFiles.filter { it.exists() }.also { validFiles ->
- matchPreferences.edit {
- putStringSet(matchesKey(formOrigin), validFiles.map { it.absolutePath }.toSet())
+ matchedFiles
+ .filter { it.exists() }
+ .also { validFiles ->
+ matchPreferences.edit {
+ putStringSet(matchesKey(formOrigin), validFiles.map { it.absolutePath }.toSet())
+ }
}
- }
)
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/extensions/Extensions.kt b/app/src/main/java/dev/msfjarvis/aps/util/extensions/Extensions.kt
index 6e14a29d..8530a216 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/extensions/Extensions.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/extensions/Extensions.kt
@@ -34,9 +34,10 @@ fun File.contains(other: File): Boolean {
if (!isDirectory) return false
if (!other.exists()) return false
val relativePath =
- runCatching { other.relativeTo(this) }.getOrElse {
- return false
- }
+ runCatching { other.relativeTo(this) }
+ .getOrElse {
+ return false
+ }
// Direct containment is equivalent to the relative path being equal to the filename.
return relativePath.path == other.name
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt
index 115c2f9f..e6eb77f5 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/GitCommandExecutor.kt
@@ -51,76 +51,76 @@ class GitCommandExecutor(
// Count the number of uncommitted files
var nbChanges = 0
return runCatching {
- for (command in operation.commands) {
- when (command) {
- is StatusCommand -> {
- val res = withContext(Dispatchers.IO) { command.call() }
- nbChanges = res.uncommittedChanges.size
- }
- is CommitCommand -> {
- // the previous status will eventually be used to avoid a commit
- if (nbChanges > 0) {
- withContext(Dispatchers.IO) {
- val name = gitSettings.authorName.ifEmpty { "root" }
- val email = gitSettings.authorEmail.ifEmpty { "localhost" }
- val identity = PersonIdent(name, email)
- command.setAuthor(identity).setCommitter(identity).call()
- }
+ for (command in operation.commands) {
+ when (command) {
+ is StatusCommand -> {
+ val res = withContext(Dispatchers.IO) { command.call() }
+ nbChanges = res.uncommittedChanges.size
}
- }
- is PullCommand -> {
- val result = withContext(Dispatchers.IO) { command.call() }
- if (result.rebaseResult != null) {
- if (!result.rebaseResult.status.isSuccessful) {
- throw PullException.PullRebaseFailed
+ is CommitCommand -> {
+ // the previous status will eventually be used to avoid a commit
+ if (nbChanges > 0) {
+ withContext(Dispatchers.IO) {
+ val name = gitSettings.authorName.ifEmpty { "root" }
+ val email = gitSettings.authorEmail.ifEmpty { "localhost" }
+ val identity = PersonIdent(name, email)
+ command.setAuthor(identity).setCommitter(identity).call()
+ }
}
- } else if (result.mergeResult != null) {
- if (!result.mergeResult.mergeStatus.isSuccessful) {
- throw PullException.PullMergeFailed
+ }
+ is PullCommand -> {
+ val result = withContext(Dispatchers.IO) { command.call() }
+ if (result.rebaseResult != null) {
+ if (!result.rebaseResult.status.isSuccessful) {
+ throw PullException.PullRebaseFailed
+ }
+ } else if (result.mergeResult != null) {
+ if (!result.mergeResult.mergeStatus.isSuccessful) {
+ throw PullException.PullMergeFailed
+ }
}
}
- }
- is PushCommand -> {
- val results = withContext(Dispatchers.IO) { command.call() }
- for (result in results) {
- // Code imported (modified) from Gerrit PushOp, license Apache v2
- for (rru in result.remoteUpdates) {
- when (rru.status) {
- RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD ->
- throw PushException.NonFastForward
- RemoteRefUpdate.Status.REJECTED_NODELETE,
- RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED,
- RemoteRefUpdate.Status.NON_EXISTING,
- RemoteRefUpdate.Status.NOT_ATTEMPTED, ->
- throw PushException.Generic(rru.status.name)
- RemoteRefUpdate.Status.REJECTED_OTHER_REASON -> {
- throw if ("non-fast-forward" == rru.message) {
- PushException.RemoteRejected
- } else {
- PushException.Generic(rru.message)
+ is PushCommand -> {
+ val results = withContext(Dispatchers.IO) { command.call() }
+ for (result in results) {
+ // Code imported (modified) from Gerrit PushOp, license Apache v2
+ for (rru in result.remoteUpdates) {
+ when (rru.status) {
+ RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD ->
+ throw PushException.NonFastForward
+ RemoteRefUpdate.Status.REJECTED_NODELETE,
+ RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED,
+ RemoteRefUpdate.Status.NON_EXISTING,
+ RemoteRefUpdate.Status.NOT_ATTEMPTED, ->
+ throw PushException.Generic(rru.status.name)
+ RemoteRefUpdate.Status.REJECTED_OTHER_REASON -> {
+ throw if ("non-fast-forward" == rru.message) {
+ PushException.RemoteRejected
+ } else {
+ PushException.Generic(rru.message)
+ }
}
- }
- RemoteRefUpdate.Status.UP_TO_DATE -> {
- withContext(Dispatchers.Main) {
- Toast.makeText(
- activity.applicationContext,
- activity.applicationContext.getString(R.string.git_push_up_to_date),
- Toast.LENGTH_SHORT
- )
- .show()
+ RemoteRefUpdate.Status.UP_TO_DATE -> {
+ withContext(Dispatchers.Main) {
+ Toast.makeText(
+ activity.applicationContext,
+ activity.applicationContext.getString(R.string.git_push_up_to_date),
+ Toast.LENGTH_SHORT
+ )
+ .show()
+ }
}
+ else -> {}
}
- else -> {}
}
}
}
- }
- else -> {
- withContext(Dispatchers.IO) { command.call() }
+ else -> {
+ withContext(Dispatchers.IO) { command.call() }
+ }
}
}
}
- }
.also { snackbar.dismiss() }
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt
index 444a9fee..ed210a65 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/GitLogModel.kt
@@ -25,10 +25,11 @@ private fun commits(): Iterable<RevCommit> {
logcat(TAG, ERROR) { "Could not access git repository" }
return listOf()
}
- return runCatching { Git(repo).log().call() }.getOrElse { e ->
- logcat(TAG, ERROR) { e.asLog("Failed to obtain git commits") }
- listOf()
- }
+ return runCatching { Git(repo).log().call() }
+ .getOrElse { e ->
+ logcat(TAG, ERROR) { e.asLog("Failed to obtain git commits") }
+ listOf()
+ }
}
/**
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt
index f487b195..576a802d 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt
@@ -109,14 +109,14 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
private fun getSshKey(make: Boolean) {
runCatching {
- val intent =
- if (make) {
- Intent(callingActivity.applicationContext, SshKeyGenActivity::class.java)
- } else {
- Intent(callingActivity.applicationContext, SshKeyImportActivity::class.java)
- }
- callingActivity.startActivity(intent)
- }
+ val intent =
+ if (make) {
+ Intent(callingActivity.applicationContext, SshKeyGenActivity::class.java)
+ } else {
+ Intent(callingActivity.applicationContext, SshKeyImportActivity::class.java)
+ }
+ callingActivity.startActivity(intent)
+ }
.onFailure { e -> logcat(ERROR) { e.asLog() } }
}
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt
index f2db6067..d5aaff33 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshKey.kt
@@ -84,19 +84,19 @@ object SshKey {
val mustAuthenticate: Boolean
get() {
return runCatching {
- if (type !in listOf(Type.KeystoreNative, Type.KeystoreWrappedEd25519)) return false
- when (val key = androidKeystore.getKey(KEYSTORE_ALIAS, null)) {
- is PrivateKey -> {
- val factory = KeyFactory.getInstance(key.algorithm, PROVIDER_ANDROID_KEY_STORE)
- return factory.getKeySpec(key, KeyInfo::class.java).isUserAuthenticationRequired
+ if (type !in listOf(Type.KeystoreNative, Type.KeystoreWrappedEd25519)) return false
+ when (val key = androidKeystore.getKey(KEYSTORE_ALIAS, null)) {
+ is PrivateKey -> {
+ val factory = KeyFactory.getInstance(key.algorithm, PROVIDER_ANDROID_KEY_STORE)
+ return factory.getKeySpec(key, KeyInfo::class.java).isUserAuthenticationRequired
+ }
+ is SecretKey -> {
+ val factory = SecretKeyFactory.getInstance(key.algorithm, PROVIDER_ANDROID_KEY_STORE)
+ (factory.getKeySpec(key, KeyInfo::class.java) as KeyInfo).isUserAuthenticationRequired
+ }
+ else -> throw IllegalStateException("SSH key does not exist in Keystore")
}
- is SecretKey -> {
- val factory = SecretKeyFactory.getInstance(key.algorithm, PROVIDER_ANDROID_KEY_STORE)
- (factory.getKeySpec(key, KeyInfo::class.java) as KeyInfo).isUserAuthenticationRequired
- }
- else -> throw IllegalStateException("SSH key does not exist in Keystore")
}
- }
.getOrElse { error ->
// It is fine to swallow the exception here since it will reappear when the key
// is
@@ -316,19 +316,24 @@ object SshKey {
private object KeystoreNativeKeyProvider : KeyProvider {
override fun getPublic(): PublicKey =
- runCatching { androidKeystore.sshPublicKey!! }.getOrElse { error ->
- logcat { error.asLog() }
- throw IOException("Failed to get public key '$KEYSTORE_ALIAS' from Android Keystore", error)
- }
+ runCatching { androidKeystore.sshPublicKey!! }
+ .getOrElse { error ->
+ logcat { error.asLog() }
+ throw IOException(
+ "Failed to get public key '$KEYSTORE_ALIAS' from Android Keystore",
+ error
+ )
+ }
override fun getPrivate(): PrivateKey =
- runCatching { androidKeystore.sshPrivateKey!! }.getOrElse { error ->
- logcat { error.asLog() }
- throw IOException(
- "Failed to access private key '$KEYSTORE_ALIAS' from Android Keystore",
- error
- )
- }
+ runCatching { androidKeystore.sshPrivateKey!! }
+ .getOrElse { error ->
+ logcat { error.asLog() }
+ throw IOException(
+ "Failed to access private key '$KEYSTORE_ALIAS' from Android Keystore",
+ error
+ )
+ }
override fun getType(): KeyType = KeyType.fromKey(public)
}
@@ -336,22 +341,23 @@ object SshKey {
private object KeystoreWrappedEd25519KeyProvider : KeyProvider {
override fun getPublic(): PublicKey =
- runCatching { parseSshPublicKey(sshPublicKey!!)!! }.getOrElse { error ->
- logcat { error.asLog() }
- throw IOException("Failed to get the public key for wrapped ed25519 key", error)
- }
+ runCatching { parseSshPublicKey(sshPublicKey!!)!! }
+ .getOrElse { error ->
+ logcat { error.asLog() }
+ throw IOException("Failed to get the public key for wrapped ed25519 key", error)
+ }
override fun getPrivate(): PrivateKey =
runCatching {
- // The current MasterKey API does not allow getting a reference to an existing one
- // without specifying the KeySpec for a new one. However, the value for passed here
- // for `requireAuthentication` is not used as the key already exists at this point.
- val encryptedPrivateKeyFile = runBlocking { getOrCreateWrappedPrivateKeyFile(false) }
- val rawPrivateKey = encryptedPrivateKeyFile.openFileInput().use { it.readBytes() }
- EdDSAPrivateKey(
- EdDSAPrivateKeySpec(rawPrivateKey, EdDSANamedCurveTable.ED_25519_CURVE_SPEC)
- )
- }
+ // The current MasterKey API does not allow getting a reference to an existing one
+ // without specifying the KeySpec for a new one. However, the value for passed here
+ // for `requireAuthentication` is not used as the key already exists at this point.
+ val encryptedPrivateKeyFile = runBlocking { getOrCreateWrappedPrivateKeyFile(false) }
+ val rawPrivateKey = encryptedPrivateKeyFile.openFileInput().use { it.readBytes() }
+ EdDSAPrivateKey(
+ EdDSAPrivateKeySpec(rawPrivateKey, EdDSANamedCurveTable.ED_25519_CURVE_SPEC)
+ )
+ }
.getOrElse { error ->
logcat { error.asLog() }
throw IOException("Failed to unwrap wrapped ed25519 key", error)
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt
index 50c146cc..a9f84fa9 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/git/sshj/SshjSessionFactory.kt
@@ -93,9 +93,8 @@ private fun makeTofuHostKeyVerifier(hostKeyFile: File): HostKeyVerifier {
return object : HostKeyVerifier {
override fun verify(hostname: String?, port: Int, key: PublicKey?): Boolean {
val digest =
- runCatching { SecurityUtils.getMessageDigest("SHA-256") }.getOrElse { e ->
- throw SSHRuntimeException(e)
- }
+ runCatching { SecurityUtils.getMessageDigest("SHA-256") }
+ .getOrElse { e -> throw SSHRuntimeException(e) }
digest.update(PlainBuffer().putPublicKey(key).compactData)
val digestData = digest.digest()
val hostKeyEntry = "SHA256:${Base64.encodeToString(digestData, Base64.NO_WRAP)}"
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt b/app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt
index e6915853..8cbf84d9 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/settings/GitSettings.kt
@@ -140,9 +140,10 @@ constructor(
newBranch: String
): UpdateConnectionSettingsResult {
val parsedUrl =
- runCatching { URIish(newUrl) }.getOrElse {
- return UpdateConnectionSettingsResult.FailedToParseUrl
- }
+ runCatching { URIish(newUrl) }
+ .getOrElse {
+ return UpdateConnectionSettingsResult.FailedToParseUrl
+ }
val newProtocol =
when (parsedUrl.scheme) {
in listOf("http", "https") -> Protocol.Https
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt b/app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt
index 87cf33c6..5f3d04e3 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/viewmodel/SearchableRepositoryViewModel.kt
@@ -229,9 +229,8 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel
.filter { it.first > 0 }
.toList()
.sortedWith(
- compareByDescending<Pair<Int, PasswordItem>> { it.first }.thenBy(itemComparator) {
- it.second
- }
+ compareByDescending<Pair<Int, PasswordItem>> { it.first }
+ .thenBy(itemComparator) { it.second }
)
.map { it.second }
}
diff --git a/app/src/nonFree/java/dev/msfjarvis/aps/autofill/oreo/ui/AutofillSmsActivity.kt b/app/src/nonFree/java/dev/msfjarvis/aps/autofill/oreo/ui/AutofillSmsActivity.kt
index 4c751bb0..e6cc3920 100644
--- a/app/src/nonFree/java/dev/msfjarvis/aps/autofill/oreo/ui/AutofillSmsActivity.kt
+++ b/app/src/nonFree/java/dev/msfjarvis/aps/autofill/oreo/ui/AutofillSmsActivity.kt
@@ -130,8 +130,8 @@ class AutofillSmsActivity : AppCompatActivity() {
private suspend fun waitForSms() {
val smsClient = SmsCodeRetriever.getAutofillClient(this@AutofillSmsActivity)
runCatching {
- withContext(Dispatchers.IO) { smsClient.startSmsCodeRetriever().suspendableAwait() }
- }
+ withContext(Dispatchers.IO) { smsClient.startSmsCodeRetriever().suspendableAwait() }
+ }
.onFailure { e ->
if (e is ResolvableApiException) {
e.startResolutionForResult(this@AutofillSmsActivity, 1)
diff --git a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategyDsl.kt b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategyDsl.kt
index 9348fab8..35006468 100644
--- a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategyDsl.kt
+++ b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategyDsl.kt
@@ -105,31 +105,34 @@ internal class SingleFieldMatcher(
}
override fun match(fields: List<FormField>, alreadyMatched: List<FormField>): List<FormField>? {
- return fields.minus(alreadyMatched).filter { take(it, alreadyMatched) }.let { contestants ->
- when (contestants.size) {
- 1 -> return@let listOf(contestants.single())
- 0 -> return@let null
- }
- var current = contestants
- for ((i, tieBreaker) in tieBreakers.withIndex()) {
- // Successively filter matched fields via tie breakers...
- val new = current.filter { tieBreaker(it, alreadyMatched) }
- // skipping those tie breakers that are not satisfied for any remaining field...
- if (new.isEmpty()) {
- logcat { "Tie breaker #${i + 1}: Didn't match any field; skipping" }
- continue
+ return fields
+ .minus(alreadyMatched)
+ .filter { take(it, alreadyMatched) }
+ .let { contestants ->
+ when (contestants.size) {
+ 1 -> return@let listOf(contestants.single())
+ 0 -> return@let null
}
- // and return if the available options have been narrowed to a single field.
- if (new.size == 1) {
- logcat { "Tie breaker #${i + 1}: Success" }
+ var current = contestants
+ for ((i, tieBreaker) in tieBreakers.withIndex()) {
+ // Successively filter matched fields via tie breakers...
+ val new = current.filter { tieBreaker(it, alreadyMatched) }
+ // skipping those tie breakers that are not satisfied for any remaining field...
+ if (new.isEmpty()) {
+ logcat { "Tie breaker #${i + 1}: Didn't match any field; skipping" }
+ continue
+ }
+ // and return if the available options have been narrowed to a single field.
+ if (new.size == 1) {
+ logcat { "Tie breaker #${i + 1}: Success" }
+ current = new
+ break
+ }
+ logcat { "Tie breaker #${i + 1}: Matched ${new.size} fields; continuing" }
current = new
- break
}
- logcat { "Tie breaker #${i + 1}: Matched ${new.size} fields; continuing" }
- current = new
+ listOf(current.singleOrNull() ?: return null)
}
- listOf(current.singleOrNull() ?: return null)
- }
}
}
diff --git a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FeatureAndTrustDetection.kt b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FeatureAndTrustDetection.kt
index 849113cf..2556a2f6 100644
--- a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FeatureAndTrustDetection.kt
+++ b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FeatureAndTrustDetection.kt
@@ -251,8 +251,7 @@ public fun getInstalledBrowsersWithAutofillSupportLevel(
.map { it to getBrowserAutofillSupportLevel(context, it.activityInfo.packageName) }
.filter { it.first.isDefault || it.second != BrowserAutofillSupportLevel.None }
.map {
- context
- .packageManager
+ context.packageManager
.getApplicationLabel(it.first.activityInfo.applicationInfo)
.toString() to it.second
}
diff --git a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FormField.kt b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FormField.kt
index 30d80d1d..96813be5 100644
--- a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FormField.kt
+++ b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FormField.kt
@@ -182,9 +182,10 @@ internal class FormField(
// Basic type detection for HTML fields
private val htmlTag = node.htmlInfo?.tag
private val htmlAttributes: Map<String, String> =
- node.htmlInfo?.attributes?.filter { it.first != null && it.second != null }?.associate {
- Pair(it.first.lowercase(Locale.US), it.second.lowercase(Locale.US))
- }
+ node.htmlInfo
+ ?.attributes
+ ?.filter { it.first != null && it.second != null }
+ ?.associate { Pair(it.first.lowercase(Locale.US), it.second.lowercase(Locale.US)) }
?: emptyMap()
private val htmlAttributesDebug = htmlAttributes.entries.joinToString { "${it.key}=${it.value}" }
private val htmlInputType = htmlAttributes["type"]
diff --git a/build-logic/kotlin-plugins/src/main/kotlin/com.github.android-password-store.kotlin-kapt.gradle.kts b/build-logic/kotlin-plugins/src/main/kotlin/com.github.android-password-store.kotlin-kapt.gradle.kts
index 14542655..ac0f5337 100644
--- a/build-logic/kotlin-plugins/src/main/kotlin/com.github.android-password-store.kotlin-kapt.gradle.kts
+++ b/build-logic/kotlin-plugins/src/main/kotlin/com.github.android-password-store.kotlin-kapt.gradle.kts
@@ -32,9 +32,9 @@ afterEvaluate {
}
}
// disable kapt tasks for unit tests
-tasks.matching { it.name.startsWith("kapt") && it.name.endsWith("UnitTestKotlin") }.configureEach {
- enabled = false
-}
+tasks
+ .matching { it.name.startsWith("kapt") && it.name.endsWith("UnitTestKotlin") }
+ .configureEach { enabled = false }
fun Project.hasDaggerCompilerDependency(): Boolean {
return configurations.any {
diff --git a/crypto-pgpainless/src/main/kotlin/dev/msfjarvis/aps/crypto/PGPKeyManager.kt b/crypto-pgpainless/src/main/kotlin/dev/msfjarvis/aps/crypto/PGPKeyManager.kt
index 3cc68ab3..137bd141 100644
--- a/crypto-pgpainless/src/main/kotlin/dev/msfjarvis/aps/crypto/PGPKeyManager.kt
+++ b/crypto-pgpainless/src/main/kotlin/dev/msfjarvis/aps/crypto/PGPKeyManager.kt
@@ -79,17 +79,17 @@ constructor(
when (id) {
is GpgIdentifier.KeyId -> {
val keyIdMatch =
- keys.map { key -> key to tryGetId(key) }.firstOrNull { (_, keyId) ->
- keyId?.id == id.id
- }
+ keys
+ .map { key -> key to tryGetId(key) }
+ .firstOrNull { (_, keyId) -> keyId?.id == id.id }
keyIdMatch?.first
}
is GpgIdentifier.UserId -> {
val selector = SelectUserId.byEmail(id.email)
val userIdMatch =
- keys.map { key -> key to tryParseKeyring(key) }.firstOrNull { (_, keyRing) ->
- selector.firstMatch(keyRing) != null
- }
+ keys
+ .map { key -> key to tryParseKeyring(key) }
+ .firstOrNull { (_, keyRing) -> selector.firstMatch(keyRing) != null }
userIdMatch?.first
}
}