diff --git a/app/src/main/java/app/passwordstore/ui/autofill/AutofillSaveActivity.kt b/app/src/main/java/app/passwordstore/ui/autofill/AutofillSaveActivity.kt
index 138c4a737c..176f148e0c 100644
--- a/app/src/main/java/app/passwordstore/ui/autofill/AutofillSaveActivity.kt
+++ b/app/src/main/java/app/passwordstore/ui/autofill/AutofillSaveActivity.kt
@@ -128,6 +128,7 @@ class AutofillSaveActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val repo = PasswordRepository.getRepositoryDirectory()
+ val saveRoot = AutofillPreferences.saveDirectory(this)
val saveIntent =
Intent(this, PasswordCreationActivity::class.java).apply {
putExtras(
@@ -136,7 +137,7 @@ class AutofillSaveActivity : AppCompatActivity() {
putString(BasePGPActivity.EXTRA_REPO_PATH, repo.absolutePath)
putString(
BasePGPActivity.EXTRA_FILE_PATH,
- repo
+ saveRoot
.resolve(intent.getStringExtra(EXTRA_FOLDER_NAME) ?: throw NullPointerException())
.absolutePath,
)
diff --git a/app/src/main/java/app/passwordstore/ui/settings/AutofillSettings.kt b/app/src/main/java/app/passwordstore/ui/settings/AutofillSettings.kt
index ce009a1071..684a09cc11 100644
--- a/app/src/main/java/app/passwordstore/ui/settings/AutofillSettings.kt
+++ b/app/src/main/java/app/passwordstore/ui/settings/AutofillSettings.kt
@@ -109,6 +109,18 @@ class AutofillSettings(private val activity: FragmentActivity) : SettingsProvide
summaryProvider = { activity.getString(R.string.preference_custom_public_suffixes_summary) }
textInputHintRes = R.string.preference_custom_public_suffixes_hint
}
+ editText(PreferenceKeys.AUTOFILL_SAVE_DIRECTORY) {
+ dependency = PreferenceKeys.AUTOFILL_ENABLE
+ titleRes = R.string.preference_autofill_save_directory_title
+ summaryProvider = { value ->
+ activity.getString(
+ R.string.preference_autofill_save_directory_summary,
+ value?.takeUnless { it.isBlank() }
+ ?: activity.getString(R.string.preference_autofill_save_directory_root_placeholder),
+ )
+ }
+ textInputHintRes = R.string.preference_autofill_save_directory_hint
+ }
}
}
}
diff --git a/app/src/main/java/app/passwordstore/util/autofill/AutofillPreferences.kt b/app/src/main/java/app/passwordstore/util/autofill/AutofillPreferences.kt
index f9298b2c11..2b7d03708b 100644
--- a/app/src/main/java/app/passwordstore/util/autofill/AutofillPreferences.kt
+++ b/app/src/main/java/app/passwordstore/util/autofill/AutofillPreferences.kt
@@ -7,6 +7,7 @@ package app.passwordstore.util.autofill
import android.content.Context
import androidx.core.content.edit
import app.passwordstore.data.passfile.PasswordEntry
+import app.passwordstore.data.repo.PasswordRepository
import app.passwordstore.util.extensions.getString
import app.passwordstore.util.extensions.sharedPrefs
import app.passwordstore.util.services.getDefaultUsername
@@ -22,6 +23,25 @@ object AutofillPreferences {
return DirectoryStructure.fromValue(value)
}
+ /**
+ * The directory Autofill-saved credentials should be placed under, relative to the repository
+ * root. Backed by [PreferenceKeys.AUTOFILL_SAVE_DIRECTORY]; falls back to the repository root
+ * itself when unset. This only affects saves made through the Autofill framework (the system
+ * "Save to Password Store?" prompt) — it has no effect on entries created from within the app.
+ */
+ fun saveDirectory(context: Context): File {
+ val root = PasswordRepository.getRepositoryDirectory()
+ // Drop empty and ".." segments to prevent escaping the repository root.
+ val configured =
+ context.sharedPrefs
+ .getString(PreferenceKeys.AUTOFILL_SAVE_DIRECTORY)
+ ?.split('/')
+ ?.filter { it.isNotBlank() && it != ".." }
+ ?.joinToString("/")
+ ?.takeUnless { it.isBlank() }
+ return if (configured == null) root else root.resolve(configured)
+ }
+
fun strictDomainSearch(context: Context): Boolean {
return context.sharedPrefs.getBoolean(PreferenceKeys.STRICT_DOMAIN_SEARCH, true)
}
diff --git a/app/src/main/java/app/passwordstore/util/settings/PreferenceKeys.kt b/app/src/main/java/app/passwordstore/util/settings/PreferenceKeys.kt
index c090b7cc0f..5261d0c57f 100644
--- a/app/src/main/java/app/passwordstore/util/settings/PreferenceKeys.kt
+++ b/app/src/main/java/app/passwordstore/util/settings/PreferenceKeys.kt
@@ -58,6 +58,7 @@ object PreferenceKeys {
const val OREO_AUTOFILL_CUSTOM_PUBLIC_SUFFIXES = "oreo_autofill_custom_public_suffixes"
const val OREO_AUTOFILL_DEFAULT_USERNAME = "oreo_autofill_default_username"
const val DIRECTORY_STRUCTURE = "oreo_autofill_directory_structure"
+ const val AUTOFILL_SAVE_DIRECTORY = "oreo_autofill_save_directory"
const val STRICT_DOMAIN_SEARCH = "oreo_autofill_strict_domain_search"
const val PREF_KEY_PWGEN_TYPE = "pref_key_pwgen_type"
const val REPOSITORY_INITIALIZED = "repository_initialized"
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index cb18607fe7..88d50e883b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -330,6 +330,10 @@
Custom domains
Autofill will distinguish subdomains of these domains.
company.com\npersonal.com
+ Save directory
+ Credentials saved via Autofill are placed under this folder instead of the store root. Currently: %1$s
+ e.g. www
+ store root
Password item edited