Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ examples/
.github/
.pre-commit-config.yaml
.goreleaser.yml
*.md
*.md
2 changes: 1 addition & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ brews:
repository:
owner: berbyte
name: homebrew-tap
token: "{{ .Env.GH_PAT }}"
token: "{{ .Env.GH_PAT }}"
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
CMD ["./sinkzone", "resolver", "--api-port", "8080", "--port", "5353"]
2 changes: 1 addition & 1 deletion README-Docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,4 @@ docker compose restart

# Rebuild and restart
docker compose up -d --build
```
```
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ services:
- "5335:53/udp"
restart: unless-stopped
networks:
dns_net:
dns_net:
24 changes: 16 additions & 8 deletions docs/sinkzone-cli.tape
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
Output examples/demo-cli.gif
Set FontSize 20
Set Width 1200
Set Height 1000
Set Theme "Rose Pine"
Set Margin 30
Set MarginFill "#6B50FF"
Set Padding 10
Set WindowBar Colorful
Set BorderRadius 10
Set TypingSpeed 0.03

Hide
Type "sinkzone allowlist remove github.com && clear"
Expand All @@ -23,39 +25,45 @@ Enter
Type "sinkzone monitor | head -10"
Sleep 500ms
Enter
Sleep 2s
Sleep 1s

Type "# Let's allow github.com"
Sleep 500ms
Enter
Type "sinkzone allowlist add github.com"
Sleep 500ms
Enter
Sleep 2s
Sleep 1s

Type "# Let's start a focus session"
Sleep 500ms
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
Binary file modified examples/demo-cli.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions internal/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -143,15 +143,15 @@ 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)
log.Printf("API Client: Health check failed with status %d, body: %s", resp.StatusCode, string(body))
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
}
3 changes: 0 additions & 3 deletions internal/api/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
54 changes: 14 additions & 40 deletions internal/tui/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package tui

import (
"fmt"
"os"
"path/filepath"
"strings"
"time"

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand Down