Перейти к основному содержимому

Identity API — карта областей и реестр investor-области

HTTP-API identity разбит на области по актору (папки api/). Эта страница — реестр public/investor-области (18 операций СМС-входа инвестора + refresh/sign-out), общие enum-ы аутентификации и единые правила ответов/ошибок. Реестры остальных областей — в их подпапках.

Области API (папки по актору)

Область (папка)АкторЧто покрываетРеестр
investor/User / Anonymous (частный инвестор)СМС-вход, 2FA, пин-код, профиль, смена контактов, refresh/sign-out; агент-онбординг: accept/decline приглашения, become-agent (ADR-0061)этот файл (ниже)
company-user/User (сотрудник компании)компания, пользователи, роли (Scoped-RBAC), назначения, каталог permissions, приглашение/отзыв агента по телефону (ADR-0061)company-user/README.md
agent/User (сам агент)self-действия над членством: выход из агентства (leave), возврат к инвестору (become-investor) — ADR-0061agent/README.md
admin/ExternalSystem (система администрирования, m2m, ADR-0053)блокировка/удаление/сброс факторов/отзыв сессий учётокadmin/README.md
internal/ExternalSystem (gateway/сервисы, m2m)authorize/check-permission (enforcement)internal/README.md

Единые правила ответов/ошибок (см. ниже) применяются во всех областях; area-специфичные правила (policy AdminSystemOnly, tenancy CompanyId, m2m audience) — в реестрах соответствующих папок.

Metadata

ПолеЗначение
Сервис/контекстidentity
Статусконтракты стабильны, изменение — через migration-план
Owning teamPIN Platform Core
Область действияinvestor/public area (СМС-вход, 2FA, пин-код, профиль, смена контактов) + общие правила ответов/ошибок; company-user/admin/internal — отдельные реестры (см. «Области API»)
AssumptionsКлиент обрабатывает 200/400 типизированно; 401/429/5xx попадают в общую ветку ошибок (при 401 клиент очищает локальную сессию — refresh-flow вводится отдельно)
Зависимостиdomain/user.md, domain/user-session.md

Реестр операций (18)

#ОперацияHTTPRouteFeature groupАкторДокумент
1requestSignInCodePOST/api/investors/auth/request-sign-in-codeauthAnonymousrequest-sign-in-code.md
2signUpOrSignInPOST/api/investors/auth/sign-up-or-sign-inauthAnonymoussign-up-or-sign-in.md
3confirmSignInPOST/api/investors/auth/confirm-sign-inauthAnonymousconfirm-sign-in.md
4verifySignInPasswordPOST/api/investors/auth/verify-sign-in-passwordauthAnonymousverify-sign-in-password.md
5signUpPOST/api/investors/auth/sign-upauthAnonymoussign-up.md
6getCurrentInvestorGET/api/investors/meprofileUserget-current-investor.md
7updateInvestorPUT/api/investors/meprofileUserupdate-investor.md
8changePasswordPOST/api/investors/me/password/changesecurityUserchange-password.md
9setPinCodePOST/api/investors/me/pin-code/setsecurityUserset-pin-code.md
10clearPinCodePOST/api/investors/me/pin-code/clearsecurityUserclear-pin-code.md
11requestEnableTwoFactorPOST/api/investors/me/2fa/enable-requestsecurityUserrequest-enable-two-factor.md
12confirmEnableTwoFactorPOST/api/investors/me/2fa/enable-confirmsecurityUserconfirm-enable-two-factor.md
13requestDisableTwoFactorPOST/api/investors/me/2fa/disable-requestsecurityUserrequest-disable-two-factor.md
14confirmDisableTwoFactorPOST/api/investors/me/2fa/disable-confirmsecurityUserconfirm-disable-two-factor.md
15requestEmailChangePOST/api/investors/me/email/change-requestcontactsUserrequest-email-change.md
16confirmEmailChangePOST/api/investors/me/email/change-confirmcontactsUserconfirm-email-change.md
17requestPhoneChangePOST/api/investors/me/phone/change-requestcontactsUserrequest-phone-change.md
18confirmPhoneChangePOST/api/investors/me/phone/change-confirmcontactsUserconfirm-phone-change.md

Ответы и ошибки

Единые правила для всех областей API identity:

  • Успех (200) — тело содержит модель результата операции (у каждой операции своя, описана в её документе).
  • Бизнес-ошибка (400) — тело содержит список ошибок операции. У каждой ошибки: безопасный код/сообщение (без PII), опциональный контекст (пары ключ-значение — каждая операция перечисляет свои ключи в своём документе) и, для ошибок валидации входа, список ошибок по полям (имя поля + код правила валидации + локализованное сообщение). Диагностика исключений — только в non-prod контурах.
  • 401 / 429 / 5xx — без специальной схемы (общая ветка ошибок); при 401 клиент очищает локальную сессию (refresh-flow вводится отдельно).

Каждый ответ несёт идентификаторы сквозной корреляции (trace/span) для диагностики.

Общие модели аутентификации

JwtTokenModel — access-токен

ПолеТипОбязательностьОписание
tokenstringДаПодписанный JWT (claims: sub = UserId/investorId; PII в claims отсутствует).
notBeforestring (ISO 8601)ДаМомент начала действия.
typeTokenTypeДаJwtToken / RefreshToken (выдаётся JwtToken; refresh вводится отдельно).
expirationDatestring (ISO 8601)ДаМомент истечения.

Enum SignInNextStep — следующий шаг входа

ЗначениеКогда возвращается
RequiresPasswordУ инвестора установлен пароль (hasPassword = true) — фронт показывает форму пароля (verifySignInPassword).
RequiresSmsCodeОтправлен СМС-код — фронт показывает форму кода (confirmSignIn с signInConfirmationRequestId + confirmationCode).
RequiresPinCodeЗадан пин-код (hasPinCode = true) — фронт показывает форму пин-кода (confirmSignIn с pinCode).

Enum AuthNextAction — необязательная подсказка UI после входа

ЗначениеКогда
FillNameИмя пустое (lazy-регистрация) — предложить заполнить ФИО.
FillPinCodeПин-код не задан — предложить установить.
FillEmailEmail не задан.
FillPasswordПароль не установлен.

Не блокирует аутентификацию; сервер вычисляет первую применимую подсказку в порядке FillName → FillPinCode → FillEmail → FillPassword.

Enum SignUpOrSignInOutcome: Registered (создан новый инвестор) / SignedIn (найден существующий).

FullName — дом полей в domain/user.md (VO: firstName, lastName, middleName?, max 128).

Общие правила безопасности (все 18 операций)

ПравилоЗначение
Rate-limit отправки кодовINV-S4 (user-session.md): ≤ 1 СМС на номер в 60 сек, ≤ 5 в час (по PhoneNumber + IpAddress) → IDENTITY_CONFIRMATION_RATE_LIMITED (429)
Попытки кодаINV-S2: 5 неверных вводов → запрос Exhausted, нужен новый request-шаг
TTL кодаINV-S3: 5 минут (ExpiresAt)
LockoutINV-8 (user.md): 10 неуспешных проверок пароля/пин-кода → LockoutUntil = now + 15 мин
Маскирование PIIТелефон в логах/событиях UI — +7***1234; email — d***@mail; сами коды/пароли/пин-коды не логируются никогда; хранение — только хэши (HMAC-SHA256 для кодов, Argon2id для пароля/пин-кода)
User enumerationОшибки входа не раскрывают, существует ли номер: единый IDENTITY_SIGN_IN_FAILED-паттерн для неверного пароля/пин-кода; исключение: signUp возвращает конфликт телефона (DUPLICATE_PHONE-паттерн) — зафиксировано как известное поведение
Тест-контурrealConfirmationCodeDispatched = false — код не отправлялся реально (заглушка verifier), в тест-контуре действует фиксированный код

Следующий шаг входа: разрешение неоднозначности

Ответ шага входа несёт ровно одно значение SignInNextStep. Если у инвестора заданы и пароль, и пин-код, сервер выбирает шаг детерминированно (единый порядок на всех клиентах), клиент не решает сам. RequiresSmsCode возвращается, когда сильных факторов нет (свежая lazy-регистрация) либо пользователь явно инициировал вход по коду. Конкретный приоритет — в документе операции входа; клиент обрабатывает любое из трёх значений и не предполагает, что вернётся именно СМС-ветка.

Асинхронные последствия входа (окно согласованности)

Успешный вход завершается синхронно выдачей JwtTokenModel (200); дальнейшие эффекты — асинхронные и пользователь видит их с небольшим лагом (секунды):

  • публикуется UserSignedInKafkaEvent (pin.identity.sign-ins.v1, key = UserId) — по нему user-activity/history/favorites связывают анонимную сессию (anonymous_id из referrerUrl/клиента) с учёткой: история просмотров и избранное, накопленные до входа, «доклеиваются» к пользователю после применения события, не в момент ответа;
  • по тому же событию срабатывает алерт о входе с нового устройства (notifications);
  • до применения события клиент может краткий промежуток не видеть смёрженную анонимную историю — это ожидаемое поведение, повторное действие не требуется.

Операции refresh-flow investor-области

Расширение auth-контракта; вводится под feature-флагом identity.refresh-flow.enabled.

ОперацияHTTPRouteFeature groupАктор / доступДокумент
refreshTokenPOST/api/v1/auth/refreshauthAnonymous (аутентификация refresh-токеном)refresh-token.md
signOutPOST/api/v1/auth/sign-outauthauthenticatedsign-out.md

Агент-онбординг investor-области (ADR-0061)

Self-действия инвестора-адресата приглашения и самостоятельного перехода в агенты. Авторизация accept/decline — по совпадению телефона (INV-CI2), не по tenant.

ОперацияHTTPRouteFeature groupАктор / доступДокумент
acceptInvitationPOST/api/v1/me/agent-invitations/{invitationId}/acceptagent-onboardingUser (адресат, phone-match)accept-invitation.md
declineInvitationPOST/api/v1/me/agent-invitations/{invitationId}/declineagent-onboardingUser (адресат, phone-match)decline-invitation.md
becomeAgentPOST/api/v1/me/become-agentagent-onboardingUser (инвестор, self)become-agent.md

Операции остальных областей

Реестры не-investor областей — в подпапках (см. «Области API» выше); здесь только указатели:

  • company-user (компании / роли / permissions / назначения, 16 операций; +приглашение и отзыв агента по телефону, ADR-0061) — company-user/README.md.
  • agent (self-действия агента: выход из агентства, возврат к инвестору, ADR-0061) — agent/README.md.
  • admin (блокировка / удаление / сброс факторов / отзыв сессий учёток, m2m, ADR-0053) — admin/README.md. Создание компаний Agency/Broker/Partner и платформенных ролей — отдельная система администрирования, здесь не документируется.
  • internal (authorize/check-permission, m2m enforcement) — internal/README.md.

Связанные документы