# auth.py - Autentikasi dengan session yang benar from flask import Blueprint, request, jsonify, session from werkzeug.security import generate_password_hash, check_password_hash from database import Database from datetime import datetime import re auth_bp = Blueprint('auth', __name__) db = Database() def validate_email(email): pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$' return re.match(pattern, email) is not None def validate_username(username): pattern = r'^[a-zA-Z0-9_]{3,20}$' return re.match(pattern, username) is not None # ============ REGISTER ============ @auth_bp.route('/api/auth/register', methods=['POST']) def register(): data = request.get_json() username = data.get('username', '').strip() email = data.get('email', '').strip() password = data.get('password', '') full_name = data.get('full_name', '').strip() print(f"📝 [REGISTER] Attempt: username={username}, email={email}") # Validasi if not email: return jsonify({'error': 'Email harus diisi'}), 400 if not username: return jsonify({'error': 'Username harus diisi'}), 400 if not password: return jsonify({'error': 'Password harus diisi'}), 400 if not validate_username(username): return jsonify({'error': 'Username harus 3-20 karakter (huruf, angka, underscore)'}), 400 if not validate_email(email): return jsonify({'error': 'Format email tidak valid'}), 400 if len(password) < 6: return jsonify({'error': 'Password minimal 6 karakter'}), 400 # Cek duplikasi if db.get_user_by_username(username): return jsonify({'error': 'Username sudah digunakan'}), 400 if db.get_user_by_email(email): return jsonify({'error': 'Email sudah terdaftar'}), 400 # Buat user password_hash = generate_password_hash(password) user = db.create_user( username=username, email=email, password_hash=password_hash, full_name=full_name if full_name else username ) if not user: return jsonify({'error': 'Gagal membuat akun'}), 500 print(f"✅ [REGISTER] User created: id={user.id}") # SET SESSION - LANGSUNG LOGIN session.clear() session['user_id'] = user.id session['username'] = user.username session['user_email'] = user.email session['user_fullname'] = user.full_name session.permanent = True print(f"✅ [REGISTER] Session set: user_id={session.get('user_id')}") return jsonify({ 'success': True, 'user': { 'id': user.id, 'username': user.username, 'email': user.email, 'full_name': user.full_name } }) # ============ LOGIN ============ @auth_bp.route('/api/auth/login', methods=['POST']) def login(): data = request.get_json() identifier = data.get('identifier', '').strip() password = data.get('password', '') print(f"🔐 [LOGIN] Attempt: identifier={identifier}") if not identifier or not password: return jsonify({'error': 'Email/Username dan password diperlukan'}), 400 # Cari user user = db.get_user_by_email(identifier) if not user: user = db.get_user_by_username(identifier) if not user: print(f"❌ [LOGIN] User not found: {identifier}") return jsonify({'error': 'Email/Username atau password salah'}), 401 if not check_password_hash(user.password_hash, password): print(f"❌ [LOGIN] Wrong password for: {identifier}") return jsonify({'error': 'Email/Username atau password salah'}), 401 # Update last login db.update_user(user.id, last_login=datetime.utcnow()) # SET SESSION session.clear() session['user_id'] = user.id session['username'] = user.username session['user_email'] = user.email session['user_fullname'] = user.full_name session.permanent = True print(f"✅ [LOGIN] Success: user_id={user.id}, username={user.username}") return jsonify({ 'success': True, 'user': { 'id': user.id, 'username': user.username, 'email': user.email, 'full_name': user.full_name } }) # ============ LOGOUT ============ @auth_bp.route('/api/auth/logout', methods=['POST']) def logout(): user_id = session.get('user_id') print(f"🔓 [LOGOUT] User: {user_id}") session.clear() return jsonify({'success': True}) # ============ GET CURRENT USER ============ @auth_bp.route('/api/auth/me', methods=['GET']) def get_current_user(): user_id = session.get('user_id') print(f"🔍 [ME] Checking session, user_id={user_id}") if not user_id: return jsonify({'error': 'Not logged in'}), 401 user = db.get_user_by_id(user_id) if not user: print(f"❌ [ME] User not found in database: {user_id}") session.clear() return jsonify({'error': 'Not logged in'}), 401 print(f"✅ [ME] User found: {user.username}") return jsonify({ 'id': user.id, 'username': user.username, 'email': user.email, 'full_name': user.full_name }) # ============ UPDATE PROFILE ============ @auth_bp.route('/api/auth/update-profile', methods=['PUT']) def update_profile(): user_id = session.get('user_id') if not user_id: return jsonify({'error': 'Not logged in'}), 401 data = request.get_json() full_name = data.get('full_name') if full_name: db.update_user(user_id, full_name=full_name) session['user_fullname'] = full_name return jsonify({'success': True, 'message': 'Profil berhasil diperbarui'}) return jsonify({'error': 'Tidak ada data yang diupdate'}), 400 # ============ CHANGE PASSWORD ============ @auth_bp.route('/api/auth/change-password', methods=['POST']) def change_password(): user_id = session.get('user_id') if not user_id: return jsonify({'error': 'Not logged in'}), 401 data = request.get_json() old_password = data.get('old_password') new_password = data.get('new_password') if not old_password or not new_password: return jsonify({'error': 'Password lama dan baru diperlukan'}), 400 if len(new_password) < 6: return jsonify({'error': 'Password baru minimal 6 karakter'}), 400 user = db.get_user_by_id(user_id) if not check_password_hash(user.password_hash, old_password): return jsonify({'error': 'Password lama salah'}), 401 new_hash = generate_password_hash(new_password) db.update_user(user.id, password_hash=new_hash) return jsonify({'success': True, 'message': 'Password berhasil diubah'})