package cmd import ( "context" "fmt" "net/http" "os" "os/signal" "syscall" "github.com/go-chi/chi/v5" "github.com/salvacybersec/keyhunter/pkg/bot" "github.com/salvacybersec/keyhunter/pkg/providers" "github.com/salvacybersec/keyhunter/pkg/recon" "github.com/salvacybersec/keyhunter/pkg/web" "github.com/spf13/cobra" "github.com/spf13/viper" ) var ( servePort int serveTelegram bool ) var serveCmd = &cobra.Command{ Use: "serve", Short: "Start KeyHunter web dashboard and optional Telegram bot", RunE: func(cmd *cobra.Command, args []string) error { ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer cancel() // Open shared resources. reg, err := providers.NewRegistry() if err != nil { return fmt.Errorf("loading providers: %w", err) } db, encKey, err := openDBWithKey() if err != nil { return fmt.Errorf("opening database: %w", err) } defer db.Close() reconEng := recon.NewEngine() // Optional Telegram bot. if serveTelegram { token := viper.GetString("telegram.token") if token == "" { token = os.Getenv("TELEGRAM_BOT_TOKEN") } if token == "" { return fmt.Errorf("telegram token required: set telegram.token in config or TELEGRAM_BOT_TOKEN env var") } b, err := bot.New(bot.Config{ Token: token, DB: db, ScanEngine: nil, ReconEngine: reconEng, ProviderRegistry: reg, EncKey: encKey, }) if err != nil { return fmt.Errorf("creating bot: %w", err) } go b.Start(ctx) fmt.Println("Telegram bot started.") } // Web dashboard. webSrv := web.NewServer(web.ServerConfig{ DB: db, EncKey: encKey, Providers: reg, ReconEngine: reconEng, }) r := chi.NewRouter() webSrv.Mount(r) addr := fmt.Sprintf(":%d", servePort) fmt.Printf("KeyHunter dashboard at http://localhost%s\n", addr) go func() { if err := http.ListenAndServe(addr, r); err != nil && err != http.ErrServerClosed { fmt.Fprintf(os.Stderr, "web server error: %v\n", err) } }() <-ctx.Done() fmt.Println("\nShutting down.") return nil }, } func init() { serveCmd.Flags().IntVar(&servePort, "port", 8080, "HTTP server port") serveCmd.Flags().BoolVar(&serveTelegram, "telegram", false, "enable Telegram bot") }