Skip to content

About

Android mail client for Microsoft Exchange 2007 SP1+ (ActiveSync + EWS) — Kotlin, Jetpack Compose, offline-first

Topics

Resources

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

iwo Mail Client

CI Release License Platform Min API Kotlin

🇬🇧 English: README_EN.md

Почтовый клиент для Android с основным фокусом на Microsoft Exchange Server 2007 SP1+ через Exchange ActiveSync (EAS) и Exchange Web Services (EWS). IMAP/POP3 присутствуют как beta-направление с ограниченной функциональностью.

Важно: 🚧 Работа над проектом активно ведётся. Следующая версия в релизе — 1.7.0. Отличия от 1.6.1 и последующих beta-сборок будут значительными.

Версия: 1.6.3b · Пакет: com.dedovmosol.iwomail · Разработчик: DedovMosol · Telegram: @i_wantout · Email: andreyid@outlook.com

📖 О проекте

  • Production-фокус: Exchange 2007 SP1/SP2 и совместимые on-premise Exchange-серверы.
  • Основной протокол: EAS 12.0/12.1/14.0/14.1 для почты, папок, контактов, Direct Push и части операций.
  • EWS-дополнение: календарь, задачи, заметки, черновики, вложения календаря, ответы на встречи и fallback-сценарии для Exchange 2007.
  • Auth: Basic Auth; для EWS-операций дополнительно NTLMv2-fallback. EAS-транспорт работает только с Basic Auth. OAuth 2.0 / Modern Auth пока не реализованы.
  • Локальная модель: offline-first через Room DB, UI читает данные через Flow, фоновые сервисы обновляют базу.

✨ Возможности

  • 📧 Почта: синхронизация системных и пользовательских папок, отправка HTML-писем, вложения, inline-изображения, CC/BCC, важность, поиск, фильтры, избранное, мультивыбор, batch-операции.
  • 📝 Черновики: серверный режим через Exchange/EWS и локальный beta-режим, выбор режима в онбординге и настройках аккаунта.
  • 📤 Отправка: отложенная отправка, очередь исходящих для offline-сценариев, undo-send, MDN/DSN-запросы.
  • 👥 Контакты: локальные и Exchange-контакты, GAL, группы, избранное, импорт/экспорт vCard/CSV, автодополнение адресов.
  • 🗓 Календарь: события, встречи, участники, ответы на приглашения, повторения, исключения, напоминания, вложения, онлайн-ссылки, локальная корзина, окончательное удаление только после подтверждения сервера.
  • ✅ Задачи: активные/выполненные/важные/просроченные задачи, сроки, приоритеты, назначение, напоминания, корзина и восстановление.
  • 🗒 Заметки: синхронизация Exchange Notes, создание/редактирование, корзина и восстановление.
  • 🔔 Уведомления: Direct Push через EAS Ping, WorkManager-синхронизация, AlarmManager fallback, уведомления писем, календаря, задач, обновлений и исходящих.
  • 🎨 Интерфейс: Jetpack Compose, Material 3, RU/EN локализация, тёмная/светлая тема, цветовые схемы, ежедневные темы, кастомные иконки файлов, drag selection.
  • 📊 Виджет и shortcuts: домашний виджет Glance, быстрый доступ к письмам, поиску, календарю, задачам и созданию письма; данные виджета читаются лёгкими Room-проекциями без загрузки тяжёлых тел писем/событий.
  • ⬆️ Обновления: проверка update.json на GitHub, выбор APK по ABI, скачивание, установка и подготовка отката.
🗓 Календарь и вложения — как это устроено
  • DRY для повторяющихся событий: вложения календаря хранятся как JSON-метаданные (fileReference, имя, размер), а не как копии файлов для каждого occurrence.
  • Exchange 2007 SP1: загрузка/получение вложений календаря идёт через EWS CreateAttachment/GetItem; для recurring-серий используется master ItemId.
  • Окончательное удаление: локальное удаление из БД выполняется только после успешного удаления на сервере; операции сериализованы с календарной синхронизацией per-account mutex.
  • Защита от CRA resurrection: attendee-встречи перед удалением отклоняются через MeetingResponse/EWS DeclineItem; если исходный meeting request не найден, локальное удаление не выполняется.
  • Приглашения на встречи: на Exchange 2010/2013 (EAS 14.x) встречи с участниками создаются и правятся через EWS CreateItem/UpdateItem, чтобы сервер разослал приглашения/обновления; обычная встреча без участников остаётся на EAS.
  • Preview cache: предпросмотр вложений использует временный каталог cacheDir/calendar_preview, стабильные имена по fileReference и отложенную очистку без гонок с внешними просмотрщиками.
🧩 Виджет и производительность
  • Лёгкие DAO-проекции: виджет читает только отображаемые поля для последних непрочитанных писем, ближайшей задачи и события календаря.
  • Корректная логика непрочитанных: список новых писем в виджете фильтруется по Inbox и read = 0.
  • Защита от гонок: updateMailWidget() сериализует GlanceAppWidget.updateAll() через общий mutex и использует applicationContext.
  • Адаптивная раскладка: нижний ряд действий подстраивается под ширину виджета (Glance Row не переносит содержимое) — на узких размерах меньше аватаров и без метки времени синхронизации, чтобы кнопки не обрезались; аватары масштабируются вместе с виджетом.
  • Room v42: индексы под горячие widget-запросы: unread Inbox, тип папки, активные задачи, текущие и ближайшие события календаря.

📸 Скриншоты


Главный экран — сводка дня и плитки разделов

Боковое меню — папки и разделы

Настройки аккаунта

Входящие

Просмотр письма — HTML-рендеринг

Создание письма

Задачи — фильтры, приоритеты, сроки

Заметки

Календарь (список событий)

Просмотр события календаря

⬇️ Установка

  1. Откройте страницу Releases и скачайте последнюю версию.

  2. Выберите *.apk под архитектуру вашего устройства (или universal, если не уверены):

    ABI Для каких устройств
    arm64-v8a большинство современных телефонов (рекомендуется)
    armeabi-v7a старые 32-битные ARM-устройства
    x86_64 / x86 эмуляторы и x86-планшеты
    universal один APK для всех архитектур
  3. Разрешите установку из этого источника и установите *.apk.

  4. При первом запуске пройдите онбординг и добавьте аккаунт Exchange.

Встроенный апдейтер проверяет update.json в репозитории, подбирает *.apk по ABI и готовит откат.

🖥 Требования

Параметр Минимум Рекомендуется
Android 8.0+ (API 26) —
RAM 2 ГБ 4+ ГБ
Свободное место 50 МБ 100+ МБ
CPU/ABI armeabi-v7a / x86 arm64-v8a / x86_64
  • Compile SDK: 36 · Target SDK: 36 · Java/Kotlin target: JVM 17
  • APK: universal + ABI splits для armeabi-v7a, arm64-v8a, x86, x86_64
  • Сборка: требуется JDK 17 (минимум JDK 11 для Android Gradle Plugin 8.7.3)

🔌 Поддерживаемые серверы

Сервер Статус
Exchange 2007 SP1/SP2 ✅ Стабильный основной сценарий
Exchange 2010/2013/2016 on-premise 🟡 Архитектурно поддерживается через EAS/EWS, требует проверки на конкретной инфраструктуре
Office 365 / Exchange Online 🟠 Ограничено: требуется OAuth/Modern Auth, который пока не реализован
IMAP/POP3 🧪 Beta: чтение/синхронизация через JavaMail, без полного parity с Exchange

🔒 Безопасность и совместимость

  • Conscrypt: добавлен для TLS 1.0/1.1 и совместимости со старыми Exchange 2007-инсталляциями.
  • Сертификаты сервера: поддержка системных, пользовательских и самоподписанных сертификатов.
  • mTLS: клиентские сертификаты PKCS#12 (.p12/.pfx) с кэшированием KeyManager.
  • Certificate Pinning: хранение SHA-256, CN/O и дат сертификата в аккаунте.
  • Пароли: EncryptedSharedPreferences (Android KeyStore, AES256-GCM) для основного пути; при недоступности KeyStore — fallback на PBKDF2-обфусцированное хранилище с уведомлением пользователя и опциональным fail-closed режимом.
  • Alternate URL: основной и резервный URL Exchange с fallback при сетевых ошибках и последующим auto-switchback.
  • XSS-защита тел писем: sanitizeEmailHtml блокирует <script>, plugin-контейнеры (iframe/object/embed/applet), event-handlers, meta http-equiv="refresh", javascript: и data:text/html URI во всех атрибутах с URL-контекстом; комбинируется с нонс-CSP и loadDataWithBaseURL(null, ...) в WebView для изоляции от cross-origin контекста.

⚠️ Известные ограничения

  • OAuth 2.0 / Modern Auth: не поддерживается.
  • Office 365: без Basic Auth обычно не работает.
  • NTLM для EAS: EAS-транспорт поддерживает только Basic Auth (NTLMv2 применяется только к EWS-операциям); виртуальный каталог /Microsoft-Server-ActiveSync должен разрешать Basic Auth.
  • IMAP/POP3: beta-реализация, не покрывает календарь, контакты, задачи, заметки, Direct Push и EWS-функции.
  • S/MIME: подписи и шифрование не реализованы.
  • EAS 16.x: явно не является целевой версией проекта; основной диапазон в коде — EAS 12.x-14.1.

🧱 Технологический стек

Категория Технологии
Язык Kotlin 1.9.22, Java 17
Android AGP 8.7.3, minSdk 26, targetSdk 36
UI Jetpack Compose, Compose BOM 2024.06.00, Material 3
Асинхронность Coroutines 1.7.3, Flow
Хранилище Room 2.6.1 (MailDatabase v42), DataStore Preferences
Сеть OkHttp 4.12.0, Conscrypt 2.5.2
Протоколы EAS, EWS, JavaMail IMAP/POP3
Фоновые задачи WorkManager 2.9.0, Foreground Service, AlarmManager
Безопасность AndroidX Security Crypto, TLS/mTLS, Certificate Pinning
UI extras Coil, Glance AppWidget
DI Manual DI через RepositoryProvider

🏗 Архитектура

UI Layer
  Jetpack Compose, Navigation, Theme, Localization
  MainScreen, Setup/Verification, Mail, Compose, Contacts, Calendar, Notes, Tasks, Updates
    ↓
Repository Layer
  AccountRepository, MailRepository, CalendarRepository, ContactRepository,
  NoteRepository, TaskRepository, SettingsRepository, AccountServerHealthRepository
  EmailSyncService, EmailOperationsService, FolderSyncService, AppFileCleanupService
    ↓
Protocol Layer
  EasClient facade
  EasTransport + EAS services + EWS client + IMAP/POP3 beta clients
    ↓
Persistence / Network
  Room MailDatabase v42, DataStore
  HttpClientProvider, NetworkMonitor, NtlmAuthenticator
    ↓
Background
  PushService, SyncWorker, OutboxWorker, reminders, notifications, watchdogs

Подробно: Архитектура проекта

🛠 Сборка

Рекомендуемый production-способ сборки — через Android Studio с JDK 17. CLI-команды ниже подходят как вспомогательный вариант при корректно настроенном JAVA_HOME.

./gradlew assembleDebug
./gradlew assembleRelease

На Windows:

.\gradlew.bat assembleDebug
.\gradlew.bat assembleRelease

📚 Документация

♻️ Важно: переименование пакета

Версия 1.6.1 изменила пакет с com.iwo.iwomail на com.dedovmosol.iwomail.

  • Обновление старых APK как обычный апдейт невозможно: Android считает это другим приложением.
  • Нужна переустановка: удалить старую версию, установить новую и заново добавить аккаунты.
  • Перед переходом со старого пакета рекомендуется экспортировать локальные контакты/данные.

💬 Обратная связь

⚖️ Лицензия

Распространяется на условиях GNU General Public License v3.0. Версии до перехода на GPLv3 выпускались под MIT и остаются под ней.


© 2025-2026 DedovMosol

About

Android mail client for Microsoft Exchange 2007 SP1+ (ActiveSync + EWS) — Kotlin, Jetpack Compose, offline-first

Topics

Resources

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages