ITADN
forwardemail/mail.forwardemail.net
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈

Forward Email - Webmail, Desktop, and Mobile

这是 Forward Email 的官方、开源且端到端加密的 webmail 客户端。它以快速现代的 web 应用、支持 Windows、macOS 和 Linux 的跨平台桌面应用,以及适用于 iOS 和 Android 的原生移动应用形式提供。

Table of Contents

下载与发布

官方桌面版和 Android 版制品发布在 GitHub Releases 页面。桌面版构建由公开的 GitHub Actions 发布工作流生成,桌面版发布矩阵现针对 macOS arm64/x64Windows x64/arm64Linux x64/arm64

平台架构下载商店
Webmail.forwardemail.net
Windowsx64.msi / .exe on GitHub Releases
Windowsarm64-setup.exe on GitHub Releases
macOSApple Silicon & Intel.dmg on GitHub ReleasesApp Store (Coming Soon)
Linuxx64.deb / .AppImage / .rpm on GitHub Releases
Linuxarm64.deb / .rpm on GitHub Releases
AndroidUniversal.apk / .aab on GitHub ReleasesGoogle Play (Coming Soon)
iOSarm64TestFlight / App Store distributionApp Store (Coming Soon)

Ubuntu / Debian 安装

对于 Ubuntu x64 / amd64,请下载当前的 .deb 资产,来自 GitHub Releases,然后使用以下命令安装:

sudo apt update
sudo apt install ./Forward.Email_<version>_amd64.deb

对于 Ubuntu arm64 / aarch64,以相同方式安装对应的 arm64 .deb

sudo apt update
sudo apt install ./Forward.Email_<version>_arm64.deb

对于可移植的 Linux x64 / amd64 二进制文件,请从 GitHub Releases 下载 Forward.Email_<version>_amd64.AppImage,使其可执行,并直接运行。发布矩阵未提供 arm64 AppImage;Linux arm64 用户应改为安装 .deb.rpm 资源。

chmod +x Forward.Email_<version>_amd64.AppImage
./Forward.Email_<version>_amd64.AppImage

如果你正在构建自己的自定义 Linux 二进制文件,而不是安装已发布的版本,请使用 docs/desktop-setup.md 中的桌面开发指南。

macOS 用户注意: 如果你从 GitHub Releases 下载 .dmg,当看到“已损坏”或未验证的应用程序错误时,可能需要运行以下命令:

sudo xattr -rd com.apple.quarantine "/Applications/Forward Email.app"

如果你将应用程序安装在其他位置,请将 /Applications/Forward Email.app 替换为实际路径。

截图

截图截至 2026 年 8 月 5 日。

这些截图是在每次成功发布后,从生产环境的 Demo Account 自动捕获的。展开主题和设备组以浏览其视图。

深色模式 — 桌面端
视图截图
登录页面Dark mode login page
邮件视图Dark mode mail view
消息视图Dark mode message view
撰写窗口Dark mode compose window
联系人页面Dark mode contacts page
日历页面Dark mode calendar page
个人资料页面Dark mode profile page
诊断页面Dark mode diagnostics page
常规设置页面Dark mode general settings page
外观设置页面Dark mode appearance settings page
隐私和安全页面Dark mode privacy and security page
文件夹和标签设置页面Dark mode folders and labels settings page
搜索设置页面Dark mode search settings page
高级设置页面Dark mode advanced settings page
键盘快捷键页面Dark mode keyboard shortcuts page
关于和帮助页面Dark mode about and help page
深色模式 — 移动端
视图截图
登录页面Dark mode mobile login page
邮件视图Dark mode mobile mail view
消息视图Dark mode mobile message view
撰写窗口Dark mode mobile compose window
联系人页面Dark mode mobile contacts page
日历页面Dark mode mobile calendar page
个人资料页面Dark mode mobile profile page
诊断页面Dark mode mobile diagnostics page
常规设置页面Dark mode mobile general settings page
外观设置页面Dark mode mobile appearance settings page
隐私和安全页面Dark mode mobile privacy and security page
文件夹和标签设置页面Dark mode mobile folders and labels settings page
搜索设置页面Dark mode mobile search settings page
高级设置页面Dark mode mobile advanced settings page
键盘快捷键页面Dark mode mobile keyboard shortcuts page
关于和帮助页面Dark mode mobile about and help page
浅色模式 — 桌面端
视图截图
登录页面Light mode login page
邮件视图Light mode mail view
消息视图Light mode message view
撰写窗口Light mode compose window
联系人页面Light mode contacts page
日历页面Light mode calendar page
个人资料页面Light mode profile page
诊断页面Light mode diagnostics page
常规设置页面Light mode general settings page
外观设置页面Light mode appearance settings page
隐私和安全页面Light mode privacy and security page
文件夹和标签设置页面Light mode folders and labels settings page
搜索设置页面Light mode search settings page
高级设置页面Light mode advanced settings page
键盘快捷键页面Light mode keyboard shortcuts page
关于和帮助页面Light mode about and help page
浅色模式 — 移动端
视图截图
登录页面Light mode mobile login page
邮件视图Light mode mobile mail view
消息视图Light mode mobile message view
撰写窗口Light mode mobile compose window
联系人页面Light mode mobile contacts page
日历页面Light mode mobile calendar page
个人资料页面Light mode mobile profile page
诊断页面Light mode mobile diagnostics page
常规设置页面Light mode mobile general settings page
外观设置页面Light mode mobile appearance settings page
隐私和安全页面Light mode mobile privacy and security page
文件夹和标签设置页面Light mode mobile folders and labels settings page
搜索设置页面Light mode mobile search settings page
高级设置页面Light mode mobile advanced settings page
键盘快捷键页面Light mode mobile keyboard shortcuts page
关于和帮助页面Light mode mobile about and help page

安全与隐私

安全是本应用的基础原则。我们致力于保持透明,并赋予用户对其数据的控制权。有关我们安全实践的详细说明,请参阅:

客户端加密与应用锁

该应用提供强大的应用锁功能,可对您的整个客户端数据库和设置进行加密——无论是在浏览器、桌面还是移动设备上。当从设置 > 隐私与安全菜单启用时,所有本地存储的敏感数据(包括消息正文、联系人和 API 令牌)都会使用经过审计的 libsodium 库中的 XSalsa20-Poly1305 流密码进行静态加密。

此功能可通过以下两种方式进行保护:

  1. 通行密钥 (WebAuthn):为了获得最高级别的安全性,您可以使用符合 FIDO2/WebAuthn 标准的身份验证器来锁定和解锁应用。这允许您使用硬件安全密钥或设备内置的生物识别功能。加密密钥直接通过 PRF 扩展从身份验证器派生,这意味着密钥本身不会存储在设备上。
  2. PIN 码:为了方便起见,您可以设置一个简单的 PIN 码。这提供了类似 iOS 的锁屏体验,非常适合在移动设备上快速访问。

我们的实现支持用于基于通行密钥的应用锁的广泛身份验证器:

TypeExamples
Platform AuthenticatorsApple Touch ID, Face ID, Optic ID, Windows Hello, Android Biometrics (fingerprint, face)
Hardware Security KeysYubiKey 5 Series, YubiKey Bio, Google Titan, Feitian ePass/BioPass, SoloKeys, Nitrokey 3, HID Crescendo, Ledger
Cloud/Software PasskeysiCloud Keychain, Google Password Manager, Samsung Pass, 1Password, Dashlane, Bitwarden, Proton Pass

防篡改构建

所有构建均由公共 GitHub Actions 工作流直接从源代码处理。桌面应用程序使用平台特定的证书进行签名(Apple Developer ID 和 Windows Authenticode),并且 Tauri 更新器使用 Ed25519 签名来验证每个更新包。邮箱内容和 WebSocket 更新直接在应用程序和 Forward Email 之间传输。仅在操作系统要求时才使用平台交付基础设施:iOS 上的 APNs,Android 上的 FCM 或用户选择的 UnifiedPush 分发器,以及用于桌面更新包的 GitHub Releases。Forward Email 不会在这些路径中添加广告、分析或跟踪中间件。

功能

  • 极速体验: 基于 Rust 和 Svelte 5 构建,提供轻量且响应迅速的使用体验。
  • 端到端加密: 为您的整个客户端应用提供加密保护——无论是浏览器、桌面端还是移动端。
  • 开源: Web、桌面和移动应用的所有代码均可在 GitHub 上获取。
  • 无广告或跟踪中间件: 邮箱数据和实时 WebSocket 更新仅在应用与 Forward Email 之间传输。平台推送服务商和发布托管仅用于交付原生通知和签名的应用更新。
  • 实时更新: 邮箱更新通过 WebSockets 即时推送。
  • 跨平台通知: 原生桌面和移动推送通知。
  • 多账户 — 使用多个 Forward Email 账户登录,别名认证,以及可选的 API 密钥覆盖。
  • 邮箱 — 文件夹、消息线程、批量操作、键盘快捷键、附件处理、PGP 解密。
  • 撰写 — 富文本编辑器 (TipTap),CC/BCC,表情选择器,附件,草稿自动保存,离线发件箱队列。
  • 搜索 — 基于 FlexSearch 的全文搜索,可选正文索引,保存的搜索,后台索引。
  • 离线支持: 自定义的主线程同步引擎提供离线访问并排队出站操作,取代了对 Service Worker 的需求,并确保在所有平台(包括 Ionic/Capacitor 移动端)上的功能正常。
  • 日历 — 月/周/日视图,快速添加/编辑/删除,iCal 导出。
  • Contacts — CRUD 操作,vCard 导入/导出,用于撰写/搜索的深度链接。
  • Demo Mode:无需账户即可离线评估应用功能。
  • mailto: Handler:在桌面平台上注册为默认邮件客户端。
  • Auto-Updates:桌面应用会自动安全地检查并安装新版本。

架构概览

该应用基于统一架构构建,在所有平台上复用同一个 Svelte 5 Web 应用作为 UI。Tauri v2 提供跨平台外壳,使用 Rust 后端实现原生功能,并使用系统 webview 渲染 UI。

graph TD
    subgraph "Web App (Svelte 5 + Vite)"
        A[UI Components] --> B(Stores)
        B --> C{API Client}
        C --> D[REST API]
        B --> E{WebSocket Client}
        E --> F[Real-time API]
    end
    subgraph "Tauri (Desktop & Mobile)"
        G[Rust Backend] --> H{System WebView}
        H -- loads --> A
        I[Tauri IPC] -- JS Bridge --> A
        G -- IPC --> I
        J[Tauri Plugins] --> G
    end
    D --- M(api.forwardemail.net)
    F --- M

有关更多详细信息,请参阅完整的架构文档

技术栈

类别技术
WebSvelte 5, Vite, pnpm
Desktop & MobileTauri v2 (Rust 后端, Svelte 前端)
StylingTailwind CSS 4, PostCSS
StateSvelte Stores
DatabaseDexie 4 (IndexedDB)
SearchFlexSearch
EditorTipTap 2
Calendarschedule-x
Real-time使用 msgpackr 二进制编码的 WebSocket
Encryptionlibsodium-wrappers (XSalsa20-Poly1305, Argon2id), OpenPGP
Passkeys@passwordless-id/webauthn (带 PRF 扩展的 FIDO2/WebAuthn)
TestingVitest, 用于 E2E 测试的 Playwright, 用于 Tauri 二进制测试的 WebdriverIO
ToolingESLint 9, Prettier 3, Husky, commitlint

关键组件

  • Main Thread — Svelte 组件、stores、路由、UI 渲染
  • db.worker — 通过 Dexie 拥有 IndexedDB,处理所有数据库操作
  • sync.worker — API 获取、消息解析(PostalMime)、数据规范化
  • search.worker — FlexSearch 索引和查询执行

Documentation

详细的架构文档可在 docs/ 目录中找到:

项目结构

src/
├── main.ts                 # App bootstrap, routing, service worker registration
├── config.ts               # Environment configuration
├── stores/                 # Svelte stores (state management)
│   ├── mailboxStore.ts     # Message list, folders, threading
│   ├── mailboxActions.ts   # Move, delete, flag, label actions
│   ├── messageStore.ts     # Selected message, body, attachments
│   ├── searchStore.ts      # Search queries and index health
│   ├── settingsStore.ts    # User preferences, theme, PGP keys
│   └── ...
├── svelte/                 # Svelte components
│   ├── Mailbox.svelte      # Main email interface
│   ├── Compose.svelte      # Email composer
│   ├── Calendar.svelte     # Calendar view
│   ├── Contacts.svelte     # Contact management
│   ├── Settings.svelte     # User settings
│   └── components/         # Reusable components
├── workers/                # Web Workers
│   ├── db.worker.ts        # IndexedDB operations
│   ├── sync.worker.ts      # API sync and parsing
│   └── search.worker.ts    # Search indexing
├── utils/                  # Utilities
│   ├── remote.js           # API client
│   ├── db.js               # Database initialization
│   ├── storage.js          # LocalStorage management
│   └── ...
├── lib/components/ui/      # UI component library (shadcn/ui)
├── styles/                 # CSS (Tailwind + custom)
├── locales/                # i18n translations
└── types/                  # TypeScript definitions

快速开始

前置条件

安装

pnpm install

开发

pnpm dev              # Start web dev server (http://localhost:5174)
pnpm tauri dev        # Start desktop dev mode
pnpm tauri:android:dev  # Start Android dev mode (preflight checks + adb setup)
pnpm tauri:ios:dev      # Start iOS dev mode (preflight checks + simulator boot)

构建

pnpm build        # Build to dist/ + generate service worker
pnpm preview      # Preview production build locally
pnpm analyze      # Build with bundle analyzer

代码质量

pnpm lint         # Run ESLint
pnpm lint:fix     # Fix linting issues
pnpm format       # Check formatting
pnpm format:fix   # Fix formatting
pnpm check        # Run svelte-check

测试

# Unit tests (Vitest)
pnpm test              # Run all tests
pnpm test:watch        # Watch mode
pnpm test:coverage     # Generate coverage report

# E2E tests (Playwright)
pnpm exec playwright install --with-deps  # First-time setup
pnpm test:e2e          # Run e2e tests

贡献

提交信息

本项目使用由 commitlint 强制执行的 Conventional Commits。每条提交信息都必须遵循以下格式:

type(scope): description
类型使用时机版本提升
feat新功能minor
fix缺陷修复patch
docs仅文档更新none
refactor既不修复也不新增的代码变更none
perf性能改进patch
test添加或更新测试none
chore构建、CI、工具链变更none

作用域是可选的:fix(compose): handle pasted recipientsfix: handle pasted recipients 均有效。

要触发 major 版本提升,请添加 BREAKING CHANGE: 页脚:

feat: redesign settings page

BREAKING CHANGE: settings store schema changed, requires cache clear

发布

发布在本地使用 np 进行管理。版本升级仍然通过 pnpm release 进行,桌面端工件的发布由 Tauri 桌面端发布工作流以及用于桌面端专用热修复的 pnpm release:desktop 辅助工具处理。

pnpm release            # interactive version prompt, runs checks, pushes, publishes GitHub Release

该命令将执行以下操作:

  1. 验证工作区干净且 main 分支为最新状态
  2. 运行 lint、格式化、测试和构建
  3. 更新 package.json 中的版本号并创建 git 标签
  4. 将提交和标签推送到 GitHub
  5. 发布 GitHub Release

对于桌面端发布,推送桌面标签或手动运行工作流会触发 Release Desktop (Tauri) (.github/workflows/release-desktop.yml),该流程会创建或更新一个草稿 GitHub Release,并上传 macOS x64/arm64、Windows x64/arm64 和 Linux x64/arm64 的桌面端构建产物。

配置

创建一个 .env 文件以覆盖默认设置:

# API base URL (Vite requires VITE_ prefix for client exposure)
VITE_WEBMAIL_API_BASE=https://api.forwardemail.net

部署

首次设置? 请参阅完整的 部署清单,了解 Cloudflare、GitHub Actions 和 DNS 配置的逐步说明。

基础设施

graph TB
    subgraph Edge["Cloudflare Edge"]
        subgraph Worker["Cloudflare Worker"]
            W1["SPA routing (returns index.html for /mailbox, etc)"]
            W2["Cache headers (immutable for assets, no-cache HTML)"]
        end
        Worker --> R2
        subgraph R2["Cloudflare R2"]
            R2A["Static assets (dist/)"]
            R2B["Fingerprinted bundles (/assets/*.js, *.css)"]
        end
    end

缓存策略

资源类型Cache-Control原因
index.html, /mailbox, /calendar, 等no-cache, no-store始终获取最新 HTML 以进行更新
/assets/* (JS, CSS)immutable, max-age=31536000由 Vite 进行指纹处理,可永久缓存
sw.js, sw-*.js, version.jsonno-cache, must-revalidateService worker 必须检查更新
/icons/*max-age=259200030 天,很少更改
字体 (.woff2)immutable, max-age=31536000已指纹处理,永久缓存

CI/CD 流水线

顶层 Release 工作流 (.github/workflows/release.yml) 是每个 v* 标签的生产环境编排器。它运行 WebView E2E 门禁,创建草稿 GitHub Release,调用可复用的桌面和移动工作流,将 Web 应用程序部署到 Cloudflare R2 和 Workers,发布版本,生成校验和,并可选地发送 Matrix 通知。

编排器调用两个可复用的平台工作流:

  1. Release Desktop (Tauri) (.github/workflows/release-desktop.yml) 构建 macOS x64/arm64、Windows x64/arm64 和 Linux x64/arm64 桌面工件。请参阅 Desktop Build CI guide 了解平台矩阵、运行器详情和工件预期。
  2. Release Mobile (.github/workflows/release-mobile.yml) 构建已签名的双提供商 Android APK/AAB 和已签名的 iOS IPA,然后上传已配置的商店工件。请参阅 Release ProcessiOS SetupSecrets 了解确切的签名输入和发布流程。

独立的 deploy.yml 工作流是手动 workflow_dispatch 恢复路径,用于重新部署当前的 web 构建;常规的带标签发布从 release.yml 内联部署。

发布工作的本地验证在标记发布之前,仍应涵盖标准的 Web 检查:

  1. Installpnpm install --frozen-lockfile
  2. Lintpnpm lint
  3. Formatpnpm format
  4. Unit testspnpm test -- --run
  5. Buildpnpm build
  6. Desktop build smoke testpnpm tauri:build for the target platform you are validating

如需精确的密钥生成、GitHub 环境配置以及特定平台的签名步骤,请以 docs/SECRETS.md 作为权威指南,并以 docs/desktop-ci-secrets.mddocs/ios-setup.md 作为特定平台的配套文档。

必需的密钥与变量

GitHub 机密:

SecretDescription
R2_ACCOUNT_IDCloudflare 账户 ID(也用于 Workers)
R2_ACCESS_KEY_IDR2 API 访问密钥
R2_SECRET_ACCESS_KEYR2 API 密钥
CLOUDFLARE_ZONE_ID用于缓存清除的 Zone ID
CLOUDFLARE_API_TOKEN具有 R2 + Workers + 缓存清除权限的 API 令牌
TAURI_SIGNING_PRIVATE_KEYTauri 更新器 Ed25519 签名密钥
TAURI_SIGNING_PRIVATE_KEY_PASSWORDTauri 签名密钥的密码
APPLE_CERTIFICATEBase64 编码的 macOS .p12 签名证书
APPLE_CERTIFICATE_PASSWORD用于导出 macOS .p12 的密码
APPLE_SIGNING_IDENTITYApple Developer ID 签名身份
APPLE_ID用于公证的 Apple ID
APPLE_PASSWORD用于公证的应用专用密码
APPLE_TEAM_IDApple Developer 团队 ID
WINDOWS_CERTIFICATEBase64 编码的可导出 Windows .pfx 代码签名证书
WINDOWS_CERTIFICATE_PASSWORD用于导出 Windows .pfx 的密码
ANDROID_KEYSTORE_BASE64Android 签名密钥库(base64)
ANDROID_KEYSTORE_PASSWORDAndroid 密钥库的密码
ANDROID_KEY_ALIASAndroid 签名密钥别名
ANDROID_KEY_PASSWORDAndroid 签名密钥的密码
IOS_CERTIFICATE_BASE64Base64 编码的 iOS Apple Distribution .p12
IOS_CERTIFICATE_PASSWORD用于导出 iOS .p12 的密码
IOS_PROVISIONING_PROFILE_BASE64Base64 编码的 App Store 描述文件
APP_STORE_CONNECT_API_KEY下载的 App Store Connect .p8 密钥的完整内容
APP_STORE_CONNECT_KEY_IDApp Store Connect API 密钥 ID
APP_STORE_CONNECT_ISSUER_IDApp Store Connect 颁发者 ID
GOOGLE_SERVICES_JSON_BASE64双提供商构建的 Firebase Android 客户端配置
GOOGLE_PLAY_SERVICE_ACCOUNT可选的 Google Play 发布服务账户 JSON
MATRIX_TOKEN可选的用于发布和活动通知的仓库密钥

上述所有密钥中,除 MATRIX_TOKEN 外,均属于 release 环境。MATRIX_TOKEN 是仓库级 Actions 密钥,因为通知作业未附加 release 环境。GITHUB_TOKEN 由 GitHub Actions 自动提供,不得手动创建。

GitHub 变量:

变量描述
R2_BUCKET用于静态资产的 R2 存储桶名称
IOS_SIGNING_IDENTITY可选的 iOS 签名身份覆盖;默认为 Apple Distribution
VAPID_PUBLIC_KEY嵌入 Android 发布构建中的后端 VAPID 密钥对的必需公钥部分
PLAY_TRACK可选的 Google Play 轨道;默认为 internal
ALLOW_NO_UPDATER紧急桌面端覆盖;true 允许在没有更新器签名的情况下发布构建产物

ALLOW_NO_UPDATER 是应急仓库变量,而非常规发布设置。请保持其未设置状态,以便在 TAURI_SIGNING_PRIVATE_KEY 缺失时桌面端发布失败关闭。

有关生成步骤、存储位置、必需/可选状态以及确切的设置说明,请参阅 docs/SECRETS.md.

Cloudflare API 令牌设置

My Profile → API Tokens → Create Token → Create Custom Token 处创建令牌:

权限:

作用域权限访问
用户用户详情读取
账户Workers 脚本编辑
区域缓存清除清除

账户资源:

  • 选择 Include → Specific account → [Your Account]
  • Include → All accounts(如果您只有一个账户)

区域资源:

  • 选择 Include → Specific zone → [Your Domain]
  • Include → All zones

常见错误: 设置了权限,但将“账户/区域资源”保留为“所有来自……的账户”下拉菜单,而未明确进行选择。您必须点击并选择特定的账户/区域。

工作节点设置

CDN 工作器(worker/)处理:

  1. SPA Routing — Returns index.html for navigation requests to /mailbox, /calendar, /contacts, /login
  2. Cache Headers — Sets correct Cache-Control per asset type
  3. Security HeadersX-Content-Type-Options, X-Frame-Options

首次部署后,配置自定义域名:

  1. Cloudflare 控制台 → Workers & Pages → webmail-cdn
  2. 设置 → 触发器 → 添加自定义域名
  3. 输入您的域名(例如,mail.example.com

手动部署

# Build the app
pnpm build

# Deploy to R2 (requires AWS CLI configured with R2 credentials)
aws --endpoint-url "https://ACCOUNT_ID.r2.cloudflarestorage.com" \
    s3 sync dist/ "s3://BUCKET_NAME/" --delete

# Deploy worker
cd worker
pnpm install
npx wrangler deploy

# Purge Cloudflare cache
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache" \
    -H "Authorization: Bearer API_TOKEN" \
    -H "Content-Type: application/json" \
    --data '{"purge_everything":true}'

故障排除

部署后资源未更新:

  • 在 GitHub Actions 日志中验证缓存清除是否成功
  • 检查浏览器 DevTools → Network → Disable cache 并刷新
  • 磁盘缓存了 HTML 的用户可能需要清除浏览器缓存或等待回退恢复 UI

SPA 路由返回 404:

  • 确保 worker 已部署并绑定到您的域名
  • 检查 worker 日志:cd worker && npx wrangler tail

Service worker 未更新:

  • 检查 version.json 是否被重新获取(无缓存)
  • 验证 sw.js 在 Network 标签页中是否有 no-cache

许可证

Business Source License 1.1 - Forward Email LLC