updated docs
This commit is contained in:
parent
e2badaa170
commit
1eb4affdb6
5 changed files with 41 additions and 451 deletions
113
CLAUDE.md
113
CLAUDE.md
|
|
@ -1,113 +0,0 @@
|
||||||
# CLAUDE.md
|
|
||||||
|
|
||||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
||||||
|
|
||||||
## Project Overview
|
|
||||||
|
|
||||||
**tui_mail** is a TUI email client built with Rust and Ratatui. It supports standard IMAP servers (including Gmail) and ProtonMail (via an in-process bridge). It displays inbox messages with a split-pane interface: email list on top, message preview on the bottom.
|
|
||||||
|
|
||||||
**User documentation:** see [`USAGE.md`](USAGE.md) for setup instructions, keyboard shortcuts, and configuration reference.
|
|
||||||
|
|
||||||
## Build and Run Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build the project (standard IMAP)
|
|
||||||
cargo build
|
|
||||||
|
|
||||||
# Run the application
|
|
||||||
cargo run
|
|
||||||
|
|
||||||
# Build/run with ProtonMail support
|
|
||||||
cargo build --features proton
|
|
||||||
cargo run --features proton
|
|
||||||
|
|
||||||
# Build optimized release version
|
|
||||||
cargo build --release
|
|
||||||
|
|
||||||
# Check code without building
|
|
||||||
cargo check
|
|
||||||
|
|
||||||
# Format code
|
|
||||||
cargo fmt
|
|
||||||
|
|
||||||
# Run clippy linter
|
|
||||||
cargo clippy
|
|
||||||
```
|
|
||||||
|
|
||||||
## Test Mail Server
|
|
||||||
|
|
||||||
A Docker-based IMAP mail server is available for testing:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Start the mail server
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
# Create a test user
|
|
||||||
docker exec -it mailserver setup email add test@example.com password123
|
|
||||||
|
|
||||||
# Stop the mail server
|
|
||||||
docker-compose down
|
|
||||||
```
|
|
||||||
|
|
||||||
Connection details: localhost:143 (IMAP) or localhost:993 (IMAPS). See `MAIL_SERVER_SETUP.md` for detailed usage including Gmail configuration.
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
### Main app (`src/`)
|
|
||||||
|
|
||||||
- **`src/main.rs`** — Terminal setup/teardown, delegates to `lib::main`
|
|
||||||
- **`src/lib.rs`** — Main event loop, UI rendering, worker thread coordination
|
|
||||||
- **`src/inbox.rs`** — IMAP inbox operations (refresh, fetch older, fetch body, search, delete)
|
|
||||||
- **`src/connect.rs`** — IMAP connection handling (plain TCP and TLS)
|
|
||||||
- **`src/config.rs`** — Configuration loading from `config.toml`; provider selection (IMAP vs Proton)
|
|
||||||
- **`src/credentials.rs`** — OS keychain access via the `keyring` crate
|
|
||||||
- **`src/smtp.rs`** — Outgoing mail via SMTP using `lettre`
|
|
||||||
- **`src/setup.rs`** — First-run interactive setup wizard
|
|
||||||
- **`src/store.rs`** — Local encrypted body cache (AES-256-GCM, key stored in `storage.key` file)
|
|
||||||
|
|
||||||
### ProtonMail bridge (`proton-bridge/`)
|
|
||||||
|
|
||||||
A separate workspace crate that runs as an in-process local IMAP/SMTP server.
|
|
||||||
|
|
||||||
- **`proton-bridge/src/lib.rs`** — Entry point (`start()`); authenticates with ProtonMail API, binds local ports, spawns async tasks
|
|
||||||
- **`proton-bridge/src/imap_server.rs`** — Local IMAP server (LOGIN, SELECT, FETCH, SEARCH, STORE, EXPUNGE)
|
|
||||||
- **`proton-bridge/src/smtp_server.rs`** — Local SMTP server for outgoing mail
|
|
||||||
- **`proton-bridge/src/api.rs`** — ProtonMail REST API client (message list, fetch, delete, send)
|
|
||||||
- **`proton-bridge/src/auth.rs`** — SRP authentication and session management
|
|
||||||
- **`proton-bridge/src/crypto.rs`** — PGP key derivation and message decryption/encryption
|
|
||||||
- **`proton-bridge/src/store.rs`** — In-memory message metadata store for the bridge
|
|
||||||
- **`proton-bridge/src/srp.rs`** — SRP-6a implementation matching ProtonMail's go-srp
|
|
||||||
|
|
||||||
### Key patterns
|
|
||||||
|
|
||||||
- IMAP operations run in a **background worker thread** communicating via `mpsc` channels, keeping the UI responsive
|
|
||||||
- Emails are loaded in **batches of 50**, with lazy loading when scrolling past the end
|
|
||||||
- A **navigation debounce** (150 ms) avoids firing body fetches on every keypress while scrolling
|
|
||||||
- The worker checks `wanted_body_seq` (an `AtomicU32`) to drop stale body requests
|
|
||||||
- **Body cache**: fetched message bodies are AES-256-GCM encrypted and written to `{data_dir}/tuimail/bodies/{hash}.enc`; cache key is the `Message-ID` header value
|
|
||||||
- Credentials (IMAP/SMTP/Proton passwords) are stored in the **OS keychain** via `keyring`
|
|
||||||
- The encryption key for the body cache is stored in `{data_dir}/tuimail/storage.key` (mode 0600) to avoid repeated keychain prompts
|
|
||||||
- **Tab** switches focus between inbox list and preview pane
|
|
||||||
- Selection is preserved across refreshes by matching IMAP sequence numbers
|
|
||||||
|
|
||||||
## Key Dependencies
|
|
||||||
|
|
||||||
- **ratatui (0.30)**: TUI framework providing widgets, layouts, and rendering
|
|
||||||
- **crossterm (0.29)**: Cross-platform terminal manipulation (raw mode, events, alternate screen)
|
|
||||||
- **imap (2.4)**: IMAP protocol client
|
|
||||||
- **native-tls (0.2)**: TLS support for secure IMAP connections
|
|
||||||
- **lettre (0.11)**: SMTP client for sending mail
|
|
||||||
- **chrono (0.4)**: Date parsing and timezone conversion
|
|
||||||
- **mailparse (0.15)**: MIME email paursing for body extraction
|
|
||||||
- **aes-gcm (0.10)**: AES-256-GCM authenticated encryption for the body cache
|
|
||||||
- **keyring (3)**: OS keychain access (apple-native / linux-native / windows-native)
|
|
||||||
- **dirs (5)**: Platform-correct data directory paths
|
|
||||||
|
|
||||||
## Development Notes
|
|
||||||
|
|
||||||
- Uses Rust edition 2024
|
|
||||||
- Terminal is set to raw mode to capture individual key presses
|
|
||||||
- The alternate screen prevents terminal history pollution
|
|
||||||
- `config.toml` contains credentials and is gitignored — see `config.toml.example` for the format
|
|
||||||
- `proton-bridge/bridge.toml` contains ProtonMail credentials and is gitignored
|
|
||||||
- The ProtonMail bridge imap_server SELECT response must **not** include `UIDVALIDITY`/`UIDNEXT` lines — imap-proto 0.10 (used by imap 2.4) does not fully consume them, causing tag desync on subsequent commands
|
|
||||||
|
|
@ -1,124 +0,0 @@
|
||||||
# Mail Server Setup
|
|
||||||
|
|
||||||
## Gmail Configuration
|
|
||||||
|
|
||||||
### 1. Enable 2-Step Verification
|
|
||||||
|
|
||||||
App Passwords require 2-Step Verification to be enabled on your Google account.
|
|
||||||
|
|
||||||
1. Go to https://myaccount.google.com/security
|
|
||||||
2. Under "How you sign in to Google", click **2-Step Verification**
|
|
||||||
3. Follow the prompts to enable it
|
|
||||||
|
|
||||||
### 2. Create an App Password
|
|
||||||
|
|
||||||
1. Go to https://myaccount.google.com/apppasswords
|
|
||||||
2. Enter a name (e.g. "Mail TUI") and click **Create**
|
|
||||||
3. Google will display a 16-character password — copy it
|
|
||||||
|
|
||||||
### 3. Configure tuimail
|
|
||||||
|
|
||||||
Run the setup wizard:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo run -- --configure
|
|
||||||
```
|
|
||||||
|
|
||||||
When prompted for provider choose `imap`, then enter:
|
|
||||||
- IMAP host: `imap.gmail.com`, port: `993`, TLS: `true`
|
|
||||||
- Username: your Gmail address
|
|
||||||
- Password: the 16-character App Password from step 2 (spaces are optional)
|
|
||||||
- SMTP host: `smtp.gmail.com`, port: `465`, TLS mode: `smtps`
|
|
||||||
|
|
||||||
Passwords are stored securely in the OS keychain — they are never written to `config.toml`.
|
|
||||||
|
|
||||||
## Local Test Server (Docker)
|
|
||||||
|
|
||||||
### Quick Start
|
|
||||||
|
|
||||||
1. **Start the mail server:**
|
|
||||||
```bash
|
|
||||||
docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Create a test user:**
|
|
||||||
```bash
|
|
||||||
docker exec -it mailserver setup email add test@example.com password123
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Verify the server is running:**
|
|
||||||
```bash
|
|
||||||
docker-compose ps
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configure tuimail for the local server
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo run -- --configure
|
|
||||||
```
|
|
||||||
|
|
||||||
Choose provider `imap` and enter:
|
|
||||||
- IMAP host: `localhost`, port: `143`, TLS: `false`
|
|
||||||
- Username: `test@example.com`, password: `password123`
|
|
||||||
- SMTP host: `localhost`, port: `25`, TLS mode: `none`
|
|
||||||
|
|
||||||
### IMAP Connection Details
|
|
||||||
|
|
||||||
- **Host:** localhost
|
|
||||||
- **IMAP Port:** 143 (unencrypted) or 993 (SSL/TLS)
|
|
||||||
- **Username:** test@example.com
|
|
||||||
- **Password:** password123
|
|
||||||
|
|
||||||
### Useful Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Stop the mail server
|
|
||||||
docker-compose down
|
|
||||||
|
|
||||||
# View logs
|
|
||||||
docker-compose logs -f mailserver
|
|
||||||
|
|
||||||
# List all email accounts
|
|
||||||
docker exec -it mailserver setup email list
|
|
||||||
|
|
||||||
# Add another user
|
|
||||||
docker exec -it mailserver setup email add user2@example.com pass456
|
|
||||||
|
|
||||||
# Delete a user
|
|
||||||
docker exec -it mailserver setup email del test@example.com
|
|
||||||
|
|
||||||
# Access the container shell
|
|
||||||
docker exec -it mailserver bash
|
|
||||||
```
|
|
||||||
|
|
||||||
### Testing with telnet
|
|
||||||
|
|
||||||
You can test IMAP connectivity:
|
|
||||||
```bash
|
|
||||||
telnet localhost 143
|
|
||||||
```
|
|
||||||
|
|
||||||
Then try IMAP commands:
|
|
||||||
```
|
|
||||||
a1 LOGIN test@example.com password123
|
|
||||||
a2 LIST "" "*"
|
|
||||||
a3 SELECT INBOX
|
|
||||||
a4 LOGOUT
|
|
||||||
```
|
|
||||||
|
|
||||||
### Send Test Email
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# From within the container
|
|
||||||
docker exec -it mailserver bash
|
|
||||||
echo "Test email body" | mail -s "Test Subject" test@example.com
|
|
||||||
```
|
|
||||||
|
|
||||||
Or use SMTP (port 25/587) from your application.
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
- Gmail: if login fails, verify that 2-Step Verification is enabled and you're using an App Password (not your regular password)
|
|
||||||
- Docker: check logs with `docker-compose logs mailserver`
|
|
||||||
- Ensure ports aren't already in use
|
|
||||||
- Data persists in `./docker-data/` directory
|
|
||||||
83
PROTON.md
83
PROTON.md
|
|
@ -1,83 +0,0 @@
|
||||||
# ProtonMail Mini-Bridge
|
|
||||||
|
|
||||||
A minimal ProtonMail Bridge implementation in Rust that exposes local IMAP and SMTP servers,
|
|
||||||
allowing `skim` (and any other standard email client) to connect without code changes.
|
|
||||||
|
|
||||||
The full ProtonMail Bridge is ~50,000 lines of Go. This mini-bridge targets only the subset
|
|
||||||
of functionality that `skim` needs: one account, INBOX only, one concurrent client.
|
|
||||||
|
|
||||||
## Components
|
|
||||||
|
|
||||||
### 1. Project scaffold
|
|
||||||
New binary crate with `Cargo.toml` dependencies (`tokio`, `reqwest`, `proton-srp`, `rpgp`,
|
|
||||||
`serde`, `toml`). Config file format covering ProtonMail credentials and local bind ports.
|
|
||||||
|
|
||||||
### 2. ProtonMail authentication
|
|
||||||
SRP 6a login flow against the Proton API:
|
|
||||||
- POST `/auth/info` with username → receive modulus, server ephemeral, salt
|
|
||||||
- Compute SRP proof locally using `proton-srp`
|
|
||||||
- POST `/auth/login` with client proof → receive access token + encrypted private keys
|
|
||||||
- Handle optional TOTP 2FA interactively on first run
|
|
||||||
- Persist session (access token + refresh token) to disk to avoid re-authenticating on restart
|
|
||||||
|
|
||||||
### 3. ProtonMail API client
|
|
||||||
Thin `reqwest`-based HTTP wrapper around the endpoints the bridge needs:
|
|
||||||
- List messages (with pagination)
|
|
||||||
- Fetch single message (metadata + encrypted body)
|
|
||||||
- Delete message
|
|
||||||
- Fetch recipient public key (for outbound encryption)
|
|
||||||
- Send message (modelled from the open-source `ProtonMail/proton-bridge` Go implementation)
|
|
||||||
|
|
||||||
### 4. Crypto layer
|
|
||||||
Using `rpgp` or `proton-crypto-rs`:
|
|
||||||
- Decrypt the user's private key (delivered encrypted by the API, unlocked with the mailbox password)
|
|
||||||
- Decrypt incoming message bodies with the private key
|
|
||||||
- Encrypt outbound messages to recipient public keys
|
|
||||||
|
|
||||||
### 5. Message store
|
|
||||||
In-memory (optionally persisted) mapping between IMAP sequence numbers and Proton message IDs.
|
|
||||||
IMAP uses stable sequential integers; Proton uses opaque string IDs. The store must:
|
|
||||||
- Assign sequence numbers to messages in order
|
|
||||||
- Renumber correctly after deletes
|
|
||||||
- Survive restarts without breaking existing client state
|
|
||||||
|
|
||||||
### 6. IMAP server
|
|
||||||
TCP listener on `localhost:143` (configurable). Implements the nine commands `skim` uses:
|
|
||||||
|
|
||||||
| Command | Purpose |
|
|
||||||
|---------|---------|
|
|
||||||
| `LOGIN` | Accept local credentials (no real auth needed) |
|
|
||||||
| `NOOP` | Keepalive / connection check |
|
|
||||||
| `SELECT INBOX` | Open mailbox, report message count |
|
|
||||||
| `FETCH range BODY.PEEK[HEADER.FIELDS (SUBJECT FROM DATE)]` | List emails |
|
|
||||||
| `FETCH seq BODY.PEEK[]` | Fetch full message body |
|
|
||||||
| `SEARCH OR SUBJECT "..." FROM "..."` | Search by subject or sender |
|
|
||||||
| `STORE seq +FLAGS (\Deleted)` | Mark for deletion |
|
|
||||||
| `EXPUNGE` | Delete marked messages |
|
|
||||||
| `LOGOUT` | Disconnect |
|
|
||||||
|
|
||||||
Each command translates to API client + crypto layer calls via the message store.
|
|
||||||
|
|
||||||
### 7. SMTP server
|
|
||||||
TCP listener on `localhost:587` (configurable). Minimal implementation:
|
|
||||||
- EHLO, AUTH, MAIL FROM, RCPT TO, DATA, QUIT
|
|
||||||
- On DATA completion: hand the message to the crypto layer to encrypt, then POST via API client
|
|
||||||
|
|
||||||
## Build order
|
|
||||||
|
|
||||||
Components 2 → 3 → 4 can be built and tested with a simple CLI harness before any
|
|
||||||
network server exists. Component 5 is pure logic with no I/O. Components 6 and 7 are
|
|
||||||
the final pieces and can be validated by pointing `tuimail` at localhost.
|
|
||||||
|
|
||||||
## References
|
|
||||||
|
|
||||||
- [ProtonMail/proton-bridge](https://github.com/ProtonMail/proton-bridge) — official Bridge (Go, open source)
|
|
||||||
- [ProtonMail/go-proton-api](https://github.com/ProtonMail/go-proton-api) — official Go API client
|
|
||||||
- [ProtonMail/proton-crypto-rs](https://github.com/ProtonMail/proton-crypto-rs) — official Rust crypto crates
|
|
||||||
- [ProtonMail/proton-srp](https://github.com/ProtonMail/proton-srp) — official Rust SRP implementation
|
|
||||||
- [rpgp](https://github.com/rpgp/rpgp) — pure Rust OpenPGP implementation
|
|
||||||
|
|
||||||
More work:
|
|
||||||
- local storge in the proton-bridge. Decide whether to store the message body pgp-encrypted, as it came from the proton server, or
|
|
||||||
use decrypt it (and serve to the client using imap) and create a AES-256-GCM encrypted cache
|
|
||||||
- email replies in the tui client have not yet been implemented
|
|
||||||
|
|
@ -4,52 +4,34 @@ tuimail is a terminal email client. It shows your inbox in a split-pane view:
|
||||||
the email list on top, the message preview on the bottom.
|
the email list on top, the message preview on the bottom.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
### Configure tuimail
|
||||||
|
Sorry, there is no binary release for now. This setup requires that you have rust cargo installed.
|
||||||
|
|
||||||
## Setup
|
Run the setup wizard:
|
||||||
|
|
||||||
tuimail stores passwords securely in the **OS keychain** (macOS Keychain,
|
|
||||||
GNOME Keyring, KWallet, Windows Credential Manager). No passwords are ever
|
|
||||||
written to disk in plain text.
|
|
||||||
|
|
||||||
### First-time setup
|
|
||||||
|
|
||||||
Simply run tuimail — if no config file exists it launches an interactive
|
|
||||||
wizard automatically:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo run
|
|
||||||
```
|
|
||||||
|
|
||||||
The wizard prompts for your provider, server settings, and passwords, then
|
|
||||||
saves the config file and stores all passwords in the OS keychain.
|
|
||||||
|
|
||||||
### Re-configure / update credentials
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo run -- --configure
|
cargo run -- --configure
|
||||||
```
|
```
|
||||||
|
(the first time --configure is active by default)
|
||||||
|
|
||||||
All prompts show current values in brackets. Press Enter to keep a value, or
|
When prompted for provider choose `imap/proton`, choose your provider:
|
||||||
type a new one. Password prompts show `[stored]` when a value already exists
|
|
||||||
in the keychain.
|
|
||||||
|
|
||||||
### Headless / CI environments (env-var fallback)
|
For Imap:
|
||||||
|
- IMAP host: `imap.gmail.com`, port: `993`, TLS: `true`
|
||||||
|
- Username
|
||||||
|
- Password
|
||||||
|
- SMTP host: `smtp.gmail.com`, port: `465`, TLS mode: `smtps`
|
||||||
|
|
||||||
If the OS keychain is unavailable, export the passwords as environment
|
For Proton
|
||||||
variables:
|
- Username: your proton account user name
|
||||||
|
- Password:
|
||||||
|
|
||||||
| Variable | Credential |
|
Tuimail stores passwords securely in the **OS keychain** (macOS Keychain,
|
||||||
|----------|------------|
|
GNOME Keyring, KWallet, Windows Credential Manager). No passwords are ever
|
||||||
| `TUIMAIL_IMAP_PASSWORD` | IMAP password |
|
written to disk in plain text.
|
||||||
| `TUIMAIL_SMTP_PASSWORD` | SMTP password |
|
|
||||||
| `TUIMAIL_PROTON_PASSWORD` | ProtonMail login password |
|
|
||||||
| `TUIMAIL_PROTON_MAILBOX_PASSWORD` | ProtonMail mailbox password (two-password mode) |
|
|
||||||
|
|
||||||
Example:
|
Note: every time you recreate the binary file using cargo,
|
||||||
|
Macos will need reapproval (4 times) for access to the keychain.
|
||||||
```bash
|
|
||||||
TUIMAIL_IMAP_PASSWORD=hunter2 cargo run
|
|
||||||
```
|
|
||||||
|
|
||||||
**Common provider settings**
|
**Common provider settings**
|
||||||
|
|
||||||
|
|
@ -57,51 +39,33 @@ TUIMAIL_IMAP_PASSWORD=hunter2 cargo run
|
||||||
|----------|-----------|-----------|---------|-----------|-----------|----------|
|
|----------|-----------|-----------|---------|-----------|-----------|----------|
|
||||||
| Gmail | imap.gmail.com | 993 | true | smtp.gmail.com | 465 | smtps |
|
| Gmail | imap.gmail.com | 993 | true | smtp.gmail.com | 465 | smtps |
|
||||||
| Outlook/Hotmail | outlook.office365.com | 993 | true | smtp.office365.com | 587 | starttls |
|
| Outlook/Hotmail | outlook.office365.com | 993 | true | smtp.office365.com | 587 | starttls |
|
||||||
| ProtonMail | see ProtonMail section below ||||| |
|
|
||||||
| Local test server | localhost | 143 | false | localhost | 25 | none |
|
|
||||||
|
|
||||||
> **Gmail note:** You must use an [App Password](https://myaccount.google.com/apppasswords),
|
|
||||||
> not your regular password. Enable 2-Step Verification first, then generate an
|
|
||||||
> App Password for "Mail".
|
|
||||||
|
|
||||||
### ProtonMail
|
### ProtonMail
|
||||||
|
Tuimail can talk to ProtonMail directly — no separate bridge process needed!
|
||||||
tuimail can talk to ProtonMail directly — no separate bridge process needed.
|
All transport is secure, except on localhost between client and built-in bridge service. This will be addressed soon.
|
||||||
The bridge starts automatically in-process when `provider = "proton"` is set.
|
|
||||||
|
|
||||||
**1. Build with ProtonMail support:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo build --features proton
|
|
||||||
```
|
|
||||||
|
|
||||||
**2. Run the setup wizard:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo run --features proton -- --configure
|
|
||||||
```
|
|
||||||
|
|
||||||
The wizard prompts for your ProtonMail username and password (stored in
|
|
||||||
keychain), two-password mode, and bridge ports. The bridge local password is
|
|
||||||
auto-generated and stored in the keychain.
|
|
||||||
|
|
||||||
**3. Run:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo run --features proton
|
|
||||||
```
|
|
||||||
|
|
||||||
The bridge authenticates with ProtonMail before the TUI opens. Messages are
|
|
||||||
decrypted on the fly; sent mail is encrypted end-to-end automatically.
|
|
||||||
|
|
||||||
Then run (standard providers):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo run --release
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Local cache:
|
||||||
|
Messages are safely stored locally using AES-256-GCM.
|
||||||
|
|
||||||
|
## Extra Configuration needed for Gmail
|
||||||
|
|
||||||
|
### 1. Enable 2-Step Verification
|
||||||
|
|
||||||
|
App Passwords require 2-Step Verification to be enabled on your Google account.
|
||||||
|
|
||||||
|
1. Go to https://myaccount.google.com/security
|
||||||
|
2. Under "How you sign in to Google", click **2-Step Verification**
|
||||||
|
3. Follow the prompts to enable it
|
||||||
|
|
||||||
|
### 2. Create an App Password
|
||||||
|
|
||||||
|
1. Go to https://myaccount.google.com/apppasswords
|
||||||
|
2. Enter a name (e.g. "Mail TUI") and click **Create**
|
||||||
|
3. Google will display a 16-character password — copy it
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Interface
|
## Interface
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -223,27 +187,3 @@ progress. Your current selection is preserved across refreshes.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Configuration Reference
|
|
||||||
|
|
||||||
### `[imap]`
|
|
||||||
|
|
||||||
| Key | Type | Description |
|
|
||||||
|-----|------|-------------|
|
|
||||||
| `host` | string | IMAP server hostname |
|
|
||||||
| `port` | integer | IMAP port (usually 993 with TLS, 143 without) |
|
|
||||||
| `username` | string | Login username (usually your full email address) |
|
|
||||||
| `use_tls` | bool | `true` for IMAPS (port 993), `false` for plain/STARTTLS |
|
|
||||||
|
|
||||||
> Password is stored in the OS keychain. Use `--configure` to set or update it.
|
|
||||||
|
|
||||||
### `[smtp]`
|
|
||||||
|
|
||||||
| Key | Type | Description |
|
|
||||||
|-----|------|-------------|
|
|
||||||
| `host` | string | SMTP server hostname |
|
|
||||||
| `port` | integer | SMTP port |
|
|
||||||
| `username` | string | Login username |
|
|
||||||
| `tls_mode` | string | `none`, `starttls`, or `smtps` |
|
|
||||||
| `from` | string | Sender address shown to recipients, e.g. `Name <addr>` |
|
|
||||||
|
|
||||||
> Password is stored in the OS keychain. Use `--configure` to set or update it.
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
|
||||||
mailserver:
|
|
||||||
image: mailserver/docker-mailserver:latest
|
|
||||||
container_name: mailserver
|
|
||||||
hostname: mail.example.com
|
|
||||||
ports:
|
|
||||||
- "25:25" # SMTP
|
|
||||||
- "143:143" # IMAP
|
|
||||||
- "587:587" # SMTP Submission
|
|
||||||
- "993:993" # IMAPS
|
|
||||||
volumes:
|
|
||||||
- ./docker-data/mail-data:/var/mail
|
|
||||||
- ./docker-data/mail-state:/var/mail-state
|
|
||||||
- ./docker-data/mail-logs:/var/log/mail
|
|
||||||
- ./docker-data/config:/tmp/docker-mailserver
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
environment:
|
|
||||||
- ENABLE_SPAMASSASSIN=0
|
|
||||||
- ENABLE_CLAMAV=0
|
|
||||||
- ENABLE_FAIL2BAN=0
|
|
||||||
- ENABLE_POSTGREY=0
|
|
||||||
- ONE_DIR=1
|
|
||||||
- DMS_DEBUG=0
|
|
||||||
- PERMIT_DOCKER=network
|
|
||||||
- SSL_TYPE=
|
|
||||||
cap_add:
|
|
||||||
- NET_ADMIN
|
|
||||||
restart: unless-stopped
|
|
||||||
Loading…
Add table
Reference in a new issue