package cli import ( "bufio" "bytes" "encoding/json" "fmt" "net/http" "os" "strings" "syscall" "github.com/spf13/cobra" "golang.org/x/term" ) const apiURL = "http://localhost:8080" var rootCmd = &cobra.Command{ Use: "termbox", Short: "Termbox CLI - A secure messaging platform", Long: "Termbox CLI allows you to register, login, and send messages securely.", } var registerCmd = &cobra.Command{ Use: "register", Short: "Register a new account", Long: "Register a new account with username, email, and password. You'll need to verify your email.", Run: runRegister, } var loginCmd = &cobra.Command{ Use: "login", Short: "Login to your account", Long: "Login to your account with username and password.", Run: runLogin, } var verifyCmd = &cobra.Command{ Use: "verify", Short: "Verify your email address", Long: "Verify your email address with the code sent to your email.", Run: runVerify, } func init() { rootCmd.AddCommand(registerCmd) rootCmd.AddCommand(loginCmd) rootCmd.AddCommand(verifyCmd) } func Execute() error { return rootCmd.Execute() } func runRegister(cmd *cobra.Command, args []string) { fmt.Print("Username: ") reader := bufio.NewReader(os.Stdin) username, _ := reader.ReadString('\n') username = strings.TrimSpace(username) fmt.Print("Email: ") email, _ := reader.ReadString('\n') email = strings.TrimSpace(email) fmt.Print("Password: ") passwordBytes, err := term.ReadPassword(int(syscall.Stdin)) if err != nil { fmt.Printf("Error reading password: %v\n", err) return } password := string(passwordBytes) fmt.Println() requestBody, _ := json.Marshal(map[string]string{ "username": username, "email": email, "password": password, }) resp, err := http.Post(apiURL+"/auth/register", "application/json", bytes.NewBuffer(requestBody)) if err != nil { fmt.Printf("Error registering: %v\n", err) return } defer resp.Body.Close() var response map[string]interface{} json.NewDecoder(resp.Body).Decode(&response) if resp.StatusCode == http.StatusCreated { fmt.Printf("✅ Registration successful! Check your email (%s) for verification code.\n", email) fmt.Println("Run 'termbox verify' to complete registration.") } else { fmt.Printf("❌ Registration failed: %s\n", response["error"]) } } func runVerify(cmd *cobra.Command, args []string) { fmt.Print("Email: ") reader := bufio.NewReader(os.Stdin) email, _ := reader.ReadString('\n') email = strings.TrimSpace(email) fmt.Print("Verification code: ") code, _ := reader.ReadString('\n') code = strings.TrimSpace(code) requestBody, _ := json.Marshal(map[string]string{ "email": email, "code": code, }) resp, err := http.Post(apiURL+"/auth/verify", "application/json", bytes.NewBuffer(requestBody)) if err != nil { fmt.Printf("Error verifying: %v\n", err) return } defer resp.Body.Close() var response map[string]interface{} json.NewDecoder(resp.Body).Decode(&response) if resp.StatusCode == http.StatusOK { fmt.Println("✅ Account verified successfully! You can now login.") } else { fmt.Printf("❌ Verification failed: %s\n", response["error"]) } } func runLogin(cmd *cobra.Command, args []string) { fmt.Print("Username: ") reader := bufio.NewReader(os.Stdin) username, _ := reader.ReadString('\n') username = strings.TrimSpace(username) fmt.Print("Password: ") passwordBytes, err := term.ReadPassword(int(syscall.Stdin)) if err != nil { fmt.Printf("Error reading password: %v\n", err) return } password := string(passwordBytes) fmt.Println() requestBody, _ := json.Marshal(map[string]string{ "username": username, "password": password, }) resp, err := http.Post(apiURL+"/auth/login", "application/json", bytes.NewBuffer(requestBody)) if err != nil { fmt.Printf("Error logging in: %v\n", err) return } defer resp.Body.Close() var response map[string]interface{} json.NewDecoder(resp.Body).Decode(&response) if resp.StatusCode == http.StatusOK { user := response["user"].(map[string]interface{}) fmt.Printf("✅ Login successful! Welcome back, %s!\n", user["username"]) } else { fmt.Printf("❌ Login failed: %s\n", response["error"]) } }