Ë
    ÉÌj  ã                   óZ  — d dl Z d dlZd dlZd dlmZmZmZ d dlmZ d dlm	Z	 d dl
mZmZ d dl
mZ d dlmZmZ d dlmZmZmZmZ  e j,                  e«      Zdd	ed
efd„Zddœdededededz  d
ef
d„Zdeded
efd„Zdeded
efd„Zdedededed
df
d„Z dededed
efd„Z!deded
efd„Z"y)é    N)ÚdatetimeÚ	timedeltaÚtimezone)ÚSession)ÚSettings)ÚPasswordResetTokenÚUser)ÚUserRole)Úhash_passwordÚverify_password)Úrender_password_reset_otp_htmlÚrender_password_reset_otp_plainÚrender_verification_otp_htmlÚrender_verification_otp_plainÚlengthÚreturnc                 ój   ‡— t         j                  Šdj                  ˆfd„t        | «      D «       «      S )NÚ c              3   óH   •K  — | ]  }t        j                  ‰«      –— Œ y ­w)N)ÚsecretsÚchoice)Ú.0Ú_Úalphabets     €ú;/var/www/html/kelly/kelly-backend/app/services/email_otp.pyÚ	<genexpr>zgenerate_otp.<locals>.<genexpr>   s   øè ø€ ÐC±]°”7—>‘> (×+±]ùs   ƒ")ÚstringÚdigitsÚjoinÚrange)r   r   s    @r   Úgenerate_otpr!      s%   ø€ Ü�}‰}€HØ�7‰7ÓC´U¸6´]ÓCÓCÐCó    )Ú	html_bodyÚto_emailÚsubjectÚbodyr#   c              ƒ   ó\  K  — t        «       }|j                  st        j                  d| «       ydd l}ddlm}m} ddlm	} | j                  «       }	|j                  j                  «       }
 |«       }||d<   |
|d<   |	|d<   |j                  |«       |r|j                  |d	¬
«       t        j                  d|
|	|«       	 |j                  ||j                  |j                   |j"                  |j$                  j                  «       |j&                  ¬«      ƒ d {  –—†  t        j                  d|	«       y7 Œ# |$ rA}t        j                  d|j"                  |j                  |j                   |«       Y d }~yd }~w|t(        f$ r!}t        j+                  d| |«       Y d }~yd }~ww xY w­w)Nu,   SMTP not configured â€” email not sent to %sFr   ©ÚSMTPAuthenticationErrorÚSMTPException©ÚEmailMessageÚSubjectÚFromÚToÚhtml)Úsubtypez Sending email from %s to %s (%s)©ÚhostnameÚportÚusernameÚpasswordÚ	start_tlszEmail sent to %sTuN   SMTP login failed for %s@%s:%s â€” check SMTP_USER / SMTP_PASSWORD in .env: %súSMTP send failed for %s: %s)r   Ú	smtp_hostÚloggerÚwarningÚ
aiosmtplibÚaiosmtplib.errorsr)   r*   Úemail.messager,   ÚstripÚ	smtp_fromÚset_contentÚadd_alternativeÚinfoÚsendÚ	smtp_portÚ	smtp_userÚsmtp_passwordÚsmtp_tlsÚOSErrorÚ	exception)r$   r%   r&   r#   Úsettingsr<   r)   r*   r,   Ú	recipientÚsenderÚmsgÚexcs                r   Ú_send_emailrP      s�  è ø€ ô ‹z€HØ×ÒÜ�‰ÐEÀxÔPØãßHÝ*à—‘Ó €IØ×Ñ×%Ñ%Ó'€Fá
‹.€CØ€Cˆ	�NØ€Cˆ�KØ€Cˆ�IØ‡O�O�DÔÙØ×Ñ˜I¨vÐÔ6ä
‡K�KÐ2°F¸IÀwÔOðGØ�o‰oØØ×'Ñ'Ø×#Ñ#Ø×'Ñ'Ø×+Ñ+×1Ñ1Ó3Ø×'Ñ'ð ó 
÷ 	
ð 	
ô 	�‰Ð&¨	Ô2Øð	
ùð #ò 
Ü�‰Ø\Ø×ÑØ×ÑØ×ÑØ÷	
ð 	
ð ûð œ7Ð#ò GÜ×ÑÐ6¸À#×FÐFØûðGüsU   ‚B>F,ÃAD9 ÄD7ÄD9 Ä6F,Ä7D9 Ä9F)Ä>7E:Å5F,Å:F)ÆF$ÆF,Æ$F)Æ)F,Úotpc              ƒ   ód   K  — t        | dt        |¬«      t        |¬«      ¬«      ƒ d {  –—† S 7 Œ­w)Nu*   Pole Power Academy â€” password reset code©rQ   ©r$   r%   r&   r#   )rP   r   r   )r$   rQ   s     r   Úsend_password_reset_emailrU   P   s3   è ø€ ÜØØ<Ü,°Ô5Ü0°SÔ9ô	÷ ð ð ús   ‚'0©.ª0c              ƒ   óš   K  — t        | dt        |¬«      t        |¬«      ¬«      ƒ d{  –—† }|st        j	                  d| |«       |S 7 Œ­w)z4Send a verification / OTP code (registration, etc.).u(   Pole Power Academy â€” verification coderS   rT   Nz,Verification OTP for %s (email not sent): %s)rP   r   r   r:   r;   )r$   rQ   Úsents      r   Úsend_otp_emailrX   Y   sL   è ø€ äØØ:Ü*¨sÔ3Ü.°3Ô7ô	÷ €Dñ Ü�‰ÐEÀxÐQTÔUØ€Kðús   ‚'A©A	ª AÚtitleÚmessageÚnotification_typec          	   ƒ   óH  K  — t        «       }|j                  st        j                  d| ||«       y dd l}ddlm}m} ddlm	} | j                  «       }	|j                  j                  «       }
|j                  dd«      j                  «       } |«       }||d<   |
|d<   |	|d	<   |j                  d
|› d|› d|› d�«       t        j                  d|
|	«       	 |j!                  ||j                  |j"                  |j$                  |j&                  j                  «       |j(                  ¬«      ƒ d {  –—†  t        j                  d|	«       y 7 Œ# |$ r!}t        j                  d|	|«       Y d }~y d }~w|t*        f$ r!}t        j-                  d|	|«       Y d }~y d }~ww xY w­w)Nu6   SMTP not configured â€” notification for %s: %s â€” %sr   r(   r+   r   Ú r-   r.   r/   zYou have a new z( notification from Pole Power Academy.

z

z3

Log in to the app to view all your notifications.z/Sending member notification email from %s to %sr2   z$Member notification email sent to %su8   SMTP login failed â€” notification not emailed to %s: %sr8   )r   r9   r:   r;   r<   r=   r)   r*   r>   r,   r?   r@   ÚreplacerY   rA   rC   rD   rE   rF   rG   rH   rI   rJ   )r$   rY   rZ   r[   rK   r<   r)   r*   r,   rL   rM   Ú
type_labelrN   rO   s                 r   Úsend_member_notification_emailr`   f   s˜  è ø€ ô ‹z€HØ×ÒÜ�‰ØDØØØô		
ð 	ãßHÝ*à—‘Ó €IØ×Ñ×%Ñ%Ó'€FØ"×*Ñ*¨3°Ó4×:Ñ:Ó<€Já
‹.€CØ€Cˆ	�NØ€Cˆ�KØ€Cˆ�IØ‡O�OØ
˜*˜Ð%OØˆ'�Øˆ)ð <ð	=ôô ‡K�KÐAÀ6È9ÔUðHØ�o‰oØØ×'Ñ'Ø×#Ñ#Ø×'Ñ'Ø×+Ñ+×1Ñ1Ó3Ø×'Ñ'ð ó 
÷ 	
ð 	
ô 	�‰Ð:¸IÕFð	
ùð #ò cÜ�‰ÐQÐS\Ð^a×bÑbûØœ7Ð#ò HÜ×ÑÐ6¸	À3×GÑGûðHüsU   ‚CF"ÃAE Ä1EÄ2E ÅF"ÅE ÅFÅE0Å+F"Å0FÅ>FÆF"ÆFÆF"ÚdbÚemailc                óH  — | j                  t        «      j                  t        j                  |k(  t        j                  t
        j                  k(  «      j                  «       }|st        d«      ‚|j                  r|S | j                  t        «      j                  t        j                  |j                  k(  t        j                  j                  d«      «      j                  t        j                   j#                  «       «      j                  «       }|rt%        ||j&                  «      st        d«      ‚|j(                  t+        j,                  t.        j0                  «      k  rt        d«      ‚d|_        d|_	        | j3                  «        | j5                  |«       |S )z?Validate OTP and mark the user's email as verified (once only).zInvalid requestFzInvalid or expired OTPzOTP expiredT)Úqueryr	   Úfilterrb   Úroler
   ÚuserÚfirstÚ
ValueErrorÚemail_verifiedr   Úuser_idÚidÚusedÚis_Úorder_byÚ
created_atÚdescr   Úotp_hashÚ
expires_atr   Únowr   ÚutcÚcommitÚrefresh)ra   rb   rQ   rg   Ú	token_rows        r   Úverify_email_with_otpry   œ   s+  € à�8‰8”D‹>× Ñ ¤§¡¨uÑ!4´d·i±iÄ8Ç=Á=Ñ6PÓQ×WÑWÓY€DÙÜÐ*Ó+Ð+à×ÒØˆð 	�‰Ô#Ó$ß	‰Ô"×*Ñ*¨d¯g©gÑ5Ô7I×7NÑ7N×7RÑ7RÐSXÓ7YÓ	Zß	‰Ô$×/Ñ/×4Ñ4Ó6Ó	7ß	‰‹ð	 ñ œO¨C°×1CÑ1CÔDÜÐ1Ó2Ð2à×ÑœhŸl™l¬8¯<©<Ó8Ò8Ü˜Ó'Ð'à€I„NØ€DÔØ‡I�I„KØ‡J�JˆtÔØ€Kr"   rg   c                 óæ  — | j                  t        «      j                  t        j                  |j                  k(  t        j
                  j                  d«      «      j                  ddi«       t        «       }t        |j                  t        |«      t        j                  t        j                  «      t        d¬«      z   d¬«      }| j                  |«       ||_        | j#                  «        |S )zBInvalidate old tokens, create new OTP, return plain OTP for email.Frm   Té   )Úminutes)rk   rr   rs   rm   )rd   r   re   rk   rl   rm   rn   Úupdater!   r   r   rt   r   ru   r   ÚaddrQ   rv   )ra   rg   rQ   Úrows       r   Úcreate_password_reset_flowr€   ¸   s­   € à‡H�HÔÓ ×'Ñ'Ü×"Ñ" d§g¡gÑ-Ô/A×/FÑ/F×/JÑ/JÈ5Ó/Qóç�fˆf�dˆ^ÔÜ
‹.€CÜ
Ø—‘Ü˜sÓ#Ü—<‘<¤§¡Ó-´	À"Ô0EÑEØô	€Cð ‡F�Fˆ3„KØ€D„HØ‡I�I„KØ€Jr"   )é   )#Úloggingr   r   r   r   r   Úsqlalchemy.ormr   Ú
app.configr   Ú
app.modelsr   r	   r
   Úapp.securityr   r   Úapp.services.email_templatesr   r   r   r   Ú	getLoggerÚ__name__r:   ÚintÚstrr!   ÚboolrP   rU   rX   r`   ry   r€   © r"   r   Ú<module>rŽ      sA  ðÛ Û Û ß 2Ñ 2å "å ß /Ý ß 7÷ó ð 
ˆ×	Ñ	˜8Ó	$€ñD˜ð D Só Dð !ò2àð2ð ð2ð ð	2ð
 �T‰zð2ð 
ó2ðj¨cð ¸ð Àó ð
 3ð 
¨Sð 
°Tó 
ð3HØð3Hð ð3Hð ð	3Hð
 ð3Hð 
ó3Hðl˜gð °ð ¸3ð À4ó ð8 7ð °$ð ¸3ô r"   