0.16.0

Итерация 12 плана аудита: Email-канал — пароли, path traversal, sessionKey.

Fixed

  • sessionKey в poller: заменён string(rune(accountID)) на strconv.FormatInt(accountID, 10) — старый код конвертировал ID в Unicode-символ, что приводило к коллизиям
  • Расшифровка паролей перед использованием: пароли хранились зашифрованными (AES-256-GCM), но нигде не расшифровывались перед IMAP/SMTP — добавлены decryptPassword() в poller, EmailChannel, EmailSendTool, EmailInboxTool, TestConnection handler
  • Пароль убран из bus.Metadata_email_smtp_pass больше не передаётся через шину сообщений; EmailChannel.Send получает аккаунт из store и расшифровывает пароль локально
  • Path traversal в email-attachments: sanitizeAttachmentFilename()filepath.Base() + regex-фильтрация небезопасных символов + ограничение 255 runes
  • IMAP \Seen: после fetch все обработанные письма помечаются как Seen через STORE +FLAGS.SILENT (\Seen) — иначе рестарт poller’а приводил к повторной обработке
  • Re: prefix dedup: buildReplySubject() проверяет Re:/RE:/re: и не добавляет повторный
  • UTF-8 safe truncation: utf8.RuneCountInString() + обрезка по rune boundary вместо побайтовой
  • TLS MinVersion: tls.VersionTLS12 для IMAP и SMTP соединений
  • processedUIDs LRU: FIFO-eviction при превышении 10000 записей — предотвращает неограниченный рост памяти

Added

  • AgentLoop.SetEncKey() — передача encryption key в agent loop для расшифровки email-паролей
  • encKey параметр в NewEmailSendTool/NewEmailInboxTool
  • buildReplySubject() helper в channels/email.go
  • sanitizeAttachmentFilename() helper в email/imap.go
  • decryptEmailPassword() helper в server/handler/email.go
  • 19 unit-тестов: санитизация filename (11 кейсов), UTF-8 truncation (2 теста), LRU eviction (2 теста), sessionKey (2 теста), расшифровка паролей (3 теста), Re: prefix (6 кейсов)