"""Email sending utilities for password reset, account confirmation, and newsletters.""" import smtplib from email.mime.text import MIMEText from os import getenv from secrets import token_hex from dotenv import load_dotenv from utils.auth import generate_token from .user_utils import get_session_info_email import redis from database.database import Database REDIS_URL = "redis://redis:6379/1" r = redis.from_url(REDIS_URL, decode_responses=True) load_dotenv() url = getenv("HOMEPAGE_URL") def send_email(email, func) -> None: """ Send a verification email to the user. """ # Setup the sender email details smtp_server = "smtp.gmail.com" smtp_port = 587 smtp_email = getenv("EMAIL") smtp_password = getenv("EMAIL_PASSWORD") # Setup up the receiver details body, subject = func() msg = MIMEText(body, "html") msg["Subject"] = subject msg["From"] = smtp_email msg["To"] = email # Send the email using smtplib with smtplib.SMTP(smtp_server, smtp_port) as smtp: try: smtp.starttls() # TLS handshake to start the connection smtp.login(smtp_email, smtp_password) smtp.ehlo() smtp.send_message(msg) except TimeoutError: print("Server timed out", flush=True) except smtplib.SMTPException as e: print("Error: ", e, flush=True) def forgot_password_body(email) -> str: """ Handles the creation of the email body for resetting password """ salt = token_hex(32) token = generate_token(email, salt) token += "R3sET" r.setex(token, 3600, salt) username = (get_session_info_email(email))["username"] full_url = url + "/reset_password/" + token content = f"""

Gander

Password Reset Request

Click the button below to reset your password for your account {username}. This link is valid for 1 hour.

Reset Password
""" return content, "Gander - Forgot Password" def confirm_account_creation_body(email) -> str: """ Handles account confirmation email body for account creation """ salt = token_hex(32) token = generate_token(email, salt) token += "CrEaTe" r.setex(token, 3600, salt) full_url = url + "/confirm_account_creation/" + token content = f"""

Gander

Confirm Account Creation

Click the button below to create your account. This link is valid for 1 hour.

Create Account
""" return content, "Gander - Confirm Account Creation" def newsletter_conf(email): """ Handles sending a confirmation email that a user has joined a newsletter """ salt = token_hex(32) token = generate_token(email, salt) token += "DaNeWs" r.setex(token, 3600, salt) full_url = url + "/user/unsubscribe/" + token content = f"""

Gander

Welcome to the Official Gander Newsletter!

If you are receiving this email, it means that you have been officially added to the Monthly Gander newsletter.

In this newsletter, you will receive updates about: your favourite streamers; important Gander updates; and more!

Unsubscribe?
""" # Check if user is already in database with Database() as db: user_exists = db.fetchone(""" SELECT * FROM newsletter WHERE email = ?;""", (email,)) print(user_exists, flush=True) if user_exists is None: add_to_newsletter(email) return content, "Gander - Newsletter" def add_to_newsletter(email): """ Add a person to the newsletter database """ # Create connection to the database with Database() as db: # Add the users email to the newsletter table db.execute(""" INSERT INTO newsletter (email) VALUES (?); """, (email,)) def remove_from_newsletter(email): """ Remove a person from the newsletter database """ # Create connection to the database with Database() as db: # Remove the users email from the newsletter table db.execute(""" DELETE FROM newsletter WHERE email = ?; """, (email,)) def email_exists(email): """ Returns whether email exists within database """ with Database() as db: data = db.fetchone(""" SELECT * FROM users WHERE email = ? """, (email,)) return bool(data)