# business/auth/signin_business.py from typing import Tuple, Optional from app.authentication.backend.services.auth.user_auth_service import UserAuthService from infra.i18n.region_handler import RegionHandler from services.auth.achievement_service import AchievementService from services.auth.event_service import EventService from services.auth.profile_service import ProfileService from utils.enums.auth import UserLoginAction, NewUserMethod from infra.config import settings from infra.exception.exceptions import InvalidAuthCodeException from app.authentication.backend.models.constants import UserLoginAction from app.authentication.backend.services.user.user_management_service import ( UserManagementService, ) class SignInManager: def __init__(self): self.user_auth_service = UserAuthService() self.region_handler = RegionHandler() self.user_management_service = UserManagementService() self.achievement_service = AchievementService() self.event_service = EventService() self.profile_service = ProfileService() async def signin_with_email_and_code( self, email: str, code: str, host: str, time_zone: Optional[str] = "UTC" ) -> Tuple[int, Optional[int], Optional[str], Optional[str]]: """ Handles the business logic for signing in with email and code. """ user_id = await self.user_auth_service.get_user_id_by_email(email) is_new_user = user_id is None preferred_region = self.region_handler.detect_from_host(host) if await self.user_auth_service.verify_email_with_code(email, code): if is_new_user: user_id = await self.user_management_service.create_new_user_account( method=NewUserMethod.EMAIL, region=preferred_region ) await self.user_service.initialize_new_user_data( user_id=user_id, email=email, region=preferred_region, time_zone=time_zone, ) await self.event_service.log_signup_event( user_id=user_id, email=email, region=preferred_region, time_zone=time_zone, ) user_account = await self.user_service.get_user_account(user_id) # This will be done by sending the notification back to Freeleaps App # await self.achievement_service.record_login_event(user_id) if await self.profile_service.is_flid_reset_required(user_id): return ( UserLoginAction.REVIEW_AND_REVISE_FLID, user_account.role, user_id, email.split("@")[0], preferred_region, ) flid = await self.profile_service.get_user_flid(user_id) if await self.user_service.is_password_reset_required(user_id): return ( UserLoginAction.NEW_USER_SET_PASSWORD, user_account.role, user_id, flid, preferred_region, ) return ( UserLoginAction.USER_SIGNED_IN, user_account.role, user_id, flid, preferred_region, ) else: return UserLoginAction.VERIFY_EMAIL_WITH_AUTH_CODE, None, None, None, None async def verify_email_with_code(self, email: str, code: str, host: str): user_id = await self.user_auth_service.get_user_id_by_email(email) if not await self.user_auth_service.verify_email_with_code(email, code): raise InvalidAuthCodeException() is_new_user = user_id is None preferred_region = self.region_handler.detect_from_host(host) return user_id, is_new_user, preferred_region