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

POST /api/investors/me/pin-code/set — Установка/обновление пин-кода (setPinCode)

Назначение

Установить или обновить пин-код быстрого входа (4–12 цифр) текущего пользователя. Вызывается аутентифицированным пользователем; подтверждений не требует (пользователь уже аутентифицирован токеном). После установки вход предлагает шаг RequiresPinCode.

Metadata

ПолеЗначение
Сервис/контекстidentity
API areapublic
Feature groupsecurity
Статусapproved
Документdocs/06-services/identity/api/investor/set-pin-code.md

Актор и доступ

ПроверкаЗначение
Actor typeUser (Bearer JWT)
Auth policy / Permissionsauthenticated; permission identity.security.manage-self
Scope (RBAC)self
Record-levelтолько собственная запись (UserId из sub)
Tenant isolationне применяется (ADR-0052)
Auditsecurity-change: событие UserSecurityChangedEvent (PinCodeSet)

HTTP-контракт

ПолеЗначение
MethodPOST
Route/api/investors/me/pin-code/set
Success status200
Idempotency headerне применяется (повтор с тем же пином — та же цель)
Correlationсквозной trace через traceparent

Входные данные / параметры запроса (body SetPinCodeForm)

ПолеИсточникТипОбязательностьВалидация / ОграниченияБезопасность
UserIdidentity claims (sub)GuidДавалидный JWT401 без токена
pinCodebodystringДаmin 1; pattern ^\d{4,12}$ (INV-5 PinCodeFormat)никогда не логируется

Модель ответа SetPinCodeCommandResult

ПолеТипОбязательностьИсточникMaskingОписание
investorIdstring (Guid)ДаUserEntity.IdИдентификатор пользователя.

Алгоритм

  1. Проверить формат пин-кода: строго ^\d{4,12}$ (INV-5) — 4–12 цифр, ведущие нули значимы (пин — строка, не число); пустой ввод, нецифровые символы, длина < 4 или > 12 → ValidationError.
  2. Получить пользователя-актора (UserId из токена); он должен быть Active → иначе IDENTITY_USER_BLOCKED.
  3. Установить пин-код (хэш Argon2id), перезаписывая прежний, если был (INV-5); обнулить счётчик неудачных попыток (FailedAccessAttempts = 0).
  4. Зафиксировать доменное событие UserSecurityChangedEvent (вид PinCodeSet) для аудита.
  5. Ответ — investorId, HTTP 200.
Особенности поведения

Операция не отзывает активные сессии (INV-S7 охватывает смену пароля/телефона и блокировку, но не установку пин-кода). Повтор с любым валидным значением — та же цель (перезапись); конкурентная установка разрешается оптимистической блокировкой (побеждает последняя запись по значению). Производный флаг hasPinCode станет true при следующем чтении профиля (get-current-investor.md). Пин-код и хэш наружу/в события/в снапшот pin.identity.users.v1 не попадают.

Предусловия и постусловия

  • Пред: пользователь аутентифицирован и Active; pinCode соответствует ^\d{4,12}$.
  • Пост (успех): PinCodeHash установлен/перезаписан; FailedAccessAttempts = 0; зафиксирован доменный UserSecurityChangedEvent(PinCodeSet) (лента админ-аудита); hasPinCode = true; активные сессии сохранены; интеграционные события не публикуются.

Acceptance Criteria

  • Given Active-пользователь, When POST .../pin-code/set с pinCode = "1234", Then 200 {investorId}; hasPinCode при следующем GET /me = true; последующий вход предлагает шаг RequiresPinCode.
  • Given пользователь с уже заданным пин-кодом, When установка нового валидного значения, Then прежний хэш перезаписан, FailedAccessAttempts обнулён, активные сессии не отозваны.
  • Given pinCode = "0007", When установка, Then 200 — ведущие нули сохранены (значение — строка).
  • Given pinCode короче 4 / длиннее 12 / с нецифровыми символами / пустой, When установка, Then ValidationError (400) (INV-5).
  • Given учётка Blocked/Archived, When установка, Then IDENTITY_USER_BLOCKED (400).
  • Given запрос без валидного JWT, When установка, Then 401, клиент уходит на re-login.

Ошибки и failure modes

КодHTTP statusУсловиеСообщениеRetry
— (auth)401Нет/просрочен JWTклиент выполняет re-loginre-login
ValidationError400Пин-код не соответствует ^\d{4,12}$ (INV-5)Список ошибок валидацииno retry
IDENTITY_USER_BLOCKED400Status != Active«Учётная запись заблокирована»no retry

Совместимость и наблюдаемость

Контракт формата

Паттерн пин-кода — контрактный, менять нельзя без миграции клиентов.

Logs: UserId, факт установки (без значения); metrics: identity_pin_code_set_total; traces — OTel.

Обратные ссылки

Автоссылки: где используется этот документ.

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