beeproject / forget.py
abidjoyia's picture
Upload 6 files
3cd2ab5 verified
import os
import logging
from flask import jsonify
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
from database import generate_reset_code, verify_reset_code, update_user_password
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Email configuration using environment variables
EMAIL_ADDRESS = os.environ.get('EMAIL_ADDRESS')
SENDGRID_API_KEY = os.environ.get('SENDGRID_API_KEY')
SENDER_NAME = os.environ.get('SENDER_NAME', 'BeeGuardian Team')
COMPANY_ADDRESS = os.environ.get('COMPANY_ADDRESS', 'Namal University')
COMPANY_CITY = os.environ.get('COMPANY_CITY', 'Mianwali')
COMPANY_STATE = os.environ.get('COMPANY_STATE', 'Punjab')
COMPANY_ZIP = os.environ.get('COMPANY_ZIP', '42200')
COMPANY_COUNTRY = os.environ.get('COMPANY_COUNTRY', 'Pakistan')
# Send email with reset code using SendGrid
def send_reset_email(email, code):
if not EMAIL_ADDRESS or not SENDGRID_API_KEY:
logger.error("Email configuration missing")
return False, "Email configuration missing"
# Email content with BeeGuardian intro and CAN-SPAM compliant footer
footer = (
f"\n\n--\n"
f"{SENDER_NAME}\n"
f"{COMPANY_ADDRESS}\n"
f"{COMPANY_CITY}, {COMPANY_STATE} {COMPANY_ZIP}\n"
f"{COMPANY_COUNTRY}"
)
content = (
f"Welcome to BeeGuardian! We are a team of students from Namal University Mianwali who created an innovative app to help beekeepers monitor bee health using mobile phone recordings. Our mission is to protect bees and support biodiversity.\n\n"
f"To reset your password, please use this code: {code}\n"
f"This code is valid for 15 minutes.{footer}"
)
message = Mail(
from_email=(EMAIL_ADDRESS, SENDER_NAME),
to_emails=email,
subject='Password Reset Code for BeeGuardian',
plain_text_content=content
)
try:
sg = SendGridAPIClient(SENDGRID_API_KEY)
response = sg.send(message)
return True, None
except Exception as e:
logger.error(f"Failed to send email to {email}: {str(e)}")
return False, str(e)
# Forgot password logic
def forgot_password(request):
data = request.json
if 'email' not in data:
logger.warning("Forgot password request missing email")
return jsonify({"error": "Email is required"}), 400
try:
code = generate_reset_code(data['email'])
if not code:
return jsonify({"error": "Email not found"}), 404
success, error_msg = send_reset_email(data['email'], code)
if success:
return jsonify({"success": True, "message": "Reset code sent to email"}), 200
logger.error(f"Failed to send reset email: {error_msg}")
return jsonify({"error": f"Failed to send email: {error_msg}"}), 500
except Exception as e:
logger.error(f"Error in forgot_password for {data['email']}: {str(e)}")
return jsonify({"error": str(e)}), 500
# Verify reset code logic
def verify_reset_code_endpoint(request):
data = request.json
if not all(key in data for key in ['email', 'code']):
logger.warning("Verify reset code request missing email or code")
return jsonify({"error": "Email and code are required"}), 400
try:
valid = verify_reset_code(data['email'], data['code'])
if valid:
return jsonify({"success": True, "message": "Code verified"}), 200
return jsonify({"error": "Invalid or expired code"}), 400
except Exception as e:
logger.error(f"Error in verify_reset_code for {data['email']}: {str(e)}")
return jsonify({"error": str(e)}), 500
# Reset password logic
def reset_password(request):
data = request.json
if not all(key in data for key in ['email', 'new_password']):
logger.warning("Reset password request missing required fields")
return jsonify({"error": "Email and new password are required"}), 400
try:
updated = update_user_password(data['email'], data['new_password'])
if updated:
return jsonify({"success": True, "message": "Password reset successfully"}), 200
logger.error(f"Failed to update password for {data['email']}")
return jsonify({"error": "Failed to update password"}), 500
except Exception as e:
logger.error(f"Error in reset_password for {data['email']}: {str(e)}")
return jsonify({"error": str(e)}), 500