Что нового
0.7.22026-08-17
Добавлено
- Кнопка «Собрать» в окне «Контакты» — пересобирает адресную книгу из всей
скачанной почты, не дожидаясь новых писем. Полезно после догрузки истории
или добавления ящика. Нажимать можно сколько угодно: счётчики частоты
пересчитываются заново, а имена и заметки, введённые вручную, сохраняются.
0.7.12026-08-17
Исправлено
- Адресная книга оставалась пустой. Контакты собирались только из новых
писем, а вся уже скачанная почта их не пополняла — открыв «Контакты», вы
видели пустой список. Теперь при первом запуске книга заполняется из
накопленных писем.
- «Контакты» было не найти — пункт прятался в настройках. Теперь он в
боковой панели, рядом с папками и аккаунтами.
0.7.02026-08-17
Добавлено
- Адресная книга. Контакты собираются сами из переписки — и те, кто писал
вам, и те, кому писали вы. Свои адреса в книгу не попадают.
- Подсказки адресов при написании письма — в полях «Кому» и «Копия»
дополняется тот адрес, который набираете сейчас; выше те, кому пишете чаще.
- Окно «Контакты» (Настройки → Контакты): поиск, добавление и правка
вручную, заметки, удаление, кнопка «Написать».
- Импорт и экспорт vCard (.vcf) — перенос контактов из другого почтового
клиента и обратно. Понимаются выгрузки Thunderbird, Outlook, Google и
Яндекса, включая кириллицу в старом формате Outlook.
Имя, введённое вручную, автосбор не перезаписывает: если вы записали
«Марина, бухгалтерия», следующее письмо не вернёт служебное «noreply».
0.6.02026-08-12
Исправлено
- Удаление писем не доходило до сервера. Письмо исчезало из списка, но на
сервере оставалось: операция падала с «UID MOVE No such folder» и после семи
повторов отбрасывалась. Папки только добавлялись в кэш и никогда не
удалялись, поэтому копились записи папок, которых на сервере уже нет — у
Яндекса на роль «Корзина» приходилось три записи, и выбиралась произвольная.
Теперь синхронизация убирает папки, отсутствующие на сервере, а для операций
выбирается реально работающая папка.
- После запуска до пяти минут показывалась старая почта — синхронизация
шла только по интервалу. Теперь она стартует сразу при открытии приложения.
- Очередь операций копила мусор: записи удалённых аккаунтов и давние
неудачи оставались в базе навсегда. Добавлена автоматическая уборка.
- В «Отправленных» и «Черновиках» показывался отправитель — то есть вы
сами, и список выглядел как письма от себя. Теперь в строке отображается
адресат, как и ожидается от почтового клиента.
Добавлено
- «Всегда показывать картинки от этого отправителя» — кнопка «Всегда» в
плашке блокировки; письма от доверенных отправителей открываются с
картинками сразу.
- Настройка окна отмены отправки (сразу / 5 / 10 / 30 секунд) — раньше
окно было жёстко 10 секунд, а настройка ни на что не влияла.
- Выбор папки для вложений — нативный диалог в настройках; раньше вложения
всегда сохранялись в системные «Загрузки».
- Счётчик непрочитанных в подсказке трея — видно количество, не открывая окно.
Внутреннее
- Тесты критической логики: очередь операций (повторы, задержка, терминальные
отказы, UIDVALIDITY), отправка (отмена, отложенная отправка, восстановление
после сбоя), правила фильтрации, доверенные отправители, санитайзер писем.
- Санитайзер: регрессионные тесты на класс атак «разметка проходит фильтр, но
опасна при отрисовке» (label[for], CSS-псевдоклассы, скрытие через opacity).
- Убрано глобальное разрешение
dead_code: мёртвый код удалён, дублирование
SQL в движке синхронизации устранено, осознанные исключения помечены точечно.
- Миграции V011 (доверенные отправители) и V012 (очередь операций больше не
хранит копии учётных данных, которые устаревали при смене настроек аккаунта).
0.5.22026-07-15
Внутреннее
scripts/release.ps1сам настраивает подпись обновления: ключ берёт из
$HOME\.corvo\corvo_updater.key, пароль — из $HOME\.corvo\corvo_updater.pass
(шифрование DPAPI, привязано к учётке Windows). Пароль спрашивается один раз,
дальше деплой идёт без вопросов. Раньше про переменные окружения приходилось
помнить, и сборка падала на бандле («A public key has been found, but no
private key»), а публикация — на отсутствующем .sig.
Исправлено (этап B ТЗ — честная синхронизация)
- B1. Сервер — источник правды. Письмо, удалённое с телефона или в
веб-интерфейсе, теперь исчезает и в Corvo: после синка папка сверяется с
сервером (UID SEARCH ALL), и всё, чего на сервере нет, удаляется из
локального кэша. Раньше кэш только рос и расходился с ящиком.
- B1. Флаги по всему кэшу. Прочитанное/помеченное подхватывается для всех
писем папки, а не только в окне последних 500 UID — старое письмо больше не
висит непрочитанным навсегда. Письма с неотправленными операциями в очереди
по-прежнему не затираются серверными флагами.
- B2. Догрузка истории. Список писем больше не упирается в последние 500:
при прокрутке вниз ядро догружает более старые письма страницами по 200
(messages_load_older, миграция V010 — колонка folders.history_complete).
Дойдя до начала ящика, список показывает «Это все письма» и на сервер больше
не ходит.
Изменено
- D2. Виртуализация списка (
react-virtuoso): в DOM держатся только видимые
строки. Без этого догруженные тысячи писем (B2) сделали бы прокрутку тяжёлой.
Липкие заголовки дат и раскрытие цепочек сохранены.
- C2. Пул IMAP-соединений (≤ 3 на аккаунт, проверка живости через
NOOP).
Синхронизация, открытие письма, скачивание вложения и очередь операций
переиспользуют соединения вместо полного входа (TCP+TLS+LOGIN) на каждое
действие. Это устраняет причину ошибок лимита одновременных сессий у Яндекса —
в A7 мы лечили симптом автоповтором.
Добавлено
- Иконка в системном трее (desktop). Меню: «Открыть Corvo», «Написать
письмо», «Проверить почту», «Выход»; левый клик по иконке разворачивает окно.
- Сворачивание в трей вместо закрытия. Кнопка «Закрыть» прячет окно, и
Corvo продолжает проверять почту и слать уведомления в фоне. Отключается в
настройках («При закрытии сворачивать в трей»).
- Автозапуск вместе с системой (
tauri-plugin-autostart) — переключатель в
настройках. При автозапуске приложение стартует сразу в трей (--minimized),
без мелькания окна.
0.5.12026-07-15
- Трей и автозапуск с системой
0.5.02026-07-15
Исправлено (аудит целостности и безопасности)
- Порча данных при синке (критично).
upsert_messageна ветке обновления
возвращал чужой rowid (last_insert_rowid), из-за чего FTS-индекс портился
каждым синком, а автоправила могли применяться к постороннему письму (вплоть
до удаления не того письма на сервере). Переведено на RETURNING id.
- Отправка после отмены (критично). Воркер очереди отправки перетирал
статус cancelled — письмо могло уйти после успешного «Отменить». Перевод в
sending теперь только WHERE status='queued'.
- Потеря писем из очереди отправки при аварийном завершении между
sending
и SMTP: зависшие записи возвращаются в очередь при старте.
- UIDVALIDITY в очереди операций. Отложенные offline-операции больше не
выполняются при смене UIDVALIDITY папки (миграция V009) — исключено
удаление/перемещение не того письма.
- Пропавшие письма при >500 новых за синк (обработка старейших первыми,
без «дыры» в кэше) и пере-обработка верхнего письма каждый цикл.
- Атомарность записи тела и вложений (одна транзакция); атомарные миграции.
- Безопасность: SSRF-фильтр приватных адресов при загрузке внешних
картинок; точечная замена только в src (ссылки/текст не портятся); CSP
iframe письма переведена с unsafe-inline на nonce; проверка источника
postMessage; горячие клавиши не срабатывают при открытых диалогах.
- Стабильность IMAP: одна сессия на аккаунт на батч операций (меньше риск
бана за частые логины); управляемые IDLE-воркеры (новый аккаунт
подхватывается без перезапуска, удалённый — останавливается);
пер-аккаунтный замок синка; устойчивость к «отравленному» мьютексу БД.
- UI: устранены гонки при переключении папок/аккаунтов/поиска; откат
optimistic-действий с уведомлением; тихие ошибки загрузки теперь видимы;
счётчики непрочитанного считаются по всем аккаунтам; вложения передаются
как base64 вместо массива чисел (быстрее и легче по памяти).
Прочее
- Новая иконка приложения (конверт на фирменном градиенте): обновлены
src-tauri/icons/*, добавлен исходник app-icon.png для tauri icon
(desktop/Android/iOS).
- Мобильная раскладка (этап 1). Отзывчивый слой только для мобильных
платформ (Android/iOS): экран «Входящие» со списком писем, нижний лист
«Ящики/папки», чтение письма полноэкранно, FAB «Написать» (хук useIsMobile,
components/mobile/MobileApp). На десктопе не активируется ни при какой ширине
окна (гейт по платформе). Дальше — поиск, мобильный композер, экран
аккаунтов/настроек, свайпы, планшетный split-view.
- Подготовка к Android-сборке. Desktop-only крейты (
keyring,opener,
tauri-plugin-updater/process) изолированы под cfg(not android); секреты
вынесены в core::secret_store (desktop — keyring, Android — файловый
бэкенд); команды окна/открытия ссылок гейтированы под cfg(desktop).
TLS переведён с native-tls/OpenSSL на rustls + ring (IMAP через ручной
rustls-поток imap_client::connect_tls_stream; lettre/reqwest/oauth2 —
фичи rustls) — Perl/OpenSSL для сборки больше не нужны. Инструкция —
docs/ANDROID.md.
- Этап B: честный синк (реконсиляция удалений/флагов, папки).
0.4.112026-07-07
Добавлено
- A8: картинки в письмах. (1) Inline-картинки
cid:— MIME-разбор извлекает
inline-части (Content-ID, image/*), в теле src="cid:…" заменяется на
data:-URL (лимит 5 МБ, после ammonia): логотипы Госуслуг видны сразу и
офлайн. (2) Внешние http(s)-картинки по кнопке «Показать» скачиваются ядром
(messages_inline_remote_images: таймаут 10 с, ≤10 МБ, ≤20 шт., только
image/*) и встраиваются как data:-URL; результат кэшируется
(message_bodies.html_with_images, миграция V008) — после этого картинки
доступны офлайн, а IP не светится при каждом открытии. Пока картинки скрыты —
без «битых» иконок (спрятаны в CSS iframe). Глобальный CSP приложения не
ослаблен. Вложения хранят mime_type и content_id. Unit-тесты на cid и
извлечение внешних src.
Исправлено
- A7: понятная причина ошибки загрузки письма. Общий разбор ошибок
(api/error.ts): панель чтения показывает реальный текст (а не общее
«Не удалось загрузить письмо») и кнопку «Повторить». При ограничении числа
IMAP-подключений (типично для Яндекса) — понятный текст и один автоповтор
через 3 с. Тот же разбор применён в композере и диалогах аккаунта.
0.4.102026-07-07
Этап A ТЗ v0.5.0 (часть 3) + улучшение UX.
Добавлено
- A3: реальная проверка соединения. Кнопка «Проверить соединение» в диалоге
добавления аккаунта теперь действительно подключается: IMAP — вход по паролю
с таймаутом 10 с и LOGOUT, SMTP — доступность сервера и TLS. Результат
показывается раздельно по каждому протоколу со спиннером на время проверки.
Ошибки человекочитаемые и различают неверный пароль («ошибка аутентификации»)
и недоступность сервера («сервер недоступен»). Заглушка test_imap_connection
осталась только для базовой валидации входных данных. Добавлены Rust
unit-тесты классификатора ошибок.
- Переключатель цепочек писем в настройках. «Группировать письма в цепочки»
(Вкл/Выкл): при выключении каждое письмо отображается отдельной строкой без
группировки по теме. Настройка сохраняется в БД (по умолчанию — включено).
- Лицензионное соглашение (EULA). Единый текст (
LICENSE.md) в трёх местах:
экран лицензии в установщике (NSIS, bundle.licenseFile), раздел «О программе»
в приложении (кнопка «Лицензионное соглашение») и страница на сайте
([corvo_license], ссылка в подвале). Программа распространяется бесплатно;
правообладатель — физическое лицо, применимое право — РФ.
- A5: копия отправленных писем в папке «Отправленные». После успешной
отправки приложение кладёт письмо в папку с ролью sent через IMAP APPEND
(флаг \Seen). Для провайдеров, которые сохраняют копию сами (Яндекс, Mail.ru,
Gmail), APPEND не делается — во избежание дубликатов. Поведение настраивается
по каждому ящику (миграция V006, галочка в «Настройках ящика»). Ошибка APPEND
не считается ошибкой отправки: письмо помечается отправленным, а в событии
outbox:status приходит appendFailed, и показывается ненавязчивый тост.
- A6: цитирование в ответе, Cc и реальные получатели. Ответ и пересылка
теперь цитируют оригинал (HTML-цитата blockquote с атрибуцией
«{дата}, {отправитель} пишет:», фолбэк — текст; курсор над цитатой).
«Ответить всем» собирает получателей из отправителя, «Кому» и «Копии» (минус
свой адрес, без дублей; Cc уходит в Cc). В шапке письма показываются реальные
адресаты («Кому: …, и ещё N», раскрытие по клику — полный список То/Копия).
При синке сохраняются Cc (cc_addrs) и цепочка References (миграция V007);
ответ уходит с корректными In-Reply-To/References (id в угловых скобках),
поэтому попадает в тред у получателя.
Исправлено
- A4: роли папок через SPECIAL-USE и запрет молчаливого удаления. Роли папок
определяются по атрибутам RFC 6154 (\Sent, \Drafts, \Trash, \Junk,
\Archive, \All), эвристика по имени — только фолбэк; INBOX всегда
«Входящие». Если Корзина не найдена, удаление не выполняется безвозвратно
молча: команда возвращает TRASH_NOT_FOUND, а приложение спрашивает
«Удалить безвозвратно?» и повторяет с явным подтверждением. Из самой Корзины
удаление требует подтверждения «Удалить навсегда?». Автоправило delete без
Корзины пропускается с предупреждением в лог. Добавлены Rust unit-тесты
маппинга SPECIAL-USE и фолбэк-эвристики.
0.4.92026-07-07
Исправлено
- Усилен мост ссылок в письме (перехват средней кнопки/Ctrl-клика, Enter,
запрет сабмита форм) — переход по ссылке гарантированно уходит в браузер.
- Понятные ошибки загрузки письма: панель чтения показывает конкретную
причину, а ядро логирует детальную ошибку команды (Ошибка команды: …).
- Полнотекстовый поиск больше не падал — в запросе FTS5 использовался алиас
таблицы в MATCH (x MATCH ?), из-за чего SQLite выдавал «no such column: x»
и поиск всегда возвращал пусто. Теперь используется имя таблицы messages_fts.
0.4.82026-07-07
Этап A ТЗ v0.5.0 (часть 1): критические дефекты.
Исправлено
- A1: синхронизация не выбивает из письма/папки. IDLE-события, ручная и
периодическая синхронизация больше не переключают активную папку и не
сбрасывают выделение/скролл — список текущего вида перечитывается и мерджится
(syncAccount теперь только запускает синк, новый refreshCurrentList
перечитывает вид). Если открытое письмо удалено на сервере — панель чтения
закрывается с ненавязчивым тостом. Добавлен минимальный тост-механизм в сторе.
- A2: ссылки в письмах открываются в системном браузере. iframe письма
получил безопасный мост (sandbox="allow-scripts", CSP `script-src
'unsafe-inline'): клик по ссылке уходит в ядро (shell_open_url` с валидацией
схемы http/https и unit-тестами), mailto: открывает композер; при наведении
внизу панели виден реальный URL. Прочие схемы (javascript/file/data) игнорируются.
0.4.72026-07-06
- Настройки ящика, все папки, объединённый inbox опция
0.4.72026-07-06
Изменено
- Объединённый inbox стал опцией. По умолчанию приложение открывает
ящик пользователя (его «Входящие»), а не «Все входящие» всех ящиков.
«Все входящие» и смарт-папки (Непрочитанные / С вложениями / Отложенные)
показываются только при включённой настройке «Объединённый inbox (все ящики
вместе)».
- Видны ВСЕ папки ящика. Сайдбар больше ничего не скрывает и не схлопывает:
показываются входящие, все системные и все пользовательские папки под своими
реальными именами (со счётчиками непрочитанных).
Исправлено
- Панель быстрых действий при наведении больше не перекрывает кнопку разворота
цепочки — счётчик/шеврон цепочки перенесён левее темы письма.
Добавлено
- Настройки ящика (правый клик по аккаунту → «Настройки ящика»): название,
параметры подключения (IMAP/SMTP хосты и порты) и подпись для писем.
- Авто-уведомление о новой версии — приложение само проверяет обновления при
запуске и периодически, пока открыто. Если вышла новая версия: системное
уведомление + плашка в приложении с кнопкой «Обновить сейчас» / «Позже».
Технически
- Команда
accounts_update(имя + подключение); настройкаunified_inbox;
initApp выбирает стартовый вид по настройке; компонент AccountSettingsDialog.
0.4.62026-07-06
Добавлено
- Обратная связь в приложении — в настройках пункт «Обратная связь
(замечания и предложения)»: открывает письмо с предзаполненным получателем
it@konstmax.ru (отправляется из аккаунта пользователя).
0.4.52026-07-06
Исправлено
- Две иконки настроек — убрана дублирующая шестерёнка из подвала сайдбара.
Настройки открываются одной кнопкой-шестерёнкой в титлбаре (вверху справа).
- Видимость дублирующих папок — если у ящика две папки одной роли (напр.
«Sent» и «Отправленные»), одна остаётся системным пунктом, а вторая теперь
показывается в разделе «Папки» под своим именем (раньше пряталась).
0.4.42026-07-06
Исправлено
- Кракозябры в именах папок (напр. «&BB4EQgQ…»). Нелатинские имена IMAP-папок
приходят в кодировке modified UTF-7 (RFC 3501); теперь они декодируются при
отображении в сайдбаре и заголовке списка. В БД имя остаётся «серверным»
(mUTF-7) — как требуется для IMAP-операций.
0.4.32026-07-06
Добавлено
- Установщик (NSIS .exe) и система автообновлений (Tauri updater).
- В приложении: диалог «О программе» (Настройки → О программе) с версией и
кнопкой «Проверить обновления»; скачивание, установка и перезапуск.
- Сборка: bundle.targets = nsis, createUpdaterArtifacts, подписанные
артефакты; endpoint https://corvo-mail.ru/update/latest.json.
- Раздача обновлений: веб-корень сайта corvo-mail.ru
(/var/www/fsk/data/www/corvo-mail.ru/update), без Docker.
- Скрипт релиза: scripts/publish-update.ps1 (формирует latest.json и
заливает установщик в веб-корень по scp).
- Гайд: docs/UPDATES.md (ключи, каталог, сборка, публикация).
Технически
- Плагины
tauri-plugin-updaterиtauri-plugin-process; JS
@tauri-apps/plugin-updater / @tauri-apps/plugin-process; разрешения
updater:default, process:default в capabilities.
0.4.22026-07-04
Добавлено
- Экран настроек (шестерёнка в сайдбаре), значения сохраняются в БД:
- тема оформления (светлая/тёмная/системная);
- плотность списка писем (обычная/плотная — плотная скрывает превью текста);
- интервал автосинхронизации (1/5/15/30 мин) — периодически синхронизирует
все аккаунты;
- уведомления о новых письмах (вкл/выкл) — реально гейтит показ уведомлений
в IDLE-воркере;
- быстрый переход к правилам фильтрации.
Технически
- Миграция
V005__settings.sql(таблицаapp_settings, JSON);
repo_settings + реальные settings_get/settings_set; в сторе — settings,
loadSettings, updateSettings; периодический синк и открытие настроек — в App.
0.4.12026-07-04
Добавлено
- Счётчики непрочитанных у папок в сайдбаре (число справа от папки, как в
вебе провайдера) — для системных и пользовательских папок активного аккаунта.
- Горячие клавиши (стиль Gmail):
J/K— следующее/предыдущее письмо,
C — написать, R — ответить, E — архивировать, # — удалить,
/ — фокус на поиск, ? — справка по клавишам, Esc — закрыть. Клавиши
игнорируются при вводе в поля и при открытом композере.
Технически
- Команда
folders_unread_counts+repo_messages::unread_counts; в сторе —
unreadCounts и действия `selectNext/selectPrev/archiveSelected/trashSelected/
replySelected; глобальный обработчик клавиш в App, компонент ShortcutsHelp`.
0.4.02026-07-04
Добавлено
- Полнотекстовый поиск (FTS5) — Этап 6. Поиск по заголовкам и телам писем
всех аккаунтов с задержкой ввода (debounce). Операторы: from:, to:,
subject:, has:attachment, in: (роль или имя папки),
before:YYYY-MM-DD, after:YYYY-MM-DD; свободный текст комбинируется с ними.
Результаты группируются в цепочки, совпадения подсвечиваются.
- Индексация заголовков — при синхронизации, тел — при открытии письма;
результаты чистятся из индекса при удалении писем.
Технически
- Миграция
V004__fts_rebuild.sql:messages_ftsпересоздана как обычная FTS5
(не contentless — иначе невозможны DELETE/UPDATE для переиндексации);
разовая индексация заголовков уже загруженных писем.
repo_messages::search(FTS MATCH + SQL-фильтры), парсер операторов в
commands::search; fts::index_message вызывается из sync_engine.
0.3.122026-07-04
Исправлено
- Пользовательские папки не показывались в сайдбаре. Отображались только
системные папки (с ролью), а обычные папки аккаунта (напр. «1С документооборот»,
«БИТРИКС») скрывались, хотя синхронизировались и хранились в БД. Добавлен
раздел «Папки» со всеми пользовательскими папками активного аккаунта (клик —
открыть, drag-and-drop писем — поддержан). Вложенные папки показываются
последним сегментом (Parent/Child → Child), полное имя — в подсказке.
0.3.112026-07-04
Добавлено
- Правила фильтрации входящих — Этап 5 завершён. Условие «поле
(Отправитель / Тема / Кому) содержит подстроку» → действие: переместить в
папку (Архив / Спам / Корзина), отметить прочитанным, в избранное или удалить.
Управление — в диалоге (шестерёнка в сайдбаре): добавление, включение/
выключение, удаление правил. Правила применяются к новым входящим при
синхронизации (первичный бэкап и служебные папки не затрагиваются).
Технически
- Миграция
V003__rules.sql(таблицаrules);repo_rules(CRUD);
команды rules_list/rules_add/rules_set_enabled/rules_delete; применение —
в sync_engine (действия ставятся в очередь операций с retry).
0.3.102026-07-04
Добавлено
- Отложить письмо (snooze). В контекстном меню — пресеты «На час»,
«Сегодня вечером», «Завтра утром», «Через неделю». Отложенное письмо
пропадает из «Входящих»/смарт-папок и появляется в новой смарт-папке
«Отложенные»; по наступлении срока автоматически возвращается во
«Входящие». В папке «Отложенные» — пункт «Вернуть во Входящие» (снять отложку).
Технически
- Ядро:
messages_snooze(проставляетsnoozed_until),messages_snoozed
(snoozed_until > now); выборки inbox/smart учитывают
snoozed_until IS NULL OR <= now (авто-возврат без фонового воркера).
0.3.92026-07-04
Добавлено
- Группировка писем в цепочки (треды). Ядро вычисляет
thread_key
(корневой message-id по References → In-Reply-To → собственный
message-id) и сохраняет его при синхронизации. В списке письма одной
переписки сворачиваются в один пункт с счётчиком; шеврон разворачивает
цепочку — вложенные письма показываются под представителем. Представитель —
самое свежее письмо; непрочитанность/вложение/звезда агрегируются по всей
цепочке. Группировка работает и в объединённом inbox (между аккаунтами).
Технически
imap_client: разборReferences/In-Reply-To(ids_from_header).repo_messages::upsert_message: параметрthread_key.sync_engine::compute_thread_key; во фронтенде — агрегатор цепочек в
MessageList и поля threadKey/dateUtc в модели отображения.
0.3.82026-07-04
Исправлено
- Входящие загружались не полностью. При первичной синхронизации окно
писем бралось по UID (UIDNEXT − 500). Из-за удалённых писем UID'ы разрежены,
поэтому «последние 500 UID» содержали лишь несколько реальных писем. Теперь
первый синк берёт последние ~500 писем по порядковому номеру (sequence,
диапазон EXISTS−500 : EXISTS) — это всегда ровно N самых свежих писем,
независимо от «дыр» в UID. Инкрементальный синк по-прежнему по UID > last_seen.
- Дублирование системных папок в сайдбаре (напр. «Отправленные», «Корзина»
дважды): на одну роль сервер может отдавать несколько папок (Sent и
Отправленные). Теперь в сайдбаре показывается один пункт на роль.
Технически
select_infoтеперь возвращает иEXISTS; добавленfetch_headers_recent
(выборка по sequence); разбор FETCH вынесен в envelope_from_fetch.
0.3.72026-07-04
Добавлено
- Объединённый inbox «Все входящие» — единый список писем всех аккаунтов
(папки с ролью inbox), отсортированный по дате. Отдельный пункт в самом
верху сайдбара; открывается по умолчанию при старте.
- Смарт-папки «Непрочитанные» и «С вложениями» теперь работают по всем
аккаунтам сразу (реальные выборки из БД, а не заглушки).
- В объединённых списках цветная полоска и аватар письма окрашиваются в цвет
аккаунта-отправителя (стабильная палитра по позиции аккаунта).
Изменено
- Кнопка «Обновить» (в титлбаре и над списком) в объединённом/смарт-режиме
синхронизирует все аккаунты и перечитывает представление.
- Персональный inbox аккаунта в сайдбаре больше не дублирует «Все входящие»:
под аккаунтом остаются Отправленные, Черновики, Архив, Спам, Корзина.
- Заголовок центральной панели отражает текущее представление (папку/смарт-папку).
Технически
- Ядро:
messages_unified/messages_unread/messages_with_attachments
(JOIN folders, фильтр role='inbox', учёт snoozed_until); в модель
Message добавлено поле account_id.
0.3.62026-07-04
Исправлено
- Первичная синхронизация тянула все заголовки папки (
1:*) и «висела» на
больших ящиках (напр. Яндекс). Теперь при первом синке грузятся только
последние ~500 UID на папку (по UIDNEXT), как и предписывает ТЗ.
0.3.52026-07-04
Исправлено
- Автоопределение хостов для доменов Яндекса
ya.ruиyandex.com
(раньше распознавался только yandex.ru).
0.3.42026-07-04
Добавлено
- Удаление аккаунта из UI (правый клик по аккаунту в сайдбаре) с очисткой
секретов из keyring (пароль и OAuth-токены).
0.3.32026-07-04
Исправлено
- OAuth: access-токен теперь хранится и используется напрямую (в keyring —
JSON access+refresh+срок), refresh вызывается только по истечении. Это
устраняет ошибку Обновление токена не удалось: Server returned error response
(Яндекс отвергал лишний refresh; его токен и так долгоживущий).
- Повторный вход по тому же email обновляет токены, а не падает на уникальности.
0.3.22026-07-04
Изменено
- Детальное логирование ошибок OAuth-входа IMAP (получение токена / XOAUTH2) —
чтобы видеть реальную причину, а не генерализованное сообщение.
0.3.12026-07-04
Исправлено
- OAuth: браузер на Windows открывался через
cmd start, из-за чего URL
авторизации обрезался на первом & и терялся client_id (ошибка Яндекса
«отсутствует client_id»). Теперь используется rundll32 FileProtocolHandler.
0.3.02026-07-04
Этап 4 завершён: OAuth 2.0 (Яндекс, Mail.ru) работает.
Добавлено
- XOAUTH2 для IMAP (SASL) и SMTP — OAuth-аккаунты читают и отправляют
почту по access-токену.
- Единый вход
account_manager::open_imap(пароль или OAuth) и
get_access_token (обновление по refresh-токену) — используются во всех
путях: синхронизация, чтение тела, вложения, очередь операций, отправка,
сохранение черновика.
0.2.92026-07-04
Добавлено
- Иконка приложения (ворон, выныривающий из конверта; палитра 1B «Про»):
src-tauri/icons/* + bundle.icon в конфиге; исходники в assets/brand/.
Изменено
- OAuth переведён на OOB-поток (
verification_code): вместо loopback-порта
(который Яндекс не регистрирует) пользователь подтверждает доступ в браузере и
вставляет код. Redirect URI для Яндекса: https://oauth.yandex.ru/verification_code.
Двухшаговые команды accounts_oauth_start + accounts_add_oauth.
0.2.82026-07-03
Этап 4 (слайс 1): OAuth 2.0 для Яндекс и Mail.ru.
Добавлено
- OAuth-поток по RFC 8252: системный браузер + локальный loopback-редирект +
PKCE; обмен кода на токены (oauth2).
- Ключи
client_id/client_secretчитаются изoauth.jsonв каталоге данных
приложения (шаблон oauth.json.example, в репозиторий не коммитится).
- Команда
accounts_add_oauth; кнопки «Войти через Яндекс / Mail.ru» в диалоге
добавления аккаунта; refresh-токен хранится в системном keyring.
0.2.72026-07-03
Этап 3 завершён.
Добавлено
- WYSIWYG-редактор письма (TipTap): тулбар — жирный, курсив, маркированный
и нумерованный списки, цитата; письмо отправляется как multipart/alternative
(HTML + текст). Зависимости: @tiptap/react, @tiptap/starter-kit, @tiptap/pm.
0.2.62026-07-03
Этап 3 (хвост):
Добавлено
- Сохранение черновика на сервере (IMAP APPEND в папку Drafts с флагом
\Draft) — кнопка «Черновик» в композере.
0.2.52026-07-03
Исправлено
- Отправка почты: ошибка SMTP
501 Syntactically invalid EHLO argument(s)—
для EHLO теперь используется домен из адреса отправителя, а не имя
компьютера (которое могло содержать недопустимые символы, напр. кириллицу).
0.2.42026-07-03
Этап 3 (продолжение):
Добавлено
- Вложения в композере: прикрепление файлов (multipart/mixed), чипы с
размером и удалением, предупреждение при размере > 20 МБ.
- Подписи per-account: редактор в композере (сохраняется локально по
аккаунту), автоподстановка в конец новых писем.
0.2.32026-07-03
Добавлено
- Показ результата отправки в UI: тост «Письмо отправлено» / «Не удалось
отправить: …» (подписка на событие outbox:status).
- Логирование отправки в
app.log(успех — info, ошибка — warn) для диагностики.
0.2.22026-07-03
Этап 3 (продолжение):
Добавлено
- Ответить всем — получатели собираются из отправителя и списка «Кому»
(без своего адреса).
- Автосохранение черновика нового письма (localStorage) с восстановлением
при повторном открытии «Написать»; очистка после отправки.
0.2.12026-07-03
Этап 3 (частично): отправка почты и композер.
Добавлено
- SMTP-отправка через
lettre(implicit TLS на 465 / STARTTLS на 587). - Очередь исходящих
outbox+ фоновый воркер; окно отмены отправки (undo,
10 сек) с тостом «Отменить»; статусы через событие outbox:status.
- Композер: новое письмо («Написать»), ответ и пересылка — с
цитированием и заголовками In-Reply-To / References.
- Отложенная отправка (выбор даты/времени).
- Проверки перед отправкой: пустая тема, упомянуто вложение без файла.
0.2.02026-07-03
Закрыт Этап 2 (синхронизация, push, операции) и финализирован дизайн.
Добавлено
- Инкрементальная синхронизация с проверкой
UIDVALIDITY: докачиваются только
новые письма (UID > last_seen), обновляются флаги в недавнем окне, при смене
UIDVALIDITY — полный ресинк папки.
- IMAP IDLE: фоновые воркеры на INBOX каждого аккаунта; при новых письмах —
системное уведомление (tauri-plugin-notification) и авто-подтягивание.
- Персистентная очередь операций (
op_queue, миграция V002) с фоновым
воркером: смена флагов, перемещение, удаление уходят на сервер с retry и
экспоненциальным backoff; работает в оффлайне (optimistic-UI локально).
- Двунаправленная синхронизация флагов/папок с сервером (STORE, MOVE, EXPUNGE).
- Контекстное меню письма, быстрые действия при наведении, drag-and-drop
писем в папки.
- Индикатор состояния соединения аккаунта (online/offline/reauth) через событие
account:connection_state.
- Финальный дизайн: нативный оконный chrome Windows (кастомный титлбар,
кнопки свернуть/развернуть/закрыть, перетаскивание, Segoe UI, decorations:false).
Изменено
- Заголовки писем декодируются через
mail-parser(RFC 2047, кодировки charset)
вместо ручного разбора.
- Плашка блокировки изображений показывается только при наличии реальных
внешних картинок в письме.
- Обновлены токены дизайн-системы (
textMuted) под финальный макет.
Удалено
- Демонстрационные данные интерфейса — только реальная почта.
0.1.02026-07-02
Этапы 0–1: каркас и чтение почты.
Добавлено
- Каркас Tauri 2 + React 18 + TypeScript + Vite; SQLite с системой миграций
(V001), логирование tracing в файл, базовые модули ядра.
- Трёхпанельный интерфейс в дизайне «Corvo 1B — Про», светлая/тёмная темы.
- Добавление IMAP-аккаунта по паролю (keyring), автоопределение хостов для
Яндекс/Mail.ru/Gmail/Outlook/Rambler, реальная проверка соединения.
- Синхронизация папок и заголовков, список писем из БД с группировкой по датам.
- Чтение письма: докачка тела, разбор MIME (
mail-parser), санитизация HTML
(ammonia), рендер в sandbox-iframe с CSP, блокировка удалённых изображений.
- Вложения: список, скачивание в «Загрузки», открытие системным приложением,
предупреждение об исполняемых расширениях.
[Не выпущено]: https://gitflic.ru/project/konstmax13/corvo
[0.3.6]: https://gitflic.ru/project/konstmax13/corvo
[0.3.5]: https://gitflic.ru/project/konstmax13/corvo
[0.3.4]: https://gitflic.ru/project/konstmax13/corvo
[0.3.3]: https://gitflic.ru/project/konstmax13/corvo
[0.3.2]: https://gitflic.ru/project/konstmax13/corvo
[0.3.1]: https://gitflic.ru/project/konstmax13/corvo
[0.3.0]: https://gitflic.ru/project/konstmax13/corvo
[0.2.9]: https://gitflic.ru/project/konstmax13/corvo
[0.2.8]: https://gitflic.ru/project/konstmax13/corvo
[0.2.7]: https://gitflic.ru/project/konstmax13/corvo
[0.2.6]: https://gitflic.ru/project/konstmax13/corvo
[0.2.5]: https://gitflic.ru/project/konstmax13/corvo
[0.2.4]: https://gitflic.ru/project/konstmax13/corvo
[0.2.3]: https://gitflic.ru/project/konstmax13/corvo
[0.2.2]: https://gitflic.ru/project/konstmax13/corvo
[0.2.1]: https://gitflic.ru/project/konstmax13/corvo
[0.2.0]: https://gitflic.ru/project/konstmax13/corvo
[0.1.0]: https://gitflic.ru/project/konstmax13/corvo