7
7
import resend
8
8
from dotenv import load_dotenv
9
9
from sqlmodel import Session , select
10
- from passlib . context import CryptContext
10
+ from bcrypt import gensalt , hashpw , checkpw
11
11
from datetime import UTC , datetime , timedelta
12
12
from typing import Optional
13
13
from fastapi import Depends , Cookie , HTTPException , status
19
19
20
20
# --- AUTH ---
21
21
22
- pwd_context = CryptContext (schemes = ["bcrypt" ], deprecated = "auto" )
23
22
SECRET_KEY = os .getenv ("SECRET_KEY" )
24
23
ALGORITHM = "HS256"
25
24
ACCESS_TOKEN_EXPIRE_MINUTES = 30
@@ -43,16 +42,27 @@ def validate_password_strength(password: str) -> bool:
43
42
- At least 8 characters long
44
43
"""
45
44
pattern = re .compile (
46
- r"(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@$!%*?&] )[A-Za-z\d@$!%*?&]{8,}" )
45
+ r"(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@$!%*?&{}<>.,\\'#\-_=+\(\)\[\]:;|~] )[A-Za-z\d@$!%*?&{}<>.,\\'#\-_=+\(\)\[\]:;|~ ]{8,}" )
47
46
return bool (pattern .match (password ))
48
47
49
48
50
49
def get_password_hash (password : str ) -> str :
51
- return pwd_context .hash (password )
50
+ """
51
+ Hash a password using bcrypt with a random salt
52
+ """
53
+ # Convert the password to bytes and generate the hash
54
+ password_bytes = password .encode ('utf-8' )
55
+ salt = gensalt ()
56
+ return hashpw (password_bytes , salt ).decode ('utf-8' )
52
57
53
58
54
59
def verify_password (plain_password : str , hashed_password : str ) -> bool :
55
- return pwd_context .verify (plain_password , hashed_password )
60
+ """
61
+ Verify a password against a bcrypt hash
62
+ """
63
+ password_bytes = plain_password .encode ('utf-8' )
64
+ hashed_bytes = hashed_password .encode ('utf-8' )
65
+ return checkpw (password_bytes , hashed_bytes )
56
66
57
67
58
68
def create_access_token (data : dict , expires_delta : Optional [timedelta ] = None ) -> str :
0 commit comments