Пункты 75.1–75.3 чек-листа Jambotron v0.2.3: прототип → можно развернуть, не открывая дыр.
Безопасность (75.1)
нет открытого релея: на чужой домен — только после AUTH, иначе 550 5.7.1; после входа MAIL FROM — только свой адрес
права доступа: раньше любой вошедший читал, отмечал и удалял чужие письма и вложения по номеру — теперь только владелец, чужие → 404
имена вложений без ../ (выход из папки), заголовок скачивания безопасный
секреты без значений по умолчанию (DB_PASSWORD, JWT_SECRET, ≥ 32 байт), пароль admin123 и /api/simulate/receive — только профиль dev, регистрация закрыта, ящики только в своих доменах
docker-compose.prod.yml удалён: открытый релей, Postgres наружу с паролем secret, свой Caddy с docker.sock
Почта (75.2)
SMTP: разбор по строкам (пачка команд, строка в двух пакетах), 250 только после сохранения, иначе 451; лимит размера; база и DNS не в сетевом потоке
отправка: очередь outbound_queue (V2) с повторами ~22 ч и уведомлением о недоставке; Jakarta Mail, MX по приоритету, режимы off / mx / smarthost (Resend); старый клиент принимал 550 за успех и не проверял сертификат
не сделано: TLS, IMAP (выключен), вложения входящих — в README «Не сделано»
Jambotron (75.3)
веб-клиент внутри jar, /api относительный; Dockerfile: Angular → Spring Boot → JRE не от root, health
docker-compose.jambotron.yml: секреты создаёт secrets-init при первом запуске, наружу только 8080, SMTP внутри, OUTBOUND_MODE=off
gradle-wrapper.jar был в .gitignore — сборка (и Dockerfile) не запускалась
Проверено: 26 тестов (SMTP настоящим клиентом и сокетом, GreenMail, DKIM подпись + проверка, очередь); живой прогон на временном Postgres: миграции, вход, письмо в ящик через веб и SMTP, релей отклонён, чужие письма — 404, ключ DKIM после перезапуска. Образ Docker целиком не собирал (на Contabo), фронтенд и jar собираются по отдельности.
Пункты 75.1–75.3 чек-листа Jambotron v0.2.3: прототип → можно развернуть, не открывая дыр.
**Безопасность (75.1)**
- нет открытого релея: на чужой домен — только после `AUTH`, иначе `550 5.7.1`; после входа `MAIL FROM` — только свой адрес
- **права доступа:** раньше любой вошедший читал, отмечал и удалял чужие письма и вложения по номеру — теперь только владелец, чужие → 404
- имена вложений без `../` (выход из папки), заголовок скачивания безопасный
- секреты без значений по умолчанию (`DB_PASSWORD`, `JWT_SECRET`, ≥ 32 байт), пароль `admin123` и `/api/simulate/receive` — только профиль `dev`, регистрация закрыта, ящики только в своих доменах
- `docker-compose.prod.yml` удалён: открытый релей, Postgres наружу с паролем `secret`, свой Caddy с `docker.sock`
**Почта (75.2)**
- SMTP: разбор по строкам (пачка команд, строка в двух пакетах), `250` только после сохранения, иначе `451`; лимит размера; база и DNS не в сетевом потоке
- отправка: очередь `outbound_queue` (V2) с повторами ~22 ч и уведомлением о недоставке; Jakarta Mail, MX по приоритету, режимы `off` / `mx` / `smarthost` (Resend); старый клиент принимал `550` за успех и не проверял сертификат
- DKIM: подпись `utils-mail-dkim`, проверка входящих — Apache jDKIM (старая проверяла чужие подписи нашим ключом); ключ после перезапуска читается (раньше — нет)
- не сделано: TLS, IMAP (выключен), вложения входящих — в README «Не сделано»
**Jambotron (75.3)**
- веб-клиент внутри jar, `/api` относительный; Dockerfile: Angular → Spring Boot → JRE не от root, health
- `docker-compose.jambotron.yml`: секреты создаёт `secrets-init` при первом запуске, наружу только 8080, SMTP внутри, `OUTBOUND_MODE=off`
- `gradle-wrapper.jar` был в `.gitignore` — сборка (и Dockerfile) не запускалась
**Проверено:** 26 тестов (SMTP настоящим клиентом и сокетом, GreenMail, DKIM подпись + проверка, очередь); живой прогон на временном Postgres: миграции, вход, письмо в ящик через веб и SMTP, релей отклонён, чужие письма — 404, ключ DKIM после перезапуска. Образ Docker целиком не собирал (на Contabo), фронтенд и jar собираются по отдельности.
— α
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- SMTP-сервер переписан: разбор по строкам, AUTH PLAIN/LOGIN, нет открытого релея,
MAIL FROM только свой после входа, 250 только после сохранения (иначе 451), лимит размера
- отправка наружу: очередь outbound_queue (V2) с повторами ~22 ч и уведомлением о недоставке;
Jakarta Mail, режимы off / mx / smarthost, байты письма не меняются (DKIM)
- DKIM: подпись utils-mail-dkim, проверка Apache jDKIM; ключ PKCS#8, старый PKCS#1 читается
- права: письма, папки, вложения — только владельцу (было: любой по номеру); имена вложений без ../
- секреты без значений по умолчанию (DB_PASSWORD, JWT_SECRET), регистрация закрыта,
admin123 и /api/simulate/receive — только профиль dev
- веб-клиент внутри jar (относительный /api), Dockerfile в 3 этапа, не root, health;
docker-compose.jambotron.yml: секреты создаются при первом запуске, наружу только 8080
- gradle-wrapper.jar был в .gitignore — сборка не запускалась
- тесты: 26 (SMTP реальным клиентом и сокетом, GreenMail, DKIM подпись+проверка, очередь)
α
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Пункты 75.1–75.3 чек-листа Jambotron v0.2.3: прототип → можно развернуть, не открывая дыр.
Безопасность (75.1)
AUTH, иначе550 5.7.1; после входаMAIL FROM— только свой адрес../(выход из папки), заголовок скачивания безопасныйDB_PASSWORD,JWT_SECRET, ≥ 32 байт), парольadmin123и/api/simulate/receive— только профильdev, регистрация закрыта, ящики только в своих доменахdocker-compose.prod.ymlудалён: открытый релей, Postgres наружу с паролемsecret, свой Caddy сdocker.sockПочта (75.2)
250только после сохранения, иначе451; лимит размера; база и DNS не в сетевом потокеoutbound_queue(V2) с повторами ~22 ч и уведомлением о недоставке; Jakarta Mail, MX по приоритету, режимыoff/mx/smarthost(Resend); старый клиент принимал550за успех и не проверял сертификатutils-mail-dkim, проверка входящих — Apache jDKIM (старая проверяла чужие подписи нашим ключом); ключ после перезапуска читается (раньше — нет)Jambotron (75.3)
/apiотносительный; Dockerfile: Angular → Spring Boot → JRE не от root, healthdocker-compose.jambotron.yml: секреты создаётsecrets-initпри первом запуске, наружу только 8080, SMTP внутри,OUTBOUND_MODE=offgradle-wrapper.jarбыл в.gitignore— сборка (и Dockerfile) не запускаласьПроверено: 26 тестов (SMTP настоящим клиентом и сокетом, GreenMail, DKIM подпись + проверка, очередь); живой прогон на временном Postgres: миграции, вход, письмо в ящик через веб и SMTP, релей отклонён, чужие письма — 404, ключ DKIM после перезапуска. Образ Docker целиком не собирал (на Contabo), фронтенд и jar собираются по отдельности.
— α
🤖 Generated with Claude Code