From 59cb9ac0d18defa201713f91f033702339ff45e6 Mon Sep 17 00:00:00 2001 From: Randall Winkhart Date: Sat, 31 May 2025 23:29:12 -0400 Subject: [PATCH] Support libmutton's EntryRefresh() feature --- go.mod | 2 +- go.sum | 4 ++-- mutn.go | 38 +++++++++++++++++++++++++++----------- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 57413ba..6e0d5a8 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/Trojan2021/BEAN v0.0.0-20241210230804-8f294833b514 github.com/charmbracelet/glamour v0.7.0 github.com/rwinkhart/go-boilerplate v0.0.0-20250529185306-e2e64d7fa43b - github.com/rwinkhart/libmutton v0.3.2-0.20250531214811-ca277ba7735d + github.com/rwinkhart/libmutton v0.3.2-0.20250601004130-4dab9f2c93e5 golang.org/x/term v0.32.0 ) diff --git a/go.sum b/go.sum index a22841d..4e588de 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,8 @@ github.com/rwinkhart/go-boilerplate v0.0.0-20250529185306-e2e64d7fa43b h1:ENgsUl github.com/rwinkhart/go-boilerplate v0.0.0-20250529185306-e2e64d7fa43b/go.mod h1:cnzIF45I0FCOvE4YIB+26pLCUx2kWyY2llKYZruNaRY= github.com/rwinkhart/go-winio-easy-pipe-handles v0.0.0-20250407031321-96994a0e8410 h1:NhHwFM3Pgm6zRUfFKvi0p5ndjfFbVWsRwmmhyFlG4PE= github.com/rwinkhart/go-winio-easy-pipe-handles v0.0.0-20250407031321-96994a0e8410/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/rwinkhart/libmutton v0.3.2-0.20250531214811-ca277ba7735d h1:3CdwTMhr7wNn8qmHyyMsT/jPEAB1ebCd4OX58oHrmtA= -github.com/rwinkhart/libmutton v0.3.2-0.20250531214811-ca277ba7735d/go.mod h1:uIz4AJcXW7ZHvvoPlLNWQofTBIbFa1UJ2JI6O+FSQ60= +github.com/rwinkhart/libmutton v0.3.2-0.20250601004130-4dab9f2c93e5 h1:ofZcQ4Pns5PsJY4ksejkt92ldDyDZ+FPhXMoRHehw4I= +github.com/rwinkhart/libmutton v0.3.2-0.20250601004130-4dab9f2c93e5/go.mod h1:uIz4AJcXW7ZHvvoPlLNWQofTBIbFa1UJ2JI6O+FSQ60= github.com/rwinkhart/peercred-mini v0.1.0 h1:TiS6u8cEWzW55S9X4iVpU72Iuy/NG6rMUJMtUEVEFLw= github.com/rwinkhart/peercred-mini v0.1.0/go.mod h1:+x4Mxc2veE+YePSOpcUasjimh7n799c1KraLuQwHR20= github.com/rwinkhart/rcw v0.2.0 h1:/rFgJ+20OSThipKAX5KPwW2xbPpgh1zl49THmEkkPis= diff --git a/mutn.go b/mutn.go index 22615b6..139ef90 100644 --- a/mutn.go +++ b/mutn.go @@ -188,23 +188,25 @@ func main() { back.PrintError("Failed to sync entries: "+err.Error(), global.ErrorSyncProcess, true) } case "init": - var rcwPass []byte - for { // get master passphrase - rcwPass = front.InputHidden("Master passphrase:") - if !bytes.Equal(rcwPass, front.InputHidden("Confirm master passphrase:")) || len(rcwPass) == 0 { - fmt.Println(back.AnsiError + "Passphrases do not match" + back.AnsiReset) - continue - } - break - } err := core.LibmuttonInit(front.Input, [][3]string{{"MUTN", "textEditor", cmp.Or(front.Input("Text editor (leave blank for $EDITOR, falls back to \""+cli.FallbackEditor+"\"):"), os.Getenv("EDITOR"), cli.FallbackEditor)}}, - rcwPass, false) + confirmRCWPassphrase("new"), false) if err != nil { back.PrintError("Initialization failed: "+err.Error(), 0, true) } case "tweak": - back.PrintError("\"tweak\" is not yet implemented", 0, true) + choice := front.InputMenuGen("Action:", []string{"Change master passphrase/Optimize entries"}) + switch choice { + case 1: + oldPassphrase := confirmRCWPassphrase("old") + newPassphrase := confirmRCWPassphrase("new") + fmt.Print("\nRe-encrypting entries. Please wait; do not force close this process.\n") + err := core.EntryRefresh(oldPassphrase, newPassphrase, false) + if err != nil { + back.PrintError("Re-encryption failed: "+err.Error(), global.ErrorEncryption, true) + } + fmt.Println("\nRe-encryption complete.") + } case "copy": cli.HelpCopy() case "edit": @@ -221,3 +223,17 @@ func main() { } } } + +// confirmRCWPassphrase prompts the user for a master passphrase and confirms it +// is typed correctly. Returns the passphrase as a byte slice. +func confirmRCWPassphrase(lowercasePrefix string) []byte { + for { + // get master passphrase + rcwPass := front.InputHidden(strings.ToUpper(string(lowercasePrefix[0])) + lowercasePrefix[1:] + " master passphrase:") + if !bytes.Equal(rcwPass, front.InputHidden("Confirm "+lowercasePrefix+" master passphrase:")) || len(rcwPass) == 0 { + fmt.Println(back.AnsiError + "Passphrases do not match or passphrase is invalid" + back.AnsiReset) + continue + } + return rcwPass + } +}