from hashlib import sha256 from random import choices from email_validator import validate_email, EmailNotValidError from rio import Column, Component, event, Text, TextStyle, TextInput, TextInputChangeEvent, Button from src.ez_lan_manager import ConfigurationService, UserService, MailingService from src.ez_lan_manager.components.MainViewContentBox import MainViewContentBox from src.ez_lan_manager.pages import BasePage class ForgotPasswordPage(Component): def on_email_changed(self, change_event: TextInputChangeEvent) -> None: try: validate_email(change_event.text, check_deliverability=False) self.email_input.is_valid = True self.submit_button.is_sensitive = True except EmailNotValidError: self.email_input.is_valid = False self.submit_button.is_sensitive = False async def on_submit_button_pressed(self) -> None: self.submit_button.is_loading = True await self.submit_button.force_refresh() lan_info = self.session[ConfigurationService].get_lan_info() user_service = self.session[UserService] mailing_service = self.session[MailingService] user = await user_service.get_user(self.email_input.text.strip()) if user is not None: new_password = "".join(choices(user_service.ALLOWED_USER_NAME_SYMBOLS, k=16)) user.user_password = sha256(new_password.encode(encoding="utf-8")).hexdigest() await user_service.update_user(user) await mailing_service.send_email( subject=f"Dein neues Passwort für {lan_info.name}", body=f"Du hast für den EZ-LAN Manager der {lan_info.name} ein neues Passwort angefragt. " f"Und hier ist es schon:\n\n{new_password}\n\nSolltest du kein neues Passwort angefordert haben, " f"ignoriere diese E-Mail.\n\nLiebe Grüße\nDein {lan_info.name} - Team", receiver=self.email_input.text.strip() ) self.submit_button.is_loading = False self.email_input.text = "" self.info_text.text = "Falls für diese E-Mail ein Konto besteht, " \ "bekommst du in den nächsten Minuten ein neues Passwort zugeschickt. " \ "Bitte prüfe dein Spam-Postfach.", @event.on_populate async def on_populate(self) -> None: await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Passwort vergessen") def build(self) -> Component: self.email_input = TextInput( label="E-Mail Adresse", text="", margin_left=1, margin_right=1, margin_bottom=1, grow_x=True, on_change=self.on_email_changed ) self.submit_button = Button( content=Text( "Neues Passwort anfordern", style=TextStyle(fill=self.session.theme.background_color, font_size=0.9), align_x=0.5 ), grow_x=True, margin_top=2, margin_left=1, margin_right=1, margin_bottom=1, shape="rectangle", style="minor", color=self.session.theme.secondary_color, on_press=self.on_submit_button_pressed, is_sensitive=False ) self.info_text = Text( text="", style=TextStyle( fill=self.session.theme.background_color, font_size=1 ), margin_top=2, margin_left=1, margin_right=1, margin_bottom=2, wrap=True ) return BasePage( content=Column( MainViewContentBox( content=Column( Text( "Passwort vergessen", style=TextStyle( fill=self.session.theme.background_color, font_size=1.2 ), margin_top=2, margin_bottom=2, align_x=0.5 ), self.email_input, self.submit_button, self.info_text ) ), align_y=0, ) )