""" Authentication routes - Register, Login, Logout, Profile """ from flask import Blueprint, request, jsonify from app.services.auth_service import AuthService, token_required from app.models.user import User, Customer from app.models.domain import db auth_bp = Blueprint('auth', __name__, url_prefix='/api/auth') @auth_bp.route('/register', methods=['POST']) def register(): """ Register new customer Request body: { "email": "user@example.com", "password": "password123", "password_confirm": "password123", "full_name": "John Doe", "company_name": "Acme Inc" (optional) } """ try: data = request.json # Validate required fields required_fields = ['email', 'password', 'password_confirm', 'full_name'] for field in required_fields: if not data.get(field): return jsonify({ 'status': 'error', 'message': f'{field} is required' }), 400 # Validate email format email = data['email'].lower().strip() if '@' not in email or '.' not in email: return jsonify({ 'status': 'error', 'message': 'Invalid email format' }), 400 # Validate password match if data['password'] != data['password_confirm']: return jsonify({ 'status': 'error', 'message': 'Passwords do not match' }), 400 # Validate password strength password = data['password'] if len(password) < 8: return jsonify({ 'status': 'error', 'message': 'Password must be at least 8 characters' }), 400 # Register user user, customer, error = AuthService.register_user( email=email, password=password, full_name=data['full_name'].strip(), company_name=data.get('company_name', '').strip() or None ) if error: return jsonify({ 'status': 'error', 'message': error }), 400 # Generate token token = AuthService.generate_token(user.id, user.role) return jsonify({ 'status': 'success', 'message': 'Registration successful', 'token': token, 'user': user.to_dict(), 'customer': customer.to_dict() }), 201 except Exception as e: db.session.rollback() return jsonify({ 'status': 'error', 'message': f'Registration failed: {str(e)}' }), 500 @auth_bp.route('/login', methods=['POST']) def login(): """ Login user Request body: { "email": "user@example.com", "password": "password123" } """ try: data = request.json # Validate required fields if not data.get('email') or not data.get('password'): return jsonify({ 'status': 'error', 'message': 'Email and password are required' }), 400 # Login user user, token, error = AuthService.login_user( email=data['email'].lower().strip(), password=data['password'] ) if error: return jsonify({ 'status': 'error', 'message': error }), 401 # Get customer profile if customer role customer_data = None if user.role == 'customer' and user.customer: customer_data = user.customer.to_dict() return jsonify({ 'status': 'success', 'message': 'Login successful', 'token': token, 'user': user.to_dict(), 'customer': customer_data }), 200 except Exception as e: return jsonify({ 'status': 'error', 'message': f'Login failed: {str(e)}' }), 500 @auth_bp.route('/me', methods=['GET']) @token_required def get_profile(current_user): """ Get current user profile Headers: Authorization: Bearer """ try: customer_data = None if current_user.role == 'customer' and current_user.customer: customer_data = current_user.customer.to_dict() return jsonify({ 'status': 'success', 'user': current_user.to_dict(), 'customer': customer_data }), 200 except Exception as e: return jsonify({ 'status': 'error', 'message': f'Failed to get profile: {str(e)}' }), 500 @auth_bp.route('/verify-token', methods=['POST']) def verify_token(): """ Verify if token is valid Request body: { "token": "jwt_token_here" } """ try: data = request.json token = data.get('token') if not token: return jsonify({ 'status': 'error', 'message': 'Token is required', 'valid': False }), 400 payload = AuthService.verify_token(token) if not payload: return jsonify({ 'status': 'error', 'message': 'Invalid or expired token', 'valid': False }), 401 return jsonify({ 'status': 'success', 'message': 'Token is valid', 'valid': True, 'payload': { 'user_id': payload['user_id'], 'role': payload['role'] } }), 200 except Exception as e: return jsonify({ 'status': 'error', 'message': str(e), 'valid': False }), 500