diff --git a/app/methods/user_methods.py b/app/methods/user_methods.py index 5d5c994..98b2845 100644 --- a/app/methods/user_methods.py +++ b/app/methods/user_methods.py @@ -1,5 +1,6 @@ from __future__ import annotations import datetime, random, secrets +import urllib.parse from typing import Dict, List, Optional, Set, Union from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator @@ -575,8 +576,8 @@ def email_user_auth_key_url( else: enable_to_str = '-- Not Set --' auth_key = user_obj.auth_key - user_login_url = f'{root_url}user/login?username={username}' - user_login_auth_key_url = f'{root_url}?user_id={user_id_random}&auth_key={new_auth_key}' + user_login_url = f'{root_url}user/login?username={urllib.parse.quote(username)}&email={urllib.parse.quote(to_email)}' + user_login_auth_key_url = f'{root_url}?user_id={urllib.parse.quote(user_id_random)}&auth_key={urllib.parse.quote(new_auth_key)}&valid_email={True}' subject = f'{account_short_name}: One Time Use Sign In Link ({new_auth_key})' diff --git a/app/models/response_models.py b/app/models/response_models.py index 6ffa24e..8a90af1 100644 --- a/app/models/response_models.py +++ b/app/models/response_models.py @@ -90,6 +90,7 @@ def mk_resp( log.debug(response) if status_code == 400: response.status_code = status.HTTP_400_BAD_REQUEST elif status_code == 401: response.status_code = status.HTTP_401_UNAUTHORIZED + # elif status_code == 402: response.status_code = status.HTTP_402_X elif status_code == 403: response.status_code = status.HTTP_403_FORBIDDEN elif status_code == 404: response.status_code = status.HTTP_404_NOT_FOUND elif status_code == 408: response.status_code = status.HTTP_408_REQUEST_TIMEOUT diff --git a/app/routers/user.py b/app/routers/user.py index f651947..bc37575 100644 --- a/app/routers/user.py +++ b/app/routers/user.py @@ -230,6 +230,7 @@ async def user_authenticate( username: Optional[str] = Query(None, min_length=3, max_length=50), password: Optional[str] = Query(None, min_length=8, max_length=100), auth_key: Optional[str] = Query(None, min_length=11, max_length=22), + valid_email: Optional[bool] = None, x_account_id: str = Header(...), inc_user_role_list: bool = False, inc_contact: bool = False, @@ -301,6 +302,8 @@ async def user_authenticate( update_user_data = {} update_user_data['id'] = user_rec_result.get('user_id', None) # Using ID, not ID Random update_user_data['auth_key'] = None + if valid_email: + update_user_data['email_verified'] = True if user_rec_update_result := sql_update(table_name='user', data=update_user_data): log.info(f'The user record was updated with a NULL auth_key. User ID: {user_id}') @@ -356,6 +359,19 @@ async def user_authenticate( else: log.warning('The enable_to datetime was not set. Ignoring this check.') + update_user_data = {} + update_user_data['id'] = user_rec_result.get('user_id', None) # Using ID, not ID Random + if valid_email: + update_user_data['email_verified'] = True + update_user_data['logged_in_on'] = datetime.datetime.utcnow() + + if user_rec_update_result := sql_update(table_name='user', data=update_user_data): + log.info(f'The user record was updated with a NULL auth_key. User ID: {user_id}') + else: + log.error(f'The user record was not updated with a NULL auth_key. User ID: {user_id}') + log.debug(update_user_data) + log.debug(user_rec_update_result) + # Try to load the user object if user_obj_result := load_user_obj( user_id = user_id,