feat(auth): add profile update and password change endpoints; enhance provider list handling
This commit is contained in:
@@ -272,3 +272,115 @@ def me():
|
||||
"""Get current user information."""
|
||||
user = get_current_user()
|
||||
return {"user": user}
|
||||
|
||||
|
||||
@bp.route("/profile", methods=["PATCH"])
|
||||
@require_auth
|
||||
def update_profile():
|
||||
"""Update current user profile information."""
|
||||
from flask import request
|
||||
from app.database import db
|
||||
from app.models.user import User
|
||||
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return {"error": "No data provided"}, 400
|
||||
|
||||
user_data = get_current_user()
|
||||
if not user_data:
|
||||
return {"error": "User not authenticated"}, 401
|
||||
|
||||
user = User.query.get(int(user_data["id"]))
|
||||
if not user:
|
||||
return {"error": "User not found"}, 404
|
||||
|
||||
# Update allowed fields
|
||||
if "name" in data:
|
||||
name = data["name"].strip()
|
||||
if not name:
|
||||
return {"error": "Name cannot be empty"}, 400
|
||||
if len(name) > 100:
|
||||
return {"error": "Name too long (max 100 characters)"}, 400
|
||||
user.name = name
|
||||
|
||||
try:
|
||||
db.session.commit()
|
||||
|
||||
# Return fresh user data from database
|
||||
updated_user = {
|
||||
"id": str(user.id),
|
||||
"email": user.email,
|
||||
"name": user.name,
|
||||
"picture": user.picture,
|
||||
"role": user.role,
|
||||
"is_active": user.is_active,
|
||||
"provider": "password", # This endpoint is only for password users
|
||||
"providers": [p.provider for p in user.oauth_providers],
|
||||
"plan": user.plan.to_dict() if user.plan else None,
|
||||
"credits": user.credits,
|
||||
}
|
||||
|
||||
return {
|
||||
"message": "Profile updated successfully",
|
||||
"user": updated_user
|
||||
}
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return {"error": f"Failed to update profile: {str(e)}"}, 500
|
||||
|
||||
|
||||
@bp.route("/password", methods=["PUT"])
|
||||
@require_auth
|
||||
def change_password():
|
||||
"""Change or set user password."""
|
||||
from flask import request
|
||||
from app.database import db
|
||||
from app.models.user import User
|
||||
from werkzeug.security import check_password_hash
|
||||
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return {"error": "No data provided"}, 400
|
||||
|
||||
user_data = get_current_user()
|
||||
if not user_data:
|
||||
return {"error": "User not authenticated"}, 401
|
||||
|
||||
user = User.query.get(int(user_data["id"]))
|
||||
if not user:
|
||||
return {"error": "User not found"}, 404
|
||||
|
||||
new_password = data.get("new_password")
|
||||
current_password = data.get("current_password")
|
||||
|
||||
if not new_password:
|
||||
return {"error": "New password is required"}, 400
|
||||
|
||||
# Password validation
|
||||
if len(new_password) < 6:
|
||||
return {"error": "Password must be at least 6 characters long"}, 400
|
||||
|
||||
# Check authentication method: if user logged in via password, require current password
|
||||
# If user logged in via OAuth, they can change password without current password
|
||||
current_auth_method = user_data.get("provider", "unknown")
|
||||
|
||||
if user.password_hash and current_auth_method == "password":
|
||||
# User has a password AND logged in via password, require current password for verification
|
||||
if not current_password:
|
||||
return {"error": "Current password is required to change password"}, 400
|
||||
|
||||
if not check_password_hash(user.password_hash, current_password):
|
||||
return {"error": "Current password is incorrect"}, 400
|
||||
# If user logged in via OAuth (google, github, etc.), they can change password without current password
|
||||
|
||||
# Set the new password
|
||||
try:
|
||||
user.set_password(new_password)
|
||||
db.session.commit()
|
||||
|
||||
return {
|
||||
"message": "Password updated successfully"
|
||||
}
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
return {"error": f"Failed to update password: {str(e)}"}, 500
|
||||
|
||||
Reference in New Issue
Block a user