Public Auth API — /api/v1/auth

Auth model: JWT с audience public для protected routes

Response envelope: формат ответа A (см. api-overview.html)

JWT

---

POST /api/v1/auth/register

Регистрация публичного пользователя.

Auth: None

Request body:

ПолеТипОбяз.Описание
usernamestringда3–64 символа
emailstringдаmax 128
passwordstringдаmin 8, max 128
consent_pdbooleanнетсогласие на обработку ПД
consent_versionstringнетверсия политики, max 64

Responses:

КодОписание
201{ "success": true, "data": {...} }
422validation_error
409email_already_exists, username_already_exists
403registration_disabled, consent_required

---

POST /api/v1/auth/login

Вход, выдача пары JWT.

Auth: None

Request body:

ПолеТипОбяз.Описание
usernamestringда
passwordstringда
mfa_codestringнетTOTP при включённом MFA

Response 200 — data:

ПолеТипОписание
access_tokenstringJWT access
токен обновленияstringJWT refresh
token_typestring"Bearer"
expires_inintTTL access token (сек)
mfa_requiredbooltrue если нужен второй фактор

Error codes: invalid_credentials, email_not_verified, account_locked, ip_locked, mfa_required, mfa_invalid, rate_limited, public_api_blocked

---

POST /api/v1/auth/email/verify

Подтверждение email по токену из письма.

Auth: None

Request body:

ПолеТипОбяз.
tokenstringда (min 8)

---

GET /api/v1/auth/me

Профиль текущего пользователя.

Auth: токен доступа (JWT), audience=public

Response 200 — data (PublicUserProfile):

ПолеТипОписание
idint
usernamestring
emailstring
email_verifiedbool
pending_emailstring \nullожидает подтверждения
rolestring \null
permissionsstring[]

---

PATCH /api/v1/auth/me

Обновление профиля или запрос смены email.

Auth: токен доступа (JWT), audience=public

Request (обновление username):

{ "username": "new_name" }

Request (смена email):

{ "email": "new@example.com" }

Если в body только email без username — трактуется как ChangeEmailRequest.

---

PATCH /api/v1/auth/me/password

Смена пароля.

Auth: токен доступа (JWT), audience=public

Request body:

ПолеТипОбяз.
current_passwordstringда
new_passwordstringда (min 8)

Response 200: { "success": true, "message": "Password updated" }

---

POST /api/v1/auth/token/refresh

Обновление пары JWT.

Auth: None (refresh token в body)

Request body:

ПолеТипОбяз.
токен обновленияstringда

Response 200 — data (TokenPairResponse): access_token, токен обновления, token_type, expires_in

---

POST /api/v1/auth/logout

Выход, инвалидация токенов.

Auth: токен доступа (JWT) + optional refresh в body

Request body (optional):

ПолеТипОписание
токен обновленияstringдля инвалидации refresh

Response 200: { "success": true, "message": "Logged out" }

---

POST /api/v1/auth/mfa/setup

Инициализация MFA — secret и данные для QR.

Auth: токен доступа (JWT), audience=public

Response 200: { "success": true, "data": { "secret": "...", ... } }

---

POST /api/v1/auth/mfa/enable

Включение MFA после верификации TOTP-кода.

Auth: токен доступа (JWT), audience=public

Request body:

ПолеТипОбяз.
secretstringда (из setup)
codestringда (TOTP)

---

POST /api/v1/auth/mfa/disable

Отключение MFA.

Auth: токен доступа (JWT), audience=public

Request body:

ПолеТипОбяз.
current_passwordstringда
codestringда (TOTP)

---

Коды ошибок (полный список)

CodeHTTPОписание
validation_error422проверка формата данных validation
invalid_credentials401Неверный login/password
email_not_verified403Email не подтверждён
account_locked403Аккаунт заблокирован
ip_locked403IP заблокирован
rate_limited429Rate limit (+ Retry-After)
mfa_required401Требуется MFA code
mfa_invalid401Неверный MFA code
token_invalid401Невалидный token
token_expired401Истёкший token
registration_disabled403Регистрация отключена
email_already_exists409Email занят
username_already_exists409Username занят
weak_password422Слабый пароль
password_policy_violation422Политика паролей
consent_required403Нужно согласие ПД
service_unavailable503Auth service недоступен
unauthorized401Нет/неверный JWT