
    i2                        d dl mZmZmZmZ d dlmZ d dlmZm	Z	 d dl
Z
d dlZd dlZd dlmZmZ d dlZd dlZd dlZd dlmZ d dlm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# d dl$m%Z% d dl&m'Z' d dl(m)Z)  e            Z* ee*          Z+ ej,        ej-        d            ej.        e/          Z0 eddg          Z1 ed          Z2 e!dgdd          Z3 G d de          Z4d5dZ5d6dZ6d  Z7 e)e1d!d"ge#          e18                    d$e%          d&efd'                        Z9e1:                    d$e%           ed(           ed(           ed(          fd&ed)e;d*e;d+e;fd,            Z<e18                    d-          d&ed.e=d/e;fd0            Z>e1:                    d-           ed(           ed(           ed(           ed           ed          fd&ed1e=d2e;d3e;d*e%e;         d+e%e;         fd4            Z?dS )7    )	APIRouterFormRequestQuery)Jinja2Templates)	BaseModelfield_validatorN)HTMLResponseRedirectResponse)MIMEText)MIMEMultipart)get_pingconf_vars
open_mysqlget_mysql_creds)contextmanager)CryptContext)	parseaddr)Optional)HTTP_302_FOUND)add_dual_routez)%(asctime)s - %(levelname)s - %(message)s)levelformatz/resetpwresetpw)prefixtags	templates)	directorybcryptauto2b)schemes
deprecatedbcrypt__identc                   R    e Zd ZU eed<    ed          ed                         ZdS )	ResetForm
identifierc                 t    |r|                                 st          d          |                                 S )NzUsername or email is required)strip
ValueError)clsvs     */wd/v2025.freedom4um.com/routes/resetpw.pyvalidate_identifierzResetForm.validate_identifier*   s8      	>		 	><===wwyy    N)__name__
__module____qualname__str__annotations__r	   classmethodr-    r.   r,   r%   r%   '   sM         OOO_\""  [ #"  r.   r%      c                     d                     d t          j        t          j        z   D                       d                     fdt	          |           D                       S )N c              3   "   K   | ]
}|d v|V  dS )oO0iIl1Nr5   ).0cs     r,   	<genexpr>z(generate_captcha_code.<locals>.<genexpr>2   s-      ZZ!qPYGYGYAGYGYGYGYZZr.   c              3   @   K   | ]}t          j                  V  d S Nrandomchoicer;   _charss     r,   r=   z(generate_captcha_code.<locals>.<genexpr>3   -      ??A6=''??????r.   )joinstringascii_lettersdigitsrangelengthrE   s    @r,   generate_captcha_coderN   1   sZ    GGZZv3fmCZZZZZE77????v??????r.      c                     t           j        t           j        z   d                    fdt	          |           D                       S )Nr8   c              3   @   K   | ]}t          j                  V  d S r?   r@   rC   s     r,   r=   z&generate_reset_code.<locals>.<genexpr>8   rF   r.   )rH   rI   rJ   rG   rK   rL   s    @r,   generate_reset_coderR   6   s?     6=0E77????v??????r.   c           	      @   dt           d          d| d| }dt           d          d| d| d	t           d          d
	}dt           d          d| d| dt           d          d	}t          d          }t           d          d|d<   dt           d          |d<   | |d<   t          |d          }t          |d          }	|                    |           |                    |	           	 t	          j        t           d         d          5 }
|
                    |d         | g|                                           d d d            n# 1 swxY w Y   t          	                    d|             d S # t          $ r&}t                              d|  d|             d }~ww xY w)Nzhttps://HomeURLDomainz :1443/resetpw/resetpwconfirm?id=z&code=z-You have requested a password reset for your SiteNamez# account associated with username 'z@'.

Please reset your password by clicking the following link:

zW

If you did not request this reset, please disregard this message.

Best regards,
The z Team
a  <!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"></head>
<body style="font-family: Arial, sans-serif; background-color: #f5f1e9; color: #193048; margin:0; padding:20px;">
  <div style="max-width:600px; margin:auto; padding:20px; background:#fff; border:3px solid #C6BBA3; border-radius:8px;">
    <h1 style="color:#7ed957;">Password Reset Request</h1>
    <p>You have requested a password reset for your <strong>z3</strong> account associated with username <strong>zh</strong>.</p>
    <p>Please reset your password by clicking the link below:</p>
    <p>
      <a href="z" style="color:#ffde59; font-weight:bold; text-decoration:none;">
        Reset Password
      </a>
    </p>
    <hr style="border-color:#C6BBA3;">
    <p>If you did not request this, please disregard this email.</p>
    <p>Best regards,<br>The z# Team</p>
  </div>
</body>
</html>
alternativez Password ResetSubjectznoreply@FromToplainhtmlOutMailServer   zReset email sent to zFailed to send reset email to z: )PingConfr   r   attachsmtplibSMTPsendmail	as_stringloggerdebug	Exceptionerror)email	handle_id
reset_codeusername	reset_urltextr[   msgpart1part2serveres               r,   send_reset_emailrs   ;   sX   s8O4ssV_ssgqssI.6z.B go 
   j  D >Fj=Q  GO     &j1!  D, 
&
&C ,===C	N8Xo688CKCIT7##ET6""EJJuJJu\(?3R88 	CFOOCK%#--//BBB	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C 	C3E3344444   BeBBqBBCCCs<   & E- 1E7E- EE- 
E E- -
F7!FFr8   GET)methodsresponse_class/)rv   requestc                    K   t                      }|| j        d<   t                              d|            t                              d| d|i d          S )Ncaptcha_codez"Generated CAPTCHA code for reset: resetpw.htmlr8   rx   r&   rz   errors)rN   sessionrd   re   r   TemplateResponse)rx   rz   s     r,   get_resetpwr   w   sk       )**L&2GON#
LLDlDDEEE%%(		
 	
  r.   .r&   captcharz   c           	        K   i }d|i}t                               d|            	 t          |           nG# t          $ r:}|                                D ]}|d         d         }|d         ||<   Y d }~nd }~ww xY w| j                            dd          }	|                                                                }
|	                                }t                               d	|
 d
| d           |	r|
|k    rd|d<   |r@t                      }|| j        d<   t                              d| |d         ||dd          S d }d }d }	 t          t                    5 }|                    d          }d|v rZ|                    d|f           |                                }|                                 |r|d         }|d         }|d         }nY|                    d|f           |                                }|                                 |r|d         }|d         }|d         }|sQd|d<   t                      }|| j        d<   t                              d| |d         ||dd          cd d d            S t%                      }|                                }|                    d||f           |                                 t                               d|            t)          ||||           d d d            n# 1 swxY w Y   n# t*          j        j        t0          f$ ry}t                               d|            t5          |          |d<   t                      }|| j        d<   t                              d| |d         ||dd          cY d }~S d }~ww xY wt                              d| t6          d d          S )!Nr&   zReceived reset form data: )r&   locr   rn   rz   r8   zCAPTCHA comparison: submitted='z', stored=''z*Incorrect CAPTCHA input (case-insensitive)r   r{   r|      status_codeT
dictionary@zRSELECT HandleID, Email, Handle FROM Handles WHERE Email = %s AND StatusCode != 'D'HandleIDEmailHandlezSSELECT HandleID, Email, Handle FROM Handles WHERE Handle = %s AND StatusCode != 'D'z4No account found with this username or email addressz5UPDATE Handles SET ResetCode = %s WHERE HandleID = %sz#Reset code generated for HandleID: zError during reset: databasezresetpw_success.html)rx   r^   )rd   re   r%   r)   r}   r~   getr(   lowerrN   r   r   r   mysql_credscursorexecutefetchonefetchallrR   commitrs   mysql	connectorErrorrf   rg   r2   r^   )rx   r&   r   rz   r}   	form_datarr   rg   fieldstored_captchasubmitted_captchastored_captcha_normnew_captcha_coderi   rh   rk   connr   rowrj   s                       r,   post_resetpwr      s      FjI LL9i99:::)Z((((( ) ) )XXZZ 	) 	)E%LOE!%LF5MM	) 	) 	) 	) 	)) _((<<N--//(..00
LLg3DggQdggghhh I.2EEEHy 
022*:'))"'5 0 	   * 	
 	
 		
 IEHD
$$ 3	E[[D[11F j  s *}. . .oo''!!! - #JILE"8}H t *}. . .oo''!!! - #JILE"8}H ']|$#8#:#: 2B/ 11"#*&/&=(8"(	  !$ 2 	 	;3	E 3	E 3	E 3	E 3	E 3	E 3	E 3	ER -..J[[]]FNNGY'   KKMMMLLJyJJKKK UIz8DDDg3	E 3	E 3	E 3	E 3	E 3	E 3	E 3	E 3	E 3	E 3	E 3	E 3	E 3	E 3	Ej O!9- 
 
 
/A//000 VVz022*:'))"'5 0 	   * 	
 	
 		
 		
 		
 		
 		
 		

  %%22 &   sf   8 
A<0A77A<L DL	3L  A=L	=L 	LL LL N)0A.N$N)$N)z/resetpwconfirmidcodec           	      *  K   t                               d           |r|st          dt                    S 	 t	          t
                    5 }t          d           |                    d          }|                    d||f           |	                                }|s"t          dt                    cd d d            S |                                }|                    d|f           |
                                 d d d            n# 1 swxY w Y   n[# t          j        j        t          f$ r=}t                               d	|            t          dt                    cY d }~S d }~ww xY wt                               d
| |ddi d          S )Nzresetpwconfirm, startingz/resetpw?error=invalidurlr   z!resetpwconfirm, inside open_mysqlTr   zdSELECT HandleID, ResetCode FROM Handles WHERE HandleID = %s AND ResetCode = %s AND StatusCode != 'D'z7UPDATE Handles SET ResetCode = NULL WHERE HandleID = %sz Error validating reset confirm: resetpwconfirm.htmlr8   rx   ri   passwordconfirm_passwordr}   )rd   re   r   r   r   r   printr   r   r   r   r   r   r   rf   rg   r   r   )rx   r   r   r   r   r   rr   s          r,   get_resetpw_confirmr     s      LL+,,, ZT Z$<.YYYYZ$$ 	5666[[D[11FNNvT
   //##C b',DR`aaa	 	 	 	 	 	 	 	 [[]]FNNTWYV[\\\KKMMM	 	 	 	 	 	 	 	 	 	 	 	 	 	 	  O!9- Z Z Z;;;<<<$<.YYYYYYYYYZ %% "	
 	
	 	 	sN   D A)D5D ?DD DD DD E142E,&E1,E1ri   r   r   c           
      x  K   i }||d}t                               d|            t          |          dk     rd|d<   ||k    rd|d<   |r/t                              d| ||d         |d         |d	d
          S 	 t          t                    5 }|                                }	t          	                    |          }
|	
                    d|
|f           |                                 t                               d|            d d d            n# 1 swxY w Y   n# t          j        j        t          f$ rh}t                               d|            t#          |          |d<   t                              d| ||d         |d         |d	d
          cY d }~S d }~ww xY wt%          dt&                    S )N)r   r   z/Received reset confirm form data for HandleID:    z+Password must be at least 6 characters longr   zPasswords do not matchr   r   r   r   r   zFUPDATE Handles SET Password = %s, ResetCode = NULL WHERE HandleID = %sz(Password reset successful for HandleID: zError updating password: r   z/signin/r   )rd   re   lenr   r   r   r   r   pwd_contexthashr   r   r   r   r   rf   rg   r2   r   r   )rx   ri   r   r   r   rz   r}   r   r   r   hashed_passwordrr   s               r,   post_resetpw_confirmr   *  sq      F, I LLN9NNOOO 8}}qJz###%=!"  
))!"&%j1$-.@$A    * 

 

 
	

$$ 	Q[[]]F)..x88ONNX ),   KKMMMLLOIOOPPP	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q O!9- 
 
 
444555 VVz))!"&%j1$-.@$A    * 

 

 
	
 
	
 
	
 
	
 
	
 
	

  
GGGGsD   <D  A8DD  DD  DD   F#;AFF#F#)r6   )rO   )@fastapir   r   r   r   fastapi.templatingr   pydanticr   r	   rerA   rH   starlette.responsesr
   r   mysql.connectorr   configparserr`   email.mime.textr   email.mime.multipartr   loggingosutils.pingdatar   r   r   
contextlibr   passlib.contextr   email.utilsr   typingr   starlette.statusr   utils.routesr   r^   r   basicConfigDEBUG	getLoggerr/   rd   routerr   r   r%   rN   rR   rs   r   r   postr2   r   intr   r   r5   r.   r,   <module>r      s]   4 3 3 3 3 3 3 3 3 3 3 3 . . . . . . / / / / / / / / 				   > > > > > > > >          $ $ $ $ $ $ . . . . . .  				 I I I I I I I I I I % % % % % % ( ( ( ( ( ( ! ! ! ! ! !       + + + + + + ' ' ' ' ' 'oh''  
-6    
	8	$	$	*I;	7	7	7Ok222	lH:&PTUUU    	   @ @ @ @
@ @ @ @
9 9 9x UGLIIIC--w    .- JI S.. $s))tCyy DII	w www w 	w w w /.wr $w $C $s $ $ $ $N  T#YYDII DII!T$ZZ"&$t**DH DHDHDH DH 	DH
 c]DH 3-DH DH DH  DH DH DHr.   