4141)
4242from ..products .models import Product
4343from ..users import users_service
44- from . import _auth_service , _confirmation_service
44+ from . import _auth_service
45+ from ._confirmation_repository import ConfirmationRepository
46+ from ._confirmation_service import ConfirmationService
4547from ._login_repository_legacy import (
46- AsyncpgStorage ,
4748 BaseConfirmationTokenDict ,
4849 ConfirmationTokenDict ,
4950)
5253 MSG_INVITATIONS_CONTACT_SUFFIX ,
5354 MSG_USER_DISABLED ,
5455)
55- from .settings import LoginOptions
56+ from .settings import get_plugin_options
5657
5758_logger = logging .getLogger (__name__ )
5859
5960
61+ def _get_confirmation_service (app : web .Application ) -> ConfirmationService :
62+ """Get confirmation service instance from app."""
63+ engine = app ["postgres_db_engine" ]
64+ repository = ConfirmationRepository (engine )
65+ options = get_plugin_options (app )
66+ return ConfirmationService (repository , options )
67+
68+
6069class ConfirmationTokenInfoDict (ConfirmationTokenDict ):
6170 expires : datetime
6271 url : str
@@ -112,8 +121,6 @@ async def check_other_registrations(
112121 app : web .Application ,
113122 email : str ,
114123 current_product : Product ,
115- db : AsyncpgStorage ,
116- cfg : LoginOptions ,
117124) -> None :
118125
119126 # An account is already registered with this email
@@ -133,23 +140,24 @@ async def check_other_registrations(
133140 # w/ an expired confirmation will get deleted and its account (i.e. email)
134141 # can be overtaken by this new registration
135142 #
136- _confirmation = await db .get_confirmation (
143+ confirmation_service = _get_confirmation_service (app )
144+ _confirmation = await confirmation_service .get_confirmation (
137145 filter_dict = {
138- "user " : user ,
146+ "user_id " : user [ "id" ] ,
139147 "action" : ConfirmationAction .REGISTRATION .value ,
140148 }
141149 )
142150 drop_previous_registration = (
143151 not _confirmation
144- or _confirmation_service .is_confirmation_expired (cfg , _confirmation )
152+ or confirmation_service .is_confirmation_expired (_confirmation )
145153 )
146154 if drop_previous_registration :
147155 if not _confirmation :
148156 await users_service .delete_user_without_projects (
149157 app , user_id = user ["id" ], clean_cache = False
150158 )
151159 else :
152- await db .delete_confirmation_and_user (
160+ await confirmation_service .delete_confirmation_and_user (
153161 user_id = user ["id" ], confirmation = _confirmation
154162 )
155163
@@ -175,7 +183,7 @@ async def check_other_registrations(
175183
176184
177185async def create_invitation_token (
178- db : AsyncpgStorage ,
186+ app : web . Application ,
179187 * ,
180188 user_id : IdInt ,
181189 user_email : LowerCaseEmailStr | None = None ,
@@ -198,11 +206,19 @@ async def create_invitation_token(
198206 trial_account_days = trial_days ,
199207 extra_credits_in_usd = extra_credits_in_usd ,
200208 )
201- return await db .create_confirmation (
209+ confirmation_service = _get_confirmation_service (app )
210+ confirmation = await confirmation_service .create_confirmation (
202211 user_id = user_id ,
203212 action = ConfirmationAction .INVITATION .name ,
204213 data = data_model .model_dump_json (),
205214 )
215+ return {
216+ "code" : confirmation .code ,
217+ "user_id" : confirmation .user_id ,
218+ "action" : confirmation .action ,
219+ "data" : confirmation .data ,
220+ "created_at" : confirmation .created_at ,
221+ }
206222
207223
208224@contextmanager
@@ -270,8 +286,6 @@ async def check_and_consume_invitation(
270286 invitation_code : str ,
271287 guest_email : str ,
272288 product : Product ,
273- db : AsyncpgStorage ,
274- cfg : LoginOptions ,
275289 app : web .Application ,
276290) -> ConfirmedInvitationData :
277291 """Consumes invitation: the code is validated, the invitation retrieives and then deleted
@@ -305,26 +319,34 @@ async def check_and_consume_invitation(
305319 )
306320
307321 # database-type invitations
308- if confirmation_token := await _confirmation_service .validate_confirmation_code (
309- invitation_code , db , cfg
322+ confirmation_service = _get_confirmation_service (app )
323+ if confirmation := await confirmation_service .validate_confirmation_code (
324+ invitation_code
310325 ):
311326 try :
327+ confirmation_token_dict = {
328+ "code" : confirmation .code ,
329+ "user_id" : confirmation .user_id ,
330+ "action" : confirmation .action ,
331+ "data" : confirmation .data ,
332+ "created_at" : confirmation .created_at ,
333+ }
312334 invitation_data : ConfirmedInvitationData = (
313- _InvitationValidator .model_validate (confirmation_token ).data
335+ _InvitationValidator .model_validate (confirmation_token_dict ).data
314336 )
315337 return invitation_data
316338
317339 except ValidationError as err :
318340 _logger .warning (
319341 "%s is associated with an invalid %s.\n Details: %s" ,
320342 f"{ invitation_code = } " ,
321- f"{ confirmation_token = } " ,
343+ f"{ confirmation = } " ,
322344 f"{ err = } " ,
323345 )
324346
325347 finally :
326- await db .delete_confirmation (confirmation_token )
327- _logger .info ("Invitation with %s was consumed" , f"{ confirmation_token = } " )
348+ await confirmation_service .delete_confirmation (confirmation )
349+ _logger .info ("Invitation with %s was consumed" , f"{ confirmation = } " )
328350
329351 raise web .HTTPForbidden (
330352 text = (
0 commit comments