93957e3989
- Storage.IsDataEncrypted() checks if hosts.json is encrypted - TUI auto-detects encrypted files, prompts password automatically - Root command: --password flag for all CLI commands - newStorage() helper applies password flag to storage - add/list/edit/delete commands now support encrypted storage - passwordSetMsg loads hosts after password is set
82 lines
1.9 KiB
Go
82 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
"github.com/spf13/cobra"
|
|
|
|
"git.tukangketik.id/swanadiva/hostkeeper/pkg/config"
|
|
"git.tukangketik.id/swanadiva/hostkeeper/pkg/knownhosts"
|
|
"git.tukangketik.id/swanadiva/hostkeeper/pkg/storage"
|
|
"git.tukangketik.id/swanadiva/hostkeeper/pkg/tui"
|
|
)
|
|
|
|
var encryptFlag bool
|
|
|
|
// tuiCmd represents the tui command
|
|
var tuiCmd = &cobra.Command{
|
|
Use: "tui",
|
|
Short: "Launch terminal user interface",
|
|
Long: `Launch an interactive terminal user interface for managing SSH hosts and connections.`,
|
|
RunE: runTUI,
|
|
}
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(tuiCmd)
|
|
tuiCmd.Flags().BoolVar(&encryptFlag, "encrypt", false, "Enable AES-256-GCM encryption for sensitive data")
|
|
}
|
|
|
|
func runTUI(cmd *cobra.Command, args []string) error {
|
|
cfg := appCfg
|
|
if cfg == nil {
|
|
var err error
|
|
cfg, err = config.New()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to initialize config: %w", err)
|
|
}
|
|
}
|
|
|
|
store, err := storage.NewJSONStorage(cfg.GetDataDir())
|
|
if err != nil {
|
|
return fmt.Errorf("failed to initialize storage: %w", err)
|
|
}
|
|
|
|
// Initialize known_hosts
|
|
kh, err := knownhosts.New(cfg.GetDataDir())
|
|
if err != nil {
|
|
fmt.Printf("Warning: failed to load known_hosts: %v\n", err)
|
|
}
|
|
|
|
// Auto-detect encrypted data files
|
|
needPassword := encryptFlag || store.IsDataEncrypted()
|
|
|
|
model := tui.New()
|
|
model.SetDataDir(cfg.GetDataDir())
|
|
if kh != nil {
|
|
model.SetKnownHosts(kh)
|
|
}
|
|
|
|
if needPassword {
|
|
// Show password prompt first — hosts will be loaded after password is set
|
|
model.ShowEncryptPrompt()
|
|
} else {
|
|
// No encryption — load hosts normally
|
|
ctx := context.Background()
|
|
hosts, err := store.ListHosts(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to load hosts: %w", err)
|
|
}
|
|
model.LoadHosts(hosts)
|
|
}
|
|
|
|
p := tea.NewProgram(model)
|
|
model.SetProgram(p)
|
|
if _, err := p.Run(); err != nil {
|
|
return fmt.Errorf("failed to run TUI: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|