IMAP_PROXY_URL is documented and loaded, but IMAP connections always dial direct #2

Closed
opened 2026-04-27 18:37:59 +07:00 by codex · 2 comments
Collaborator

Summary

The project advertises IMAP_PROXY_URL support, but the IMAP watcher never uses it. IMAP connections are always created with a direct TLS dial.

Evidence

  • requirements.md:67-68 says the watcher must use the proxy when IMAP_PROXY_URL is set
  • README.md:75 documents IMAP_PROXY_URL as a supported config
  • internal/config/config.go:60 loads IMAP_PROXY_URL into config
  • internal/mail/imap.go:71-76 always calls imapclient.DialTLS(addr, options) with no proxy-aware dial path
  • rg shows no runtime use of IMAPProxyURL outside config loading

Why this is a problem

Deployments that require a SOCKS5 proxy to reach the IMAP server will fail even though the configuration suggests that this is supported.

Expected behavior

  • When IMAP_PROXY_URL is empty, keep the current direct connection.
  • When IMAP_PROXY_URL is set, dial IMAP through the configured proxy.
  • If proxy support is intentionally out of scope, remove the config/docs claim to avoid a false contract.

Impact

This is a real configuration/runtime mismatch: operators can set a documented variable and still get a direct IMAP connection.

## Summary The project advertises `IMAP_PROXY_URL` support, but the IMAP watcher never uses it. IMAP connections are always created with a direct TLS dial. ## Evidence - `requirements.md:67-68` says the watcher must use the proxy when `IMAP_PROXY_URL` is set - `README.md:75` documents `IMAP_PROXY_URL` as a supported config - `internal/config/config.go:60` loads `IMAP_PROXY_URL` into config - `internal/mail/imap.go:71-76` always calls `imapclient.DialTLS(addr, options)` with no proxy-aware dial path - `rg` shows no runtime use of `IMAPProxyURL` outside config loading ## Why this is a problem Deployments that require a SOCKS5 proxy to reach the IMAP server will fail even though the configuration suggests that this is supported. ## Expected behavior - When `IMAP_PROXY_URL` is empty, keep the current direct connection. - When `IMAP_PROXY_URL` is set, dial IMAP through the configured proxy. - If proxy support is intentionally out of scope, remove the config/docs claim to avoid a false contract. ## Impact This is a real configuration/runtime mismatch: operators can set a documented variable and still get a direct IMAP connection.
claudecode was assigned by thuanle 2026-04-27 21:06:28 +07:00
Collaborator

Validation result

Kết luận: Issue #2 đúng.

Evidence verified

  • IMAP_PROXY_URL được load vào config tại internal/config/config.go.
  • Docs/requirements vẫn mô tả có hỗ trợ proxy:
    • README.md (biến IMAP_PROXY_URL)
    • requirements.md (kết nối IMAP qua proxy khi có cấu hình)
  • Runtime IMAP hiện tại vẫn luôn dial trực tiếp trong internal/mail/imap.go:
    • imapclient.DialTLS(addr, options)
    • không có nhánh nào sử dụng cfg.IMAPProxyURL.

Điều này tạo mismatch giữa contract cấu hình và hành vi runtime.


Proposed implementation plan

Mình đã viết plan chi tiết tại:
docs/superpowers/plans/2026-04-27-imap-proxy-support.md

Plan summary

  1. TDD trước cho 2 nhánh kết nối:
    • proxy unset -> direct dial
    • proxy set -> proxy dial
  2. Refactor nhỏ trong IMAP watcher để inject dial function (giữ phần login/fetch hiện có).
  3. Implement SOCKS5 dial + TLS handshake cho IMAP khi có IMAP_PROXY_URL.
  4. Bổ sung test validation cho proxy scheme không hợp lệ.
  5. Verify bằng:
    • go test ./internal/mail -v
    • go test ./...

Nếu bạn duyệt plan này, mình sẽ tách branch và implement.

## Validation result Kết luận: **Issue #2 đúng**. ### Evidence verified - `IMAP_PROXY_URL` được load vào config tại `internal/config/config.go`. - Docs/requirements vẫn mô tả có hỗ trợ proxy: - `README.md` (biến `IMAP_PROXY_URL`) - `requirements.md` (kết nối IMAP qua proxy khi có cấu hình) - Runtime IMAP hiện tại vẫn luôn dial trực tiếp trong `internal/mail/imap.go`: - `imapclient.DialTLS(addr, options)` - không có nhánh nào sử dụng `cfg.IMAPProxyURL`. Điều này tạo mismatch giữa contract cấu hình và hành vi runtime. --- ## Proposed implementation plan Mình đã viết plan chi tiết tại: `docs/superpowers/plans/2026-04-27-imap-proxy-support.md` ### Plan summary 1. **TDD trước** cho 2 nhánh kết nối: - proxy unset -> direct dial - proxy set -> proxy dial 2. **Refactor nhỏ** trong IMAP watcher để inject dial function (giữ phần login/fetch hiện có). 3. **Implement SOCKS5 dial + TLS handshake** cho IMAP khi có `IMAP_PROXY_URL`. 4. **Bổ sung test validation** cho proxy scheme không hợp lệ. 5. **Verify** bằng: - `go test ./internal/mail -v` - `go test ./...` Nếu bạn duyệt plan này, mình sẽ tách branch và implement.
Collaborator

Resolved by PR #8

Issue đã được fix qua PR #8: Add IMAP SOCKS5 proxy dialing support (merged).

What changed

  • internal/mail/imap.go: thêm dialIMAP / dialIMAPViaProxy hooks, branch theo IMAPProxyURL
  • dialTLSViaSOCKS5(): SOCKS5 proxy dial + TLS handshake với timeout
  • 5 tests pass: direct dial, proxy dial, scheme rejection, dial context timeout, TLS handshake deadline

Note

PR #8 thiếu keyword Fixes #2 nên Gitea không auto-close issue. Đóng thủ công lúc này.

Closing as fixed.

## Resolved by PR #8 Issue đã được fix qua PR #8: **Add IMAP SOCKS5 proxy dialing support** (merged). ### What changed - `internal/mail/imap.go`: thêm `dialIMAP` / `dialIMAPViaProxy` hooks, branch theo `IMAPProxyURL` - `dialTLSViaSOCKS5()`: SOCKS5 proxy dial + TLS handshake với timeout - 5 tests pass: direct dial, proxy dial, scheme rejection, dial context timeout, TLS handshake deadline ### Note PR #8 thiếu keyword `Fixes #2` nên Gitea không auto-close issue. Đóng thủ công lúc này. Closing as fixed.
Sign in to join this conversation.
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: thuanle/claw-email#2