1
1
from datetime import timedelta
2
+ import hashlib
3
+ from random import randbytes
2
4
from fastapi import APIRouter , Request , Response , status , Depends , HTTPException
3
5
from pydantic import EmailStr
4
6
19
21
@router .post ('/register' , status_code = status .HTTP_201_CREATED )
20
22
async def create_user (payload : schemas .CreateUserSchema , request : Request , db : Session = Depends (get_db )):
21
23
# 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 ()
24
27
if user :
25
28
raise HTTPException (status_code = status .HTTP_409_CONFLICT ,
26
29
detail = 'Account already exist' )
@@ -40,11 +43,21 @@ async def create_user(payload: schemas.CreateUserSchema, request: Request, db: S
40
43
db .refresh (new_user )
41
44
42
45
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 ()} "
45
55
await Email (new_user , url , [payload .email ]).sendVerificationCode ()
46
56
except Exception as error :
47
57
print ('Error' , error )
58
+ user_query .update (
59
+ {'verification_code' : None }, synchronize_session = False )
60
+ db .commit ()
48
61
raise HTTPException (status_code = status .HTTP_500_INTERNAL_SERVER_E
CE44
RROR ,
49
62
detail = 'There was an error sending email' )
50
63
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
129
142
130
143
@router .get ('/verifyemail/{token}' )
131
144
def 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 ()
134
151
user = user_query .first ()
135
152
if not user :
136
153
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 )
139
157
db .commit ()
140
158
return {
141
159
"status" : "success" ,
0 commit comments