mirror of
https://github.com/complexcaresolutions/dak.c2s.git
synced 2026-03-17 19:33:41 +00:00
feat: add PUT /api/auth/profile endpoint for self-service profile update
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6bc0b3ac5a
commit
1fa5d20d40
2 changed files with 58 additions and 1 deletions
|
|
@ -16,7 +16,7 @@ from app.schemas.auth import (
|
||||||
RegisterRequest,
|
RegisterRequest,
|
||||||
TokenResponse,
|
TokenResponse,
|
||||||
)
|
)
|
||||||
from app.schemas.user import UserResponse
|
from app.schemas.user import ProfileUpdate, UserResponse
|
||||||
from app.services.auth_service import (
|
from app.services.auth_service import (
|
||||||
activate_mfa,
|
activate_mfa,
|
||||||
authenticate_user,
|
authenticate_user,
|
||||||
|
|
@ -26,6 +26,7 @@ from app.services.auth_service import (
|
||||||
register_user,
|
register_user,
|
||||||
revoke_refresh_token,
|
revoke_refresh_token,
|
||||||
setup_mfa,
|
setup_mfa,
|
||||||
|
update_profile,
|
||||||
)
|
)
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
@ -150,3 +151,15 @@ def change_password_endpoint(
|
||||||
def me(current_user: User = Depends(get_current_user)):
|
def me(current_user: User = Depends(get_current_user)):
|
||||||
"""Return the currently authenticated user's profile."""
|
"""Return the currently authenticated user's profile."""
|
||||||
return UserResponse.model_validate(current_user)
|
return UserResponse.model_validate(current_user)
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/profile", response_model=UserResponse)
|
||||||
|
def update_profile_endpoint(
|
||||||
|
data: ProfileUpdate,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
current_user: User = Depends(get_current_user),
|
||||||
|
):
|
||||||
|
"""Update the authenticated user's profile."""
|
||||||
|
update_data = data.model_dump(exclude_unset=True)
|
||||||
|
user = update_profile(db, current_user, **update_data)
|
||||||
|
return UserResponse.model_validate(user)
|
||||||
|
|
|
||||||
|
|
@ -275,3 +275,47 @@ def change_password(
|
||||||
user.password_hash = hash_password(new_password)
|
user.password_hash = hash_password(new_password)
|
||||||
user.must_change_password = False
|
user.must_change_password = False
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Profile update
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def update_profile(
|
||||||
|
db: Session,
|
||||||
|
user: User,
|
||||||
|
username: str | None = None,
|
||||||
|
email: str | None = None,
|
||||||
|
first_name: str | None = None,
|
||||||
|
last_name: str | None = None,
|
||||||
|
display_name: str | None = None,
|
||||||
|
) -> User:
|
||||||
|
"""Update the authenticated user's own profile fields."""
|
||||||
|
if username and username != user.username:
|
||||||
|
existing = db.query(User).filter(User.username == username, User.id != user.id).first()
|
||||||
|
if existing:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_409_CONFLICT,
|
||||||
|
detail="Username already taken",
|
||||||
|
)
|
||||||
|
user.username = username
|
||||||
|
|
||||||
|
if email and email != user.email:
|
||||||
|
existing = db.query(User).filter(User.email == email, User.id != user.id).first()
|
||||||
|
if existing:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_409_CONFLICT,
|
||||||
|
detail="Email already taken",
|
||||||
|
)
|
||||||
|
user.email = email
|
||||||
|
|
||||||
|
if first_name is not None:
|
||||||
|
user.first_name = first_name
|
||||||
|
if last_name is not None:
|
||||||
|
user.last_name = last_name
|
||||||
|
if display_name is not None:
|
||||||
|
user.display_name = display_name
|
||||||
|
|
||||||
|
db.commit()
|
||||||
|
db.refresh(user)
|
||||||
|
return user
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue