more fix and update

This commit is contained in:
lendry
2026-06-24 20:15:19 +03:00
parent dcab6557d3
commit 9727cf3f35
53 changed files with 3479 additions and 494 deletions

View File

@@ -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-код',