Skip to content

feat(account): верификация email и сброс пароля (итер. 37) - #42

Merged
Azazlokus merged 1 commit into
mainfrom
feat/email-verify-reset
Aug 18, 2026
Merged

Azazlokus merged 1 commit into
mainfrom
feat/email-verify-reset

Conversation

@Azazlokus

Copy link
Copy Markdown
Owner

Что

Итерация 37 — верификация email + сброс пароля, поверх auth-фундамента итер. 36.
Аккаунт может нести опциональный email с верификацией; добавлен флоу «забыл пароль»
со сбросом пароля и разлогином всех сессий.

Зачем

Восстановление доступа (забытый пароль) и подтверждение владения email — базовые
возможности аккаунтов, которых не хватало. Сброс завязан на отзыв сессий из итер. 36:
смена пароля гасит все refresh-токены (разлогин везде).

Как

  • store — миграция 0003 (sqlite+postgres): accounts.email (опционален,
    частичный UNIQUE-индекс) + email_verified; таблица account_tokens одноразовых
    токенов (в БД только SHA-256, kind различает verify/reset, used_at). Методы
    AccountByEmail/SetEmailVerified/UpdatePassword/RevokeAllRefreshTokens/
    CreateAccountToken/ConsumeAccountToken (атомарное одноразовое потребление под
    гонкой: tx + UPDATE … WHERE used_at=0 с проверкой RowsAffected). CreateAccount
    получил параметр email.
  • account — интерфейс Mailer + LogMailer (dev: печатает токен в лог, SMTP нет);
    NewService с опциями WithMailer/WithTokenTTLs. Register(+email) шлёт токен
    верификации; VerifyEmail; RequestPasswordReset (анти-энумерация — всегда без
    ошибки); ResetPassword (валидация пароля ДО расхода токена, смена + отзыв ВСЕХ
    refresh). validateEmail через net/mail.
  • api — POST /api/verify-email, /api/request-password-reset, /api/reset-password
    (под пер-IP рейт-лимитом); /me отдаёт email + email_verified; ErrEmailTaken→409.
  • cmd/server — LogMailer в wiring; env ARENA_VERIFY_TTL (24h) / ARENA_RESET_TTL (1h).
  • web — опциональный email при регистрации, кнопка forgot, обработка ссылок из
    писем ?verify=/?reset= (токен стирается из URL после обработки), email + статус
    верификации в профиле.
  • docs — README RU/EN + docs/architecture.md.

Границы

Провод (internal/protocol) и симуляция не тронуты → игровые стражи не гонялись
(прецедент итер. 21/36). Бэкенд-фича безопасности → security-review: HIGH/MEDIUM нет
(одноразовые токены только SHA-256 и одноразовы; сброс валидирует пароль до расхода
токена и отзывает все сессии; reset без энумерации; LogMailer — dev-стаб с
self-warning).

Тестирование

  • make check (vet + -race) и make integration — зелёные.
  • Покрытие: store (email + занятость, verify, смена пароля, одноразовые токены —
    kind/повтор/просрочка, revoke-all; Postgres-сьют дополнен account_tokens),
    account (register+email+verify, email taken/invalid, полный reset-флоу с разлогином
    и одноразовостью — через recording-mailer), api (end-to-end verify + reset по HTTP).
  • Live-smoke бинаря на свежей БД (миграция 0003): register→/me(unverified)→verify→
    /me(verified); reset weak(400)/ok(204)/reuse(401); login old(401)/new(200).
  • node --check web/game.js.

BENCHMARKS.md не трогался — горячего пути нет.

На базе auth из итер. 36: аккаунт может нести опциональный email с верификацией,
добавлен флоу «забыл пароль» со сбросом и разлогином всех сессий.

- store: миграция 0003 (sqlite+postgres) — accounts.email (частичный UNIQUE) +
  email_verified; таблица account_tokens одноразовых токенов (SHA-256, kind,
  used_at). Методы AccountByEmail/SetEmailVerified/UpdatePassword/
  RevokeAllRefreshTokens/CreateAccountToken/ConsumeAccountToken (атомарное
  одноразовое потребление под гонкой). CreateAccount получил email.
- account: Mailer (интерфейс) + LogMailer (dev, печатает токен в лог); NewService
  с опциями WithMailer/WithTokenTTLs. Register(+email) шлёт токен верификации;
  VerifyEmail; RequestPasswordReset (анти-энумерация — всегда nil); ResetPassword
  (валидация пароля ДО расхода токена, смена + отзыв ВСЕХ refresh). validateEmail
  через net/mail.
- api: POST /api/verify-email, /api/request-password-reset, /api/reset-password
  (все под рейт-лимитом); /me отдаёт email + email_verified; ErrEmailTaken→409.
- cmd/server: LogMailer в wiring; env ARENA_VERIFY_TTL/ARENA_RESET_TTL.
- web: опциональный email при регистрации, кнопка forgot, обработка ссылок
  ?verify=/?reset= (токен стирается из URL), email+статус в профиле.
- docs: README RU/EN + architecture.

Провод/симуляция не тронуты (игровые стражи не гонялись); security-review —
HIGH/MEDIUM findings нет. make check + integration + live-smoke зелёные.
@Azazlokus
Azazlokus merged commit 3a21f60 into main Aug 18, 2026
10 checks passed
@Azazlokus
Azazlokus deleted the feat/email-verify-reset branch August 18, 2026 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant