168 lines
4.1 KiB
Go
168 lines
4.1 KiB
Go
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"])
|
|
}
|
|
}
|