+
    „WÝj   ã                  ó  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIH	t	H
t
 ^ RIHtHt ^ RIHtHtHt ^ RIHt RtRtR	t]P.                  ! 4       t]	 ! R
 R4      4       t/ tR]R&   / tR]R&   R R ltR R ltRRRR/R R lltR# )a&  Single-flight + short replay cache for rotating refresh tokens (both refresh paths).

Rotating refresh tokens with reuse detection (Nous Portal, Authelia, most OIDC IdPs) make a
replay of an already-rotated RT fatal: the provider revokes the whole session. The desktop and
the browser both fire bursts of parallel requests on wake or after the access token lapses,
each still carrying the same old RT, so the gateway must let exactly ONE of them reach the
provider and hand the rotated session to the rest. The cookie gate (``middleware``) and the
native bearer route (``routes.auth_native_refresh``) share this one flight table.

A provider hint only orders discovery: it must neither split one rotating credential's lock
nor let an unrelated provider reuse its result. Raw refresh tokens are never keys.
)ÚannotationsN)Ú	dataclassÚfield)ÚCallableÚOptional)ÚDashboardAuthProviderÚRefreshExpiredErrorÚSession©Úscan_session_providersg      >@g      @é   c                  óV   € ] tR t^"t$ ]! ]P                  R7      tR]R&   ^ t	R]R&   Rt
R# )Ú_Flight)Údefault_factoryzthreading.LockÚlockÚintÚusers© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r   Ú	threadingÚLockr   Ú__annotations__r   Ú__static_attributes__r   ó    ÚbC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\dashboard_auth\refresh_singleflight.pyr   r   "   s   ‡ á °·±Ô@€Dˆ.Ó@Ø€Eˆ3‡Nr   r   zLdict[tuple[int, bytes], tuple[float, DashboardAuthProvider, Session | None]]Ú_cachez dict[tuple[int, bytes], _Flight]Ú_flightsc               ó    € V ^8„  d   QhRRRR/# )é   ÚnowÚfloatÚreturnÚNoner   )Úformats   "r   Ú__annotate__r'   .   s   € ÷ @ñ @�ð @˜$ñ @r   c                óÜ   € \        \        P                  4       4       F  w  pw  p pW 8:  g   K  \        V K  	  \        \        4      \        8”  d   \        \        \        R  R7       K1  R# )c                ó*   € \         V ,          ^ ,          # )é    )r   ©Úkeys   &r   Ú<lambda>Ú_prune.<locals>.<lambda>3   s   € ¬v°c­{¸1®~r   r+   N)Úlistr   ÚitemsÚlenÚ_MAX_ENTRIESÚmin)r"   r,   ÚexpiresÚ_s   &   r   Ú_pruner6   .   sQ   € Ü $¤V§\¡\£^Ö 4Ñˆ‰_ˆg�q˜!ØŽ>Ü�s’ñ !5ô Œf‹+œÔ
$Ü”3”vÑ#=Ô>Ò?ñ %r   c               ó$   € V ^8„  d   QhRRRRRR/# )r!   Úproviderr   ÚtokenÚstrr$   zSession | Noner   )r&   s   "r   r'   r'   6   s"   € ÷ (ñ (Ð 5ð (¸cð (Ànñ (r   c           	     óp  € \         P                  ! VP                  4       4      P                  4       p\	        V 4      V3p\
        ;_uu_ 4        \        \        P                  ! 4       4       \        P                  V\        4       4      pV;P                  ^,          un        RRR4        XP                  ;_uu_ 4        \
        ;_uu_ 4        \        P                  V4      pVe–   V^ ,          \        P                  ! 4       8”  du   V^,          uuRRR4       uuRRR4       \
        ;_uu_ 4        V;P                  ^,          un        VP                  ^ 8X  d   \        P!                  VR4       RRR4       # RRR4        V P#                  VR7      p\
        ;_uu_ 4        \        P                  ! 4       pYve   \&        M\(        ,           W3\        V&   \        V4       RRR4       TuuRRR4       \
        ;_uu_ 4        V;P                  ^,          un        VP                  ^ 8X  d   \        P!                  VR4       RRR4       #   + '       g   i     EL¸; i  + '       g   i     # ; i  + '       g   i     EL; i  \$         d    Rp ELi ; i  + '       g   i     LÂ; i  + '       g   i     # ; i  + '       g   i     M; i \
        ;_uu_ 4        T;P                  ^,          un        TP                  ^ 8X  d   \        P!                  TR4       RRR4       R#   + '       g   i     R# ; i  \
        ;_uu_ 4        X;P                  ^,          un        TP                  ^ 8X  d   \        P!                  TR4       RRR4       i   + '       g   i     i ; i; i)é   N)Úrefresh_token)ÚhashlibÚsha256ÚencodeÚdigestÚidÚ_guardr6   ÚtimeÚ	monotonicr   Ú
setdefaultr   r   r   r   ÚgetÚpopÚrefresh_sessionr   Ú_SUCCESS_TTLÚ_FAILURE_TTL)r8   r9   rA   r,   ÚflightÚcachedÚsessionr"   s   &&      r   Ú_refresh_providerrO   6   sB  € ô �^Š^˜EŸL™L›NÓ+×2Ñ2Ó4€FÜˆh‹<˜Ð
 €Cß	ŽÜŒt�~Š~ÓÔ Ü×$Ñ$ S¬'«)Ó4ˆØ�Š˜Õ�÷ 
ð(Ø�[�[‹[ß–ÜŸ™ C›�ØÒ%¨&°­)´d·n²nÓ6FÔ*FØ! !�9÷ ‘÷ ‰[÷  ŽVØ�LŠL˜AÕ�LØ�|‰|˜qÔ Ü—‘˜S $Ô'÷ ˆV÷ ðØ"×2Ñ2ÀÐ2ÓG�÷ –Ü—n’nÓ&�Ø"Ò6I¥lÌ|Õ\Ð^fÐp”�s‘Ü�s”÷ ð ÷ ‰[÷  ŽVØ�LŠL˜AÕ�LØ�|‰|˜qÔ Ü—‘˜S $Ô'÷ ˆV÷+ 
�ˆú÷* �Vú÷ —�ûô 'ô Ø“ðú÷ —ú÷ �Vú÷! �[úˆ[÷  ŽVØ�LŠL˜AÕ�LØ�|‰|˜qÔ Ü—‘˜S $Ô'÷ �V�VŠVû�VŽVØ�LŠL˜AÕ�LØ�|‰|˜qÔ Ü—‘˜S $Ô'÷ �V�VˆVýsÓ   ÁAIÂ-M	 ÃKÃAI:	Ä
KÄ
M	 Ä5AI'Å?KÆJÆKÆ(A J"	Ç(	KÇ1
M	 È	AJ5ÉI$	É'I7É:JÊ	KÊJÊKÊJÊKÊ"J2Ê-KÊ5KËK	ËM	 Ë*AL5Ì5M	Í	N5ÍAN"	Î	N5Î"N2Î-N5Úon_rejectedÚon_unreachablec               ó4   € V ^8„  d   QhRRRRRRRRRRR	RR
R/# )r!   r9   r:   Úprovider_hintÚphaseÚlogzlogging.LoggerrP   z1Optional[Callable[[DashboardAuthProvider], None]]rQ   r$   zOptional[tuple[Session, str]]r   )r&   s   "r   r'   r'   V   sR   € ÷ Sñ SØðSØ"ðSØ.1ðSØ8FðSàBðSð FðSð #ñ	Sr   c               ó6   a a€ R VV 3R llp\        WW#VR7      # )a�  Rotate ``token`` through the provider stack with per-provider single-flight.

``(Session, provider_name)`` or ``None`` when every provider rejects the token; a
``ProviderError`` propagates when nothing rotated and one provider was unreachable
(``scan_session_providers`` semantics, so callers keep their 503-not-relogin handling).
Synchronous and network-bound: async callers run it in a threadpool.
c               ó   € V ^8„  d   QhRR/# )r!   r8   r   r   )r&   s   "r   r'   Ú/refresh_session_coalesced.<locals>.__annotate__b   s   € ÷ &ñ &Ð-ñ &r   c                óZ   <€ \        V S4      pVf   Se	   S! V 4       R # WP                  3# )N)rO   Úname)r8   rN   rP   r9   s   & €€r   Ú_callÚ(refresh_session_coalesced.<locals>._callb   s2   ø€ Ü# H¨eÓ4ˆØŠ?ØÒ&Ù˜HÔ%ÙØŸ™Ð%Ð%r   )rT   rU   rQ   r
   )r9   rS   rT   rU   rP   rQ   r[   s   f&$$d$ r   Úrefresh_session_coalescedr]   V   s%   ù€ ÷&ñ &ô "Ø EÀ>ôSð Sr   ) Ú__conditional_annotations__Ú__doc__Ú
__future__r   r>   Úloggingr   rD   Údataclassesr   r   Útypingr   r   Úhermes_cli.dashboard_auth.baser   r   r	   Ú'hermes_cli.dashboard_auth.request_utilsr   rJ   rK   r2   r   rC   r   r   r   r   r6   rO   r]   )r^   s   @r   Ú<module>rf      s©   øðôõ #ã Û Û Û ß (ß %ç ^Ñ ^Ý Jð
 €Ø€Ø€Ø	�ŠÓ	€ð ÷ð ó ðð XZ€ÐTÓ YØ-/€Ð
*Ó /õ@õ(ð@SàEIðSð IM÷Sñ Sr   