Перейти к содержимому
CalabДокументация

Почтовый ящик

Сброс пароля корпоративного почтового ящика через бота — проверить, что ящик на хостинге оператора, и выдать человеку одноразовую ссылку с новым паролем.

На серверах Calab с почтовым хостингом — когда домен компании и ящики держит оператор — пароль ящика человеку восстанавливает бот: человек просит, бот спрашивает Calab, Calab просит хостинг завести новый пароль, и человек получает одноразовую ссылку. Маршруты открыты только ботам из списка оператора (MAILHOST_RESET_BOTS); на сервере без почтового хостинга оба отвечают 404.

Адрес ящика бот не видит никогда: hosting-check возвращает только домен и флаги. Новый пароль бот тоже не видит — он получает лишь ссылку; пароль показывает одноразовая страница, и живёт ссылка 10 минут.

Маршруты

МетодПутьЧто делает
POST/api/mailbox/hosting-checkЯщик пользователя на хостинге оператора? → {hosted, domain, verified}
POST/api/mailbox/password-resetЗавести новый пароль на хостинге → {token, redeemUrl, expiresAt}
POST/api/mailbox/password/redeemпублично: одноразовая страница человека меняет токен на {email, password}

Проверить ящик

POST /api/mailbox/hosting-check {userId} — про любого пользователя сервера, общее пространство не нужно. Ответ:

JSON
{ "hosted": true, "domain": "calab.io", "verified": true }
ПолеЧто значит
hostedадрес на доменах хостинга оператора (MAILHOST_DOMAINS)
domainдомен адреса — домен, не сам адрес
verifiedпочта аккаунта подтверждена; без этого сброс вернёт 403
curl -s -X POST $CALAB/api/mailbox/hosting-check -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d "{\"userId\": \"$USER\"}"
# → {"hosted": true, "domain": "calab.io", "verified": true}

Сбросить пароль

POST /api/mailbox/password-reset {userId} прогоняет проверки по порядку и только потом обращается к хостингу:

СитуацияОтвет
бот не в списке оператора403 FORBIDDEN
пользователя нет404 NOT_FOUND
цель — гость или бот403 FORBIDDEN
нет общего пространства с целью403 FORBIDDEN
почта цели не подтверждена403 ERROR_CODE_EMAIL_NOT_VERIFIED
домен адреса не на хостинге422 ERROR_CODE_VALIDATION, field: "domain", reason: "DOMAIN_NOT_HOSTED"
лимит сбросов429 + Retry-After
ящика нет на хостинге404 NOT_FOUND
хостинг не отвечает или злой админ-токен503 ERROR_CODE_UNAVAILABLE — повторите позже

Ответ — {token, redeemUrl, expiresAt}: сервер уже завёл на хостинге новый пароль и спрятал его под одноразовым токеном на 10 минут. Отправьте redeemUrl человеку — например, в личные сообщения.

curl -s -X POST $CALAB/api/mailbox/password-reset -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d "{\"userId\": \"$USER\"}"
# → {"token": "kQ…", "redeemUrl": "https://app.example.com/mail-reset/kQ…", "expiresAt": "2026-10-15T12:10:00Z"}

Страница человека

redeemUrl ведёт на /mail-reset/<token>. Страница сама делает единственный анонимный POST /api/mailbox/password/redeem {token} — сервер отдаёт {email, password} и тут же удаляет токен. Человек видит адрес и новый пароль один раз: моноширинно, с «Скопировать» и «Открыть в Calab». Повторное открытие или истёкшая ссылка — 410 ERROR_CODE_CODE_EXPIRED; человеку остаётся попросить бота новую. Боту этот маршрут не нужен: его вызывает страница.

Лимиты

ЛимитЗначение
Сбросы на одного человека3 в час
Сбросы одного бота10 в час
Ссылкаодна на 10 минут, одноразовая