|
from flask import Blueprint, request, jsonify, current_app |
|
from flask_jwt_extended import jwt_required, get_jwt_identity |
|
from backend.services.auth_service import register_user, login_user, get_user_by_id |
|
from backend.models.user import User |
|
|
|
auth_bp = Blueprint('auth', __name__) |
|
|
|
@auth_bp.route('/', methods=['OPTIONS']) |
|
def handle_options(): |
|
"""Handle OPTIONS requests for preflight CORS checks.""" |
|
return '', 200 |
|
|
|
@auth_bp.route('/register', methods=['OPTIONS']) |
|
def handle_register_options(): |
|
"""Handle OPTIONS requests for preflight CORS checks for register route.""" |
|
return '', 200 |
|
|
|
@auth_bp.route('/register', methods=['POST']) |
|
def register(): |
|
""" |
|
Register a new user. |
|
|
|
Request Body: |
|
email (str): User email |
|
password (str): User password |
|
confirm_password (str): Password confirmation |
|
|
|
Returns: |
|
JSON: Registration result |
|
""" |
|
try: |
|
data = request.get_json() |
|
|
|
|
|
if not data or not all(k in data for k in ('email', 'password', 'confirm_password')): |
|
return jsonify({ |
|
'success': False, |
|
'message': 'Email, password, and confirm_password are required' |
|
}), 400 |
|
|
|
email = data['email'] |
|
password = data['password'] |
|
confirm_password = data['confirm_password'] |
|
|
|
|
|
if password != confirm_password: |
|
return jsonify({ |
|
'success': False, |
|
'message': 'Passwords do not match' |
|
}), 400 |
|
|
|
|
|
if len(password) < 8: |
|
return jsonify({ |
|
'success': False, |
|
'message': 'Password must be at least 8 characters long' |
|
}), 400 |
|
|
|
|
|
result = register_user(email, password) |
|
|
|
if result['success']: |
|
return jsonify(result), 201 |
|
else: |
|
return jsonify(result), 400 |
|
|
|
except Exception as e: |
|
current_app.logger.error(f"Registration error: {str(e)}") |
|
return jsonify({ |
|
'success': False, |
|
'message': 'An error occurred during registration' |
|
}), 500 |
|
|
|
@auth_bp.route('/login', methods=['OPTIONS']) |
|
def handle_login_options(): |
|
"""Handle OPTIONS requests for preflight CORS checks for login route.""" |
|
from flask import current_app |
|
current_app.logger.info(f"OPTIONS request for /login from {request.remote_addr}") |
|
current_app.logger.info(f"Request headers: {dict(request.headers)}") |
|
return '', 200 |
|
|
|
@auth_bp.route('/login', methods=['POST']) |
|
def login(): |
|
""" |
|
Authenticate and login a user. |
|
|
|
Request Body: |
|
email (str): User email |
|
password (str): User password |
|
remember_me (bool): Remember me flag for extended session (optional) |
|
|
|
Returns: |
|
JSON: Login result with JWT token |
|
""" |
|
try: |
|
|
|
current_app.logger.info(f"Login request received from {request.remote_addr}") |
|
current_app.logger.info(f"Request headers: {dict(request.headers)}") |
|
current_app.logger.info(f"Request data: {request.get_json()}") |
|
|
|
data = request.get_json() |
|
|
|
|
|
if not data or not all(k in data for k in ('email', 'password')): |
|
current_app.logger.warning("Login failed: Missing email or password") |
|
return jsonify({ |
|
'success': False, |
|
'message': 'Email and password are required' |
|
}), 400 |
|
|
|
email = data['email'] |
|
password = data['password'] |
|
remember_me = data.get('remember_me', False) |
|
|
|
|
|
result = login_user(email, password, remember_me) |
|
|
|
if result['success']: |
|
|
|
response_data = jsonify(result) |
|
response_data.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000') |
|
response_data.headers.add('Access-Control-Allow-Credentials', 'true') |
|
current_app.logger.info(f"Login successful for user {email}") |
|
return response_data, 200 |
|
else: |
|
current_app.logger.warning(f"Login failed for user {email}: {result.get('message', 'Unknown error')}") |
|
return jsonify(result), 401 |
|
|
|
except Exception as e: |
|
current_app.logger.error(f"Login error: {str(e)}", exc_info=True) |
|
return jsonify({ |
|
'success': False, |
|
'message': 'An error occurred during login' |
|
}), 500 |
|
|
|
@auth_bp.route('/logout', methods=['OPTIONS']) |
|
def handle_logout_options(): |
|
"""Handle OPTIONS requests for preflight CORS checks for logout route.""" |
|
return '', 200 |
|
|
|
@auth_bp.route('/logout', methods=['POST']) |
|
@jwt_required() |
|
def logout(): |
|
""" |
|
Logout current user. |
|
|
|
Returns: |
|
JSON: Logout result |
|
""" |
|
try: |
|
return jsonify({ |
|
'success': True, |
|
'message': 'Logged out successfully' |
|
}), 200 |
|
|
|
except Exception as e: |
|
current_app.logger.error(f"Logout error: {str(e)}") |
|
return jsonify({ |
|
'success': False, |
|
'message': 'An error occurred during logout' |
|
}), 500 |
|
|
|
@auth_bp.route('/user', methods=['OPTIONS']) |
|
def handle_user_options(): |
|
"""Handle OPTIONS requests for preflight CORS checks for user route.""" |
|
return '', 200 |
|
|
|
@auth_bp.route('/user', methods=['GET']) |
|
@jwt_required() |
|
def get_current_user(): |
|
""" |
|
Get current authenticated user. |
|
|
|
Returns: |
|
JSON: Current user data |
|
""" |
|
try: |
|
user_id = get_jwt_identity() |
|
user_data = get_user_by_id(user_id) |
|
|
|
if user_data: |
|
return jsonify({ |
|
'success': True, |
|
'user': user_data |
|
}), 200 |
|
else: |
|
return jsonify({ |
|
'success': False, |
|
'message': 'User not found' |
|
}), 404 |
|
|
|
except Exception as e: |
|
current_app.logger.error(f"Get user error: {str(e)}") |
|
return jsonify({ |
|
'success': False, |
|
'message': 'An error occurred while fetching user data' |
|
}), 500 |