2026.06.05 frontend javítgatás és új belépési logika megvalósítva

This commit is contained in:
Roo
2026-06-05 05:46:04 +00:00
parent 59a30ac428
commit 18524a08f2
38 changed files with 3967 additions and 1028 deletions

View File

@@ -0,0 +1,89 @@
# Profile UI Refactor + Identity Docs + Change Password Implementation
## Overview
Full-stack implementation of Profile page UI/UX improvements, identity documents (identity_docs) display/editing, and secure password change functionality.
## Backend Changes
### 1. [`backend/app/schemas/user.py`](backend/app/schemas/user.py:68) — PersonUpdate Schema
- Added `identity_docs: Optional[Any] = None` field to `PersonUpdate` class (line 79)
- Created new `ChangePasswordRequest` class (lines 93-96) with:
- `current_password: str` — the user's existing password for verification
- `new_password: str` — the desired new password
### 2. [`backend/app/api/v1/endpoints/users.py`](backend/app/api/v1/endpoints/users.py:179) — PUT /me/person
- Updated imports to include `ChangePasswordRequest`, `AuthService`, `verify_password`, `get_password_hash`
- Added identity_docs merge logic (lines 219-227):
- If `identity_docs` is provided and not null, merges with existing docs using `dict.update()`
- Preserves fields not sent in the update payload (e.g., if only LICENSE is sent, ID_CARD is preserved)
- Falls back to direct assignment if either value is not a dict
### 3. [`backend/app/api/v1/endpoints/users.py`](backend/app/api/v1/endpoints/users.py:260) — PUT /me/password (New Endpoint)
Complete password change flow:
1. **Current password verification** (line 273): Uses `verify_password()` to check the provided current password against the stored hash
2. **New password ≠ old password check** (line 280): Prevents reusing the same password
3. **Complexity validation** (line 287): Calls `AuthService._validate_password_complexity()` which reads dynamic rules from `SystemParameter` (min length, uppercase, digits, special chars)
4. **Hash and save** (line 290): Uses `get_password_hash()` to bcrypt-hash the new password and commits to DB
5. **Error handling** (lines 292-297): Rollback on SQLAlchemyError, returns 500 with detail
## Frontend Changes
### 1. [`frontend/src/stores/auth.ts`](frontend/src/stores/auth.ts:19) — PersonData Interface
- Added `identity_docs: Record<string, any> | null` (line 28)
- Added `ice_contact: Record<string, any> | null` (line 29)
### 2. [`frontend/src/stores/auth.ts`](frontend/src/stores/auth.ts:430) — changePassword Action
New Pinia action that:
- Calls `PUT /users/me/password` with `{ current_password, new_password }`
- Returns `{ status: string, message: string }` on success
- Throws with error message on failure
### 3. [`frontend/src/views/ProfileView.vue`](frontend/src/views/ProfileView.vue:1) — Complete Rewrite
#### UI Design (Dark Card Theme)
- **Card backgrounds**: `bg-black/40 backdrop-blur-xl` with `border border-white/10`
- **Data text**: `text-white font-medium` (bold white for readability)
- **Labels**: `text-white/50 text-sm` (muted gray labels)
- **Accent color**: `#00E5A0` (green) used **only** for buttons and active states
- **Input fields**: `bg-white/5 border-white/10` with focus state `border-[#00E5A0]/50`
- **Close button**: Top-right X button with `hover:text-red-400`
#### Identity Docs Section (lines 214-309)
- **Read mode**: Displays ID_CARD (number, expiry_date) and LICENSE (number, expiry_date, categories) in bordered sub-cards
- **Edit mode**: Input fields for all identity doc fields, organized in sub-sections
- **Payload construction** (`buildIdentityDocsPayload()`, lines 636-663): Only sends identity_docs if at least one field is filled; constructs nested JSON `{ ID_CARD: { number, expiry_date }, LICENSE: { number, expiry_date, categories } }`
#### Change Password Modal (lines 431-528)
- **Teleport to body**: Renders outside the component tree for proper z-index stacking
- **3 fields**: Current password, new password, confirm new password
- **Frontend validation** (`submitPasswordChange()`, lines 713-751):
- All fields required
- New password must match confirmation
- Minimum 6 characters
- **API call**: Calls `authStore.changePassword()` on success
- **Success feedback**: Green success message with **auto-close after 2 seconds** (`setTimeout``closePasswordModal()`)
- **Error feedback**: Red error message from backend detail or fallback string
## Testing Results
| Test | Result |
|------|--------|
| Backend syntax check (user.py, users.py) | ✅ Pass |
| Backend module imports (PersonUpdate, ChangePasswordRequest) | ✅ Pass |
| Backend router routes (PUT /me/person, PUT /me/password) | ✅ Pass |
| Frontend Vite build (112 modules) | ✅ Pass |
| ProfileView chunk size | 27.26 kB |
## Security Considerations
1. **Password never returned in responses** — the `ChangePasswordRequest` is input-only
2. **Bcrypt hashing**`get_password_hash()` uses bcrypt with work factor
3. **Dynamic complexity rules**`_validate_password_complexity` reads from `SystemParameter` table, allowing admin to change rules without code deploy
4. **No password logging** — the endpoint never logs the password values
5. **Identity docs merge** — preserves existing data when partial updates are sent