Reset password peek across view changes
This commit is contained in:
@@ -386,20 +386,27 @@ func (u *ui) selectedAttachmentNames() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) showEntriesSection() {
|
func (u *ui) showEntriesSection() {
|
||||||
|
u.resetPasswordPeek()
|
||||||
u.state.ShowSection(appstate.SectionEntries)
|
u.state.ShowSection(appstate.SectionEntries)
|
||||||
u.filter()
|
u.filter()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) showTemplatesSection() {
|
func (u *ui) showTemplatesSection() {
|
||||||
|
u.resetPasswordPeek()
|
||||||
u.state.ShowSection(appstate.SectionTemplates)
|
u.state.ShowSection(appstate.SectionTemplates)
|
||||||
u.filter()
|
u.filter()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) showRecycleBinSection() {
|
func (u *ui) showRecycleBinSection() {
|
||||||
|
u.resetPasswordPeek()
|
||||||
u.state.ShowSection(appstate.SectionRecycleBin)
|
u.state.ShowSection(appstate.SectionRecycleBin)
|
||||||
u.filter()
|
u.filter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *ui) resetPasswordPeek() {
|
||||||
|
u.showPassword = false
|
||||||
|
}
|
||||||
|
|
||||||
func (u *ui) childGroups() []string {
|
func (u *ui) childGroups() []string {
|
||||||
u.state.SetSearchQuery(u.search.Text())
|
u.state.SetSearchQuery(u.search.Text())
|
||||||
groups, err := u.state.ChildGroups()
|
groups, err := u.state.ChildGroups()
|
||||||
@@ -506,6 +513,7 @@ func (u *ui) createVaultAction() error {
|
|||||||
u.vaultPath.SetText(u.saveAsTargetPath())
|
u.vaultPath.SetText(u.saveAsTargetPath())
|
||||||
u.noteRecentVault(u.saveAsTargetPath())
|
u.noteRecentVault(u.saveAsTargetPath())
|
||||||
}
|
}
|
||||||
|
u.resetPasswordPeek()
|
||||||
u.currentPath = append([]string(nil), u.state.CurrentPath...)
|
u.currentPath = append([]string(nil), u.state.CurrentPath...)
|
||||||
u.editingEntry = false
|
u.editingEntry = false
|
||||||
u.filter()
|
u.filter()
|
||||||
@@ -526,6 +534,7 @@ func (u *ui) openVaultAction() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
u.noteRecentVault(path)
|
u.noteRecentVault(path)
|
||||||
|
u.resetPasswordPeek()
|
||||||
u.currentPath = append([]string(nil), u.state.CurrentPath...)
|
u.currentPath = append([]string(nil), u.state.CurrentPath...)
|
||||||
u.restoreRecentVaultGroup(path)
|
u.restoreRecentVaultGroup(path)
|
||||||
u.editingEntry = false
|
u.editingEntry = false
|
||||||
@@ -573,6 +582,7 @@ func (u *ui) openRemoteAction() error {
|
|||||||
u.remotePassword.Text(),
|
u.remotePassword.Text(),
|
||||||
u.rememberRemoteAuth.Value,
|
u.rememberRemoteAuth.Value,
|
||||||
)
|
)
|
||||||
|
u.resetPasswordPeek()
|
||||||
u.enterHiddenVaultRoot()
|
u.enterHiddenVaultRoot()
|
||||||
u.editingEntry = false
|
u.editingEntry = false
|
||||||
u.filter()
|
u.filter()
|
||||||
@@ -585,7 +595,7 @@ func (u *ui) lockAction() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
u.currentPath = append([]string(nil), u.state.CurrentPath...)
|
u.currentPath = append([]string(nil), u.state.CurrentPath...)
|
||||||
u.showPassword = false
|
u.resetPasswordPeek()
|
||||||
u.editingEntry = false
|
u.editingEntry = false
|
||||||
u.filter()
|
u.filter()
|
||||||
return nil
|
return nil
|
||||||
@@ -600,6 +610,7 @@ func (u *ui) unlockAction() error {
|
|||||||
if err := u.state.Unlock(key); err != nil {
|
if err := u.state.Unlock(key); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
u.resetPasswordPeek()
|
||||||
u.currentPath = append([]string(nil), u.state.CurrentPath...)
|
u.currentPath = append([]string(nil), u.state.CurrentPath...)
|
||||||
u.editingEntry = false
|
u.editingEntry = false
|
||||||
u.filter()
|
u.filter()
|
||||||
|
|||||||
@@ -2097,6 +2097,60 @@ func TestEnterOnRemoteLifecycleScreenDefaultsToOpenRemoteVault(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMasterPasswordPeekResetsAfterOpeningVault(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
path := filepath.Join(t.TempDir(), "vault.kdbx")
|
||||||
|
var encoded bytes.Buffer
|
||||||
|
if err := vault.SaveKDBX(&encoded, vault.Model{
|
||||||
|
Entries: []vault.Entry{
|
||||||
|
{ID: "git-server", Title: "Git Server", Password: "token-1", Path: []string{"Root", "Internet"}},
|
||||||
|
},
|
||||||
|
}, "correct horse battery staple"); err != nil {
|
||||||
|
t.Fatalf("SaveKDBX() error = %v", err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile(path, encoded.Bytes(), 0o600); err != nil {
|
||||||
|
t.Fatalf("WriteFile(vault.kdbx) error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
u := newUIWithSession("desktop", &session.Manager{})
|
||||||
|
u.masterPassword.SetText("correct horse battery staple")
|
||||||
|
u.vaultPath.SetText(path)
|
||||||
|
u.showPassword = true
|
||||||
|
|
||||||
|
if err := u.openVaultAction(); err != nil {
|
||||||
|
t.Fatalf("openVaultAction() error = %v", err)
|
||||||
|
}
|
||||||
|
if u.showPassword {
|
||||||
|
t.Fatal("showPassword = true after openVaultAction(), want false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPasswordPeekResetsWhenChangingSelectedEntry(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
u := newUIWithModel("desktop", vault.Model{
|
||||||
|
Entries: []vault.Entry{
|
||||||
|
{ID: "git-server", Title: "Git Server", Password: "token-1", Path: []string{"Root", "Internet"}},
|
||||||
|
{ID: "dynadot", Title: "Dynadot", Password: "token-2", Path: []string{"Root", "Internet"}},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
u.showEntriesSection()
|
||||||
|
u.state.NavigateToPath([]string{"Root", "Internet"})
|
||||||
|
u.filter()
|
||||||
|
|
||||||
|
u.state.SelectedEntryID = "git-server"
|
||||||
|
u.loadSelectedEntryIntoEditor()
|
||||||
|
u.showPassword = true
|
||||||
|
|
||||||
|
u.state.SelectedEntryID = "dynadot"
|
||||||
|
u.loadSelectedEntryIntoEditor()
|
||||||
|
|
||||||
|
if u.showPassword {
|
||||||
|
t.Fatal("showPassword = true after selecting a different entry, want false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestEnterOnLockedScreenDefaultsToUnlockVault(t *testing.T) {
|
func TestEnterOnLockedScreenDefaultsToUnlockVault(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ func (u *ui) attachmentInput() (string, []byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) loadSelectedEntryIntoEditor() {
|
func (u *ui) loadSelectedEntryIntoEditor() {
|
||||||
|
u.resetPasswordPeek()
|
||||||
u.selectedHistoryIndex = -1
|
u.selectedHistoryIndex = -1
|
||||||
u.historyIndex.SetText("")
|
u.historyIndex.SetText("")
|
||||||
|
|
||||||
|
|||||||
+8
-4
@@ -26,7 +26,9 @@ func (u *ui) lifecycleControls(gtx layout.Context) layout.Dimensions {
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
||||||
layout.Rigid(labeledEditorHelp(u.theme, "Master Password", "Leave blank if this vault is protected by key file only.", &u.masterPassword, true)),
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.masterPasswordField(gtx, "Leave blank if this vault is protected by key file only.")
|
||||||
|
}),
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
||||||
layout.Rigid(selectorEditorHelp(u.theme, "Key File", "Optional path to a KeePass-compatible key file.", &u.keyFilePath, &u.pickKeyFile, "Choose File", false)),
|
layout.Rigid(selectorEditorHelp(u.theme, "Key File", "Optional path to a KeePass-compatible key file.", &u.keyFilePath, &u.pickKeyFile, "Choose File", false)),
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
||||||
@@ -490,7 +492,9 @@ func selectorEditorHelp(th *material.Theme, label, help string, editor *widget.E
|
|||||||
|
|
||||||
func (u *ui) unlockPanel(gtx layout.Context) layout.Dimensions {
|
func (u *ui) unlockPanel(gtx layout.Context) layout.Dimensions {
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
layout.Rigid(u.unlockPasswordField),
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.masterPasswordField(gtx, "Used alone or together with a key file to unlock the vault.")
|
||||||
|
}),
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
||||||
layout.Rigid(selectorEditorHelp(u.theme, "Key File", "Optional path to a KeePass-compatible key file.", &u.keyFilePath, &u.pickKeyFile, "Choose File", false)),
|
layout.Rigid(selectorEditorHelp(u.theme, "Key File", "Optional path to a KeePass-compatible key file.", &u.keyFilePath, &u.pickKeyFile, "Choose File", false)),
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
||||||
@@ -500,7 +504,7 @@ func (u *ui) unlockPanel(gtx layout.Context) layout.Dimensions {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) unlockPasswordField(gtx layout.Context) layout.Dimensions {
|
func (u *ui) masterPasswordField(gtx layout.Context, help string) layout.Dimensions {
|
||||||
icon := u.eyeIcon
|
icon := u.eyeIcon
|
||||||
desc := "Show master password"
|
desc := "Show master password"
|
||||||
mask := rune('•')
|
mask := rune('•')
|
||||||
@@ -542,7 +546,7 @@ func (u *ui) unlockPasswordField(gtx layout.Context) layout.Dimensions {
|
|||||||
}),
|
}),
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(2)}.Layout),
|
layout.Rigid(layout.Spacer{Height: unit.Dp(2)}.Layout),
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
lbl := material.Label(u.theme, unit.Sp(11), "Used alone or together with a key file to unlock the vault.")
|
lbl := material.Label(u.theme, unit.Sp(11), help)
|
||||||
lbl.Color = mutedColor
|
lbl.Color = mutedColor
|
||||||
return lbl.Layout(gtx)
|
return lbl.Layout(gtx)
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user