mirror of
https://github.com/spartanz51/tutabridge.git
synced 2026-06-24 10:54:32 +02:00
Centered header (app icon + tagline + nav), shields.io badges (CI, release, license, platforms, stack), an emoji feature grid, collapsible per-OS install details, a connection-settings table, and callouts. Same content, presented like a real project landing page.
259 lines
10 KiB
Markdown
259 lines
10 KiB
Markdown
<div align="center">
|
|
|
|
<img src="src-tauri/icons/icon.png" alt="TutaBridge logo" width="120" height="120" />
|
|
|
|
# TutaBridge
|
|
|
|
**Use [Tuta](https://tuta.com) encrypted email in Thunderbird, Apple Mail, or any standard mail client.**
|
|
|
|
A local IMAP/SMTP bridge that talks to Tuta's API and handles the end-to-end
|
|
encryption transparently — so your favourite desktop client just works.
|
|
|
|
<br/>
|
|
|
|
[](https://github.com/spartanz51/tutabridge/actions/workflows/ci.yml)
|
|
[](https://github.com/spartanz51/tutabridge/releases)
|
|
[](LICENSE)
|
|
[](#-install)
|
|
[](#-build-from-source)
|
|
|
|
[**Install**](#-install) · [**Getting started**](#-getting-started) · [**Features**](#-features) · [**Backup**](#-backup) · [**Architecture**](#-architecture)
|
|
|
|
</div>
|
|
|
|
> ⚠️ **Unofficial & unsigned.** TutaBridge is an independent project — not
|
|
> affiliated with, endorsed by, or supported by Tuta. It logs into your account
|
|
> and decrypts your mail locally, outside Tuta's official apps; use it at your
|
|
> own risk. The released binaries are **not code-signed**, so macOS and Windows
|
|
> warn on first launch — see [Install](#-install) for how to get past that.
|
|
|
|
---
|
|
|
|
## ✨ Features
|
|
|
|
| | |
|
|
|---|---|
|
|
| 📥 **IMAP + SMTP** | Local TLS servers on `127.0.0.1` — any standard mail client connects. |
|
|
| ⚡ **Realtime sync** | Tuta's WebSocket event bus pushes new mail, reads, moves and deletes; a heartbeat + idle-timeout reconnect dead sockets automatically. |
|
|
| 🗂️ **Whole mailbox** | Every folder and message is listed — not just a recent slice. |
|
|
| 🔍 **Honest search** | Subject / sender / date search the entire mailbox; full-text **body** search via an encrypted on-disk index. |
|
|
| 📎 **Attachments** | Both ways — incoming served as `multipart/mixed`, outgoing uploaded to Tuta on send. |
|
|
| 📝 **Folders & flags** | Drafts, custom / nested folders, move, trash, read/unread. |
|
|
| 🔐 **Encrypted cache** | Metadata in SQLCipher, bodies as individually-encrypted `.eml.enc` files — usable instantly on relaunch, only the delta is fetched. |
|
|
| 💾 **Complete backup** | Export *every* message to portable `.eml` files. |
|
|
| 🔑 **2FA (TOTP)** | Two-factor login supported. |
|
|
|
|
---
|
|
|
|
## 📦 Install
|
|
|
|
Download the latest build from the [**Releases**](https://github.com/spartanz51/tutabridge/releases)
|
|
page. Every platform ships two flavours:
|
|
|
|
- 🖥️ a **desktop app** — a normal double-click GUI, recommended for most people;
|
|
- ⌨️ a **CLI binary** — a single executable you run from a terminal, for headless / server use.
|
|
|
|
| Platform | Desktop app | CLI binary |
|
|
|----------|-------------|------------|
|
|
| **macOS** (Apple Silicon) | `TutaBridge_*_universal.dmg` | `tutabridge-macos-arm64` |
|
|
| **Windows** (x64) | `TutaBridge_*_x64-setup.exe` *(or `.msi`)* | `tutabridge-windows-x86_64.exe` |
|
|
| **Linux** (x64) | `*.AppImage` / `*.deb` / `*.rpm` | `tutabridge-linux-x86_64` |
|
|
|
|
Because the binaries aren't signed, each OS needs a **one-time nudge** to run them:
|
|
|
|
<details>
|
|
<summary><b>🍎 macOS</b></summary>
|
|
|
|
Open the `.dmg` and drag TutaBridge to **Applications**. On first launch macOS
|
|
says the app *"cannot be opened because the developer cannot be verified"* —
|
|
**right-click the app → Open → Open**, which whitelists it permanently. (A plain
|
|
double-click won't offer the override.)
|
|
</details>
|
|
|
|
<details>
|
|
<summary><b>🪟 Windows</b></summary>
|
|
|
|
Run the `.exe` or `.msi`. SmartScreen shows *"Windows protected your PC"* — click
|
|
**More info → Run anyway**.
|
|
</details>
|
|
|
|
<details>
|
|
<summary><b>🐧 Linux</b></summary>
|
|
|
|
```bash
|
|
chmod +x TutaBridge_*_amd64.AppImage && ./TutaBridge_*_amd64.AppImage
|
|
# or: sudo dpkg -i TutaBridge_*_amd64.deb # Debian / Ubuntu
|
|
# or: sudo rpm -i TutaBridge-*.x86_64.rpm # Fedora / RHEL
|
|
```
|
|
</details>
|
|
|
|
<details>
|
|
<summary><b>⌨️ CLI binary (any OS)</b></summary>
|
|
|
|
The CLI files have **no extension**, so double-clicking does nothing useful (your
|
|
OS may even open them in a text editor). Run them from a terminal:
|
|
|
|
```bash
|
|
chmod +x tutabridge-macos-arm64 # make it executable
|
|
xattr -d com.apple.quarantine tutabridge-macos-arm64 # macOS only: clear Gatekeeper
|
|
./tutabridge-macos-arm64 # run
|
|
```
|
|
</details>
|
|
|
|
---
|
|
|
|
## 🚀 Getting started
|
|
|
|
**1.** **Launch** the app (or run the CLI). On first run it asks for your Tuta
|
|
email, then your password and TOTP code if there's no saved session. The session
|
|
is stored in your OS keychain, so later launches resume automatically.
|
|
|
|
**2.** TutaBridge shows the **local connection details**. Note the **bridge
|
|
password** — this is generated by TutaBridge for local IMAP/SMTP auth and is
|
|
**not** your Tuta password. *(CLI: printed in the logs · GUI: shown on the main screen.)*
|
|
|
|
**3.** **Add the account** in your mail client with these settings:
|
|
|
|
| | Server | Port | Security | Auth |
|
|
|---|--------|------|----------|------|
|
|
| **IMAP** (incoming) | `127.0.0.1` | `1143` | SSL/TLS | Normal password |
|
|
| **SMTP** (outgoing) | `127.0.0.1` | `1025` | SSL/TLS | Normal password |
|
|
|
|
> **Username:** your Tuta email · **Password:** the bridge password from step 2
|
|
> · accept the **self-signed certificate** when prompted.
|
|
|
|
Keep TutaBridge running while you use your mail client — it *is* the local server
|
|
the client talks to.
|
|
|
|
<details>
|
|
<summary><b>Client-specific notes (Thunderbird, Apple Mail)</b></summary>
|
|
|
|
- **Thunderbird** — add the account manually (don't let auto-config probe public
|
|
servers). Set both servers to `127.0.0.1` with SSL/TLS + "Normal password", and
|
|
accept the certificate exception on first connect.
|
|
- **Apple Mail** — add an *"Other Mail Account"*, then in **Server Settings** turn
|
|
**off** "Automatically manage connection settings" so you can pin host
|
|
`127.0.0.1`, the ports above, and TLS.
|
|
</details>
|
|
|
|
> [!NOTE]
|
|
> **Search** runs in your mail client. Subject / sender / date search covers the
|
|
> whole mailbox; **body** (full-text) search covers messages whose body has been
|
|
> **downloaded**. Enable *"keep every message body offline"* (or raise the
|
|
> offline-bodies limit) for full-mailbox body search.
|
|
|
|
---
|
|
|
|
## 🧭 Architecture
|
|
|
|
Syncer-driven, store-backed — the IMAP server never makes a network call to *read*:
|
|
|
|
```
|
|
Tuta API ←── Syncer (background) ──→ MailStore (in-memory) ←── IMAP server ──→ mail client
|
|
←── GUI (stats)
|
|
```
|
|
|
|
- The **syncer** pulls from the Tuta API and populates an in-memory `MailStore`,
|
|
backed by the on-disk encrypted cache.
|
|
- The **IMAP server** only ever *reads* from the store — never an API call for reads.
|
|
- The only IMAP→network calls are mutations: mark read/unread (`STORE \Seen`) and
|
|
trash (`EXPUNGE`). Sending goes SMTP → Tuta's `DraftService` + `SendDraftService`.
|
|
|
|
The storage encryption key is derived from your Tuta session, so there's no extra
|
|
password to manage; the cache is encrypted at rest.
|
|
|
|
---
|
|
|
|
## 💾 Backup
|
|
|
|
Export **every** email to a folder of plain `.eml` files — one per message, in a
|
|
tree mirroring your IMAP folders. It enumerates all mail from the server (not just
|
|
what's currently synced), so nothing is silently left out.
|
|
|
|
```
|
|
<output>/
|
|
├── INBOX/
|
|
│ ├── 20260528-144935_OtjDuDU--3-9.eml
|
|
│ └── …
|
|
├── Sent/
|
|
├── Trash/
|
|
└── Café/Projets/…
|
|
```
|
|
|
|
```bash
|
|
tutabridge backup ~/TutaBackup # CLI
|
|
```
|
|
|
|
In the **GUI**, use the **Backup** tab — pick a folder, watch per-folder progress.
|
|
*(The bridge must be running; the backup reuses its signed-in session.)*
|
|
|
|
- **Format** — `.eml` (RFC 2822). Opens natively in Thunderbird / Apple Mail /
|
|
Outlook, survives Windows filesystems, and one corrupt file never sinks the
|
|
archive. Filenames are date-prefixed so a listing sorts chronologically.
|
|
- **Resumable / incremental** — re-running into the same folder skips messages
|
|
already on disk, so an interrupted backup resumes and a periodic re-backup only
|
|
fetches new mail.
|
|
- **Speed** — cached messages export instantly; the rest are fetched with a small
|
|
politeness delay, so a first full backup of a large mailbox can take minutes.
|
|
- **Scope** — every folder, including Trash and Spam.
|
|
|
|
---
|
|
|
|
## 🔨 Build from source
|
|
|
|
Requires the Rust toolchain and the `tuta-repo` submodule
|
|
(`git clone --recursive`, or `git submodule update --init --recursive`):
|
|
|
|
```bash
|
|
cargo build # CLI + core
|
|
cargo build -p tutabridge-core # core library only
|
|
cargo run # run the CLI from source
|
|
./dev.sh # GUI in dev mode (cargo tauri dev)
|
|
```
|
|
|
|
---
|
|
|
|
## 📁 Files & locations
|
|
|
|
Config and cache live under your platform's app-data directory — on macOS
|
|
`~/Library/Application Support/tutabridge/`:
|
|
|
|
```
|
|
config.toml account + ports + bridge_password + sync_limit
|
|
store.db SQLCipher metadata + full-text body index
|
|
mails/<id>.eml.enc per-mail encrypted bodies
|
|
```
|
|
|
|
`sync_limit` controls how many recent message **bodies** are kept offline; the
|
|
full mailbox is always listed and metadata-searchable regardless. Set it to `0`
|
|
(or tick *"keep every message body offline"* in the GUI) to download everything.
|
|
|
|
---
|
|
|
|
## 🧪 Testing
|
|
|
|
```bash
|
|
cargo test --workspace # unit + integration tests
|
|
python3 scripts/test_imap.py # integration test against a running bridge
|
|
```
|
|
|
|
The IMAP integration test connects to the local server and verifies TLS, auth,
|
|
folder list, mail count, body fetch and search. It reads the bridge password from
|
|
`config.toml` automatically.
|
|
|
|
---
|
|
|
|
## 🔌 SDK
|
|
|
|
TutaBridge depends on a few additions to Tuta's Rust SDK, vendored as the
|
|
`tuta-repo` submodule. Each change is kept as its own single-commit branch off
|
|
upstream for easy review / upstreaming — see [`SDK_PRS.md`](SDK_PRS.md) for status.
|
|
|
|
---
|
|
|
|
## 📄 License
|
|
|
|
[GPL-3.0-or-later](LICENSE). TutaBridge links Tuta's Rust SDK (part of the
|
|
GPLv3-licensed [tutanota](https://github.com/tutao/tutanota) project), so it is
|
|
distributed under the same license.
|