diff --git a/.dockerignore b/.dockerignore index 68654ea..002bb57 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,4 +7,4 @@ examples/ .github/ .pre-commit-config.yaml .goreleaser.yml -*.md \ No newline at end of file +*.md diff --git a/.goreleaser.yml b/.goreleaser.yml index ccacbde..bf7001d 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -59,4 +59,4 @@ brews: repository: owner: berbyte name: homebrew-tap - token: "{{ .Env.GH_PAT }}" \ No newline at end of file + token: "{{ .Env.GH_PAT }}" diff --git a/Dockerfile b/Dockerfile index ff85214..e22430d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,4 +29,4 @@ COPY --from=builder /app/sinkzone . EXPOSE 5353 8080 # Run the resolver with API and DNS ports -CMD ["./sinkzone", "resolver", "--api-port", "8080", "--port", "5353"] \ No newline at end of file +CMD ["./sinkzone", "resolver", "--api-port", "8080", "--port", "5353"] diff --git a/README-Docker.md b/README-Docker.md index 7280123..9b73fea 100644 --- a/README-Docker.md +++ b/README-Docker.md @@ -95,4 +95,4 @@ docker compose restart # Rebuild and restart docker compose up -d --build -``` \ No newline at end of file +``` diff --git a/docker-compose.yml b/docker-compose.yml index a35b82a..25bab83 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,4 +46,4 @@ services: - "5335:53/udp" restart: unless-stopped networks: - dns_net: \ No newline at end of file + dns_net: diff --git a/docs/sinkzone-cli.tape b/docs/sinkzone-cli.tape index 9ac2c12..2073a21 100644 --- a/docs/sinkzone-cli.tape +++ b/docs/sinkzone-cli.tape @@ -1,5 +1,6 @@ Output examples/demo-cli.gif Set FontSize 20 +Set Width 1200 Set Height 1000 Set Theme "Rose Pine" Set Margin 30 @@ -7,6 +8,7 @@ Set MarginFill "#6B50FF" Set Padding 10 Set WindowBar Colorful Set BorderRadius 10 +Set TypingSpeed 0.03 Hide Type "sinkzone allowlist remove github.com && clear" @@ -23,7 +25,7 @@ Enter Type "sinkzone monitor | head -10" Sleep 500ms Enter -Sleep 2s +Sleep 1s Type "# Let's allow github.com" Sleep 500ms @@ -31,7 +33,7 @@ Enter Type "sinkzone allowlist add github.com" Sleep 500ms Enter -Sleep 2s +Sleep 1s Type "# Let's start a focus session" Sleep 500ms @@ -39,23 +41,29 @@ Enter Type "sinkzone focus start" Sleep 500ms Enter -Sleep 2s +Sleep 1s Type "# google.com won't resolve" Sleep 500ms Enter -Type "dig google.com" +Type "nslookup google.com" Sleep 500ms Enter -Sleep 2s +Sleep 1s Type "# github.com is allowed" Sleep 500ms Enter -Type "dig github.com" +Type "nslookup github.com" Sleep 500ms Enter -Type "Enjoy the silence! :)" -Sleep 10s +Type "# Enjoy the silence! :)" +Sleep 1s +Enter + +Type sinkzone tui +Sleep 500ms +Enter +Sleep 5s diff --git a/examples/demo-cli.gif b/examples/demo-cli.gif index 46b3ff8..53f2fe5 100644 Binary files a/examples/demo-cli.gif and b/examples/demo-cli.gif differ diff --git a/internal/api/client.go b/internal/api/client.go index 70e23fe..f6cdc68 100644 --- a/internal/api/client.go +++ b/internal/api/client.go @@ -129,7 +129,7 @@ func (c *Client) GetState() (*ResolverState, error) { } func (c *Client) HealthCheck() error { - log.Printf("API Client: Attempting health check to %s/health", c.baseURL) + // log.Printf("API Client: Attempting health check to %s/health", c.baseURL) resp, err := c.client.Get(c.baseURL + "/health") if err != nil { @@ -143,7 +143,7 @@ func (c *Client) HealthCheck() error { } }() - log.Printf("API Client: Health check response status: %d", resp.StatusCode) + // log.Printf("API Client: Health check response status: %d", resp.StatusCode) if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) @@ -151,7 +151,7 @@ func (c *Client) HealthCheck() error { return fmt.Errorf("health check returned status: %d", resp.StatusCode) } - body, _ := io.ReadAll(resp.Body) - log.Printf("API Client: Health check successful, response: %s", string(body)) + // body, _ := io.ReadAll(resp.Body) + // log.Printf("API Client: Health check successful, response: %s", string(body)) return nil } diff --git a/internal/api/client_test.go b/internal/api/client_test.go index 29c4628..6a03c4d 100644 --- a/internal/api/client_test.go +++ b/internal/api/client_test.go @@ -7,9 +7,6 @@ import ( func TestNewClient(t *testing.T) { client := NewClient("http://127.0.0.1:8080") - if client == nil { - t.Fatal("NewClient returned nil") - } if client.baseURL != "http://127.0.0.1:8080" { t.Errorf("Expected baseURL to be 'http://127.0.0.1:8080', got '%s'", client.baseURL) } diff --git a/internal/tui/tui.go b/internal/tui/tui.go index 405a8b8..dd9a8f6 100644 --- a/internal/tui/tui.go +++ b/internal/tui/tui.go @@ -2,8 +2,6 @@ package tui import ( "fmt" - "os" - "path/filepath" "strings" "time" @@ -251,32 +249,6 @@ func (m Model) loadInitialData() { } } -// validatePath ensures the path is within the user's home directory and doesn't contain path traversal -func validatePath(path string) error { - homeDir, err := os.UserHomeDir() - if err != nil { - return fmt.Errorf("failed to get home directory: %w", err) - } - - // Resolve any symlinks and get absolute path - absPath, err := filepath.Abs(path) - if err != nil { - return fmt.Errorf("failed to resolve absolute path: %w", err) - } - - // Check if the path is within the home directory - if !strings.HasPrefix(absPath, homeDir) { - return fmt.Errorf("path is outside home directory: %s", path) - } - - // Check for path traversal attempts - if strings.Contains(path, "..") { - return fmt.Errorf("path contains traversal attempt: %s", path) - } - - return nil -} - func (m *Model) loadAllowlistData() { manager, err := allowlist.NewManager() if err != nil { @@ -306,7 +278,7 @@ func (m *Model) loadAllowlistData() { } } -func (m Model) enableFocusMode() error { +func (m *Model) enableFocusMode() error { // Enable focus mode for 1 hour via API if err := m.apiClient.SetFocusMode(true, "1h"); err != nil { return fmt.Errorf("failed to enable focus mode: %w", err) @@ -317,7 +289,7 @@ func (m Model) enableFocusMode() error { return nil } -func (m Model) updateFocusModeStatus() { +func (m *Model) updateFocusModeStatus() { // Get focus mode state from API if focusState, err := m.apiClient.GetFocusMode(); err == nil { // Update focus mode state from API response @@ -879,55 +851,57 @@ Use the Monitoring tab to see which domains are being accessed.` func formatAllowlistRow(domain string, domainType string, status string, isSelected bool, recentlyChanged bool) string { row := fmt.Sprintf("%-40s %-20s %-10s", domain, domainType, status) - if isSelected && recentlyChanged { + switch { + case isSelected && recentlyChanged: // Combined state: selected and recently changed - use a distinct color return lipgloss.NewStyle(). Background(lipgloss.Color("#059669")). // Green background for selected + recently changed Foreground(lipgloss.Color("#FFFFFF")). // White text Padding(0, 1). Render(row) - } else if isSelected { + case isSelected: return lipgloss.NewStyle(). Background(lipgloss.Color("#3B82F6")). // Blue background for selected Foreground(lipgloss.Color("#FFFFFF")). // White text Padding(0, 1). Render(row) - } else if recentlyChanged { + case recentlyChanged: return lipgloss.NewStyle(). Background(lipgloss.Color("#8B5CF6")). // Purple background for recently changed Foreground(lipgloss.Color("#FFFFFF")). // White text Padding(0, 1). Render(row) + default: + return row } - - return row } func formatTableRow(domain string, timestamp time.Time, status string, isSelected bool, recentlyChanged bool) string { row := fmt.Sprintf("%-40s %-20s %-10s", domain, timestamp.Format("15:04:05"), status) - if isSelected && recentlyChanged { + switch { + case isSelected && recentlyChanged: // Combined state: selected and recently changed - use a distinct color return lipgloss.NewStyle(). Background(lipgloss.Color("#059669")). // Green background for selected + recently changed Foreground(lipgloss.Color("#FFFFFF")). // White text Padding(0, 1). Render(row) - } else if isSelected { + case isSelected: return lipgloss.NewStyle(). Background(lipgloss.Color("#3B82F6")). // Blue background for selected Foreground(lipgloss.Color("#FFFFFF")). // White text Padding(0, 1). Render(row) - } else if recentlyChanged { + case recentlyChanged: return lipgloss.NewStyle(). Background(lipgloss.Color("#8B5CF6")). // Purple background for recently changed Foreground(lipgloss.Color("#FFFFFF")). // White text Padding(0, 1). Render(row) + default: + return row } - - return row } func (m *Model) addToAllowlist(domain string) error {