diff --git a/docs/man b/docs/man index ba11acb..442514b 100644 --- a/docs/man +++ b/docs/man @@ -1,7 +1,7 @@ -.TH MUTN 1 "23 November 2025" "v0.D.0" "MUTN man page" +.TH MUTN 1 "26 December 2025" "v0.D.0" "MUTN man page" .SH NAME -\fBmutn\fR - Simple, self-hosted, SSH-synchronized password and note management based on libmutton. It is the successor to sshyp. +\fBmutn\fR - Simple, self-hosted, SSH-synchronized password and note management based on libmutton. .SH SYNOPSIS Usage: mutn [/ [argument] [option]] | [argument] @@ -84,11 +84,11 @@ add: .SH TIPS 1. You can quickly read an entry with "mutn /" -2. Type "mutn" (no arguments/options) to view a list of saved entries +2. Using "add", "edit", or "copy" without specifying an option (field) will default to "password" -3. Provide "add", "edit", "copy", or "gen" as the only argument to receive more specific help +3. Various changes can be made to the configuration and stored entries from the "mutn tweak" menu -4. Using "add", "edit", or "copy" without specifying an option (field) will default to "password" +4. Type "mutn" (no arguments) to view a list of saved entries w/colored markers indicating the ages of stored passwords .SH SETUP libmutton operates on a client-server model, and thus sync support requires you to have access to your own server (whether it be a physical home server or a cloud rental) with remote access via SSH. @@ -102,6 +102,7 @@ Once this has been done, you may proceed with the client setup: 2. Run "mutn init" and follow the prompts 3. If you already have entries on the server, sync them using "mutn sync" 4. Optionally, shell completions (Bash, ZSH, and PowerShell 7+) can be enabled with your shell's respective method + 5. If importing passwords from another password manager, you may desire to use the "Age all entries" option from the "mutn tweak" menu to add initial age tracking data to the imported passwords .SH TROUBLESHOOTING .B Clipboard not clearing: diff --git a/go.mod b/go.mod index bfb5a37..c529a63 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.25.5 require ( github.com/charmbracelet/glamour v0.7.0 github.com/rwinkhart/go-boilerplate v0.1.1-0.20251211171453-df1fb21b2366 - github.com/rwinkhart/libmutton v0.4.3-0.20251227014833-6004a94b7718 + github.com/rwinkhart/libmutton v0.4.3-0.20251227024942-bdbdce61aa77 golang.org/x/term v0.38.0 ) diff --git a/go.sum b/go.sum index 0399514..1bbd95e 100644 --- a/go.sum +++ b/go.sum @@ -48,8 +48,8 @@ github.com/rwinkhart/go-highlite v0.1.1 h1:9TxbRhYVfD/3YaEgNk1BtEiZ0t8/5mxDUZqNM github.com/rwinkhart/go-highlite v0.1.1/go.mod h1:mWLMtCWcyV0BG4NeyPyAUGMjPvI0ds6vXmUq89QwBFA= github.com/rwinkhart/go-winio v0.1.0 h1:b72agLW+dETGmhR3VbcbwnStfgKfc5AfgJOXBJDkaHg= github.com/rwinkhart/go-winio v0.1.0/go.mod h1:ZWa7ssZJT30CCDGJ7fk/2SBTq9BIQrrVjrcss0UW2s0= -github.com/rwinkhart/libmutton v0.4.3-0.20251227014833-6004a94b7718 h1:sefIFWvRA8iqWHQOFRvao7A12QoH8a3HVPe6Vs4P79M= -github.com/rwinkhart/libmutton v0.4.3-0.20251227014833-6004a94b7718/go.mod h1:nOEBckA0iNZePuXzkxpTlzBevKQlZqkvwstZjMB3yBU= +github.com/rwinkhart/libmutton v0.4.3-0.20251227024942-bdbdce61aa77 h1:CQ9YH2g74HQnaXLKPgaxsp3PLRLpyOX2td58W/SpDP0= +github.com/rwinkhart/libmutton v0.4.3-0.20251227024942-bdbdce61aa77/go.mod h1:nOEBckA0iNZePuXzkxpTlzBevKQlZqkvwstZjMB3yBU= github.com/rwinkhart/peercred-mini v0.1.2 h1:4cGWDbv0whvLeVvbUdx84V/9p+2fS+DEXgrA1KxlRFo= github.com/rwinkhart/peercred-mini v0.1.2/go.mod h1:LLHG7YshHEpbpJJP+Il9nx2dnGj5O3VGE32rWmflj0c= github.com/rwinkhart/rcw v0.2.4 h1:FrRSsl+ui1WLmDwqjLSROtFPKqSeGLEfF2SPENt4qP0= diff --git a/mutn.go b/mutn.go index 1cc662c..f770f92 100644 --- a/mutn.go +++ b/mutn.go @@ -204,9 +204,17 @@ func main() { other.PrintError("Initialization failed: "+err.Error(), 0) } case "tweak": - choice := front.InputMenuGen("Action:", []string{"Change device ID", "Change master password/Optimize entries", "Set text editor", "Age all entries"}) + choice := front.InputMenuGen("Action:", []string{"Set text editor", "Change device ID", "Age all entries", "Change master password/Optimize entries"}) switch choice { case 1: + newCfg := &cfg.ConfigT{} + newThirdPartyCfg := map[string]any{"mutnTextEditor": getTextEditorInput()} + newCfg.ThirdParty = &newThirdPartyCfg + err := cfg.WriteConfig(newCfg, true) + if err != nil { + other.PrintError("Failed to set text editor: "+err.Error(), back.ErrorWrite) + } + case 2: oldDeviceID, err := global.GetCurrentDeviceID() if err != nil { other.PrintError("Failed to get current device ID: "+err.Error(), back.ErrorRead) @@ -216,7 +224,14 @@ func main() { other.PrintError("Failed to change device ID: "+err.Error(), global.ErrorSyncProcess) } fmt.Println("\nDevice ID changed successfully.") - case 2: + case 3: + forceReage := front.InputBinary("Re-age aged entries?") + fmt.Println("Aging entries; this may take awhile - do not terminate this process") + err := age.AllPasswordEntries(forceReage) + if err != nil { + other.PrintError("Failed to age entries: "+err.Error(), 1) + } + case 4: oldPassword := confirmRCWPassword("old") newPassword := confirmRCWPassword("new") fmt.Print("\nRe-encrypting entries. Please wait; do not force close this process.\n") @@ -225,21 +240,6 @@ func main() { other.PrintError("Re-encryption failed: "+err.Error(), global.ErrorEncryption) } fmt.Println("\nRe-encryption complete.") - case 3: - newCfg := &cfg.ConfigT{} - newThirdPartyCfg := map[string]any{"mutnTextEditor": getTextEditorInput()} - newCfg.ThirdParty = &newThirdPartyCfg - err := cfg.WriteConfig(newCfg, true) - if err != nil { - other.PrintError("Failed to set text editor: "+err.Error(), back.ErrorWrite) - } - case 4: - forceReage := front.InputBinary("Re-age aged entries?") - fmt.Println("Aging entries; this may take awhile - do not terminate this process") - err := age.AllPasswordEntries(forceReage) - if err != nil { - other.PrintError("Failed to age entries: "+err.Error(), 1) - } } case "copy": cli.HelpCopy() diff --git a/src/cli/printInfo.go b/src/cli/printInfo.go index d021ca0..09e41d8 100644 --- a/src/cli/printInfo.go +++ b/src/cli/printInfo.go @@ -56,9 +56,9 @@ This program comes with absolutely no warranty; type "mutn version" for details. folder|-f Add a new folder for entries ` + back.AnsiBold + "Tip 1:" + back.AnsiReset + ` You can quickly read an entry with "mutn /" -` + back.AnsiBold + "Tip 2:" + back.AnsiReset + ` Type "mutn" (no arguments/options) to view a list of saved entries -` + back.AnsiBold + "Tip 3:" + back.AnsiReset + ` Provide "add", "edit", "copy", or "gen" as the only argument to receive more specific help -` + back.AnsiBold + "Tip 4:" + back.AnsiReset + " Using \"add\", \"edit\", or \"copy\" without specifying an option (field) will default to \"password\"\n\n") +` + back.AnsiBold + "Tip 2:" + back.AnsiReset + ` Using "add", "edit", or "copy" without specifying an option (field) will default to "password" +` + back.AnsiBold + "Tip 3:" + back.AnsiReset + ` Various changes can be made to the configuration and stored entries from the "mutn tweak" menu +` + back.AnsiBold + "Tip 4:" + back.AnsiReset + " Type \"mutn\" (no arguments) to view a list of saved entries w/colored markers indicating the ages of stored passwords\n\n") os.Exit(0) } @@ -96,7 +96,8 @@ func HelpCopy() { username|-u Copy the username in an entry to your clipboard totp|-t Generate and copy the TOTP token for an entry to your clipboard url|-l Copy the URL in an entry to your clipboard - note|-n Copy the first note line in an entry to your clipboard` + "\n\n") + note|-n Copy the first note line in an entry to your clipboard + menu|-m Open interactive menu to copy any combination of fields` + "\n\n") os.Exit(0) } diff --git a/wiki/install.md b/wiki/install.md index bf40619..2ab1839 100644 --- a/wiki/install.md +++ b/wiki/install.md @@ -14,4 +14,4 @@ Please see the [usage guide](https://github.com/rwinkhart/MUTN/blob/main/wiki/us ### Dependencies (required for all installations) - A text editor (preferably CLI-based) for writing entry notes - A private key for SSH key-based authentication is required to use MUTN/libmutton in online/synced mode -- Linux: xclip (X11) or wl-clipboard (Wayland) for clipboard support +- Linux/BSD: xclip (X11) or wl-clipboard (Wayland) for clipboard support diff --git a/wiki/usage.md b/wiki/usage.md index aebf8b1..f4d6d1f 100644 --- a/wiki/usage.md +++ b/wiki/usage.md @@ -15,6 +15,7 @@ Once this has been done, you may proceed with the client setup: 2. Run `mutn init` and follow the prompts 3. If you already have entries on the server, sync them using `mutn sync` 4. Optionally, shell completions (Bash, ZSH, and PowerShell 7+) can be [enabled with your shell's respective method](https://github.com/rwinkhart/MUTN/blob/main/wiki/completions.md) +5. Optionally, [import passwords](https://github.com/rwinkhart/libmutton/blob/main/wiki/migration.md) from another password manager. After doing this, you may desire to use the "Age all entries" option from the `mutn tweak` menu to add initial age tracking data to the imported passwords ### Tips #### Operating on Passwords