Appearance
Auth Feature Design
Date: 2026-02-07
Overview
Full authentication flow for Partizap frontend: login, registration, email verification, password reset. Session-based auth with PHP backend (HTTP-only cookies, CSRF tokens).
Decisions
- Separate pages (not tabs):
/auth/login,/auth/register,/auth/verify-email,/auth/forgot-password,/auth/reset-password - Phone/SMS login: UI stubs (disabled), waiting for backend support
- Password confirmation: client-side only via Zod refine, not sent to backend
- User field:
email_verified: boolean(perfrontend-api-reference.md, notemail_verified_at) - Reset password: standard token-in-URL approach (one-time, expiring, from email link)
File Structure
app/
├── shared/
│ └── schemas/auth.ts — Zod validation schemas (login, register, etc.)
├── features/
│ └── auth/
│ └── composables/
│ └── useApiError.ts — API error → form error mapping
├── stores/auth.ts — UPDATE: add fetchUser, login, register, logout
├── entities/
│ └── user/model/user.schema.ts — UPDATE: email_verified boolean, add missing fields
├── middleware/
│ ├── auth.ts — Protect /cabinet/**, redirect to /auth/login
│ └── guest.ts — Redirect authenticated users away from /auth/**
├── plugins/auth.ts — Hydrate user on app init (GET /auth/me)
└── pages/auth/
├── login.vue — Email + password login
├── register.vue — Email + password + display_name registration
├── verify-email.vue — 6-digit code verification
├── forgot-password.vue — Request password reset email
└── reset-password.vue — Set new password (token from email)Auth Store (stores/auth.ts)
ts
interface User {
id: number
email: string
display_name: string
phone: string | null
account_type: 'personal' | 'business'
email_verified: boolean
avatar_url: string | null
city_id: number | null
district_id: number | null
metro_station_id: number | null
rating: string
reviews_count: number
products_count: number
is_active: boolean
is_admin: boolean
created_at: string
}
state: { user: User | null, loading: boolean }
getters: { isAuthenticated, isEmailVerified, isAdmin }
actions: { setUser, clearUser, fetchUser, login, register, logout }Validation Schemas (shared/schemas/auth.ts)
passwordSchema: 8-128 chars, uppercase, lowercase, digit, special char, no 3+ identicalloginSchema:registerSchema:forgotPasswordSchema:resetPasswordSchema:verifyEmailSchema:
Error Handling (features/auth/composables/useApiError.ts)
globalError: general error message for UAlertfieldErrors: per-field errors mapped from 422 detailshandleError(err): 422 → field mapping, 429 → rate limit with Retry-After, else → globalErrorclearErrors(): reset all
Middleware
auth.ts: if !authenticated → fetchUser() → if still !authenticated → redirect /auth/login guest.ts: if !authenticated → fetchUser() → if authenticated → redirect /cabinet
Plugin (plugins/auth.ts)
On SSR and first client load: call fetchUser() to hydrate auth state from session cookie.
Pages UI
All pages use Nuxt UI components: UForm, UFormField, UInput, UButton, UAlert.
/auth/login
- Email + Password fields
- "Remember me" checkbox (visual stub)
- "Forgot password?" link → /auth/forgot-password
- "Login" button
- Divider "or"
- "Login via SMS" button — disabled, tooltip "Coming soon"
- "No account? Register" → /auth/register
/auth/register
- Phone field — disabled with tooltip "Coming soon"
- Email + Password + Confirm password + Display name
- "Register" button
- "Already have an account? Login" → /auth/login
- After success → redirect /auth/verify-email
/auth/verify-email
- Text: "Enter 6-digit code sent to {email}"
- Code input (inputmode="numeric", maxlength=6)
- "Verify" button
- "Resend code" button with 60s cooldown timer
/auth/forgot-password
- Email field + "Send reset link" button
- After success → success alert + link to login
/auth/reset-password
- Token from ?token= query param (if missing → redirect /auth/forgot-password)
- New password field with passwordSchema validation
- After success → success alert + link to login
API Endpoints Used
| Action | Method | Endpoint | Auth |
|---|---|---|---|
| Register | POST | /auth/register | No |
| Login | POST | /auth/login | No |
| Current user | GET | /auth/me | Yes |
| Verify email | POST | /auth/verify-email | Yes |
| Resend code | POST | /auth/resend-verification | Yes |
| Forgot password | POST | /auth/forgot-password | No |
| Reset password | POST | /auth/reset-password | No |
| Logout | POST | /auth/logout | Yes |
i18n
Add auth-related keys to i18n/locales/ru.json under auth.* namespace.
SEO
All auth pages: useSeoMeta({ title: '...', robots: 'noindex, nofollow' }).