more fix and update
This commit is contained in:
@@ -17,9 +17,11 @@ export const apiReference: ApiTagGroup[] = [
|
||||
endpoints: [
|
||||
{ method: 'POST', path: '/auth/register', summary: 'Регистрация пользователя', description: 'Первый пользователь получает isSuperAdmin.' },
|
||||
{ method: 'POST', path: '/auth/login', summary: 'Вход по почте, телефону или логину' },
|
||||
{ method: 'POST', path: '/auth/identify', summary: 'Проверить способ входа (identifier-first)' },
|
||||
{ method: 'POST', path: '/auth/otp/send', summary: 'Отправить OTP для passwordless-входа' },
|
||||
{ method: 'POST', path: '/auth/otp/verify', summary: 'Проверить OTP' },
|
||||
{ method: 'POST', path: '/auth/identify', summary: 'Проверить способ входа (identifier-first)', description: 'Возвращает isTotpEnabled, otpChannels, methods.' },
|
||||
{ method: 'POST', path: '/auth/totp/begin', summary: 'Начать вход по TOTP', description: 'Challenge для Google Authenticator вместо SMS/email OTP.' },
|
||||
{ method: 'POST', path: '/auth/totp/verify', summary: 'Подтвердить TOTP при входе', description: 'Завершает вход после кода из приложения-аутентификатора.' },
|
||||
{ method: 'POST', path: '/auth/otp/send', summary: 'Отправить OTP для passwordless-входа', description: 'Альтернатива TOTP; channel: email | phone | backupEmail | backupPhone.' },
|
||||
{ method: 'POST', path: '/auth/otp/verify', summary: 'Проверить OTP', description: 'Завершает вход по SMS/email без повторного TOTP.' },
|
||||
{ method: 'POST', path: '/auth/login/password', summary: 'Войти по паролю' },
|
||||
{ method: 'POST', path: '/auth/ldap/login', summary: 'Войти через LDAP/LDAPS' },
|
||||
{ method: 'POST', path: '/auth/pin/verify', summary: 'Подтвердить PIN-код' },
|
||||
@@ -52,6 +54,10 @@ export const apiReference: ApiTagGroup[] = [
|
||||
endpoints: [
|
||||
{ method: 'GET', path: '/security/users/{userId}/devices', summary: 'Активные устройства', auth: true },
|
||||
{ method: 'GET', path: '/security/users/{userId}/sessions', summary: 'Активные сессии', auth: true },
|
||||
{ method: 'GET', path: '/security/users/{userId}/totp/status', summary: 'Статус TOTP', auth: true },
|
||||
{ method: 'POST', path: '/security/users/{userId}/totp/setup', summary: 'Настроить TOTP (QR + секрет)', auth: true },
|
||||
{ method: 'POST', path: '/security/users/{userId}/totp/enable', summary: 'Включить TOTP', auth: true },
|
||||
{ method: 'POST', path: '/security/users/{userId}/totp/disable', summary: 'Отключить TOTP', auth: true },
|
||||
{ method: 'POST', path: '/security/users/{userId}/pin/setup', summary: 'Настроить PIN', auth: true },
|
||||
{ method: 'POST', path: '/security/users/{userId}/revoke-all-sessions', summary: 'Выйти везде', auth: true }
|
||||
]
|
||||
|
||||
@@ -571,7 +571,7 @@ docker compose restart sso-core`
|
||||
{
|
||||
slug: 'authentication',
|
||||
title: 'Аутентификация',
|
||||
description: 'Способы входа: пароль, OTP, LDAP, PIN и refresh-сессии.',
|
||||
description: 'Способы входа: TOTP (Google Authenticator), OTP, пароль, LDAP, PIN и refresh-сессии.',
|
||||
sections: [
|
||||
{
|
||||
id: 'flows',
|
||||
@@ -581,15 +581,147 @@ docker compose restart sso-core`
|
||||
type: 'table',
|
||||
headers: ['Сценарий', 'Endpoint', 'Описание'],
|
||||
rows: [
|
||||
['Identifier-first', 'POST /auth/identify', 'Проверка существования пользователя и способа входа'],
|
||||
['Passwordless OTP', 'POST /auth/otp/send + verify', '6-значный код на почту/телефон'],
|
||||
['Пароль', 'POST /auth/login/password', 'Логин + пароль или tempAuthToken после OTP'],
|
||||
['Identifier-first', 'POST /auth/identify', 'Проверка пользователя, isTotpEnabled, otpChannels и альтернативных способов'],
|
||||
['TOTP (основной)', 'POST /auth/totp/begin + verify', 'Вход через Google Authenticator, если аутентификатор подключён'],
|
||||
['Passwordless OTP (альтернатива)', 'POST /auth/otp/send + verify', '6-значный код на почту/телефон вместо TOTP'],
|
||||
['Пароль', 'POST /auth/login/password', 'Альтернативный вход по паролю'],
|
||||
['LDAP/LDAPS', 'POST /auth/ldap/login', 'Корпоративный вход (требует LDAP_ENABLED)'],
|
||||
['PIN', 'POST /auth/pin/verify', 'Разблокировка сессии после входа с PIN']
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'totp-login',
|
||||
title: 'Вход через приложение-аутентификатор (TOTP)',
|
||||
blocks: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
text: 'Если пользователь подключил Google Authenticator (или аналог) в разделе «Безопасность», код из приложения становится основным способом входа вместо SMS/email OTP. SMS и email используются только как альтернатива через «Другой способ входа».'
|
||||
},
|
||||
{
|
||||
type: 'list',
|
||||
items: [
|
||||
'1. POST /auth/identify с почтой или телефоном — в ответе isTotpEnabled: true и otpChannels (доступные каналы для альтернативного OTP).',
|
||||
'2. POST /auth/totp/begin — создаёт challenge (totpChallengeToken, TTL 5 минут). SMS/email на этом шаге не отправляются.',
|
||||
'3. Пользователь вводит 6-значный код из приложения-аутентификатора.',
|
||||
'4. POST /auth/totp/verify с totpChallengeToken и code — выдаётся JWT и refresh token (далее при необходимости PIN).'
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'callout',
|
||||
variant: 'tip',
|
||||
title: 'TOTP и SMS/email — альтернативы',
|
||||
text: 'Код из аутентификатора и код из SMS/email не комбинируются: это два разных способа пройти один и тот же шаг входа. После успешного OTP verify TOTP повторно не запрашивается.'
|
||||
},
|
||||
{
|
||||
type: 'table',
|
||||
headers: ['Ситуация', 'Поведение UI / API'],
|
||||
rows: [
|
||||
['Аутентификатор подключён', 'После identify сразу экран TOTP (totp/begin), без автоматической отправки SMS/email'],
|
||||
['Альтернатива: код на почту/телефон', 'POST /auth/otp/send с channel: email или phone, затем POST /auth/otp/verify'],
|
||||
['Привязаны и почта, и телефон', 'Пользователь выбирает канал (otpChannels) перед отправкой OTP'],
|
||||
['Только почта или только телефон', 'OTP отправляется сразу на единственный доступный канал'],
|
||||
['Альтернатива: пароль', 'POST /auth/login/password — без дополнительного TOTP'],
|
||||
['Включён PIN', 'После TOTP или OTP — POST /auth/pin/verify для полной сессии']
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'code',
|
||||
title: 'POST /auth/identify — фрагмент ответа',
|
||||
language: 'json',
|
||||
code: `{
|
||||
"exists": true,
|
||||
"hasPassword": true,
|
||||
"isPinEnabled": false,
|
||||
"isTotpEnabled": true,
|
||||
"otpChannels": [
|
||||
{ "channel": "email", "masked": "u***@example.com" },
|
||||
{ "channel": "phone", "masked": "+7********42" }
|
||||
],
|
||||
"methods": [
|
||||
{ "kind": "password", "channel": "password", "masked": "Пароль" }
|
||||
]
|
||||
}`
|
||||
},
|
||||
{
|
||||
type: 'code',
|
||||
title: 'Начать вход по TOTP',
|
||||
language: 'bash',
|
||||
code: `curl -X POST http://localhost:3000/auth/totp/begin \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-d '{
|
||||
"recipient": "user@example.com",
|
||||
"fingerprint": "device-fingerprint-uuid",
|
||||
"deviceName": "Chrome на Windows",
|
||||
"deviceType": "WEB"
|
||||
}'
|
||||
|
||||
# Ответ: { "totpChallengeToken": "eyJ..." }`
|
||||
},
|
||||
{
|
||||
type: 'code',
|
||||
title: 'Подтвердить код аутентификатора',
|
||||
language: 'bash',
|
||||
code: `curl -X POST http://localhost:3000/auth/totp/verify \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-d '{
|
||||
"totpChallengeToken": "eyJ...",
|
||||
"code": "123456"
|
||||
}'
|
||||
|
||||
# Ответ: AuthTokens (accessToken, refreshToken, sessionId, pinVerified, user)`
|
||||
},
|
||||
{
|
||||
type: 'code',
|
||||
title: 'Альтернатива: OTP на выбранный канал',
|
||||
language: 'bash',
|
||||
code: `# Отправить код (channel: email | phone | backupEmail | backupPhone)
|
||||
curl -X POST http://localhost:3000/auth/otp/send \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-d '{
|
||||
"recipient": "user@example.com",
|
||||
"channel": "phone"
|
||||
}'
|
||||
|
||||
# Подтвердить OTP — сразу выдаёт сессию, без TOTP
|
||||
curl -X POST http://localhost:3000/auth/otp/verify \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-d '{
|
||||
"recipient": "user@example.com",
|
||||
"code": "654321",
|
||||
"fingerprint": "device-fingerprint-uuid",
|
||||
"deviceName": "Chrome на Windows",
|
||||
"deviceType": "WEB"
|
||||
}'`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'totp-setup',
|
||||
title: 'Подключение аутентификатора',
|
||||
blocks: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
text: 'Настройка выполняется в личном кабинете: Безопасность → Дополнительная защита → Подключить аутентификатор. Название в Google Authenticator берётся из SystemSetting PROJECT_NAME (не захардкожено).'
|
||||
},
|
||||
{
|
||||
type: 'list',
|
||||
items: [
|
||||
'GET /security/users/{userId}/totp/status — проверка, включён ли TOTP',
|
||||
'POST /security/users/{userId}/totp/setup — QR-код (otpauthUrl) и секретный ключ',
|
||||
'POST /security/users/{userId}/totp/enable — подтверждение первого кода и активация',
|
||||
'POST /security/users/{userId}/totp/disable — отключение с проверкой текущего кода'
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'callout',
|
||||
variant: 'info',
|
||||
title: 'Повторная настройка',
|
||||
text: 'Если настройка начата, но не завершена, повторный вызов setup возвращает тот же секрет — не нужно сканировать новый QR, пока не истёк незавершённый challenge.'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'login-example',
|
||||
title: 'Примеры входа по паролю',
|
||||
@@ -709,6 +841,24 @@ docker compose restart sso-core`
|
||||
title: 'Сессии и PIN',
|
||||
description: 'Управление устройствами, PIN-блокировка и отзыв сессий.',
|
||||
sections: [
|
||||
{
|
||||
id: 'totp',
|
||||
title: 'TOTP (Google Authenticator)',
|
||||
blocks: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
text: 'Двухфакторная аутентификация через TOTP заменяет SMS/email OTP при входе. Управление устройствами и отзыв сессий — через те же endpoints, что описаны ниже.'
|
||||
},
|
||||
{
|
||||
type: 'list',
|
||||
items: [
|
||||
'GET /security/users/{userId}/totp/status',
|
||||
'POST /security/users/{userId}/totp/setup | enable | disable',
|
||||
'POST /auth/totp/begin и POST /auth/totp/verify — вход с аутентификатором'
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'pin',
|
||||
title: 'PIN-код',
|
||||
|
||||
Reference in New Issue
Block a user