Направление работ: Mobile Код раздела: 1.3.1 Авторизация > Вход > Вход по код-паролю Статус: Готов Ответственный: Панкова Л.А. Версия: 0.1 Обновлено: 14.07.26


1. Назначение

Раздел описывает вход пользователя в мобильное приложение по ранее установленному код-паролю: напрямую без биометрической проверки или после неуспешной биометрической проверки.

Документ описывает фронтовые сценарии входа по код-паролю, состояние ошибки ввода и выход из аккаунта, если пользователь не может войти.

2. Ключевые понятия

Код-пароль - короткий цифровой пароль для повторного входа в мобильное приложение.

Биометрическая проверка - проверка пользователя через скан лица или отпечаток.

3. Scope

Входит

S1. Вход по код-паролю без биометрической проверки.

S2. Вход по код-паролю после неуспешной биометрической проверки.

S3. Состояние ошибки при неверном код-пароле.

S4. Выход из аккаунта, если пользователь не может войти.

Не входит

4. BR

Указаны в пункте 4 раздела Back: 1.1.2 Вход в систему.

5. Функциональные требования (UC + FR)

IDСценарийФункциональное требованиеBRВесСтатус
S1: #FR1.3.1-1Пользователь открывает приложение после ранее выполненного входа в аккаунт и входит в приложение по код-паролю без биометрической проверкиИнтерфейс открывает экран ввода ранее установленного код-пароля, показывает цифровую клавиатуру и прогресс ввода.1Реализовано
S2: #FR1.3.1-2Пользователь открывает приложение после ранее выполненного входа в аккаунт, но скан лица или отпечаток не сработалИнтерфейс открывает экран ввода код-пароля, показывает цифровую клавиатуру, прогресс ввода и позволяет повторить биометрическую проверку тем способом, который не сработал: скан лица или отпечаток.1Частично \ #OQ1.3.1-3 \ #OQ1.3.1-4
S3: #FR1.3.1-3Пользователь вводит неверный код-парольИнтерфейс показывает ошибку неверного код-пароля на экране ввода и позволяет повторить ввод без выхода из сценария. Лимитов на количество попыток ввода код-пароля нет.1Частично \ #OQ1.3.1-2 \ #OQ1.3.1-5
S4: #FR1.3.1-4Пользователь нажимает кнопку “Не могу войти”Интерфейс показывает окно с текстом “Выйти из аккаунта и войти по номеру телефона или почте?” и кнопками “Выйти” и “Остаться”.

По нажатию кнопки “Выйти” интерфейс завершает пользовательскую сессию и переводит пользователя в Mobile 1.3 Вход. По нажатию кнопки “Остаться” интерфейс закрывает окно и оставляет пользователя на экране ввода код-пароля.
1Не реализовано \ #OQ1.3.1-1

6. Открытые вопросы

IDИсточникВопросКомуСтатусРекомендацииИтоговое решение
#OQ1.3.1-1Код FR1.3.1-4Требование говорит: кнопка «Не могу войти» открывает окно «Выйти из аккаунта и войти по номеру телефона или почте?» с «Выйти»/«Остаться»; «Выйти» завершает сессию и ведёт в 1.3 Вход. В коде на экране пин-входа нет ни кнопки «Не могу войти», ни окна; экран без AppBar/«назад» — при забытом пине и без биометрии единственный выход это успешная биометрия. Логаут есть только в профиле. \ log_pin.dart:97-195; profile_title.dart:308-345РазработкаOpenКритично: без биометрии и при забытом пине пользователь заблокирован в приложении. FR1.3.1-4 описывает флоу полностью, продуктового выбора нет. Закрываю сам (приоритет): реализовать по BRD — кнопка «Не могу войти» + диалог, «Выйти» переиспользует AuthScope.signOut() и SecureCubit.onUnauthenticated() (сброс secure-состояния) → тикет в Bitrix.реализовать по BRD — кнопка «Не могу войти»
#OQ1.3.1-2Код FR1.3.1-3Требование говорит: показать ошибку и «позволить повторить ввод без выхода из сценария». В коде повтор ничем не ограничен: нет счётчика попыток, блокировки или тайм-аута после серии неверных вводов (BRD про лимит молчит). \ log_pin.dart:144-188; secure_cubit.dart:136-147Бизнес/РазработкаOpenBRD про лимит молчит — не додумываю. Но 4-значный пин без лимита уязвим к перебору. (А, рекоменд.) ввести счётчик + нарастающий cooldown/блок после N неверных; (Б) осознанно оставить без лимита и зафиксировать в BRD. Продукт + безопасность.(Б) осознанно оставить без лимита и зафиксировать в BRD
#OQ1.3.1-3Код FR1.3.1-2Требование говорит: повторить биометрию «тем способом, который не сработал: скан лица или отпечаток». В коде одна кнопка ретрая; метод выбирает ОС (biometricOnly), иконка — по платформе (iOS = Face ID, иначе отпечаток), а не по фактически доступному/не сработавшему методу. \ log_pin.dart:31-47,134-143,225-235Бизнес/РазработкаOpen(А, рекоменд.) показывать иконку/подпись по фактическому типу через существующий Utils.getTypeBiometric() (в пин-экране сейчас не вызывается); (Б) принять платформенную иконку как достаточную и уточнить FR1.3.1-2. Связать с OQ1.3.1-4 (тот же корень).(Б) принять платформенную иконку как достаточную и уточнить FR1.3.1-2. Связать с OQ1.3.1-4 (тот же корень)
#OQ1.3.1-4Код FR1.3.1-2Проблема: иконка биометрии выбирается только по Platform.isIOS (iOS → face_id.svg, иначе → отпечаток), а не по реально доступному типу; Utils.getTypeBiometric() возвращает фактический тип, но в пин-экране не используется → на Android с распознаванием лица покажет отпечаток. \ log_pin.dart:225-235; utils.dart:963-1008РазработкаOpenФикс — замена платформенной развилки на getTypeBiometric() с фолбэком на платформу. Зависит от решения по OQ1.3.1-3 (достаточно ли платформенной иконки). Связать с OQ1.3.1-3.принять платформенную иконку как достаточную и уточнить FR1.3.1-2
#OQ1.3.1-5Код FR1.3.1-3Проблема: ошибка неверного код-пароля выражена только тряской (_shake) и красным цветом точек; текстовое сообщение отключено (errorTextStyle fontSize:0), явной подписи «неверный код-пароль» нет. \ log_pin.dart:168-172,90-94,359-377РазработкаOpenFR1.3.1-3 требует показать ошибку; лейбл есть, но скрыт (fontSize:0) — похоже на случайное подавление (как в 1.2.1/OQ1.2.1-3). Закрываю сам: вернуть текст «Неверный код-пароль», тряску/красный оставить усилением → тикет в Bitrix. Если продукт считает цвет+тряску достаточными — отметить в FR1.3.1-3.От бизнеса: доработка, вернуть текст ошибки, вес 1.
#OQ1.3.1-6Код вне BRDЧто нашли: при УСПЕШНОЙ биометрии вызывается Haptics.vibrate(HapticsType.error) — тактильный сигнал ошибки на успешную проверку (похоже на копипаст-баг). \ log_pin.dart:41-43РазработкаOpenЯвный баг, продуктового вопроса нет. Закрываю сам: заменить HapticsType.error на HapticsType.success при успешной биометрии → тикет в Bitrix.заменить HapticsType.error на HapticsType.success
#OQ1.3.1-7Код вне BRDЧто нашли: отладочные print в потоке пина выводят соль/хэш-параметры и «Pass = Pass» в логи; хэш пина хранится в SharedPreferences (ключ secure_hashPass), а не в Keychain/Keystore. \ secure_cubit.dart:110,119,127,140; secure_source.dart:23,40-48РазработкаOpenЗакрываю сам (приоритет): убрать отладочные print с секретами перед релизом → тикет в Bitrix. Хранение хэша в SharedPreferences vs Keychain/Keystore — тот же вопрос, что в 1.2.1/OQ1.2.1-6; решение тех-лида по модели угроз ведём там, не дублирую.убрать отладочные print с секретами перед релизом

Вопросы по сверке с кодом

BRD 1.3.1 v0.1 · booking.mobile.flutter · commit dad0c65/dev · 2026-07-10 · якорь lib/src/feature/auth/log_pin/log_pin.dart + lib/src/feature/secure/ Сводка: вопросов 7 (бизнесовых 3 / программных 4) · подтверждено без вопросов 1 (FR1.3.1-1) · отрезано находок обратного прохода 1 (заглушка авто-локаута сессии: timeAutoLock=30, onAppActive/onAppInactive пустые — secure_cubit.dart:43-97) Под особым вниманием: FR1.3.1-4 (флоу «Не могу войти» отсутствует), FR1.3.1-2 (биометрия — метод/иконка), FR1.3.1-3 (видимость ошибки)

Бизнесовые

Связано сЧто в BRDЧто в кодеГде в коде
Б1FR1.3.1-4Кнопка «Не могу войти» → окно «Выйти из аккаунта и войти по номеру телефона или почте?» с «Выйти»/«Остаться»; «Выйти» завершает сессию и ведёт в 1.3 ВходНа экране пин-входа нет ни кнопки «Не могу войти», ни этого окна; экран без AppBar/кнопки «назад» — при забытом пине и без биометрии единственный выход это успешная биометрия. Логаут существует только в профиле («Выйти из аккаунта?»). — нужно решение: реализовать escape-флоу на экране пинаlog_pin.dart:97-195 (нет кнопки/диалога); profile_title.dart:308-345 (логаут только в профиле)
Б2FR1.3.1-3Показать ошибку и «позволить повторить ввод без выхода из сценария»Повтор ничем не ограничен: нет счётчика попыток, блокировки или тайм-аута после серии неверных вводов (BRD про лимит молчит). — нужно решение: вводить ли лимит попыток / cooldown для 4-значного пинаlog_pin.dart:144-188 (checkPass без счётчика); secure_cubit.dart:136-147
Б3FR1.3.1-2Повторить биометрию «тем способом, который не сработал: скан лица или отпечаток»Одна кнопка ретрая биометрии; метод выбирает ОС (biometricOnly), иконка — по платформе (iOS = Face ID, иначе отпечаток), а не по фактически не сработавшему/доступному методу. — нужно решение: достаточно ли единой кнопки по платформе или различать face/fingerprintlog_pin.dart:31-47, 134-143, 225-235

Рекомендация / варианты решения

  • Escape при невозможности входа (Б1) — критично: без биометрии и при забытом пине пользователь заблокирован в приложении. Вариант А (рекоменд.): реализовать по BRD — кнопка «Не могу войти» + диалог с «Выйти» (переиспользовать AuthScope.signOut(), ср. profile_title.dart:345, и SecureCubit.onUnauthenticated() secure_cubit.dart:79-84 для сброса secure-состояния) / «Остаться». Вариант Б: временно вести на восстановление (1.4) без полного логаута — но это расходится с текстом FR1.3.1-4.
  • Лимит попыток (Б2) — Вариант А (рекоменд.): счётчик + нарастающий cooldown/блок после N неверных (защита от перебора 4-значного пина). Вариант Б: осознанно оставить без лимита и зафиксировать это в BRD.
  • Различение метода биометрии (Б3) — Вариант А (рекоменд.): показывать иконку/подпись по фактическому типу через уже существующий Utils.getTypeBiometric() (utils.dart:963), который в пин-экране сейчас не вызывается. Вариант Б: принять платформенную иконку как достаточную и уточнить формулировку FR1.3.1-2.

Программные

Связано сЧто в BRDЧто в кодеГде в коде
П1FR1.3.1-2Повтор биометрии тем способом, что не сработал (face / отпечаток)Иконка биометрии выбирается только по Platform.isIOS (iOS → face_id.svg, иначе → Icons.fingerprint), а не по реально доступному типу; Utils.getTypeBiometric() возвращает фактический BiometricType, но в пин-экране не используется → на Android с распознаванием лица покажет отпечатокlog_pin.dart:225-235; utils.dart:963-1008
П2FR1.3.1-3«Интерфейс показывает ошибку неверного код-пароля на экране ввода»Ошибка выражена только тряской (_shake) и красным цветом точек; текстовое сообщение отключено (errorTextStyle fontSize:0). Явной подписи «неверный код-пароль» нетlog_pin.dart:168-172, 90-94, 359-377
П3вне BRDПри УСПЕШНОЙ биометрии вызывается Haptics.vibrate(HapticsType.error) — тактильный сигнал ошибки на успешную проверку (похоже на копипаст-баг)log_pin.dart:41-43
П4вне BRDОтладочные print в потоке пина выводят соль/хэш-параметры и «Pass = Pass» в логи; хэш пина хранится в SharedPreferences (ключ secure_hashPass), а не в Keychain/Keystoresecure_cubit.dart:110,119,127,140; secure_source.dart:23,40-48

Рекомендация / варианты решения

  • Иконка/тип биометрии (П1, ср. Б3) — заменить платформенную развилку на Utils.getTypeBiometric() с фолбэком на платформу, если тип не определён; так иконка совпадёт с реально доступным методом.
  • Видимая ошибка ввода (П2) — Вариант А (рекоменд.): вернуть текст ошибки (сейчас fontSize:0) с формулировкой «Неверный код-пароль»; тряску/красный оставить усилением. Вариант Б: если продукт считает цвет+тряску достаточными — зафиксировать это в BRD (иначе FR1.3.1-3 «показывает ошибку» выполнен лишь частично).
  • Тактильный сигнал (П3) — заменить HapticsType.error на HapticsType.success при успешной биометрии.
  • Логи и хранение секрета (П4) — убрать отладочные print с секретами перед релизом; рассмотреть перенос хэша в flutter_secure_storage (Keychain/Keystore). Вне BRD, но относится к безопасности пин-входа.

0 items under this folder.