From d8754b4486130c7f73e953622f50e3e6e0b905aa Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Tue, 2 Jan 2024 16:22:48 -0800 Subject: [PATCH] feat/fix: email format validation --- backend/apps/web/routers/auths.py | 56 +++++++++++++++++-------------- backend/constants.py | 1 + backend/utils/misc.py | 7 ++++ 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/backend/apps/web/routers/auths.py b/backend/apps/web/routers/auths.py index fb1139898..714982e34 100644 --- a/backend/apps/web/routers/auths.py +++ b/backend/apps/web/routers/auths.py @@ -8,6 +8,7 @@ from pydantic import BaseModel import time import uuid + from apps.web.models.auths import ( SigninForm, SignupForm, @@ -20,7 +21,7 @@ from apps.web.models.users import Users from utils.utils import get_password_hash, get_current_user, create_token -from utils.misc import get_gravatar_url +from utils.misc import get_gravatar_url, validate_email_format from constants import ERROR_MESSAGES @@ -95,33 +96,38 @@ async def signin(form_data: SigninForm): @router.post("/signup", response_model=SigninResponse) async def signup(request: Request, form_data: SignupForm): if request.app.state.ENABLE_SIGNUP: - if not Users.get_user_by_email(form_data.email.lower()): - try: - role = "admin" if Users.get_num_users() == 0 else "pending" - hashed = get_password_hash(form_data.password) - user = Auths.insert_new_auth( - form_data.email.lower(), hashed, form_data.name, role - ) + if validate_email_format(form_data.email.lower()): + if not Users.get_user_by_email(form_data.email.lower()): + try: + role = "admin" if Users.get_num_users() == 0 else "pending" + hashed = get_password_hash(form_data.password) + user = Auths.insert_new_auth( + form_data.email.lower(), hashed, form_data.name, role + ) - if user: - token = create_token(data={"email": user.email}) - # response.set_cookie(key='token', value=token, httponly=True) + if user: + token = create_token(data={"email": user.email}) + # response.set_cookie(key='token', value=token, httponly=True) - return { - "token": token, - "token_type": "Bearer", - "id": user.id, - "email": user.email, - "name": user.name, - "role": user.role, - "profile_image_url": user.profile_image_url, - } - else: - raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR) - except Exception as err: - raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) + return { + "token": token, + "token_type": "Bearer", + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + "profile_image_url": user.profile_image_url, + } + else: + raise HTTPException( + 500, detail=ERROR_MESSAGES.CREATE_USER_ERROR + ) + except Exception as err: + raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) + else: + raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN) else: - raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN) + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_EMAIL_FORMAT) else: raise HTTPException(400, detail=ERROR_MESSAGES.ACCESS_PROHIBITED) diff --git a/backend/constants.py b/backend/constants.py index 761507f2b..ec3ce3376 100644 --- a/backend/constants.py +++ b/backend/constants.py @@ -21,6 +21,7 @@ class ERROR_MESSAGES(str, Enum): "Your session has expired or the token is invalid. Please sign in again." ) INVALID_CRED = "The email or password provided is incorrect. Please check for typos and try logging in again." + INVALID_EMAIL_FORMAT = "The email format you entered is invalid. Please double-check and make sure you're using a valid email address (e.g., yourname@example.com)." INVALID_PASSWORD = ( "The password provided is incorrect. Please check for typos and try again." ) diff --git a/backend/utils/misc.py b/backend/utils/misc.py index c6508487a..5635c57ac 100644 --- a/backend/utils/misc.py +++ b/backend/utils/misc.py @@ -1,4 +1,5 @@ import hashlib +import re def get_gravatar_url(email): @@ -21,3 +22,9 @@ def calculate_sha256(file): for chunk in iter(lambda: file.read(8192), b""): sha256.update(chunk) return sha256.hexdigest() + + +def validate_email_format(email: str) -> bool: + if not re.match(r"[^@]+@[^@]+\.[^@]+", email): + return False + return True