# GreenMail

Local SMTP+IMAP email server for Elixir dev/test environments. Wraps [GreenMail](https://greenmail-mail-test.github.io/greenmail/) — catches **all** outbound email at the SMTP level. No emails leave your machine. Ever.

## Why not Swoosh.Adapters.Local?

Because it only catches emails sent through Swoosh. If your app talks SMTP directly (a `SmtpClient`, a background mailer, a third-party library), Swoosh.Local never sees those messages. GreenMail catches everything — it's a real SMTP server listening on localhost.

## Setup

### 1. Add dependency

```elixir
# mix.exs
defp deps do
  [
    {:greenmail, "~> 0.1", only: :dev}
  ]
end
```

### 2. Install the JAR

```bash
mix greenmail.install
```

Downloads `greenmail-standalone.jar` to `~/.greenmail/`. One download, shared by all projects.

**Requires:** Java 17+ (`brew install openjdk` on macOS)

### 3. Add to supervision tree (dev only)

```elixir
# application.ex
def start(_type, _args) do
  children = [
    # ... your children ...
  ] ++ greenmail_children()

  opts = [strategy: :one_for_one, name: MyApp.Supervisor]
  Supervisor.start_link(children, opts)
end

defp greenmail_children do
  if Application.get_env(:my_app, :greenmail, false) do
    [{GreenMail.Server, [supervisor: MyApp.Supervisor]}]
  else
    []
  end
end
```

```elixir
# config/dev.exs
config :my_app, greenmail: true
```

### 4. Point SMTP at GreenMail

Any SMTP config pointing at `localhost:3025` will be caught. For IMAP ingestion, use `localhost:3143`.

Auth is disabled — any username/password works and auto-provisions a mailbox for that address.

## API

```elixir
GreenMail.running?()  # => true
GreenMail.status()    # => {:ok, %{smtp_port: 3025, imap_port: 3143, os_pid: 12345, ...}}
GreenMail.stop()      # Stop server, free ports
GreenMail.start()     # Restart after stop
GreenMail.restart()   # Flush all mailboxes
```

## Ports

| Protocol | Port |
|----------|------|
| SMTP     | 3025 |
| IMAP     | 3143 |

## How it works

- GenServer starts GreenMail JAR as an Erlang port process
- Java process dies when your app dies — no orphans
- Per-address mailboxes: email to `alice@example.com` lands in that IMAP inbox
- In-memory only: emails vanish on restart
- If ports are already in use, assumes external mail server and skips startup

## Reading caught emails

Use any IMAP client. From Elixir, you can use `:gen_smtp` or `Mail`:

```elixir
# The email sent to alice@example.com is in that address's IMAP inbox
# Login: alice@example.com / any-password
# Host: localhost, Port: 3143, SSL: off
```

Or just use a mail client (Thunderbird, etc.) pointed at localhost:3143.

## License

MIT
