entidi2608 commited on
Commit
4363b00
·
1 Parent(s): f656193
db/mongoDB.py CHANGED
@@ -47,7 +47,7 @@ async def connect_to_mongo():
47
  )
48
 
49
  # 2. Kiểm tra kết nối một cách rõ ràng
50
- await mongo_db.client.admin.command('ping')
51
 
52
  # 3. Gán các đối tượng database và collection
53
  mongo_db.db = mongo_db.client[config.DB_NAME]
@@ -57,10 +57,10 @@ async def connect_to_mongo():
57
 
58
  # 4. Tạo TTL index một cách an toàn
59
  # Lấy danh sách index hiện có
60
- index_info = await mongo_db.token_blacklist.index_information()
61
  if "expires_at_1" not in index_info:
62
  # Chỉ tạo index nếu nó chưa tồn tại
63
- await mongo_db.token_blacklist.create_index("expires_at", expireAfterSeconds=0)
64
  logger.info("🔸 Successfully created TTL index for 'expires_at' in 'token_blacklist'.")
65
 
66
 
 
47
  )
48
 
49
  # 2. Kiểm tra kết nối một cách rõ ràng
50
+ mongo_db.client.admin.command('ping')
51
 
52
  # 3. Gán các đối tượng database và collection
53
  mongo_db.db = mongo_db.client[config.DB_NAME]
 
57
 
58
  # 4. Tạo TTL index một cách an toàn
59
  # Lấy danh sách index hiện có
60
+ index_info = mongo_db.token_blacklist.index_information()
61
  if "expires_at_1" not in index_info:
62
  # Chỉ tạo index nếu nó chưa tồn tại
63
+ mongo_db.token_blacklist.create_index("expires_at", expireAfterSeconds=0)
64
  logger.info("🔸 Successfully created TTL index for 'expires_at' in 'token_blacklist'.")
65
 
66
 
dependencies.py CHANGED
@@ -189,7 +189,7 @@ async def get_current_user(
189
  # 1. Kiểm tra token trong blacklist
190
  try:
191
  logger.info("GET_CURRENT_USER: Đang kiểm tra blacklist...")
192
- is_blacklisted = await mongo_db.token_blacklist.find_one({"token": token_to_verify})
193
  if is_blacklisted:
194
  logger.error(f"GET_CURRENT_USER: *** TOKEN TRONG BLACKLIST - RAISING 401 ***")
195
  raise HTTPException( # Sử dụng credentials_exception hoặc một cái cụ thể hơn
@@ -266,7 +266,7 @@ async def get_current_user(
266
  user_data: Optional[dict] = None # Khởi tạo để tránh UnboundLocalError
267
  try:
268
  logger.info(f"GET_CURRENT_USER: Đang tìm user trong DB: {email.lower()}") # email đã được validate là str
269
- user_data =await mongo_db.users.find_one({"email": email.lower()}, {"password": 0, "_id": 0})
270
  # print(user_data) # Bỏ print trong production
271
 
272
  if user_data is None:
 
189
  # 1. Kiểm tra token trong blacklist
190
  try:
191
  logger.info("GET_CURRENT_USER: Đang kiểm tra blacklist...")
192
+ is_blacklisted = mongo_db.token_blacklist.find_one({"token": token_to_verify})
193
  if is_blacklisted:
194
  logger.error(f"GET_CURRENT_USER: *** TOKEN TRONG BLACKLIST - RAISING 401 ***")
195
  raise HTTPException( # Sử dụng credentials_exception hoặc một cái cụ thể hơn
 
266
  user_data: Optional[dict] = None # Khởi tạo để tránh UnboundLocalError
267
  try:
268
  logger.info(f"GET_CURRENT_USER: Đang tìm user trong DB: {email.lower()}") # email đã được validate là str
269
+ user_data = mongo_db.users.find_one({"email": email.lower()}, {"password": 0, "_id": 0})
270
  # print(user_data) # Bỏ print trong production
271
 
272
  if user_data is None:
routers/chat.py CHANGED
@@ -66,7 +66,7 @@ async def create_chat(
66
  }
67
 
68
  try:
69
- conversations_collection.insert_one(conversation_doc)
70
  logger.info(f"Đã tạo hội thoại rỗng {chat_id} trong MongoDB cho user {current_user.email}.")
71
  except Exception as e:
72
  logger.error(f"Lỗi khi tạo hội thoại rỗng trong MongoDB cho chat {chat_id}: {e}", exc_info=True)
@@ -135,7 +135,7 @@ async def delete_chat(chat_id: str, request: Request, user: UserOut = Depends(ge
135
  # Xóa chat
136
  delete_chat_from_redis(redis, chat_id)
137
  # Xóa hội thoại trong MongoDB
138
- result = await mongo_db.conversations.delete_one({"conversation_id": chat_id, "user_id": user.email})
139
  if result.deleted_count == 0:
140
  raise HTTPException(status_code=404, detail="Chat not found in MongoDB")
141
 
@@ -147,7 +147,7 @@ async def delete_chat(chat_id: str, request: Request, user: UserOut = Depends(ge
147
  async def get_conversations(user: UserOut = Depends(get_current_user)):
148
  try:
149
  logger.info(f"Attempting to get conversations for user: {user.email}")
150
- db_conversations_cursor = await mongo_db.conversations.find({"user_id": user.email})
151
 
152
  response_list = []
153
 
@@ -182,7 +182,7 @@ async def load_conversation_and_sync_redis(
182
 
183
  # 1. Kiểm tra hội thoại trong MongoDB
184
  try:
185
- conversation_doc =await mongo_db.conversations.find_one(
186
  {"conversation_id": chat_id, "user_id": current_user.email}
187
  )
188
  if not conversation_doc:
 
66
  }
67
 
68
  try:
69
+ mongo_db.conversations.insert_one(conversation_doc)
70
  logger.info(f"Đã tạo hội thoại rỗng {chat_id} trong MongoDB cho user {current_user.email}.")
71
  except Exception as e:
72
  logger.error(f"Lỗi khi tạo hội thoại rỗng trong MongoDB cho chat {chat_id}: {e}", exc_info=True)
 
135
  # Xóa chat
136
  delete_chat_from_redis(redis, chat_id)
137
  # Xóa hội thoại trong MongoDB
138
+ result = mongo_db.conversations.delete_one({"conversation_id": chat_id, "user_id": user.email})
139
  if result.deleted_count == 0:
140
  raise HTTPException(status_code=404, detail="Chat not found in MongoDB")
141
 
 
147
  async def get_conversations(user: UserOut = Depends(get_current_user)):
148
  try:
149
  logger.info(f"Attempting to get conversations for user: {user.email}")
150
+ db_conversations_cursor = mongo_db.conversations.find({"user_id": user.email})
151
 
152
  response_list = []
153
 
 
182
 
183
  # 1. Kiểm tra hội thoại trong MongoDB
184
  try:
185
+ conversation_doc =mongo_db.conversations.find_one(
186
  {"conversation_id": chat_id, "user_id": current_user.email}
187
  )
188
  if not conversation_doc:
routers/user.py CHANGED
@@ -304,7 +304,7 @@ async def auth_google_callback(request: Request):
304
 
305
 
306
  # Kiểm tra xem user đã tồn tại trong DB chưa
307
- db_user = await mongo_db.users.find_one({"email": user_email})
308
 
309
  if not db_user:
310
  placeholder_password = f"google-oauth2|{uuid.uuid4()}"
@@ -314,7 +314,7 @@ async def auth_google_callback(request: Request):
314
 
315
 
316
  # Tạo user mới với thông tin từ Google
317
- await mongo_db.users.insert_one({
318
  "email": user_email,
319
  "username": username,
320
  "password": hashed_password, # Mật khẩu tạm thời, sẽ không dùng đến
@@ -324,7 +324,7 @@ async def auth_google_callback(request: Request):
324
  })
325
 
326
  # Lấy lại user vừa tạo để đảm bảo có _id và các trường khác
327
- db_user =await mongo_db.users.find_one({"email": user_email})
328
  if not db_user: # Kiểm tra lại sau khi insert
329
  raise HTTPException(status_code=500, detail="Could not create and retrieve new user account.")
330
 
@@ -362,7 +362,7 @@ async def exchange_google_code_for_token(request: Request,response: Response, co
362
  redis_client.delete(redis_key) # Dùng một lần
363
  user_email = user_email_bytes.decode()
364
 
365
- await mongo_db.users.update_one({
366
  "email": user_email
367
  }, {
368
  "$set": {
@@ -408,7 +408,7 @@ async def exchange_google_code_for_token(request: Request,response: Response, co
408
  path="/api/user/refresh-token",
409
  )
410
 
411
- user_info =await mongo_db.users.find_one({"email": user_email})
412
  user = {
413
  "email": user_info.get("email"),
414
  "username": user_info.get("username"),
 
304
 
305
 
306
  # Kiểm tra xem user đã tồn tại trong DB chưa
307
+ db_user = mongo_db.users.find_one({"email": user_email})
308
 
309
  if not db_user:
310
  placeholder_password = f"google-oauth2|{uuid.uuid4()}"
 
314
 
315
 
316
  # Tạo user mới với thông tin từ Google
317
+ mongo_db.users.insert_one({
318
  "email": user_email,
319
  "username": username,
320
  "password": hashed_password, # Mật khẩu tạm thời, sẽ không dùng đến
 
324
  })
325
 
326
  # Lấy lại user vừa tạo để đảm bảo có _id và các trường khác
327
+ db_user = mongo_db.users.find_one({"email": user_email})
328
  if not db_user: # Kiểm tra lại sau khi insert
329
  raise HTTPException(status_code=500, detail="Could not create and retrieve new user account.")
330
 
 
362
  redis_client.delete(redis_key) # Dùng một lần
363
  user_email = user_email_bytes.decode()
364
 
365
+ mongo_db.users.update_one({
366
  "email": user_email
367
  }, {
368
  "$set": {
 
408
  path="/api/user/refresh-token",
409
  )
410
 
411
+ user_info =mongo_db.users.find_one({"email": user_email})
412
  user = {
413
  "email": user_info.get("email"),
414
  "username": user_info.get("username"),
services/auth_service.py CHANGED
@@ -31,7 +31,7 @@ async def register_user(user: RegisterRequest):
31
 
32
  try:
33
  # Kiểm tra username đã tồn tại chưa
34
- existing_user =await mongo_db.users.find_one({"email": user.email})
35
  if existing_user:
36
  raise HTTPException(status_code=400, detail="Tài khoản đã tồn tại.")
37
 
@@ -40,7 +40,7 @@ async def register_user(user: RegisterRequest):
40
 
41
  avatar = await get_random_unsplash_image()
42
  # Lưu user mới
43
- await mongo_db.users.insert_one({
44
  "username": user.username,
45
  "password": hashed_password,
46
  "email": user.email,
@@ -54,7 +54,7 @@ async def register_user(user: RegisterRequest):
54
  raise HTTPException(status_code=e.status_code, detail=e.detail)
55
  # Hàm xác thực đăng nhập
56
  async def authenticate_user(request: LoginRequest):
57
- user =await mongo_db.users.find_one({"email": request.email})
58
  if not user:
59
  raise HTTPException(status_code=401, detail="Sai tài khoản hoặc mật khẩu")
60
 
@@ -101,7 +101,7 @@ async def logout_user(req: Request, credentials: HTTPAuthorizationCredentials =
101
  raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Access token không hợp lệ")
102
 
103
  # Blacklist access token
104
- await mongo_db.token_blacklist.insert_one({
105
  "token": token,
106
  "expires_at": datetime.fromtimestamp(exp, tz=timezone.utc)
107
  })
@@ -110,9 +110,9 @@ async def logout_user(req: Request, credentials: HTTPAuthorizationCredentials =
110
  refresh_token = req.cookies.get("refresh_token")
111
  if refresh_token:
112
  # Invalidate refresh token in database
113
- user = await mongo_db.users.find_one({"refresh_token": refresh_token})
114
  if user:
115
- await mongo_db.users.update_one(
116
  {"_id": user["_id"]},
117
  {"$set": {"refresh_token": None, "refresh_token_expiry": None, "revoked": True}}
118
  )
 
31
 
32
  try:
33
  # Kiểm tra username đã tồn tại chưa
34
+ existing_user =mongo_db.users.find_one({"email": user.email})
35
  if existing_user:
36
  raise HTTPException(status_code=400, detail="Tài khoản đã tồn tại.")
37
 
 
40
 
41
  avatar = await get_random_unsplash_image()
42
  # Lưu user mới
43
+ mongo_db.users.insert_one({
44
  "username": user.username,
45
  "password": hashed_password,
46
  "email": user.email,
 
54
  raise HTTPException(status_code=e.status_code, detail=e.detail)
55
  # Hàm xác thực đăng nhập
56
  async def authenticate_user(request: LoginRequest):
57
+ user =mongo_db.users.find_one({"email": request.email})
58
  if not user:
59
  raise HTTPException(status_code=401, detail="Sai tài khoản hoặc mật khẩu")
60
 
 
101
  raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Access token không hợp lệ")
102
 
103
  # Blacklist access token
104
+ mongo_db.token_blacklist.insert_one({
105
  "token": token,
106
  "expires_at": datetime.fromtimestamp(exp, tz=timezone.utc)
107
  })
 
110
  refresh_token = req.cookies.get("refresh_token")
111
  if refresh_token:
112
  # Invalidate refresh token in database
113
+ user = mongo_db.users.find_one({"refresh_token": refresh_token})
114
  if user:
115
+ mongo_db.users.update_one(
116
  {"_id": user["_id"]},
117
  {"$set": {"refresh_token": None, "refresh_token_expiry": None, "revoked": True}}
118
  )
services/user_service.py CHANGED
@@ -37,7 +37,7 @@ async def get_users(skip: int = 0, limit: int = 100, query: dict = None):
37
  search_query = query or {}
38
 
39
  # Thực hiện truy vấn với phân trang
40
- users_cursor =await mongo_db.users.find(
41
  search_query,
42
  {"_id": 0, "password": 0} # Loại bỏ các trường nhạy cảm
43
  ).skip(skip).limit(limit)
@@ -68,7 +68,7 @@ async def count_users(query: dict = None):
68
  """
69
  try:
70
  search_query = query or {}
71
- return await mongo_db.users.count_documents(search_query)
72
  except Exception as e:
73
  logger.error(f"Lỗi khi đếm người dùng: {str(e)}")
74
  raise HTTPException(
@@ -112,7 +112,7 @@ async def get_paginated_users(
112
  sort_criteria = [(sort_by, sort_order)]
113
 
114
  # Thực hiện truy vấn
115
- users_cursor =await mongo_db.users.find(
116
  query,
117
  {"_id": 0, "password": 0} # Loại bỏ các trường nhạy cảm
118
  ).sort(sort_criteria).skip(skip).limit(limit)
@@ -121,7 +121,7 @@ async def get_paginated_users(
121
  user_list = users_cursor.to_list(length=limit)
122
 
123
  # Đếm tổng số bản ghi
124
- total =await mongo_db.users.count_documents(query)
125
 
126
  # Tính toán thông tin phân trang
127
  total_pages = math.ceil(total / limit) if limit > 0 else 0
@@ -182,7 +182,7 @@ async def delete_user(user_id: str):
182
  bool: True nếu xóa thành công, False nếu không tìm thấy người dùng
183
  """
184
  try:
185
- result =await mongo_db.users.delete_one({"_id": user_id})
186
  return result.deleted_count > 0
187
  except Exception as e:
188
  logger.error(f"Lỗi khi xóa người dùng: {str(e)}")
@@ -204,7 +204,7 @@ async def change_password(email: str, current_password: str, new_password: str):
204
  bool: True nếu đổi mật khẩu thành công, False nếu không thành công
205
  """
206
  try:
207
- user =await mongo_db.users.find_one({"email": email})
208
  if not user:
209
  raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Người dùng không tồn tại")
210
 
@@ -216,7 +216,7 @@ async def change_password(email: str, current_password: str, new_password: str):
216
  # Hash the new password
217
  hashed_password = pwd_context.hash(new_password)
218
  # Update the password in the database
219
- result =await mongo_db.users.update_one({"email": email}, {"$set": {"password": hashed_password}})
220
  return result.modified_count > 0
221
  except HTTPException as he:
222
  raise he
@@ -248,7 +248,7 @@ async def reset_password_request(email: str) -> bool:
248
  return True
249
 
250
  # Check for rate limiting (e.g., max 3 requests per hour)
251
- reset_requests = await mongo_db.users.count_documents({
252
  "email": email.lower(),
253
  "reset_password_timestamp": {
254
  "$gte": datetime.now(tz=timezone.utc) - timedelta(hours=1)
@@ -265,7 +265,7 @@ async def reset_password_request(email: str) -> bool:
265
  expiry = datetime.now() + timedelta(minutes=10)
266
 
267
  # Store reset token and timestamp in database
268
- await mongo_db.users.update_one(
269
  {"_id": ObjectId(user["_id"])},
270
  {
271
  "$set": {
@@ -380,7 +380,7 @@ async def generate_and_store_verification_code(email: str) -> bool:
380
  expiry = datetime.now() + timedelta(minutes=10)
381
 
382
  # Store code and expiry in database
383
- result = await mongo_db.users.update_one(
384
  {"email": email.lower()},
385
  {
386
  "$set": {
@@ -425,7 +425,7 @@ async def verify_login_code(email: str, code: str, res: Response): # Bỏ kiểu
425
  HTTPException: Nếu mã không hợp lệ, đã hết hạn hoặc có lỗi hệ thống.
426
  """
427
  try:
428
- user = await mongo_db.users.find_one({ # Sử dụng await nếu mongo_db.users là async (ví dụ Motor)
429
  "email": email.lower(),
430
  "login_verification_code": code
431
  })
@@ -443,7 +443,7 @@ async def verify_login_code(email: str, code: str, res: Response): # Bỏ kiểu
443
  if not expiry or expiry < datetime.now(expiry.tzinfo if expiry.tzinfo else None): # So sánh aware với aware, naive với naive
444
  logger.warning(f"Mã xác minh đã hết hạn cho email: {email}")
445
  # Xóa mã đã hết hạn để tránh sử dụng lại
446
- await mongo_db.users.update_one(
447
  {"_id": ObjectId(user["_id"])},
448
  {
449
  "$unset": {
@@ -509,7 +509,7 @@ async def verify_login_code(email: str, code: str, res: Response): # Bỏ kiểu
509
  # --------------------
510
 
511
  # Clear verification code và cập nhật last_login
512
- await mongo_db.users.update_one( # Sử dụng await nếu là async
513
  {"_id": ObjectId(user["_id"])},
514
  {
515
  "$unset": {
@@ -567,7 +567,7 @@ async def authenticate_user(request: LoginRequest) -> dict:
567
  Raises:
568
  HTTPException: Nếu thông tin đăng nhập không hợp lệ.
569
  """
570
- user = await mongo_db.users.find_one({"email": request.email.lower()})
571
  if not user or not pwd_context.verify(request.password, user["password"]):
572
  logger.warning(f"Xác thực thất bại cho email: {request.email}")
573
  raise HTTPException(
@@ -603,7 +603,7 @@ async def refresh_access_token(req: Request , res: Response ) -> dict:
603
  )
604
 
605
  # Find user by refresh token in database
606
- user = await mongo_db.users.find_one({"refresh_token": refresh_token})
607
 
608
 
609
  if not user:
@@ -640,7 +640,7 @@ async def refresh_access_token(req: Request , res: Response ) -> dict:
640
  new_refresh_token = await create_refresh_token(email)
641
 
642
  # Update database with new refresh token
643
- await mongo_db.users.update_one(
644
  {"_id": user["_id"]},
645
  {
646
  "$set": {
 
37
  search_query = query or {}
38
 
39
  # Thực hiện truy vấn với phân trang
40
+ users_cursor = mongo_db.users.find(
41
  search_query,
42
  {"_id": 0, "password": 0} # Loại bỏ các trường nhạy cảm
43
  ).skip(skip).limit(limit)
 
68
  """
69
  try:
70
  search_query = query or {}
71
+ return mongo_db.users.count_documents(search_query)
72
  except Exception as e:
73
  logger.error(f"Lỗi khi đếm người dùng: {str(e)}")
74
  raise HTTPException(
 
112
  sort_criteria = [(sort_by, sort_order)]
113
 
114
  # Thực hiện truy vấn
115
+ users_cursor =mongo_db.users.find(
116
  query,
117
  {"_id": 0, "password": 0} # Loại bỏ các trường nhạy cảm
118
  ).sort(sort_criteria).skip(skip).limit(limit)
 
121
  user_list = users_cursor.to_list(length=limit)
122
 
123
  # Đếm tổng số bản ghi
124
+ total =mongo_db.users.count_documents(query)
125
 
126
  # Tính toán thông tin phân trang
127
  total_pages = math.ceil(total / limit) if limit > 0 else 0
 
182
  bool: True nếu xóa thành công, False nếu không tìm thấy người dùng
183
  """
184
  try:
185
+ result =mongo_db.users.delete_one({"_id": user_id})
186
  return result.deleted_count > 0
187
  except Exception as e:
188
  logger.error(f"Lỗi khi xóa người dùng: {str(e)}")
 
204
  bool: True nếu đổi mật khẩu thành công, False nếu không thành công
205
  """
206
  try:
207
+ user =mongo_db.users.find_one({"email": email})
208
  if not user:
209
  raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Người dùng không tồn tại")
210
 
 
216
  # Hash the new password
217
  hashed_password = pwd_context.hash(new_password)
218
  # Update the password in the database
219
+ result =mongo_db.users.update_one({"email": email}, {"$set": {"password": hashed_password}})
220
  return result.modified_count > 0
221
  except HTTPException as he:
222
  raise he
 
248
  return True
249
 
250
  # Check for rate limiting (e.g., max 3 requests per hour)
251
+ reset_requests = mongo_db.users.count_documents({
252
  "email": email.lower(),
253
  "reset_password_timestamp": {
254
  "$gte": datetime.now(tz=timezone.utc) - timedelta(hours=1)
 
265
  expiry = datetime.now() + timedelta(minutes=10)
266
 
267
  # Store reset token and timestamp in database
268
+ mongo_db.users.update_one(
269
  {"_id": ObjectId(user["_id"])},
270
  {
271
  "$set": {
 
380
  expiry = datetime.now() + timedelta(minutes=10)
381
 
382
  # Store code and expiry in database
383
+ result = mongo_db.users.update_one(
384
  {"email": email.lower()},
385
  {
386
  "$set": {
 
425
  HTTPException: Nếu mã không hợp lệ, đã hết hạn hoặc có lỗi hệ thống.
426
  """
427
  try:
428
+ user = mongo_db.users.find_one({ # Sử dụng await nếu mongo_db.users là async (ví dụ Motor)
429
  "email": email.lower(),
430
  "login_verification_code": code
431
  })
 
443
  if not expiry or expiry < datetime.now(expiry.tzinfo if expiry.tzinfo else None): # So sánh aware với aware, naive với naive
444
  logger.warning(f"Mã xác minh đã hết hạn cho email: {email}")
445
  # Xóa mã đã hết hạn để tránh sử dụng lại
446
+ mongo_db.users.update_one(
447
  {"_id": ObjectId(user["_id"])},
448
  {
449
  "$unset": {
 
509
  # --------------------
510
 
511
  # Clear verification code và cập nhật last_login
512
+ mongo_db.users.update_one( # Sử dụng await nếu là async
513
  {"_id": ObjectId(user["_id"])},
514
  {
515
  "$unset": {
 
567
  Raises:
568
  HTTPException: Nếu thông tin đăng nhập không hợp lệ.
569
  """
570
+ user = mongo_db.users.find_one({"email": request.email.lower()})
571
  if not user or not pwd_context.verify(request.password, user["password"]):
572
  logger.warning(f"Xác thực thất bại cho email: {request.email}")
573
  raise HTTPException(
 
603
  )
604
 
605
  # Find user by refresh token in database
606
+ user = mongo_db.users.find_one({"refresh_token": refresh_token})
607
 
608
 
609
  if not user:
 
640
  new_refresh_token = await create_refresh_token(email)
641
 
642
  # Update database with new refresh token
643
+ mongo_db.users.update_one(
644
  {"_id": user["_id"]},
645
  {
646
  "$set": {
utils/utils.py CHANGED
@@ -233,7 +233,7 @@ async def create_refresh_token(email: str) -> str:
233
 
234
 
235
  # Store refresh token in database
236
- result = await mongo_db.users.update_one(
237
  {"email": email.lower()},
238
  {
239
  "$set": {
 
233
 
234
 
235
  # Store refresh token in database
236
+ result = mongo_db.users.update_one(
237
  {"email": email.lower()},
238
  {
239
  "$set": {