11from datetime import timedelta
2+ import hashlib
3+ from random import randbytes
24from fastapi import APIRouter , Request , Response , status , Depends , HTTPException
35from pydantic import EmailStr
46
1921@router .post ('/register' , status_code = status .HTTP_201_CREATED )
2022async def create_user (payload : schemas .CreateUserSchema , request : Request , db : Session = Depends (get_db )):
2123 # Check if user already exist
22- user = db .query (models .User ).filter (
23- models .User .email == EmailStr (payload .email .lower ())).first ()
24+ user_query = db .query (models .User ).filter (
25+ models .User .email == EmailStr (payload .email .lower ()))
26+ user = user_query .first ()
2427 if user :
2528 raise HTTPException (status_code = status .HTTP_409_CONFLICT ,
2629 detail = 'Account already exist' )
@@ -40,11 +43,21 @@ async def create_user(payload: schemas.CreateUserSchema, request: Request, db: S
4043 db .refresh (new_user )
4144
4245 try :
43- token = oauth2 .create_verification_token (str (new_user .id ))
44- url = f"{ request .url .scheme } ://{ request .client .host } :{ request .url .port } /api/auth/verifyemail/{ token } "
46+ # Send Verification Email
47+ token = randbytes (10 )
48+ hashedCode = hashlib .sha256 ()
49+ hashedCode .update (token )
50+ verification_code = hashedCode .hexdigest ()
51+ user_query .update (
52+ {'verification_code' : verification_code }, synchronize_session = False )
53+ db .commit ()
54+ url = f"{ request .url .scheme } ://{ request .client .host } :{ request .url .port } /api/auth/verifyemail/{ token .hex ()} "
4555 await Email (new_user , url , [payload .email ]).sendVerificationCode ()
4656 except Exception as error :
4757 print ('Error' , error )
58+ user_query .update (
59+ {'verification_code' : None }, synchronize_session = False )
60+ db .commit ()
4861 raise HTTPException (status_code = status .HTTP_500_INTERNAL_SERVER_ERROR ,
4962 detail = 'There was an error sending email' )
5063 return {'status' : 'success' , 'message' : 'Verification token successfully sent to your email' }
@@ -129,13 +142,18 @@ def logout(response: Response, Authorize: AuthJWT = Depends(), user_id: str = De
129142
130143@router .get ('/verifyemail/{token}' )
131144def verify_me (token : str , db : Session = Depends (get_db )):
132- id = oauth2 .verify_email_token (token )
133- user_query = db .query (models .User ).filter (models .User .id == id )
145+ hashedCode = hashlib .sha256 ()
146+ hashedCode .update (bytes .fromhex (token ))
147+ verification_code = hashedCode .hexdigest ()
148+ user_query = db .query (models .User ).filter (
149+ models .User .verification_code == verification_code )
150+ db .commit ()
134151 user = user_query .first ()
135152 if not user :
136153 raise HTTPException (
137- status_code = status .HTTP_404_NOT_FOUND , detail = 'User no longer exist' )
138- user_query .update ({'verified' : True }, synchronize_session = False )
154+ status_code = status .HTTP_403_FORBIDDEN , detail = 'Email can only be verified once' )
155+ user_query .update (
156+ {'verified' : True , 'verification_code' : None }, synchronize_session = False )
139157 db .commit ()
140158 return {
141159 "status" : "success" ,
0 commit comments