+
    ^B.j                     p   R t ^ RIHt ^ RIHtHtHtHt ^ RIH	t	 ^ RI
Ht ^ RIHtHt ^ RIHt ^ RIHtHtHtHtHt ^ RIHtHtHt ^ R	IHt ^ R
IHtHtH t H!t! ]! RR.R7      t"]"PG                  R]!^R7      ]! ]4      3R R ll4       t$]"PG                  R]R7      ]! ]4      3R R ll4       t%]"PG                  R]R7      ]! ]4      3R R ll4       t&]"PO                  R]!R7      R R l4       t(]"PG                  R4      ]! ]4      3R R ll4       t)]"PG                  R4      ]! ]4      3R  R! ll4       t*R"# )#zAuthentication API routes.)	timedelta)	APIRouterDependsHTTPExceptionstatus)select)AsyncSession)RequireViewerget_current_user)get_db)create_access_tokencreate_refresh_tokendecode_tokenget_password_hashverify_password)build_provisioning_urigenerate_totp_secretverify_totp)User)Token
UserCreate	UserLoginUserResponsez/authAuthentication)prefixtagsz	/register)response_modelstatus_codec                0    V ^8  d   QhR\         R\        /#    datadb)r   r   )formats   "app\api\routes\auth.py__annotate__r%      s            c                   "   VP                  \        \        4      P                  \        P                  V P                  8H  4      4      G R j  xL
 pVP                  4       '       d   \        RRR7      h\        V P                  \        V P                  4      V P                  R7      pVP                  V4       VP                  4       G R j  xL
  V#  L L5i)N  zEmail already registeredr   detail)emailpassword_hashrole)executer   r   wherer+   scalar_one_or_noner   r   passwordr-   addflush)r!   r"   existingusers   &&  r$   registerr6      s     ZZt 2 24::3K LMMH""$$4NOOjj'6YYD
 FF4L
((*K N s+   ACCC)A&CCCCz/login)r   c                0    V ^8  d   QhR\         R\        /# r   )r   r   )r#   s   "r$   r%   r%   $   s      i \ r&   c                 `  "   VP                  \        \        4      P                  \        P                  V P                  8H  4      4      G R j  xL
 pVP                  4       pV'       d'   \        V P                  VP                  4      '       g   \        RRR7      hVP                  '       g   \        RRR7      h\        \        \        VP                  4      VP                  P                   4      \#        \        VP                  4      VP                  P                   4      R7      #  L5i)N  zInvalid credentialsr)   i  zAccount disabledaccess_tokenrefresh_token)r.   r   r   r/   r+   r0   r   r1   r,   r   	is_activer   r   stridr-   valuer   )r!   r"   resultr5   s   &&  r$   loginrB   #   s     ::fTl00tzz1IJKKF$$&Dt}}d6H6HII4IJJ>>>4FGG(TWWtyyG*3tww<I  Ls    AD.D,D.+AD.0A=D.z/refreshc                0    V ^8  d   QhR\         R\        /# )r    r<   r"   )r>   r   )r#   s   "r$   r%   r%   3   s      s  r&   c                 \  "    \        V 4      pVP                  R 4      R8w  d   \        RRR7      hVR,          pVR,          pTP                  \        \        4      P                  \        P                  T8H  4      4      G Rj  xL
 pTP                  4       pT'       d   TP                  '       g   \        RR	R7      h\        \        \        TP                  4      T4      \        \        TP                  4      T4      R
7      #   \        \        3 d    \        RRR7      hi ; i L5i)typerefreshr9   zInvalid tokenr)   subr-   zInvalid refresh tokenNzUser not foundr:   )r   getr   
ValueErrorKeyErrorr.   r   r   r/   r?   r0   r=   r   r   r>   r   )r<   r"   payloaduser_idr-   rA   r5   s   &&     r$   r<   r<   2   s     M}-;;v)+CHH%.v ::fTl00G1CDEEF$$&Dt~~~4DEE(TWWt<*3tww<>  ! M4KLLM Fs7   D,A D AD,D*D,"D,4AD,D''D,z/mec                $    V ^8  d   QhR\         /# )r    r5   )r	   )r#   s   "r$   r%   r%   I   s      } r&   c                    "   V # 5i)N )r5   s   &r$   get_merP   H   s
     Ks   z
/2fa/setupc                0    V ^8  d   QhR\         R\        /# )r    r5   r"   )r	   r   )r#   s   "r$   r%   r%   N   s      - \ r&   c                    "   V P                   '       g(   \        4       V n         VP                  4       G R j  xL
  R\        V P                   V P                  RR7      RV P
                  /#  L45i)Nprovisioning_uriTradingBinance)secretaccount_nameissuerenabled)totp_secretr   r3   r   r+   totp_enabled)r5   r"   s   &&r$   	setup_2far[   M   sg     /1hhj 	2###

 	4$$  	s   5A.A,5A.z/2fa/enablec                <    V ^8  d   QhR\         R\        R\        /# )r    coder5   r"   )r>   r	   r   )r#   s   "r$   r%   r%   ^   s!     	 	3 	m 	 	r&   c                    "   VP                   '       g   \        R RR7      h\        VP                   V 4      '       g   \        R RR7      hRVn        VP	                  4       G Rj  xL
  RR/#  L5i)r(   z2FA setup has not been startedr)   zInvalid 2FA codeTNrX   )rY   r   r   rZ   r3   )r]   r5   r"   s   &&&r$   
enable_2far_   ]   sg     4TUUt''..4FGGD
((*t s   A#A0%A.&	A0N)+__doc__datetimer   fastapir   r   r   r   
sqlalchemyr   sqlalchemy.ext.asyncior   app.api.depsr	   r
   app.core.databaser   app.core.securityr   r   r   r   r   app.core.totpr   r   r   
app.modelsr   app.schemasr   r   r   r   routerpostr6   rB   r<   rH   rP   r[   r_   rO   r&   r$   <module>rm      s'      = =  / 8 $ y y S S  B B	')9(:	; [3G8?  H Xe,4;FO  - Z.?Fv  /* E,/ 0 \<CFO   ]HOPV 	 	r&   