diff --git a/web_server/blueprints/email.py b/web_server/blueprints/email.py
index b588f7c..67d75bb 100644
--- a/web_server/blueprints/email.py
+++ b/web_server/blueprints/email.py
@@ -4,10 +4,13 @@ from email.mime.text import MIMEText
from os import getenv
from random import randrange
from dotenv import load_dotenv
+from utils.user_utils import generate_token
+from secrets import token_hex
+
load_dotenv()
-def send_email(email) -> None:
+def send_email(email, func) -> None:
"""
Send a verification email to the user.
"""
@@ -20,15 +23,8 @@ def send_email(email) -> None:
# Setup up the receiver details
login_code = randrange(100000, 1000000)
- body = f"""
-
-
-
- Thank you for choosing Gander
- Your Gander login code is: {login_code}
-
-
- """
+ body = func()
+ print(body, flush=True)
msg = MIMEText(body, "html")
msg["Subject"] = "Reset Gander Login"
msg["From"] = SMTP_EMAIL
@@ -43,7 +39,38 @@ def send_email(email) -> None:
smtp.send_message(msg)
except TimeoutError:
- print("Server timed out")
+ print("Server timed out", flush=True)
except Exception as e:
- print("Error: ", e)
\ No newline at end of file
+ print("Error: ", e, flush=True)
+
+def forgot_password_body(email):
+ token = generate_token(email, token_hex(32))
+ url = getenv("VITE_API_URL")
+
+ full_url = url + "/reset_password/" + token
+ content = f"""
+
+
+
+ Password Reset
+
+
+
+
+
Gander
+
Password Reset Request
+
Click the button below to reset your password. This link is valid for 1 hour.
+
Reset Password
+
+
+
+ """
+
+ return content
\ No newline at end of file
diff --git a/web_server/blueprints/user.py b/web_server/blueprints/user.py
index c51c1d2..6508b57 100644
--- a/web_server/blueprints/user.py
+++ b/web_server/blueprints/user.py
@@ -1,6 +1,7 @@
-from flask import Blueprint, jsonify, session, abort
+from flask import Blueprint, jsonify, session, abort, abort
from utils.user_utils import *
from blueprints.utils import login_required
+from blueprints.email import send_email, forgot_password_body
user_bp = Blueprint("user", __name__)
@@ -89,14 +90,15 @@ def get_login_status():
username = session.get("username")
return jsonify({'status': username is not None, 'username': username})
-@user_bp.route('/user/forgot_password/', methods=['POST'])
+@user_bp.route('/user/forgot_password/', methods=['GET','POST'])
def user_forgot_password(email):
"""
Will send link to email to reset password by looking at the user_id within session to see whos password should be reset
Creates a super random number to be used a the link to reset password I guess a random number generator seeded with a secret
"""
+ send_email(email, lambda: forgot_password_body(email))
+ return email
- return
@user_bp.route('/user/reset_password//')
def user_reset_password(token, new_password):
@@ -107,7 +109,7 @@ def user_reset_password(token, new_password):
if email:
response = reset_password(new_password, email)
if response:
- return "Success"
+ return 200
else:
- return "Failure"
- return "Failure"
\ No newline at end of file
+ abort(500)
+ return abort(500)
\ No newline at end of file
diff --git a/web_server/utils/user_utils.py b/web_server/utils/user_utils.py
index bb1c4f0..d454023 100644
--- a/web_server/utils/user_utils.py
+++ b/web_server/utils/user_utils.py
@@ -124,11 +124,18 @@ def subscription_expiration(user_id: int, subscribed_id: int) -> int:
return 0
-def verify_token(token: str) -> Optional[str]:
+def generate_token(email, salt_value) -> str:
+ """
+ Creates a token for password reset
+ """
+ token = serializer.dumps(email, salt=salt_value)
+ return token
+
+def verify_token(token: str, salt_value) -> Optional[str]:
"""
Given a token verifies token and decodes the token into an email
"""
- email = serializer.loads(token, salt='1', max_age=3600)
+ email = serializer.loads(token, salt=salt_value, max_age=3600)
return email if email else False
def reset_password(new_password: str, email: str) -> bool: