Дмитрий
|
75897b1636
|
phase2(rate-limit): login + 2FA verify (5/15min) + frontend lockout
- AuthController: RateLimiter::hit/clear на login + verifyTwoFactor по ключу email|ip / pending_user_id|ip
- 429 + Retry-After header + JSON retry_after (lockoutResponse helper)
- ТЗ §22.4.4: 5 попыток / 15 мин; success чистит throttle; inactive user тоже расходует попытки
- extractRateLimitRetry в api/client.ts; auth-store.lockoutSeconds; v-alert в LoginView/TwoFactorView
- Pest +6 в RateLimitTest.php (73/73 за 8.07с, 246 assertions)
- Vitest +4 в auth-store + LoginView (149/149 за 12.31с)
- Quirk: wrong-password в тестах ≥8 символов (LoginRequest::min:8) — иначе валидация падает до controller
- Quirk: vi.mock api/client в auth-store.spec — иначе axios.isAxiosError в jsdom возвращает false для plain Error
- TODO (отдельные коммиты): IP-lockout 10/час через auth_log + email при 3 неудачах
- Регресс: lint+type+format OK; build 886ms; story:build 21/28 за 37.19с; Pint+Stan passed
- CLAUDE.md v1.35→v1.36, реестр v1.44→v1.45
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-08 20:49:47 +03:00 |
|
Дмитрий
|
59299d3c2b
|
phase2(auth-frontend): axios + Pinia + auth-store + auth-guards + form integration
- axios@^1.16 + pinia@^3.0 (--legacy-peer-deps).
- api/client.ts: axios с withCredentials+withXSRFToken (Sanctum SPA auto-XSRF).
ensureCsrfCookie() + extractValidationErrors/Message helpers.
- api/auth.ts: типизированные login/register/me/logout с AuthUser interface.
- stores/auth.ts: Pinia composition-store (user/loading/requires2fa +
isAuthenticated computed + login/register/fetchMe/logout actions).
logout() catch-swallow - UI всегда выходит локально.
- LoginView/RegisterView: useAuthStore интеграция, real POST через store,
errors из 422 на v-text-fields, redirect на /dashboard или /2fa,
:loading на btn'ах.
- Auth-guard в router.beforeEach: meta.requiresAuth на 10 routes
(6 app + 4 admin), meta.guestOnly на login/register/forgot. При первом
переходе fetchMe() restore-session. Unauth → /login?redirect=<original>.
- / redirect → /dashboard (auth-guard перехватит если не залогинен).
- Pinia в app.ts через app.use(createPinia()).
- cspell-words.txt: мокаем.
Vitest +10 (всего 139/139 за 10.11s):
- auth-store 7 (initial state + login success/reject + register + fetchMe
success/401 + logout swallow).
- router 5 переписан (login.guestOnly + 6 protected + admin layout +
3 error без auth + unauth /dashboard → /login?redirect).
- LoginView/RegisterView/router тесты получили createPinia в plugins.
- vi.mock api/auth в router+auth-store specs.
Регресс: lint+type+format OK; vitest 139/139; vite build (main app-chunk
105→153.64 KB +axios+pinia+auth gzipped 54.54 KB) 806ms; story:build 21/28
за 31.73s; Pest 61/61 за 5.86s.
CLAUDE.md v1.32->v1.33, реестр Открытых_вопросов v1.41->v1.42.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-08 19:59:43 +03:00 |
|