@@ -40,7 +40,7 @@ class PasswordResetToken(db.Model):
4040 token = db .Column (db .String (128 ), unique = True , nullable = False , index = True )
4141 user_id = db .Column (db .GUID (), db .ForeignKey ("user.id" ), nullable = False )
4242 created_at = db .Column (
43- db .DateTime (), default = datetime .datetime .utcnow
43+ db .DateTime (), default = lambda : datetime .datetime .now ( datetime . UTC )
4444 )
4545 expires_at = db .Column (db .DateTime (), nullable = False )
4646 used_at = db .Column (db .DateTime (), nullable = True ) # Track when token was used
@@ -51,7 +51,7 @@ class PasswordResetToken(db.Model):
5151 def __init__ (self , user_id ):
5252 self .user_id = user_id
5353 self .token = self ._generate_secure_token ()
54- self .created_at = datetime .datetime .utcnow ( )
54+ self .created_at = datetime .datetime .now ( datetime . UTC )
5555 self .expires_at = self .created_at + datetime .timedelta (
5656 hours = PASSWORD_RESET_TOKEN_EXPIRY_HOURS
5757 )
@@ -66,12 +66,17 @@ def _generate_secure_token():
6666
6767 def is_valid (self ):
6868 """Check if the token is valid (not expired and not used)."""
69- now = datetime .datetime .utcnow ()
70- return self .used_at is None and self .expires_at > now
69+ # Make expires_at timezone-aware (assume UTC) if it's naive from the database
70+ expires_at = (
71+ self .expires_at .replace (tzinfo = datetime .UTC )
72+ if self .expires_at .tzinfo is None
73+ else self .expires_at
74+ )
75+ return self .used_at is None and expires_at > datetime .datetime .now (datetime .UTC )
7176
7277 def mark_used (self ):
7378 """Mark the token as used."""
74- self .used_at = datetime .datetime .utcnow ( )
79+ self .used_at = datetime .datetime .now ( datetime . UTC )
7580
7681 @classmethod
7782 def get_valid_token (cls , token_string ):
@@ -95,7 +100,7 @@ def invalidate_user_tokens(cls, user_id):
95100 Called when creating a new reset token to ensure only one
96101 valid token exists per user at a time.
97102 """
98- now = datetime .datetime .utcnow ( )
103+ now = datetime .datetime .now ( datetime . UTC )
99104 cls .query .filter (
100105 cls .user_id == user_id ,
101106 cls .used_at .is_ (None ),
@@ -112,7 +117,7 @@ def cleanup_expired_tokens(cls, days_old=7):
112117 Returns:
113118 Number of tokens deleted
114119 """
115- cutoff = datetime .datetime .utcnow ( ) - datetime .timedelta (days = days_old )
120+ cutoff = datetime .datetime .now ( datetime . UTC ) - datetime .timedelta (days = days_old )
116121 result = cls .query .filter (cls .created_at < cutoff ).delete (
117122 synchronize_session = False
118123 )
0 commit comments