Add autofill privacy settings controls
This commit is contained in:
+190
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"image"
|
||||
"io"
|
||||
@@ -3558,6 +3559,118 @@ func TestUIDenseLayoutPreferencePersists(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUISyncDefaultsPersistInSettings(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
configPath := filepath.Join(t.TempDir(), "settings.json")
|
||||
|
||||
first := newUIWithSession("desktop", &session.Manager{})
|
||||
first.settingsPath = configPath
|
||||
first.syncDefaultSourceMode = syncSourceRemote
|
||||
first.syncDefaultDirection = syncDirectionPush
|
||||
first.saveSettings()
|
||||
|
||||
second := newUIWithSession("desktop", &session.Manager{})
|
||||
second.settingsPath = configPath
|
||||
second.syncDefaultSourceMode = syncSourceLocal
|
||||
second.syncDefaultDirection = syncDirectionPull
|
||||
second.loadSettings()
|
||||
|
||||
if got := second.syncDefaultSourceMode; got != syncSourceRemote {
|
||||
t.Fatalf("syncDefaultSourceMode = %q, want remote", got)
|
||||
}
|
||||
if got := second.syncDefaultDirection; got != syncDirectionPush {
|
||||
t.Fatalf("syncDefaultDirection = %q, want push", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUILoadSettingsFallsBackToLegacySyncDefaultsInUIPreferences(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dir := t.TempDir()
|
||||
legacyPath := filepath.Join(dir, "ui-prefs.json")
|
||||
content, err := json.MarshalIndent(uiPreferences{
|
||||
SyncSourceDefault: string(syncSourceRemote),
|
||||
SyncDirectionDefault: string(syncDirectionPush),
|
||||
}, "", " ")
|
||||
if err != nil {
|
||||
t.Fatalf("json.MarshalIndent() error = %v", err)
|
||||
}
|
||||
if err := os.WriteFile(legacyPath, content, 0o600); err != nil {
|
||||
t.Fatalf("os.WriteFile() error = %v", err)
|
||||
}
|
||||
|
||||
reloaded := newUIWithSession("desktop", &session.Manager{})
|
||||
reloaded.uiPreferencesPath = legacyPath
|
||||
reloaded.settingsPath = filepath.Join(dir, "settings.json")
|
||||
reloaded.syncDefaultSourceMode = syncSourceLocal
|
||||
reloaded.syncDefaultDirection = syncDirectionPull
|
||||
reloaded.loadSettings()
|
||||
|
||||
if got := reloaded.syncDefaultSourceMode; got != syncSourceRemote {
|
||||
t.Fatalf("syncDefaultSourceMode = %q after legacy load, want remote", got)
|
||||
}
|
||||
if got := reloaded.syncDefaultDirection; got != syncDirectionPush {
|
||||
t.Fatalf("syncDefaultDirection = %q after legacy load, want push", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUIOpenAdvancedSyncDialogUsesSavedSyncDefaults(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
u := newUIWithSession("desktop", &session.Manager{})
|
||||
u.syncDefaultSourceMode = syncSourceRemote
|
||||
u.syncDefaultDirection = syncDirectionPush
|
||||
u.syncSourceMode = syncSourceLocal
|
||||
u.syncDirection = syncDirectionPull
|
||||
u.vaultPath.SetText("/vaults/current.kdbx")
|
||||
|
||||
u.openAdvancedSyncDialog()
|
||||
|
||||
if got := u.syncSourceMode; got != syncSourceRemote {
|
||||
t.Fatalf("syncSourceMode = %q after open, want remote default", got)
|
||||
}
|
||||
if got := u.syncDirection; got != syncDirectionPush {
|
||||
t.Fatalf("syncDirection = %q after open, want push default", got)
|
||||
}
|
||||
if got := u.syncLocalPath.Text(); got != "/vaults/current.kdbx" {
|
||||
t.Fatalf("syncLocalPath = %q after open, want current vault path", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUISaveSecuritySettingsPersistsSyncDefaults(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
manager := &session.Manager{}
|
||||
u := newUIWithSession("desktop", manager)
|
||||
u.masterPassword.SetText("correct horse battery staple")
|
||||
if err := u.createVaultAction(); err != nil {
|
||||
t.Fatalf("createVaultAction() error = %v", err)
|
||||
}
|
||||
u.securityCipher.SetText(vault.CipherAES256)
|
||||
u.securityKDF.SetText(vault.KDFAES)
|
||||
u.loadSettingsDraft()
|
||||
u.settingsDraft.Sync.SourceDefault = syncSourceRemote
|
||||
u.settingsDraft.Sync.DirectionDefault = syncDirectionPush
|
||||
u.settingsPath = filepath.Join(t.TempDir(), "settings.json")
|
||||
u.uiPreferencesPath = filepath.Join(t.TempDir(), "ui-prefs.json")
|
||||
|
||||
if err := u.saveSecuritySettingsAction(); err != nil {
|
||||
t.Fatalf("saveSecuritySettingsAction() error = %v", err)
|
||||
}
|
||||
|
||||
reloaded := newUIWithSession("desktop", &session.Manager{})
|
||||
reloaded.settingsPath = u.settingsPath
|
||||
reloaded.loadSettings()
|
||||
|
||||
if got := reloaded.syncDefaultSourceMode; got != syncSourceRemote {
|
||||
t.Fatalf("reloaded syncDefaultSourceMode = %q, want remote", got)
|
||||
}
|
||||
if got := reloaded.syncDefaultDirection; got != syncDirectionPush {
|
||||
t.Fatalf("reloaded syncDefaultDirection = %q, want push", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUIAccessibilityPreferencesPersist(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -3657,6 +3770,83 @@ func TestUINotificationPreferencesPersist(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAutofillPrivacyLinesNormalizesEntries(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := autofillPrivacyLines(" com.android.chrome \n\ncom.example.app\ncom.android.chrome\n org.keepassgo.browser ")
|
||||
want := []string{"com.android.chrome", "com.example.app", "org.keepassgo.browser"}
|
||||
if !slices.Equal(got, want) {
|
||||
t.Fatalf("autofillPrivacyLines() = %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJoinAutofillPrivacyLines(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := joinAutofillPrivacyLines([]string{"com.android.chrome", "com.example.app"})
|
||||
if got != "com.android.chrome\ncom.example.app" {
|
||||
t.Fatalf("joinAutofillPrivacyLines() = %q, want %q", got, "com.android.chrome\ncom.example.app")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUIAutofillPrivacyPreferencesPersist(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
configPath := filepath.Join(t.TempDir(), "ui-prefs.json")
|
||||
|
||||
first := newUIWithSession("desktop", &session.Manager{})
|
||||
first.uiPreferencesPath = configPath
|
||||
first.autofillFirstFillApprovalMode = autofillFirstFillApprovalBlock
|
||||
first.autofillBrowserAllowlist.SetText("https://accounts.example.com\nhttps://login.example.org\nhttps://accounts.example.com")
|
||||
first.autofillAppAllowlist.SetText("org.mozilla.firefox\ncom.android.chrome")
|
||||
first.autofillPackageRules.SetText("com.android.chrome=hostname\norg.keepassgo.browser=view-id")
|
||||
first.saveUIPreferences()
|
||||
|
||||
second := newUIWithSession("desktop", &session.Manager{})
|
||||
second.uiPreferencesPath = configPath
|
||||
second.autofillFirstFillApprovalMode = autofillFirstFillApprovalAsk
|
||||
second.loadUIPreferences()
|
||||
|
||||
if got := second.autofillFirstFillApprovalMode; got != autofillFirstFillApprovalBlock {
|
||||
t.Fatalf("autofillFirstFillApprovalMode = %q, want %q", got, autofillFirstFillApprovalBlock)
|
||||
}
|
||||
if got := second.autofillBrowserAllowlist.Text(); got != "https://accounts.example.com\nhttps://login.example.org" {
|
||||
t.Fatalf("autofillBrowserAllowlist = %q, want normalized browser allowlist", got)
|
||||
}
|
||||
if got := second.autofillAppAllowlist.Text(); got != "org.mozilla.firefox\ncom.android.chrome" {
|
||||
t.Fatalf("autofillAppAllowlist = %q, want preserved allowlist entries", got)
|
||||
}
|
||||
if got := second.autofillPackageRules.Text(); got != "com.android.chrome=hostname\norg.keepassgo.browser=view-id" {
|
||||
t.Fatalf("autofillPackageRules = %q, want persisted package rules", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUILoadUIPreferencesKeepsDefaultAutofillApprovalWhenMissing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
configPath := filepath.Join(t.TempDir(), "ui-prefs.json")
|
||||
content, err := json.Marshal(uiPreferences{
|
||||
GroupControlsHidden: true,
|
||||
LifecycleAdvancedHidden: true,
|
||||
HistoryHidden: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal(uiPreferences) error = %v", err)
|
||||
}
|
||||
if err := os.WriteFile(configPath, content, 0o600); err != nil {
|
||||
t.Fatalf("WriteFile(uiPreferences) error = %v", err)
|
||||
}
|
||||
|
||||
u := newUIWithSession("desktop", &session.Manager{})
|
||||
u.uiPreferencesPath = configPath
|
||||
u.autofillFirstFillApprovalMode = autofillFirstFillApprovalAsk
|
||||
u.loadUIPreferences()
|
||||
|
||||
if got := u.autofillFirstFillApprovalMode; got != autofillFirstFillApprovalAsk {
|
||||
t.Fatalf("autofillFirstFillApprovalMode = %q, want %q when preference missing", got, autofillFirstFillApprovalAsk)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectingRecentRemoteConnectionKeepsPasswordMasked(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user