Ë
    ’Di;/  ã            	      ó*  — d Z ddlmZ ddlZddlmZ ddlmZmZ ddl	m
Z
m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mZmZmZ ddlm Z  ddl!m"Z"m#Z#m$Z$m%Z%m&Z&  ejN                  e(«      Z)d*d„Z* ee"e# ed¬«       ed¬«      dœd¬«       edg«       eeg«      d„ «       «       «       Z+ ee"e# ed¬«       ed¬«       ed¬«      dœd¬«       edg«       eeg«      d„ «       «       «       Z, eejZ                  e# ed ¬«       ed!¬«      d"œd#¬«       edg«       eeg«      d$„ «       «       «       Z. G d%„ d&ej^                  «      Z0e eejZ                  e%e%d'œd(¬«       edg«       eeg«      d)„ «       «       «       «       Z1y)+z+API views for Telegram-only authentication.é    )ÚannotationsN)ÚOpenApiTypes)ÚOpenApiResponseÚextend_schema)ÚstatusÚviewsets)Úapi_viewÚpermission_classesÚaction)ÚAllowAny)ÚResponse)ÚRefreshToken)Úsettings)Úcsrf_exempt)ÚTelegramDataValidationErrorÚinit_data_debug_snapshotÚsend_telegram_messageÚvalidate_telegram_init_dataé   )ÚUser)ÚTelegramAuthRequestSerializerÚTelegramAuthResponseSerializerÚ#TelegramAuthenticatedUserSerializerÚ!TelegramWebhookResponseSerializerÚUserWalletSerializerc                óR  — 	 t        | t        j                  «      }|j                  d«      }|st	        ddit        j                  ¬«      S |j                  d«      |j                  dd«      |j                  d	«      |j                  d
«      |j                  d«      dœ}t        j                  j                  ||¬«      \  }}|s_g }|j                  «       D ]6  \  }	}
|
€Œ	t        ||	«      |
k7  sŒt        ||	|
«       |j!                  |	«       Œ8 |r|j#                  |¬«       |r`|j$                  sT	 t        j                  j                  |¬«      }|j&                  |j&                  k7  r||_        |j#                  dg¬«       t-        j.                  |«      }t	        t        |j0                  «      t        |«      |j&                  |j2                  |j4                  |j6                  |j8                  |j:                  |j<                  t        |j>                  «      t        |j@                  «      |jB                  |j$                  dœdœ«      S # t        $ r0}t	        dt        |«      it        j                  ¬«      cY d}~S d}~ww xY w# t        j*                  $ r Y �Œw xY w)z@Shared logic for authenticating a user from an initData payload.Úerror©r   NÚidzInvalid user dataÚusernameÚ
first_nameÚ Ú	last_nameÚlanguage_codeÚ	photo_url)r    r!   r#   r$   r%   )Útelegram_user_idÚdefaults)Úupdate_fields)Úreferral_codeÚreferred_by©r   r&   r    r!   r#   r$   r%   Úcredit_balanceÚbonus_balancer)   r*   ©ÚaccessÚrefreshÚuser)"r   r   ÚTELEGRAM_BOT_TOKENr   r   Ústrr   ÚHTTP_401_UNAUTHORIZEDÚgetÚHTTP_400_BAD_REQUESTr   ÚobjectsÚget_or_createÚitemsÚgetattrÚsetattrÚappendÚsaveÚreferred_by_idr   r*   ÚDoesNotExistr   Úfor_userÚaccess_tokenr&   r    r!   r#   r$   r%   r,   r-   r)   )Ú	init_dataÚstart_paramÚ	user_dataÚexcr&   r'   r1   ÚcreatedÚchanged_fieldsÚfieldÚvalueÚreferrerr0   s                úA/home/cursorai/projects/telegram-earn/backend/apps/users/views.pyÚ_authenticate_with_init_datarL   $   s]  € ð	
Ü/ØÜ×'Ñ'ó
ˆ	ð !—}‘} TÓ*ÐÙÜØÐ)Ð*Ü×.Ñ.ô
ð 	
ð —M‘M *Ó-Ø—m‘m L°"Ó5Ø—]‘] ;Ó/Ø"Ÿ™ Ó7Ø—]‘] ;Ó/ñ€Hô —L‘L×.Ñ.Ø)Øð /ó �M€Dˆ'ñ Ø$&ˆØ$ŸN™NÖ,‰LˆE�5ØÑ ¤W¨T°5Ó%9¸UÓ%BÜ˜˜e UÔ+Ø×%Ñ% eÕ,ð -ñ Ø�I‰I NˆIÔ3ñ ˜4×.Ò.ð	Ü—|‘|×'Ñ'°kÐ'ÓBˆHØ�{‰{˜dŸg™gÒ%Ø#+�Ô Ø—	‘	¨¨�	Ô8ô ×#Ñ# DÓ)€Gää˜'×.Ñ.Ó/Ü˜7“|à—g‘gØ$(×$9Ñ$9Ø ŸM™MØ"Ÿo™oØ!Ÿ^™^Ø!%×!3Ñ!3Ø!Ÿ^™^Ü"% d×&9Ñ&9Ó":Ü!$ T×%7Ñ%7Ó!8Ø!%×!3Ñ!3Ø#×2Ñ2ññ	
óð øôa 'ò 
ÜØ”c˜#“hÐÜ×/Ñ/ô
õ 	
ûð
ûôV × Ñ ò 	Úð	ús0   ‚I Ä4AJ É	JÉ%JÊJÊJÊJ&Ê%J&z(Missing or invalid init_data/start_param)Údescriptionz$Telegram signature validation failed)éÈ   é�  é‘  z@Authenticate a user via Telegram WebApp initData and issue JWTs.)ÚrequestÚ	responsesrM   ÚPOSTc                óÄ   — | j                   j                  d«      }| j                   j                  d«      }|st        ddit        j                  ¬«      S t        ||«      S )zN
    Authenticate a user using Telegram Web App initData and return JWTs.
    rB   rC   r   úinit_data is requiredr   )Údatar5   r   r   r6   rL   )rQ   rB   rC   s      rK   Úauthenticate_telegramrW   p   s]   € ð —‘× Ñ  Ó-€IØ—,‘,×"Ñ" =Ó1€KáÜØÐ-Ð.Ü×.Ñ.ô
ð 	
ô
 (¨	°;Ó?Ð?ó    zMissing init_datazSignature validation failedzDev auth disabled)rN   rO   rP   é”  z¸Development-only Telegram auth helper. Validates a signed initData payload and returns JWTs plus signature debug info. Only available when DEBUG=True and ENABLE_DEV_TELEGRAM_AUTH=True.c                óX  — t         j                  rt        t         dd«      st        t        j
                  ¬«      S | j                  j                  d«      }| j                  j                  d«      }|st        ddit        j                  ¬«      S t        |t         j                  «      }t        j                  d|j                  d	«      |j                  d
«      «       t        ||«      }|j                  t        j                  k(  r!t!        |j                  «      }||d<   ||_        |S )zT
    Dev-only helper endpoint to test Telegram auth flows without the Mini App.
    ÚENABLE_DEV_TELEGRAM_AUTHFr   rB   rC   r   rU   z<Dev Telegram auth debug: provided_hash=%s calculated_hash=%sÚprovided_hashÚcalculated_hashÚdebug)r   ÚDEBUGr:   r   r   ÚHTTP_404_NOT_FOUNDrV   r5   r6   r   r2   ÚloggerÚinforL   Ústatus_codeÚHTTP_200_OKÚdict)rQ   rB   rC   Ú
debug_infoÚresponseÚpayloads         rK   Úauthenticate_telegram_devri   ‹   sú   € ô( �NŠNœw¤xÐ1KÈUÔSÜœv×8Ñ8Ô9Ð9à—‘× Ñ  Ó-€IØ—,‘,×"Ñ" =Ó1€KáÜØÐ-Ð.Ü×.Ñ.ô
ð 	
ô
 *ØÜ×#Ñ#ó€Jô ‡K�KØFØ�‰�Ó'Ø�‰Ð(Ó)ôô ,¨I°{ÓC€HØ×Ñœv×1Ñ1Ò1Ü�x—}‘}Ó%ˆØ%ˆ�ÑØˆŒà€OrX   zMissing usernamez#User not found or Dev auth disabled)rN   rO   rY   z‡Development-only helper to switch the authenticated user by username. Only available when DEBUG=True and ENABLE_DEV_TELEGRAM_AUTH=True.c                ó:  — t         j                  rt        t         dd«      st        t        j
                  ¬«      S | j                  j                  d«      }|st        ddit        j                  ¬«      S 	 t        j                  j                  |¬«      }t        j                  |«      }t        t        |j                  «      t        |«      |j                   |j"                  |j$                  |j&                  |j(                  |j*                  |j,                  t        |j.                  «      t        |j0                  «      |j2                  |j4                  d
œdœ«      S # t        j                  $ r$ t        dd|› d	�it        j
                  ¬«      cY S w xY w)z=
    Dev-only helper to switch user context by username.
    r[   Fr   r    r   zusername is required)r    zUser with username 'z' not foundr+   r.   )r   r_   r:   r   r   r`   rV   r5   r6   r   r7   r?   r   r@   r3   rA   r   r&   r    r!   r#   r$   r%   r,   r-   r)   r>   )rQ   r    r1   r0   s       rK   Úswitch_user_devrk   ¾   sZ  € ô$ �NŠNœw¤xÐ1KÈUÔSÜœv×8Ñ8Ô9Ð9à�|‰|×Ñ 
Ó+€HÙÜØÐ,Ð-Ü×.Ñ.ô
ð 	
ð

Ü�|‰|×Ñ¨ÐÓ2ˆô ×#Ñ# DÓ)€Gää˜'×.Ñ.Ó/Ü˜7“|à—g‘gØ$(×$9Ñ$9Ø ŸM™MØ"Ÿo™oØ!Ÿ^™^Ø!%×!3Ñ!3Ø!Ÿ^™^Ü"% d×&9Ñ&9Ó":Ü!$ T×%7Ñ%7Ó!8Ø!%×!3Ñ!3Ø#×2Ñ2ññ	
óð øô ×Ñò 
ÜØÐ,¨X¨J°kÐBÐCÜ×,Ñ,ô
ò 	
ð
ús   Á7 E# Å#4FÆFc                  ó‚   — e Zd ZdZ edeid¬«      d„ «       Z ed ed¬«      id¬«       ed	d
g¬«      d„ «       «       Z	y)Ú	MeViewSetz/Endpoints for current user profile and wallets.rN   z*Retrieve the authenticated user's profile.)rR   rM   c                óV   — t        |j                  «      }t        |j                  «      S )z4GET /api/users/me/ returns the current user profile.)r   r1   r   rV   )ÚselfrQ   Ú
serializers      rK   ÚlistzMeViewSet.listü   s!   € ô 9¸¿¹ÓFˆ
Ü˜
Ÿ™Ó(Ð(rX   T©Úmanyz8Retrieve all wallet balances for the authenticated user.Fr5   )ÚdetailÚmethodsc                óž   — |j                   }dd|j                  dœdd|j                  dœg}t        |d¬«      }t	        |j
                  «      S )z7GET /api/users/me/wallets/ returns all wallet balances.ÚPrimaryr,   )ÚnameÚtypeÚbalanceÚBonusÚbonusTrr   )r1   r,   r-   r   r   rV   )ro   rQ   r1   Úwalletsrp   s        rK   r}   zMeViewSet.wallets  sR   € ð �|‰|ˆàÐ(8ÀT×EXÑEXÑYØ g¸$×:LÑ:LÑMð
ˆô *¨'¸Ô=ˆ
Ü˜
Ÿ™Ó(Ð(rX   N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   rq   r   r   r}   © rX   rK   rm   rm   ù   se   „ Ù9áØÐ;Ð<Ø@ôñ)ó	ð)ñ
 ØÑ,°$Ô7Ð8ØNôñ �5 5 'Ô*ñ)ó +ó	ñ
)rX   rm   )rN   é“  zbWebhook for Telegram bot updates. Returns ok/forbidden depending on the configured webhook secret.c                óÚ  — t         j                  }| j                  j                  d«      }|r||k7  rt	        dddœd¬«      S | j
                  xs i }|j                  d«      xs |j                  d«      }|j                  d	«      }d
}d}|r(|j                  d«      }|j                  dd«      xs d}n>|r<|j                  d«      xs i }|j                  d«      }|j                  dd«      xs d}|rd|vrt	        ddi«      S |d   }d
}	|j                  d«      r6|j                  d¬«      }
t        |
«      dkD  r|
d   j                  «       nd
}	n|r|j                  d«      r|d   }	t        t         dd«      }|}|r|	rd|v rdnd}|› |› d|	› �}|rdd|idœggdddœ}d}nd
}d}t        t         j                  |||¬«      }|st        j                  d |«       t	        ddi«      S )!zV
    Receive Telegram webhook updates and handle /start deep links for referrals.
    zX-Telegram-Bot-Api-Secret-TokenFÚ	forbidden)Úokr   rƒ   r   ÚmessageÚedited_messageÚcallback_queryNr"   ÚchatÚtextrV   r   r†   Tz/startr   )ÚmaxsplitÚTELEGRAM_WEBAPP_URLÚ?Ú&z	startapp=zOpen appÚurl)r‹   Úweb_app)ÚkeyboardÚresize_keyboardÚone_time_keyboardzLTap the button below to open the app. Referral code is passed automatically.z2App URL is not configured. Please try again later.)Ú	bot_tokenÚchat_idr‹   Úreply_markupz2Failed to reply to Telegram webhook for chat_id=%s)r   ÚTELEGRAM_WEBHOOK_SECRETÚheadersr5   r   rV   Ú
startswithÚsplitÚlenÚstripr:   r   r2   ra   Úwarning)rQ   Úsecret_tokenÚheader_secretÚupdater‡   r‰   rŠ   r‹   r–   rC   ÚpartsÚweb_app_urlÚ
button_urlÚ	separatorr—   Ú
reply_textÚsents                    rK   Útelegram_webhookr¨     s"  € ô$ ×3Ñ3€LØ—O‘O×'Ñ'Ð(IÓJ€MÙ˜¨Ò5Ü˜u¨{Ñ;ÀCÔHÐHà�\‰\Ò˜R€FØ�j‰j˜Ó#ÒC v§z¡zÐ2BÓ'C€GØ—Z‘ZÐ 0Ó1€Nð €DØ€DÙØ�{‰{˜6Ó"ˆØ�{‰{˜6 2Ó&Ò,¨"‰Ù	Ø ×$Ñ$ YÓ/Ò5°2ˆØ�{‰{˜6Ó"ˆØ×!Ñ! &¨"Ó-Ò3°ˆá�4˜tÑ#Ü˜˜t˜Ó%Ð%à�4‰j€GØ"€KØ‡��xÔ Ø—
‘
 A�
Ó&ˆÜ*-¨e«*°qª.�e˜A‘h—n‘nÔ&¸d‰Ù	˜N×.Ñ.¨vÔ6Ø$ VÑ,ˆäœ(Ð$9¸2Ó>€KØ€JÙ‘{Ø +Ñ-‘C°3ˆ	Ø#�} Y K¨y¸¸ÐFˆ
ñ ð
 !+Ø$)¨:Ð#6ñððð  $Ø!&ñ
ˆð5ñ 	ð
 ˆØIˆ
ä Ü×-Ñ-ØØØ!ô	€Dñ Ü�‰ÐKÈWÔUä�T˜4�LÓ!Ð!rX   )rB   r3   rC   z
str | None)2r�   Ú
__future__r   ÚloggingÚdrf_spectacular.typesr   Údrf_spectacular.utilsr   r   Úrest_frameworkr   r   Úrest_framework.decoratorsr	   r
   r   Úrest_framework.permissionsr   Úrest_framework.responser   Úrest_framework_simplejwt.tokensr   Údjango.confr   Údjango.views.decorators.csrfr   Úutils.telegramr   r   r   r   Úmodelsr   Úserializersr   r   r   r   r   Ú	getLoggerr~   ra   rL   rW   ri   ÚOBJECTrk   ÚViewSetrm   r¨   r‚   rX   rK   Ú<module>rº      sô  ðÙ 1å "ã å .ß @ß +ß JÑ JÝ /Ý ,Ý 8Ý  Ý 4÷ó õ ÷õ ð 
ˆ×	Ñ	˜8Ó	$€óIñX Ø)à+ÙÐ)SÔTÙÐ)OÔPñð
 Sôñ 
ˆ6ˆ(ÓÙ�X�JÓñ@ó  ó óð@ñ  Ø)à+ÙÐ)<Ô=ÙÐ)FÔGÙÐ)<Ô=ñ	ð	=ôñ 
ˆ6ˆ(ÓÙ�X�JÓñ ó  ó óð  ñF Ø×Ñà+ÙÐ);Ô<ÙÐ)NÔOñð	Lôñ 
ˆ6ˆ(ÓÙ�X�JÓñ*ó  ó óð*ôZ)�× Ñ ô )ð8 ÙØ×Ñà.Ø.ñð
	%ô
ñ 
ˆ6ˆ(ÓÙ�X�JÓñI"ó  ó ó
ó ñI"rX   