Skip to content

v1.3 — 2FA (TOTP + backup codes)

Choose a tag to compare

@dripips dripips released this 01 May 16:22

v1.3 — Двухфакторная аутентификация

Полноценная 2FA по стандарту RFC 6238 (TOTP) + одноразовые backup-коды для emergency-доступа.

🛡️ TOTP setup-flow

  • Страница /profile/two_factor с QR-кодом (SVG via rqrcode) — отсканируй в Google Authenticator / 1Password / Authy / любом TOTP-клиенте
  • Fallback на ручной ввод секрета (для старых клиентов)
  • Verify-step с 6-значным кодом перед включением — никакого "включил-и-забыл-как-настроил"
  • Drift-tolerance ±30s + replay-protection через otp_last_used_at (тот же код не пускают дважды в окне)

🔑 Backup codes

  • 10 одноразовых hex-кодов (8 chars) генерятся при включении 2FA
  • Plaintext показывается ОДИН раз — потом только bcrypt-хеши в БД (security best practice)
  • Каждый код consumed-after-use: использовал → удалён из набора
  • Регенерация по запросу (требует TOTP) — старые становятся невалидны

🚪 Sign-in challenge

  • После password-auth юзер с включённой 2FA попадает на /two_factor/challenge
  • Поле принимает TOTP или backup-код (single input, оба варианта работают)
  • Pending session живёт 5 минут — дальше повторный логин

🎨 UI

  • Карточка статуса 2FA в /profile/security (вкл/выкл + кол-во оставшихся backup-кодов)
  • Apple-style верстка: status-dot, card-apple--inset для отображения backup-codes
  • Confirm-required при выключении

🐛 Bonus fix

  • Submodule design-system: убран pointer-events: none со скрытого <select> внутри .filter-chip календаря — теперь chip-фильтры кликабельны без apple-select Stimulus-контроллера, используется нативный системный picker

🌍 i18n

  • +35 ключей в ru/en/de → паритет 2232/2232/2232