ó
    ±�Èjd«  ã            	       óˆ  • S SK r S SKrS SKrS SKrS SKrS SKJr  S SKJrJrJ	r	  S SK
Jr  S SKrS SKrS SKJrJrJrJr  S SKJr  S SKrS SKrS SKJr  S SKJrJrJrJrJr  S	\S
\4S jr SWS\S
\4S jjr!\" \"5      r#\" 5       r$Sr%Sr&S\'S
\(4S jr)S\S
\(4S jr*S\S\+S
\(4S jr,S
\4S jr-S\S
\(4S jr.S\S
\(4S jr/S\S\4S jr0\Rb                  " S\Rd                  " 5       5      Rg                  S5      r4S\4S  jr5S!\64S" jr7S#r8S$\S%\4S& jr9S$\S%\S
S4S' jr:SXS$\S%\S(\(S
\4S) jjr;S$\S
S4S* jr<S+\6S
\4S, jr=S-r>S.r?S/r@SYS0\S1\S
\4S2 jjrAS3\4S4 jrBS5 rC\" \5      4S	\S$\4S6 jjrD\" \5      4S	\S$\4S7 jjrES	\4S8 jrFS9 rGS:\'S$\S
\(4S; jrHS<rIS=rJ\IS>\JS?0rK\IS@\JSA0rLS:\'S$\4SB jrMS:\'S$\S
\(4SC jrNS:\'S$\S
\(4SD jrOS:\'S$\S
\4SE jrPS
\(4SF jrQS:\'S
\(4SG jrRS:\'S$\S
\S4SH jrTS$\S
\S4SI jrUS$\S
\(4SJ jrVSK\SL\'S$\S
\(4SM jrWS	\4SN jrXSK\4SO jrYS:\'S$\S
\(4SP jrZS:\'S
\(4SQ jr[SRr\\\SS-   r]\]ST-   r^SU r_SZS$\SK\4SV jjr`g)[é    N)Údefaultdict)ÚdatetimeÚ	timedeltaÚtimezone)ÚLock)ÚDependsÚHTTPExceptionÚRequestÚstatus)ÚSession)Úget_db)Ú
SECRET_KEYÚ	ALGORITHMÚACCESS_TOKEN_EXPIRE_MINUTESÚALLOWED_EXTENSIONSÚ
PROXY_HOPSÚrequestÚreturnc                 óæ  • U R                   (       a  U R                   R                  OSn[        S::  a  U$ U R                  R	                  S5      nU(       d  U$ UR                  S5       Vs/ s H)  o3R                  5       (       d  M  UR                  5       PM+     nn[        U5      [        :  a  U$  [        [        R                  " U[        *    5      5      $ s  snf ! [         a    Us $ f = f)u‚  A valÃ³di kliens-IP-t adja vissza (bejelentkezÃ©s-vÃ©delem, naplÃ³k).

Ã‰lesben az alkalmazÃ¡s Apache reverse proxy mÃ¶gÃ¶tt fut, ezÃ©rt request.client.host a proxy sajÃ¡t
(loopback) cÃ­me. A kliens cÃ­mÃ©t az `X-Forwarded-For` (XFF) fejlÃ©cbÅ‘l olvassuk - DE NEM AZ ELSÅ�
bejegyzÃ©sbÅ‘l (2026-10-04 javÃ­tÃ¡s; korÃ¡bban az elsÅ‘ volt, Ã©s az hamisÃ­thatÃ³):

  A kliens maga is kÃ¼ldhet XFF-et ("X-Forwarded-For: 9.9.9.9"). A proxy ezt nem Ã­rja felÃ¼l, hanem
  HOZZÃ�FÅ°ZI az Ã¡ltala lÃ¡tott valÃ³di cÃ­met:  "9.9.9.9, <valÃ³di kliens>". Az elsÅ‘ elem tehÃ¡t a tÃ¡madÃ³
  Ã¡ltal vÃ¡lasztott Ã©rtÃ©k (Ã­gy kijÃ¡tszhatÃ³ az IP-korlÃ¡t, vagy egy mÃ¡sik cÃ©g IP-je kitiltathatÃ³), az
  UTOLSÃ“ viszont a megbÃ­zhatÃ³ proxy Ã¡ltal hozzÃ¡fÅ±zÃ¶tt, valÃ³di cÃ­m.

A megbÃ­zhatÃ³ proxyk szÃ¡mÃ¡t a PROXY_HOPS beÃ¡llÃ­tÃ¡s adja (config.py / .env, alapÃ©rtÃ©k 1 = egy Apache):
a jobbrÃ³l szÃ¡mÃ­tott PROXY_HOPS-adik bejegyzÃ©st hasznÃ¡ljuk. Ha PROXY_HOPS=0, a fejlÃ©cet figyelmen kÃ­vÃ¼l
hagyjuk (kÃ¶zvetlen kapcsolat, pl. helyi fejlesztÃ©s). Ha a fejlÃ©c hiÃ¡nyzik, rÃ¶videbb a vÃ¡rtnÃ¡l, vagy az
Ã©rtÃ©k nem Ã©rvÃ©nyes IP-cÃ­m, a kÃ¶zvetlen kapcsolat cÃ­mÃ©t (request.client.host) adjuk vissza - Ã­gy
hamisÃ­tott/hibÃ¡s fejlÃ©c sosem "talÃ¡lhat ki" Ãºj IP-t. FIGYELEM: az alkalmazÃ¡s portja nem Ã©rhetÅ‘ el
kÃ¶zvetlenÃ¼l kÃ­vÃ¼lrÅ‘l, csak a proxy-n Ã¡t (ez az architektÃºra). EllenÅ‘rzÃ©s: docs/LOGIN_VEDELEM.md 9.1.Ú
ismeretlenr   zx-forwarded-forÚ,)ÚclientÚhostr   ÚheadersÚgetÚsplitÚstripÚlenÚstrÚ	ipaddressÚ
ip_addressÚ
ValueError)r   Ú	kozvetlenÚ	forwardedÚeÚelemeks        Ú/var/www/website/security.pyÚget_client_ipr(      sÄ   € ð$ (/§~§~�—‘×#Ò#¸<€IÜ�QƒØÐØ—‘×#Ñ#Ð$5Ó6€IÞØÐØ!*§¡°Ô!5ÓCÒ!5˜A¿¹¿‹iˆa�g‰gŽiÑ!5€FÐCÜ
ˆ6ƒ{”ZÓØÐðÜ”9×'Ò'¨´
¨{Ñ(;Ó<Ó=Ð=ùò	 Døô
 ó ØÒðús   Á-CÂ	CÂ5&C! Ã!C0Ã/C0Úalapc                 ó  • [        U [        5      (       d  U$ U R                  S5      S   R                  S5      S   n U R                  S5      (       a  U R                  S5      (       d  SU ;   a  U$ [	        S U  5       5      (       a  U$ U $ )u”  Egy felhasznÃ¡lÃ³tÃ³l Ã©rkezÅ‘ "next" (visszairÃ¡nyÃ­tÃ¡si) cÃ©l tisztÃ­tÃ¡sa - NYÃ�LT Ã�TIRÃ�NYÃ�TÃ�S ellen.

Csak a SAJÃ�T oldalon belÃ¼li, abszolÃºt Ãºtvonalat ("/valami/oldal") engedi Ã¡t, query-string Ã©s
fragment nÃ©lkÃ¼l. Minden mÃ¡s az `alap`-ra (alapbÃ³l a fÅ‘oldal) cserÃ©lÅ‘dik:
  * "//evil.hu" Ã©s "/\evil.hu" - a bÃ¶ngÃ©szÅ‘ ezeket protokoll-relatÃ­v / kÃ¼lsÅ‘ cÃ­mnek Ã©rtelmezi,
  * "https://evil.hu", "javascript:..." - nem "/"-jellel kezdÅ‘dik,
  * vezÃ©rlÅ‘karakterek (sortÃ¶rÃ©s, tabulÃ¡tor) - fejlÃ©c-injektÃ¡lÃ¡s Ã©s bÃ¶ngÃ©szÅ‘-trÃ¼kkÃ¶k ellen.
(KorÃ¡bban a valaszt_ceget() csak a "?" utÃ¡ni rÃ©szt vÃ¡gta le, Ã­gy a "//evil.hu" Ã¡tment.)Ú?r   Ú#Ú/z//Ú\c              3   óh   #   • U  H(  n[        U5      S :  =(       d    [        U5      S:H  v •  M*     g7f)é    é   N)Úord)Ú.0Úcs     r'   Ú	<genexpr>Ú*biztonsagos_atiranyitas.<locals>.<genexpr>D   s(   é € Ð
5²¨AŒ3ˆq‹6�B‰;×'œ#˜a›& C™-Ô'²ùs   ‚02)Ú
isinstancer   r   Ú
startswithÚany)Úcelr)   s     r'   Úbiztonsagos_atiranyitasr;   6   s{   € ô �cœ3×ÑØˆØ
�)‰)�C‹.˜Ñ
×
!Ñ
! #Ó
& qÑ
)€CØ�>‰>˜#×Ñ #§.¡.°×"6Ñ"6¸$À#»+ØˆÜ
Ñ
5±Ó
5×5Ñ5ØˆØ€Jó    i,  é
   Úuser_idc                 ó8  • [         R                   " 5       nSU  3n[           [        U   nU Vs/ s H  oAU-
  [        :  d  M  UPM     snUSS& [	        U5      [
        :¼  a
   SSS5        gUR                  U5        SSS5        gs  snf ! , (       d  f       g= f)ux  True, ha ez a felhasznÃ¡lÃ³ az utolsÃ³ 5 percben mÃ¡r elÃ©rte a megengedett AI-szkennelÃ©s
szÃ¡mot - ilyenkor a hÃ­vÃ³ fÃ©lnek EZT a kÃ©rÃ©st el kell utasÃ­tania, API-hÃ­vÃ¡s nÃ©lkÃ¼l. Ha False-
szal tÃ©r vissza, a kÃ©rÃ©st egyÃºttal rÃ¶gzÃ­ti is (a szÃ¡mlÃ¡lÃ³ba beleszÃ¡mÃ­t), ezÃ©rt hÃ­vÃ³nkÃ©nt
(sikertÅ‘l fÃ¼ggetlenÃ¼l) csak egyszer szabad meghÃ­vni egy adott kÃ©rÃ©shez.zuser:NTF)ÚtimeÚ_ai_szkenneles_lockÚ_ai_szkenneles_kiserletekÚ_AI_SZKENNELES_ABLAK_MASODPERCr   Ú _AI_SZKENNELES_MAX_KISERLET_USERÚappend)r>   ÚmostÚkulcsÚlistaÚts        r'   Úai_szkenneles_rate_limitalva_erJ   \   sŽ   € ô
 �9Š9‹;€DØ�G�9Ð€EÞ	Ü)¨%Ñ0ˆÙ$ÓRšu˜!¨q©Ô3QÑ(Q—A™uÑRˆ‰aˆÜˆu‹:Ô9Ó9Ø÷	 
Ð	ð
 	�‰�TÔ÷ 
ð ùò	 S÷ 
Ô	ð ús(   ¡B¯BÁBÁ	BÁ,BÂBÂ
BÚfilenamec                 óF   ^ • T (       d  g[        U 4S j[         5       5      $ )uD   EllenÅ‘rzi, hogy a fÃ¡jl kiterjesztÃ©se rajta van-e a fehÃ©rlistÃ¡n.Fc              3   ób   >#   • U  H$  nTR                  5       R                  U5      v •  M&     g 7f©N)ÚlowerÚendswith)r3   ÚextrK   s     €r'   r5   Ú$is_safe_extension.<locals>.<genexpr>p   s(   øé € ÐLÒ9K°#ˆx�~‰~Ó×(Ñ(¨×-Ð-Ò9Kùs   ƒ,/)r9   r   )rK   s   `r'   Úis_safe_extensionrS   l   s   ø€ æØÜÔLÕ9KÓLÓLÐLr<   Úfejreszc                 ó¤   • U (       a  SU ;  a  gSU R                  SS5      S   R                  5       -   nUS:X  a  USS S:H  $ US	;   a  USS
 S;   $ g)u4  Alap tartalom-ellenÅ‘rzÃ©s (fÃ¡jl-alÃ¡Ã­rÃ¡s/"magic byte") a PDF/DOCX/XLSX feltÃ¶ltÃ©sekhez -
2026-09-24-i kÃ¼lsÅ‘ biztonsÃ¡gi audit talÃ¡lata szerint eddig csak a fÃ¡jlnÃ©v kiterjesztÃ©sÃ©t
nÃ©ztÃ¼k (is_safe_extension), a tÃ©nyleges tartalmat nem, Ã­gy egy "PDF"-nek lÃ¡tszÃ³ fÃ¡jl bÃ¡rmi
lehetett. Nem helyettesÃ­ti a teljes formÃ¡tum-validÃ¡ciÃ³t (egy sÃ©rÃ¼lt, de helyes fejlÃ©cÅ± PDF-et
is Ã¡tenged), de a legdurvÃ¡bb Ã¡lcÃ¡zÃ¡st (tetszÅ‘leges binÃ¡ris tartalom PDF/DOCX/XLSX nÃ©ven)
kizÃ¡rja. A `fejresz` elÃ©g, ha a fÃ¡jl elsÅ‘ nÃ©hÃ¡ny (pl. 8) bÃ¡jtja - a hÃ­vÃ³nak nem kell a teljes
tartalmat memÃ³riÃ¡ba olvasnia csak emiatt, bÃ¡r a jelenlegi feltÃ¶ltÅ‘ vÃ©gpontok Ãºgyis beolvassÃ¡k.
KÃ©p-kiterjesztÃ©seknÃ©l nincs dolga (azokat a tomorit_kepet() PIL-alapÃº tartalmi ellenÅ‘rzÃ©se
vÃ©di) - ilyenkor True-t ad.Ú.Fé   éÿÿÿÿz.pdfNé   s   %PDF-)z.docxz.xlsxé   )s   PKs   PKs   PKT)ÚrsplitrO   )rK   rT   Úkiterjesztess      r'   Ú%tartalom_illeszkedik_e_kiterjesztesrer]   s   sm   € ö �s (Ó*ØØ˜Ÿ™¨¨aÓ0°Ñ4×:Ñ:Ó<Ñ<€LØ�vÓØ�r˜ˆ{˜hÑ&Ð&ØÐ)Ó)ð �r˜ˆ{ÐKÑKÐKØr<   c                 óŽ   • [         R                  " U 5      R                  SS5      R                  SS5      R                  SS5      $ )u_   JSON szerializÃ¡ciÃ³ <script> tagbe Ã¡gyazÃ¡shoz: megakadÃ¡lyozza a </script> kitÃ¶rÃ©st (XSS).Ú<z\u003cÚ>z\u003eÚ&z\u0026)ÚjsonÚdumpsÚreplace)Údatas    r'   Úsafe_json_for_scriptrf   ‰   s9   € ô 	�
Š
�4Óß	‰��iÓ	 ß	‰��iÓ	 ß	‰��iÓ	 ð	r<   Újelszoc                 óp   • [        U 5      =(       a%    [        U 5      S:¬  =(       a    [        U 5      (       + $ )uÙ  MinimÃ¡lis szerver-oldali jelszÃ³erÅ‘ssÃ©g-ellenÅ‘rzÃ©s. A jelszÃ³mezÅ‘k HTML `minlength="6"`-ja
eddig csak kliensoldali volt (Burp/curl-lal, vagy egy kÃ¶zvetlen POST-tal megkerÃ¼lhetÅ‘) - ez
a fÃ¼ggvÃ©ny minden jelszÃ³t beÃ¡llÃ­tÃ³/mÃ³dosÃ­tÃ³ vÃ©gponton meghÃ­vva zÃ¡rja be ezt a rÃ©st. Csak a
hosszt nÃ©zi (nem kÃ©nyszerÃ­t ki kis/nagybetÅ± vagy szÃ¡m kombinÃ¡ciÃ³t), hogy a meglÃ©vÅ‘
felhasznÃ¡lÃ³i elvÃ¡rÃ¡sokkal (Ã©s a kliensoldali szabÃ¡llyal) Ã¶sszhangban maradjon.é   )Úboolr   Újelszo_tul_hosszu_e©rg   s    r'   Újelszo_eleg_eros_erm   “   s*   € ô �‹<×PœC ›K¨1Ñ,×PÔ5HÈÓ5PÔ1PÐPr<   c                 óN   • [        U =(       d    SR                  S5      5      S:„  $ )u=  A bcrypt (5.x) 72 bÃ¡jtnÃ¡l hosszabb jelszÃ³ra ValueError-t dob (nem csonkÃ­t) - ez eddig egy kezeletlen
500-as hibÃ¡t okozott pl. egy hosszÃº, Ã©kezetes jelszÃ³-mondat vagy jelszÃ³kezelÅ‘ Ã¡ltal generÃ¡lt jelszÃ³
megadÃ¡sakor. Most 400-as hibaÃ¼zenet lesz belÅ‘le. A bÃ¡jthossz szÃ¡mÃ­t (az Ã©kezetes betÅ± 2 bÃ¡jt).Ú úutf-8éH   )r   Úencoderl   s    r'   rk   rk   œ   s#   € ô �—˜"×$Ñ$ WÓ-Ó.°Ñ3Ð3r<   Úplain_passwordÚhashed_passwordc                 ól   • [         R                  " U R                  S5      UR                  S5      5      $ ©Nrp   )ÚbcryptÚcheckpwrr   )rs   rt   s     r'   Úverify_passwordry   £   s/   € Ü�>Š>Ø×Ñ˜gÓ&Ø×Ñ˜wÓ'óð r<   s   idozites-vedelmi-dummy-jelszorp   Úpasswordc                 ó’   • [         R                  " U R                  S5      [         R                  " 5       5      R	                  S5      $ rv   )rw   Úhashpwrr   ÚgensaltÚdecode)rz   s    r'   Úget_password_hashr   ³   s4   € Ü�=Š=Ø�‰˜Ó Ü�ŠÓó÷ �fˆWƒoðr<   re   c                 ó  • U R                  5       n[        R                  " [        R                  5      nU[        [        S9-   nUR                  X2R                  5       S.5        [        R                  " U[        [        S9nU$ )N©Úminutes)ÚexpÚiat©Ú	algorithm)Úcopyr   Únowr   Úutcr   r   ÚupdateÚ	timestampÚjwtrr   r   r   )re   Ú	to_encoderF   Úexpire_timeÚencoded_jwts        r'   Úcreate_access_tokenr�   º   sa   € Ø—	‘	“€IÜ�<Š<œŸ™Ó%€DØœÔ+FÑGÑG€Kð
 ×Ñ˜[·±Ó1AÑBÔCÜ—*’*˜Y¬
¼iÑH€KØÐr<   zE-LIC-01ÚdbÚipc                 ó~  • [        U5      (       a  g[        R                  " [        R                  5      R                  SS9nUR                  UR                  UR                  pen[        R                  " S5      nXql        X1l        U=(       d    SSS Ul        U(       a‹  U(       a„  Xc[        [        S9-
  :”  aq  U R                  [        R                  " UR                   UR"                  SSS	[$         S
U SU=(       d    S SUR'                  S5       S3	S95        [)        XX%U5        U R+                  5         U$ )u
  Ãšj munkamenetet indÃ­t a felhasznÃ¡lÃ³nak: Ãºj vÃ©letlen azonosÃ­tÃ³t Ã­r a felhasznÃ¡lÃ³ sorÃ¡ba (ezzel a korÃ¡bbi munkamenet tokenje
azonnal Ã©rvÃ©nytelen lesz), Ã©s visszaadja azt a JWT-be Ã­randÃ³ `sid`-et. A rendszeradminisztrÃ¡tornak None-t ad (neki nincs
korlÃ¡tja, Ã©s a meglÃ©vÅ‘ munkameneteit sem Ã©rinti). Ha a korÃ¡bbi munkamenet mÃ©g Ã©rvÃ©nyes lett volna (a token Ã©lettartamÃ¡n belÃ¼l
indult), a JogosultsÃ¡gi naplÃ³ba bejegyzÃ©st teszÃ¼nk: ez a bizonyÃ­tÃ©k, ha egy fiÃ³kot tÃ¶bb ember hasznÃ¡l. COMMITOL.N©Útzinfoé   ro   é@   r�   u   BejelentkezÃ©sÚ-u   EgyidejÅ± belÃ©pÃ©s (u   ): az Ãºj belÃ©pÃ©s (u:   ) megszÃ¼ntette a korÃ¡bbi, mÃ©g Ã©rvÃ©nyes munkamenetet (r+   ú
, indult: ú%Y-%m-%d %H:%Mz UTC))Ú
company_idr>   Ú
field_nameÚ	old_valueÚ	new_value)Úis_rendszeradminisztratorr   rˆ   r   r‰   rd   Úaktiv_munkamenetÚmunkamenet_ipÚmunkamenet_kezdete_atÚsecretsÚ	token_hexr   r   ÚaddÚmodelsÚAuditLogr›   ÚidÚHIBAKOD_SZIMULTANÚstrftimeÚszimultan_belepes_ertesitesÚcommit)r‘   Úuserr’   rF   Úregi_sidÚregi_ipÚregi_kezdetÚsids           r'   Úmunkamenet_inditasar²   Ï   s  € ô
 ! ×&Ñ&ØÜ�<Š<œŸ™Ó%×-Ñ-°TÐ-Ð:€DØ%)×%:Ñ%:¸D×<NÑ<NÐPT×PjÑPj�{€HÜ
×
Ò
˜BÓ
€CØÔØ!%ÔØŸ(  C R˜€DÔÞ–K K¼ÔKfÑ9gÑ2gÓ$gØ
�‰Œv�ŠØ—‘Ø—G‘GØ'ØØ.Ô/@Ð.AÐAVÐWYÐVZð [Ø"Ÿ> cÐ*¨*°[×5IÑ5IÐJZÓ5[Ð4\Ð\aðcñ
ô 	ô 	$ B¨b¸;ÔGØ‡I�I„KØ€Jr<   c                 óÄ  ^•  SSK mSSKnSSKnSSKnSSKJn  SSKJn	  UR                  U 5      (       d  gUR                  U 5      n
U
(       d  g[        R                  " U	5      R                  5       nUR                  U SUR                   3UR                  SU5      (       d  gU4S jnUR                  (       a*  U R!                  ["        R$                  UR                  5      OSnUR'                  U 5      R(                  R+                  S5      S	-   nU(       a;  UR-                  [.        R0                  S
9R3                  U	5      R5                  S5      OSnSU" U[6           5       SU" [6        5       SU" UR8                  5       SU" UR:                  5       Ub  SU" UR<                  5      -   OS SU" U5       SU" U=(       d    S5       SU" U5       SU" U5       S3nUR?                  U
[6         SU[6            3USUR@                  UR                  U S9  g! [B         a5  n[E        S[6         S[G        U5      RH                   SU 35         SnAgSnAff = f)uÃ  E-LIC-01: levÃ©l a rendszeradminisztrÃ¡toroknak, hogy egy fiÃ³kot egyidejÅ±leg kÃ©t helyrÅ‘l hasznÃ¡ltak (licenckorlÃ¡t Ã¡tlÃ©pÃ©se).
OPCIONÃ�LIS: csak akkor megy, ha a rendszeradmin bekapcsolta (email_sor.szimultan_ertesites_be_van; alapbÃ³l KI) - a JogosultsÃ¡gi
naplÃ³ba a szimultÃ¡n belÃ©pÃ©s a kapcsolÃ³tÃ³l fÃ¼ggetlenÃ¼l MINDIG bekerÃ¼l (l. munkamenet_inditasa).
Ã�RVÃ�Z-VÃ‰DELEM: ha kÃ©t ember percenkÃ©nt kidobja egymÃ¡st, az nem jelenthet percenkÃ©nt levelet - fiÃ³konkÃ©nt NAPONTA EGY levÃ©l megy
(a tovÃ¡bbi esetek a JogosultsÃ¡gi naplÃ³ban lÃ¡tszanak). A hiba SOHA nem akaszthatja meg a belÃ©pÃ©st: itt minden kivÃ©tel elnyelÅ‘dik.
NEM commitol (a hÃ­vÃ³ commitol a naplÃ³bejegyzÃ©ssel egyÃ¼tt).r   N)Ú	HIBAKODOK)ÚHELYI_TZz
szimultan:rW   c                 óF   >• TR                  U c  SSS9$ [        U 5      SS9$ )Nro   T)Úquote)Úescaper   )ÚxÚhtmls    €r'   Ú<lambda>Ú-szimultan_belepes_ertesites.<locals>.<lambda>  s#   ø€ �t—{‘{¨© 2Àd�{ÑK¼¸A»Àd�{ÑKr<   r-   z/felhasznalokr”   rš   r+   z<p><b>u   </b> (HibakÃ³d: z)</p><p>A(z) <b>u   </b> fiÃ³kot (z, ro   u=   ) egyidejÅ±leg kÃ©t helyrÅ‘l hasznÃ¡ltÃ¡k: az Ãºj belÃ©pÃ©s (u4   ) kidobta a korÃ¡bbi, mÃ©g Ã©rvÃ©nyes munkamenetet (r™   uG   helyi idÅ‘).</p><p>Egy fiÃ³k egyszerre csak egy helyen hasznÃ¡lhatÃ³; a gyakori ismÃ©tlÅ‘dÃ©s arra utalhat, hogy a cÃ©g a fiÃ³kot tÃ¶bb szemÃ©ly kÃ¶zÃ¶tt osztja meg (licenckorlÃ¡t Ã¡tlÃ©pÃ©se). FiÃ³konkÃ©nt naponta legfeljebb egy ilyen levelet kÃ¼ldÃ¼nk; a tovÃ¡bbi esetek a JogosultsÃ¡gi naplÃ³ban lÃ¡thatÃ³k.</p><p><a href="u   ">FelhasznÃ¡lÃ³k</a></p>z: Úrendszer)Ú	kategoriaÚ	prioritasr›   r‘   u   â�Œ u    Ã©rtesÃ­tÃ©s sikertelen: )%rº   Úemail_beallitasokÚ	email_sorÚlogin_vedelemÚ	hibakodokr´   Útemplates_envrµ   Úszimultan_ertesites_be_vanÚrendszeradmin_cimekr   rˆ   ÚdateÚkikuldheto_e_es_rogzitr¨   r›   r   r¦   ÚCompanyÚbetoltÚalkalmazas_url_vagy_alapÚrstriprd   r   r‰   Ú
astimezonerª   r©   ÚemailÚusernameÚnevÚsorba_allitÚPRIORITAS_SURGOSÚ	ExceptionÚprintÚtypeÚ__name__)r‘   r­   r’   r¯   r°   rÀ   rÁ   rÂ   r´   rµ   ÚcimekÚmaÚ_eÚcegÚlinkÚregiÚtorzsr%   rº   s                     @r'   r«   r«   ê   sJ  ø€ ð [ÛÛ ÛÛÝ'Ý*à×3Ñ3°B×7Ñ7ØØ×1Ñ1°"Ó5ˆÞØÜ�\Š\˜(Ó#×(Ñ(Ó*ˆØ×/Ñ/°°jÀÇÁÀ	Ð4JÈDÏOÉOÐ]^Ð`b×cÑcØÜKˆØ9=¿¿ˆb�f‰f”V—^‘^ T§_¡_Ô5ÈdˆØ ×'Ñ'¨Ó+×DÑD×KÑKÈCÓPÐSbÑbˆÞkvˆ{×"Ñ"¬(¯,©,Ð"Ð7×BÑBÀ8ÓL×UÑUÐVfÔgÐ|ˆà‘R˜	Ô"3Ñ4Ó5Ð6Ð6FÁrÔJ[ÓG\ÐF]ð ^Ù˜TŸZ™Z›.Ð)¨¹¸4¿=¹=Ó8IÐ7JØ%(¡_ˆt‘b˜Ÿ™“kÒ!¸"Ð=ð >!Ù!# B£ Ð(\Ñ]_Ð`g×`nÐknÓ]oÐ\pÐpzÑ{}ð  Có  |Dð  {Eð Eñ ˜t›H˜:Ð%>ð@ð 	ð 	×Ñ˜eÔ(9Ð':¸"¸YÔGXÑ=YÐ<ZÐ%[Ð]bÐnxØ(1×(BÑ(BÈtÏÉÐceð 	ò 	gøäó [Ü�Ô&Ð'Ð'AÄ$ÀqÃ'×BRÑBRÐASÐSUÐVWÐUXÐY×ZÑZûð[ús*   ƒ2H  ¶H  ÁAH  Â%E:H  È 
IÈ*+IÉIÚmfac                 óz   • SUR                   0nU(       a  SUS'   [        XU5      nU(       a  XTS'   [        U5      $ )uö   A TELJES munkamenet tokenje belÃ©pÃ©s utÃ¡n (jelszÃ³ vagy 2FA-kÃ³d elfogadÃ¡sa utÃ¡n): Ãºj munkamenetet indÃ­t, Ã©s sid-del adja ki.
Minden belÃ©pÃ©si pont ezt hasznÃ¡lja (routers/auth.py, routers/mfa.py), hogy a korlÃ¡t ne legyen megkerÃ¼lhetÅ‘.ÚsubTrÞ   r±   )rÎ   r²   r�   )r‘   r­   r’   rÞ   Úadatr±   s         r'   Úbelepesi_tokenrâ     s?   € ð �4—:‘:Ð€DÞ
ØˆˆU‰Ü
˜b¨Ó
+€CÞ
ØˆU‰Ü˜tÓ$Ð$r<   c                 óP   • [        U5      (       a  gSUl        SUl        SUl        g)uý   KilÃ©pÃ©skor: a felhasznÃ¡lÃ³ munkamenet-azonosÃ­tÃ³ja tÃ¶rlÅ‘dik, Ã­gy a (esetleg mÃ¡shovÃ¡ Ã¡tmÃ¡solt) token sem hasznÃ¡lhatÃ³ tovÃ¡bb.
A rendszeradminisztrÃ¡tornak nincs mit tÃ¶rÃ¶lni. COMMITOL (a hÃ­vÃ³ commitoljon, ha a naplÃ³bejegyzÃ©st is Ã­rja).N)rŸ   r    r¢   r¡   )r‘   r­   s     r'   Úmunkamenet_megszunteteserä      s*   € ô ! ×&Ñ&ØØ €DÔØ!%€DÔØ€DÕr<   Úpayloadc                 óÚ   • [        U 5      (       a  gUR                  S5      nU(       a  U R                  (       d  g[        R                  " [        U5      U R                  5      (       a  gg)ut  A token munkamenet-azonosÃ­tÃ³jÃ¡t veti Ã¶ssze a felhasznÃ¡lÃ³ sorÃ¡Ã©val. VisszatÃ©r: "ok" (Ã©rvÃ©nyes, vagy a rendszeradminra nem
vonatkozik), "masik_helyen" (a tokennek van sid-je, de azÃ³ta mÃ¡shol lÃ©ptek be: ez a kidobÃ¡s), "lejart" (nincs sid vagy nincs
Ã©rvÃ©nyes munkamenet: pl. a bevezetÃ©s elÅ‘tt kiadott token, vagy kilÃ©pÃ©s utÃ¡n). A hÃ­vÃ³ dÃ¶nt, mit mutat.Úokr±   ÚlejartÚmasik_helyen)rŸ   r   r    r£   Úcompare_digestr   )r­   rå   Ú	token_sids      r'   Úmunkamenet_ervenyes_erì   *  sQ   € ô ! ×&Ñ&ØØ—‘˜EÓ"€IÞ˜D×1×1ØÜ×Òœc )›n¨d×.CÑ.C×DÑDØØr<   Úmfa_pendingrY   é   rÎ   r:   c           
      óä   • [         R                  " [        R                  5      nUS:X  a  [        O[
        n[        R                  " U SX[        US9-   UR                  5       S.[        [        S9$ )uð   Az Ã¡tmeneti token. `cel`: "kod" (a belÃ©pÃ©shez kÃ³dot kÃ©rÃ¼nk) vagy "beallitas" (a felhasznÃ¡lÃ³nak mÃ©g nincs
2FA-beÃ¡llÃ­tÃ¡sa: a QR-oldalra irÃ¡nyÃ­tjuk, 3. fÃ¡zis). A kÃ©t cÃ©l kÃ¼lÃ¶n vÃ©gpontokhoz tartozik, egymÃ¡s helyett nem jÃ³.Ú	beallitasrí   r�   )rà   Útypr:   rƒ   r„   r…   )r   rˆ   r   r‰   ÚMFA_BEALLITAS_PERCÚMFA_PENDING_PERCrŒ   rr   r   r‹   r   r   )rÎ   r:   rF   Úpercs       r'   Úcreate_mfa_pending_tokenrõ   B  s]   € ô �<Š<œŸ™Ó%€DØ!$¨Ó!3ÕÔ9I€DÜ�:Š:Ø˜m°CÄyÐY]ÑG^Ñ@^Ðgk×guÑguÓgwÑxÜœiñ)ð )r<   Útokenc                 ó¤   • U (       d  g [         R                  " U [        [        /S9nUR                  S5      S:X  a  U$ S$ ! [         a     gf = f)u^   Az Ã¡tmeneti token tartalma, vagy None (hiÃ¡nyzik / lejÃ¡rt / hamis / nem Ã¡tmeneti tÃ­pusÃº).N©Ú
algorithmsrñ   rí   )rŒ   r~   r   r   rÓ   r   )rö   rå   s     r'   Údecode_mfa_pending_tokenrú   L  sR   € æØðÜ—*’*˜U¤J¼I¸;ÑGˆð —k‘k %Ó(¨MÓ9ˆ7ÐC¸tÐCøô ó Ùðús   ŠA Á
AÁAc                 óZ   • U R                  SS5      n[        R                  " SSU5      nU$ )u.   KiberbiztonsÃ¡gi vÃ©delem Path Traversal ellenÚ Ú_z[^a-zA-Z0-9_\-\.]ro   )rd   Úrerà   )rK   Ú
tiszta_nevÚbiztonsagos_nevs      r'   Úsanitize_filenamer  W  s-   € à×!Ñ! # sÓ+€JÜ—f’fÐ1°2°zÓB€OØÐr<   c                 ó¬  • U R                   R                  S5      nU(       d  [        [        R                  SS0S9e [
        R                  " U[        [        /S9nUR                  S5      nUR                  S5      b  [        [        R                  SS0S9eUR                  [        R                  5      R                  [        R                  R                  U:H  5      R                  5       nU(       a   UR                  (       a  UR                   SL a  [        [        R                  SS0S9eUR"                  bl  UR                  S	5      nUb>  [$        R&                  " U[(        R*                  S
9R-                  S S9UR"                  :  a  [        [        R                  SS0S9eUR                  S5      (       d4  [.        R0                  " XSS9(       a  [        [        R                  SS0S9e[3        XS5      nUS:X  a!  [        [        R                  SS[4         30S9eUS:w  a  [        [        R                  SS0S9eUR6                  bN  U R8                  R:                  S;  a4  SS KnUR?                  X5      (       a  [        [        R                  SS0S9eU$ ! [         a    e [@         a    [        [        R                  SS0S9ef = f)NÚaccess_tokenÚLocationz/login©Ústatus_coder   rø   rà   rñ   Fr„   )Útzr”   rÞ   T©Úgyorsitotarré   z/login?hibakod=rç   )z/profilz/sajat-jelszo-cserer   z/profil?jelszo=lejart#jelszo)!Úcookiesr   r	   r   ÚHTTP_303_SEE_OTHERrŒ   r~   r   r   Úqueryr¦   ÚUserÚfilterrÎ   ÚfirstÚaktivÚ	aktivalvaÚjelszo_valtozott_atr   Úfromtimestampr   r‰   rd   Ú	mfa_utilsÚszukseges_erì   r©   Újelszo_lejarat_atÚurlÚpathÚjelszo_hazirendÚkenyszeritett_csere_erÓ   )	r   r‘   rö   rå   rÎ   r­   r„   Ú
munkamenetr  s	            r'   Úget_current_userr  ^  s˜  € Ø�O‰O×Ñ Ó/€EÞÜÜ×1Ñ1Ø Ð*ñ
ð 	
ð
O
Ü—*’*˜U¤J¼I¸;ÑGˆØ—‘˜EÓ"ˆð �;‰;�uÓÑ)ÜÜ"×5Ñ5Ø# XÐ.ñð ð
 �x‰xœŸ™Ó$×+Ñ+¬F¯K©K×,=Ñ,=ÀÑ,FÓG×MÑMÓOˆæ˜4Ÿ:Ÿ:¨¯©¸5Ò)@ÜÜ"×5Ñ5Ø# XÐ.ñð ð ×#Ñ#Ñ/Ø—+‘+˜eÓ$ˆCØ‰{œh×4Ò4°S¼X¿\¹\ÑJ×RÑRÐZ^ÐRÐ_Ðbf×bzÑbzÓzÜ#Ü &× 9Ñ 9Ø'¨Ð2ñð ð �{‰{˜5×!Ñ!¤i×&;Ò&;¸BÐRV×&WÜÜ"×5Ñ5Ø# XÐ.ñð ô +¨4Ó9ˆ
Ø˜Ó'ÜÜ"×5Ñ5Ø# Ô7HÐ6IÐ%JÐKñð ð ˜ÓÜÜ"×5Ñ5Ø# XÐ.ñð ð ×!Ñ!Ñ-°'·+±+×2BÑ2BÐJlÓ2lÛ"Ø×4Ñ4°R×>Ñ>Ü#Ü &× 9Ñ 9Ø'Ð)GÐHñð ð
 ˆøäó ØÜó 
ÜÜ×1Ñ1Ø Ð*ñ
ð 	
ð
ús   ¾I%J$ Ê$/Kc                 ót  • U R                   R                  S5      nU(       d  g [        R                  " U[        [
        /S9nUR                  S5      b  gUR                  S5      nUR                  [        R                  5      R                  [        R                  R                  U:H  5      R                  5       nU(       a   UR                  (       a  UR                  SL a  gUR                  S5      (       d  [        R                  " XSS	9(       a  g[!        XS5      S
:w  a  gU$ ! ["         a     gf = f)uv  Mint a get_current_user, de sosem dob kivÃ©telt/irÃ¡nyÃ­t Ã¡t - None-t ad vissza, ha nincs
Ã©rvÃ©nyes bejelentkezÃ©s. KizÃ¡rÃ³lag olyan nyilvÃ¡nos oldalaknÃ¡l hasznÃ¡landÃ³ (pl. a "/" alatti
marketing kezdÅ‘lap), ahol a bejelentkezett Ã©s a bejelentkezetlen lÃ¡togatÃ³nak is mÃ¡s tartalom
jÃ¡r, tehÃ¡t a hiÃ¡nyzÃ³ bejelentkezÃ©s nem hiba, hanem az egyik Ã©rvÃ©nyes Ã¡llapot.r  Nrø   rñ   rà   FrÞ   Tr  rç   )r
  r   rŒ   r~   r   r   r  r¦   r  r  rÎ   r  r  r  r  r  rì   rÓ   )r   r‘   rö   rå   rÎ   r­   s         r'   Úget_current_user_optionalr  ¸  sì   € ð
 �O‰O×Ñ Ó/€EÞØðÜ—*’*˜U¤J¼I¸;ÑGˆØ�;‰;�uÓÑ)ØØ—‘˜EÓ"ˆØ�x‰xœŸ™Ó$×+Ñ+¬F¯K©K×,=Ñ,=ÀÑ,FÓG×MÑMÓOˆÞ˜4Ÿ:Ÿ:¨¯©¸5Ò)@ØØ�{‰{˜5×!Ñ!¤i×&;Ò&;¸BÐRV×&WØÜ  Ó/°4Ó7ØØˆøÜó Ùðús*   ¥1D* ÁBD* Ã'0D* ÄD* Ä(D* Ä*
D7Ä6D7c                 ó\  ^ • T R                   S;   a€  S[        4U 4S jjnUR                  R                  S5      nU(       a   [	        U5      nU" U5      (       a  U$  T R                  (       a#  U" T R                  5      (       a  T R                  $ T R                  $ ! [
         a     NLf = f)uè  Szuper-Admin Ã©s KÃ¼lsÅ‘s SzakÃ©rtÅ‘ funkciÃ³: EllenÅ‘rzi Ã©s kezeli az aktÃ­v cÃ©gkÃ¶rnyezetet.
ElsÅ‘kÃ©nt a biztonsÃ¡gos Cookie-bÃ³l olvassuk ki (ha a bÃ¶ngÃ©szÅ‘ben friss a vÃ¡ltÃ¡s), ennek
hiÃ¡nyÃ¡ban a felhasznÃ¡lÃ³hoz tartÃ³san (adatbÃ¡zisban) mentett legutÃ³bbi cÃ©gvÃ¡lasztÃ¡sra esÃ¼nk
vissza - Ã­gy Ãºj bejelentkezÃ©s utÃ¡n vagy mÃ¡s eszkÃ¶zÃ¶n is automatikusan a legutÃ³bb tÃ©nylegesen
hasznÃ¡lt cÃ©get mutatja a rendszer, nem mindig a felhasznÃ¡lÃ³ sajÃ¡t (company_id) cÃ©gÃ©t.©ÚAdminõ   EmelÅ‘gÃ©p szakÃ©rtÅ‘õ   EmelÅ‘gÃ©p vizsgÃ¡lÃ³õ   EmelÅ‘gÃ©p Ã¼gyintÃ©zÅ‘u   KarbantartÃ³r   c                 ó¼   >• [        T5      nU TR                   Vs/ s H  o"R                  PM     sn;   nU TR                  :H  nU=(       d    U=(       d    U$ s  snf rN   )rŸ   Úallowed_companiesr¨   r›   )Úview_idÚis_adminr4   Úis_allowed_companyÚis_own_companyÚcurrent_users        €r'   Ú_valaszthato_eÚ.get_working_company_id.<locals>._valaszthato_eÙ  sZ   ø€ ô 1°Ó>ˆHØ")¸L×<ZÒ<ZÓ-[Ò<Z°q¯d¬dÑ<ZÑ-[Ñ"[ÐØ%¨×)@Ñ)@Ñ@ˆNØ×CÐ1×C°^ÐCùò .\s   œAÚworkspace_id)Úrolerj   r
  r   Úintr"   Úutolso_ceg_idr›   )r+  r   r,  r.  r'  s   `    r'   Úget_working_company_idr2  Ò  s¬   ø€ ð ×Ñð  Có  Cð	D¤t÷ 	Dð —‘×*Ñ*¨>Ó:ˆÞðÜ˜lÓ+�Ù! '×*Ñ*Ø"�Nð +ð
 ×%×%©.¸×9SÑ9S×*TÑ*TØ×-Ñ-Ð-à×"Ñ"Ð"øô ó Ùðús   ÁB Â
B+Â*B+c                 ó
  • UR                   S;   a  U $ UR                  S:X  ah  / nUR                   H  nUR                  UR                  5        M      U R                  [        R                  R                  R                  U5      5      $ UR                  S:X  ah  / nUR                   H  nUR                  UR                  5        M      U R                  [        R                  R                  R                  U5      5      $ U $ )u8   SzigorÃº adatszeparÃ¡ciÃ³ a ListÃ¡knÃ¡l Ã©s KeresÅ‘knÃ©l)r!  Ú	TELEPHELYÚGEP)r/  Úhozzaferes_szintÚallowed_sitesrE   r¨   r  r¦   ÚMachineÚsite_idÚin_Úallowed_machines)r  r+  Úsite_idsÚsÚmachine_idsÚms         r'   Úapply_user_data_scope_filterr@  õ  sÎ   € à×Ñ˜IÓ%Øˆà×$Ñ$¨Ó3ØˆØ×+Ô+ˆAØ�O‰O˜AŸD™DÖ!ñ ,ð �|‰|œFŸN™N×2Ñ2×6Ñ6°xÓ@ÓAÐAà	×	&Ñ	&¨%Ó	/ØˆØ×.Ô.ˆAØ×Ñ˜qŸt™tÖ$ñ /ð �|‰|œFŸN™N×-Ñ-×1Ñ1°+Ó>Ó?Ð?à€Lr<   r›   c                 óì   • UR                  [        R                  5      R                  [        R                  R                  U :H  5      R                  5       n[        U=(       a    UR                  5      $ )ur   InaktivÃ¡lt (tÃ¶rÃ¶lt Ã¼gyfÃ©lnek szÃ¡nt) cÃ©geknÃ©l minden szerkesztÃ©s tiltott - csak megtekintÃ©s/export marad.)r  r¦   rÉ   r  r¨   r  rj   r  )r›   r‘   rÚ   s      r'   Úis_company_activerB    sK   € à
�(‰(”6—>‘>Ó
"×
)Ñ
)¬&¯.©.×*;Ñ*;¸zÑ*IÓ
J×
PÑ
PÓ
R€CÜ�×!˜Ÿ	™	Ó"Ð"r<   Úinaktiv_cegÚcsak_olvasasu<   Ez a cÃ©g inaktÃ­v stÃ¡tuszÃº, szerkesztÃ©s nem lehetsÃ©ges!uM   Csak megtekintÃ©si jogosultsÃ¡ggal rendelkezel, szerkesztÃ©s nem lehetsÃ©ges!z/lista?inaktiv_ceg=1z/lista?csak_olvasas=1c                 ó^   • [        X5      (       d  [        $ U R                  (       a  [        $ g)u}  None, ha a felhasznÃ¡lÃ³ Ã­rhat a megadott cÃ©g adataiba; kÃ¼lÃ¶nben a tiltÃ¡s oka
(IRASI_TILTAS_INAKTIV_CEG vagy IRASI_TILTAS_CSAK_OLVASAS). A sorrend (elÅ‘bb a cÃ©g, aztÃ¡n a fiÃ³k)
megegyezik a korÃ¡bbi kÃ©zi ellenÅ‘rzÃ©sekÃ©vel. A RENDSZERADMIN-only route-okra NEM erre van szÃ¼ksÃ©g:
az RA inaktÃ­v cÃ©gen is dolgozik (aktivÃ¡lÃ¡s, tÃ¶rlÃ©s), ott csak a csak_olvasas szÃ¡mÃ­t.N)rB  ÚIRASI_TILTAS_INAKTIV_CEGrD  ÚIRASI_TILTAS_CSAK_OLVASAS)r+  r›   r‘   s      r'   Úirasi_tiltas_okarH  #  s'   € ô
 ˜Z×,Ñ,Ü'Ð'Ø× × Ü(Ð(Ør<   c                 óì   • UR                  [        R                  5      R                  [        R                  R                  U :H  [        R                  R
                  S:H  5      R                  5       SL$ )u  J-14 (v75): be van-e kapcsolva a cÃ©gben a napi (mÅ±szakkezdÅ‘) ellenÅ‘rzÃ©s (BeÃ¡llÃ­tÃ¡sok / "NapiEllenorzesAktiv",
a /kapcsol-napi-ellenorzes route Ã­rja: a sor meglÃ©te = bekapcsolva). KorÃ¡bban a kapcsolÃ³ csak megjelent a
beÃ¡llÃ­tÃ¡sok oldalon, a szerver nem Ã©rvÃ©nyesÃ­tette.ÚNapiEllenorzesAktivN)r  r¦   Ú
Dictionaryr  r›   r¾   r  )r›   r‘   s     r'   Únapi_ellenorzes_aktiv_erL  /  s_   € ð �8‰8”F×%Ñ%Ó&×-Ñ-Ü×Ñ×$Ñ$¨
Ñ2Ü×Ñ×#Ñ#Ð'<Ñ<ó÷ �eƒg�Tðð r<   c                 ó*  • UR                  [        R                  5      R                  [        R                  R                  U :H  [        R                  R
                  S:H  5      R                  5       n[        U=(       a    UR                  S:H  5      $ )u¢   CÃ©genkÃ©nt kapcsolhatÃ³: megjelenjenek-e a sÃºgÃ³ buborÃ©kok Ã©s a HasznÃ¡lati ÃºtmutatÃ³ oldal -
kizÃ¡rÃ³lag rendszeradmin engedÃ©lyezi/tiltja a CÃ©gek oldalon.ÚSugoEngedelyezveÚTrue©	r  r¦   rK  r  r›   r¾   r  rj   Úertek©r›   r‘   rð   s      r'   Úsugo_engedelyezverS  9  ss   € ð —‘œ×*Ñ*Ó+×2Ñ2Ü×Ñ×$Ñ$¨
Ñ2Ü×Ñ×#Ñ#Ð'9Ñ9ó÷ �eƒgð ô �	×7˜iŸo™o°Ñ7Ó8Ð8r<   c                 ó0  • UR                  [        R                  5      R                  [        R                  R                  U :H  [        R                  R
                  S:H  5      R                  5       nU(       a  UR                  S;   a  UR                  $ g)uv   CÃ©genkÃ©nt beÃ¡llÃ­thatÃ³ gÃ©ppazonosÃ­tÃ¡si mÃ³d a matricÃ¡khoz: 'QR', 'NFC' vagy 'Mindketto'. AlapÃ©rtelmezett: QR.ÚAzonositasMod)ÚQRÚNFCÚ	MindkettorV  )r  r¦   rK  r  r›   r¾   r  rQ  rR  s      r'   Úget_azonositas_modrY  C  ss   € à—‘œ×*Ñ*Ó+×2Ñ2Ü×Ñ×$Ñ$¨
Ñ2Ü×Ñ×#Ñ# Ñ6ó÷ �eƒgð ö �Y—_‘_Ð(BÓBØ�‰ÐØr<   c                 óL   • U R                   S:H  =(       a    U R                  S:H  $ )u³   A rendszeradminisztrÃ¡tor (Admin szerepkÃ¶r, az AlapÃ©rtelmezett CÃ©g / company_id==1
alÃ¡ tartozÃ³ felhasznÃ¡lÃ³) minden modulhoz automatikusan, korlÃ¡tozÃ¡s nÃ©lkÃ¼l hozzÃ¡fÃ©r.r!  rW   )r/  r›   )r+  s    r'   rŸ   rŸ   N  s%   € ð ×Ñ Ñ'×H¨L×,CÑ,CÀqÑ,HÐHr<   c                 óž   • [        U 5      (       a  gXR                  :X  a  gXR                   Vs/ s H  o"R                  PM     sn;   $ s  snf )uY  Igaz, ha a felhasznÃ¡lÃ³ jogosult az adott cÃ©ghez hozzÃ¡fÃ©rni: a valÃ³di rendszeradmin
bÃ¡rmelyikhez, mindenki mÃ¡s csak a sajÃ¡t cÃ©gÃ©hez vagy a neki kifejezetten kiosztott
(allowed_companies) cÃ©gekhez - FONTOS: egy cÃ©ges Admin (role=='Admin', de mÃ¡s company_id)
NEM automatikusan jogosult minden cÃ©ghez, csak mert a szerepkÃ¶re 'Admin'.T)rŸ   r›   r&  r¨   )r+  r›   r4   s      r'   Úis_company_accessibler\  T  sF   € ô
 ! ×.Ñ.ØØ×,Ñ,Ó,ØØ×(FÒ(FÓGÒ(F 1Ÿ$œ$Ñ(FÑGÑGÐGùÒGs   °A
c                 óN  • UR                  [        R                  5      R                  [        R                  R                  U :H  5      R                  5       nU(       d
  [        5       $ UR                   Vs1 s H!  o3R                  (       d  M  UR                  iM#     sn$ s  snf )uf   Melyik modulokat engedÃ©lyezte a rendszeradminisztrÃ¡tor az adott cÃ©gnek (elÅ‘fizetÃ©s-szintÅ± kapu).)
r  r¦   rÉ   r  r¨   r  ÚsetÚengedelyezett_modulokr  Úkod)r›   r‘   rÚ   r?  s       r'   Úget_company_modul_kodokra  `  sk   € à
�(‰(”6—>‘>Ó
"×
)Ñ
)¬&¯.©.×*;Ñ*;¸zÑ*IÓ
J×
PÑ
PÓ
R€CÞÜ‹uˆØ×4Ò4Ó@Ò4�a¿½‹EˆA�EŒEÑ4Ñ@Ð@ùÒ@s   Á7B"ÂB"c                 ó¼  • [        U 5      (       aq  UR                  [        R                  5      R	                  [        R                  R
                  S:H  5      R                  5        Vs1 s H  o"R                  iM     sn$ [        U R                  U5      nU R                   Vs1 s H!  o"R
                  (       d  M  UR                  iM#     nnX4-  $ s  snf s  snf )uß   A felhasznÃ¡lÃ³ tÃ©nylegesen elÃ©rhetÅ‘ moduljai: a cÃ©g Ã¡ltal engedÃ©lyezettek metszete
azzal, amit a felhasznÃ¡lÃ³hoz konkrÃ©tan hozzÃ¡rendeltek. RendszeradminisztrÃ¡tornak
korlÃ¡tozÃ¡s nÃ©lkÃ¼l minden aktÃ­v modul jÃ¡r.T)rŸ   r  r¦   ÚModulr  r  Úallr`  ra  r›   Úsajat_modulok)r+  r‘   r?  Úceg_modulokre  s        r'   Úget_user_modul_kodokrg  h  s£   € ô ! ×.Ñ.Ø!Ÿx™x¬¯©Ó5×<Ñ<¼V¿\¹\×=OÑ=OÐSWÑ=WÓX×\Ñ\Ô^Ó_Ò^˜!—”Ñ^Ñ_Ð_Ü)¨,×*AÑ*AÀ2ÓF€KØ$0×$>Ò$>ÓJÒ$>˜qÇ'Å'“U�Q—U”UÑ$>€MÐJØÑ&Ð&ùò `ùâJs   Á*CÂ&CÂ>Cc                 óR   • [        U 5      (       a  g[        [        X5      5      S:„  $ )uØ   A modulvÃ¡ltÃ³ gomb csak akkor legyen lÃ¡thatÃ³, ha tÃ©nylegesen van hova vÃ¡ltani -
rendszeradminnak mindig (a rendszeradminisztrÃ¡ciÃ³ csempe miatt), mÃ¡snak csak ha 1-nÃ©l
tÃ¶bb aktÃ­v modulhoz van hozzÃ¡fÃ©rÃ©se.TrW   )rŸ   r   rg  )r+  r‘   s     r'   Úvan_e_tobb_moduljari  s  s(   € ô ! ×.Ñ.ØÜÔ# LÓ5Ó6¸Ñ:Ð:r<   Ú	modul_kodÚworking_company_idc                 ó~   • U[        X5      ;  a  g[        U 5      (       d  X R                  :X  a  gU[        X#5      ;   $ )u¯  J-15 (v72): a modul-kapu a felhasznÃ¡lÃ³ SAJÃ�T cÃ©ge mellett a kivÃ¡lasztott MUNKAKÃ–RNYEZET cÃ©gÃ©nek elÅ‘fizetÃ©sÃ©t is nÃ©zi.
KorÃ¡bban csak a sajÃ¡t cÃ©g moduljait ellenÅ‘rizte, Ã­gy a kÃ¼lsÅ‘s szakÃ©rtÅ‘ olyan Ã¼gyfÃ©lcÃ©g moduljÃ¡t is elÃ©rte, amely nem
fizetett elÅ‘ rÃ¡. A rendszeradminisztrÃ¡tor korlÃ¡tlan (minden aktÃ­v modul). A sajÃ¡t cÃ©gben dolgozÃ³nÃ¡l a kÃ©t vizsgÃ¡lat
ugyanaz, tehÃ¡t nÃ¡luk semmi nem vÃ¡ltozik.FT)rg  rŸ   r›   ra  )r+  rj  rk  r‘   s       r'   Ú"modul_elerheto_a_munkakornyezetbenrm  |  sA   € ð
 Ô,¨\Ó>Ó>ØÜ  ×.Ñ.Ð2D×H_ÑH_Ó2_ØØÔ/Ð0BÓGÑGÐGr<   c                 óÂ   • U R                   R                  U R                   R                  (       a  SU R                   R                  -   OS-   nSUR                   S3nX#4$ )u�  Ã–njavÃ­tÃ³ vÃ¡lasz, ha a kivÃ¡lasztott munkakÃ¶rnyezet cÃ©gÃ©nek nincs meg a kÃ©rt modulja: a munkakÃ¶rnyezetet a felhasznÃ¡lÃ³
SAJÃ�T cÃ©gÃ©re Ã¡llÃ­tja vissza (a modul-ellenÅ‘rzÃ©s ott mÃ¡r Ã¡tment, tehÃ¡t nincs Ã¡tirÃ¡nyÃ­tÃ¡si hurok), Ã©s ugyanarra az oldalra
irÃ¡nyÃ­t vissza. A visszatÃ©rÃ©si Ã©rtÃ©k (url, Set-Cookie fejlÃ©c) a hÃ­vÃ³ dolga: a HTTPException / RedirectResponse Ã¶sszerakja.r+   ro   zworkspace_id=z7; Max-Age=86400; Path=/; HttpOnly; Secure; SameSite=lax)r  r  r  r›   )r   r+  r:   Úsutiks       r'   Ú!munkakornyezet_visszaallitasa_getrp  ˆ  sT   € ð �+‰+×
Ñ
¸7¿;¹;×;L×;L˜s W§[¡[×%6Ñ%6Ò6ÐRTÑ
U€CØ˜L×3Ñ3Ð4Ð4kÐl€EØˆ:Ðr<   c                 óŒ   ^ • [        [        5      [        [        5      4S[        S[        S[
        R                  4U 4S jjjnU$ )u  FastAPI dependency-gyÃ¡r: csak akkor engedi tovÃ¡bb a kÃ©rÃ©st, ha a felhasznÃ¡lÃ³nak
van hozzÃ¡fÃ©rÃ©se a megadott modulhoz - egyÃ©bkÃ©nt a modul-vÃ¡lasztÃ³ oldalra irÃ¡nyÃ­t.
J-15 (v72): a kivÃ¡lasztott munkakÃ¶rnyezet cÃ©gÃ©nek is elÅ‘ kell fizetnie a modulra. Ha nem (Ã©s a sajÃ¡t cÃ©gÃ©ben
van meg a modul), GET kÃ©rÃ©snÃ©l a munkakÃ¶rnyezet a sajÃ¡t cÃ©gre Ã¡ll vissza Ã©s az oldal ÃºjratÃ¶ltÅ‘dik, egyÃ©b
metÃ³dusnÃ¡l (POST...) 403 - hogy egy mÃ¡sik cÃ©g modul nÃ©lkÃ¼li adatÃ¡ba ne lehessen se olvasni, se Ã­rni.r   r‘   r+  c                 ó2  >• T[        X!5      ;  a  [        [        R                  SS0S9e[	        X 5      n[        UTX15      (       dO  U R                  S:X  a'  [        X5      u  pE[        [        R                  XES.S9e[        [        R                  SS9eU$ )Nr  z/valassz-modultr  ÚGET)r  z
Set-CookieuG   A kivÃ¡lasztott munkakÃ¶rnyezet cÃ©ge nem fizetett elÅ‘ erre a modulra!)r  Údetail)	rg  r	   r   r  r2  rm  Úmethodrp  ÚHTTP_403_FORBIDDEN)r   r‘   r+  rk  r:   ro  rj  s         €r'   Ú_dependencyÚ"require_modul.<locals>._dependency—  s¦   ø€ ð
 Ô0°ÓBÓBÜÜ"×5Ñ5Ø#Ð%6Ð7ñð ô 4°LÓJÐÜ1°,À	ÐK]×bÑbØ�~‰~ Ó&Ü>¸wÓU‘
�Ü#Ü &× 9Ñ 9Ø),ÑBñð ô  Ü"×5Ñ5Ø`ñð ð Ðr<   )r   r   r  r
   r   r¦   r  )rj  rw  s   ` r'   Úrequire_modulry  ‘  sE   ø€ ô œf“oÜ$+Ô,<Ó$=ñÜðäðô —k‘k÷ð ð. Ðr<   c                 ó*  • UR                  [        R                  5      R                  [        R                  R                  U :H  [        R                  R
                  S:H  5      R                  5       n[        U=(       a    UR                  S:H  5      $ )uª   CÃ©genkÃ©nt kapcsolhatÃ³: a tÅ±zoltÃ³ kÃ©szÃ¼lÃ©kek oltÃ³anyagegysÃ©g-igÃ©nyÃ©t a rendszer
az alapterÃ¼let alapjÃ¡n (OTSZ 16. mellÃ©klet 2. tÃ¡blÃ¡zata) is felajÃ¡nlja-e.ÚOEAlapteruletSzamitasrO  rP  rR  s      r'   Úget_oe_alapterulet_szamitasr|  ±  ss   € ð —‘œ×*Ñ*Ó+×2Ñ2Ü×Ñ×$Ñ$¨
Ñ2Ü×Ñ×#Ñ#Ð'>Ñ>ó÷ �eƒgð ô �	×7˜iŸo™o°Ñ7Ó8Ð8r<   c                 ó   • [        X5      $ )u¿  IDOR VÃ©delem: EllenÅ‘rzi, hogy a felhasznÃ¡lÃ³nak van-e jogosultsÃ¡ga az adott cÃ©ghez.
KRITIKUS JAVÃ�TÃ�S: korÃ¡bban `current_user.role == "Admin"` esetÃ©n feltÃ©tel nÃ©lkÃ¼l True-t
adott - ez BÃ�RMELYIK Ã¼gyfÃ©lcÃ©g sajÃ¡t Admin-jÃ¡t (nem csak a valÃ³di rendszeradminisztrÃ¡tort)
Ã¡tengedte, ami a fÃ¡jlkiszolgÃ¡lÃ³ route-oknÃ¡l (pl. `/uploads/{company_id}/...`, ahol a
company_id kÃ¶zvetlenÃ¼l URL-paramÃ©ter, nem a hamisÃ­tÃ¡s ellen vÃ©dett working_company_id)
lehetÅ‘vÃ© tette, hogy bÃ¡rmelyik cÃ©g Admin-ja egy mÃ¡sik cÃ©g company_id-jÃ©t kitalÃ¡lva/
megszerezve hozzÃ¡fÃ©rjen annak dokumentumaihoz/fÃ©nykÃ©peihez. MostantÃ³l ugyanazt a helyes
logikÃ¡t kÃ¶veti, mint az `is_company_accessible()`.)r\  )r+  r›   s     r'   Úis_company_allowedr~  »  s   € ô ! Ó:Ð:r<   )r!  r$  )r"  r#  )u   FelhasznÃ¡lÃ³c                 ó˜  • [        XR                  5      (       d  gUR                  S:X  a  gUR                  S:X  a?  / nUR                   H  nUR                  UR                  5        M      U R                  U;   $ UR                  S:X  a?  / nUR                   H  nUR                  UR                  5        M      U R                  U;   $ g)u]   IDOR VÃ©delem: EllenÅ‘rzi, hogy az egyedileg megnyitott gÃ©phez van-e joga a felhasznÃ¡lÃ³nakFr!  Tr4  r5  )	r~  r›   r/  r6  r7  rE   r¨   r9  r;  )Úgepr+  r<  r=  r>  r?  s         r'   Úis_machine_allowedr�  Ï  s°   € ä˜l¯N©N×;Ñ;Øð ×Ñ˜GÓ#Øà×$Ñ$¨Ó3ØˆØ×+Ô+ˆAØ�O‰O˜AŸD™DÖ!ñ ,à�{‰{˜hÑ&Ð&à×$Ñ$¨Ó-ØˆØ×.Ô.ˆAØ×Ñ˜qŸt™tÖ$ñ /à�v‰v˜Ñ$Ð$àr<   c                 ód  • [        U 5      (       a.  UR                  [        R                  5      R	                  5       nO¸U R
                  S;   a¦  [        U R                  5      S:”  aŠ  / nU R                  (       a  UR                  U R                  5        U R                   H  nUR                  U5        M     0 nU H  nUc  M  XvUR                  '   M     [        UR                  5       5      nO/ nO/ nU(       a-  U Vs/ s H   or[        UR                  U5      ;   d  M  UPM"     nnU$ s  snf )uÃ  Visszaadja azokat a cÃ©geket, amik kÃ¶zÃ¶tt a felhasznÃ¡lÃ³ vÃ¡lthat a felsÅ‘ menÃ¼ben -
opcionÃ¡lisan (modul_kod megadÃ¡sÃ¡val) csak azokat, amelyeknÃ©l az adott modul (pl. 'EBK')
elÅ‘ van fizetve. FONTOS: csak a valÃ³di rendszeradminisztrÃ¡tor (company_id==1) lÃ¡that
minden cÃ©get - egy cÃ©ges Admin (role=='Admin', de mÃ¡s company_id) NEM az, Å‘ legfeljebb
a sajÃ¡t cÃ©gÃ©t Ã©s a neki kifejezetten kiosztott (allowed_companies) cÃ©geket lÃ¡thatja.r   r   )rŸ   r  r¦   rÉ   rd  r/  r   r&  rÚ   rE   r¨   ÚlistÚvaluesra  )r+  r‘   rj  ÚcegekrH   Ú	allowed_cÚegyedi_cegekr4   s           r'   Úget_allowed_companies_listrˆ  ê  s  € ô ! ×.Ñ.Ø—‘œŸ™Ó(×,Ñ,Ó.‰à	×	Ñ	ð  Eó  
EÜˆ|×-Ñ-Ó.°Ó2ØˆEØ××Ø—‘˜\×-Ñ-Ô.Ø)×;Ô;�	Ø—‘˜YÖ'ñ <ð ˆLÛ�Ø“=Ø)* §¡Ó&ñ ô ˜×,Ñ,Ó.Ó/‰Eà‰EàˆæÙ!ÓTšE�qÔ2IÈ!Ï$É$ÐPRÓ2SÑ%S—™EˆÐTà€Lùò Us   ÄD-Ä#D-)r-   )F)r`  rN   )ar    rb   rþ   r£   r@   Úcollectionsr   r   r   r   Ú	threadingr   rw   rŒ   Úfastapir   r	   r
   r   Úsqlalchemy.ormr   r¦   r  Údatabaser   Úconfigr   r   r   r   r   r   r(   r;   rƒ  rB   rA   rC   rD   r0  rj   rJ   rS   Úbytesr]   rf   rm   rk   ry   r|   r}   r~   ÚDUMMY_PASSWORD_HASHr   Údictr�   r©   r²   r«   râ   rä   rì   ÚMFA_PENDING_COOKIEró   rò   rõ   rú   r  r  r  r2  r@  rB  rF  rG  ÚIRASI_TILTAS_UZENETEKÚIRASI_TILTAS_LISTA_URLrH  rL  rS  rY  rŸ   r\  r^  ra  rg  ri  rm  rp  ry  r|  r~  ÚEMELOGEP_KEZELO_SZEREPKOROKÚEMELOGEP_SZAKMAI_SZEREPKOROKÚEMELOGEP_SZEREPKOROKr�  rˆ  © r<   r'   Ú<module>r™     s&  ðÛ Û Û 	Û Û Ý #ß 2Ñ 2Ý ã Û 
ß ;Ó ;Ý "ã Û Ý ß eÕ eð˜7ð  sô ñB sð °Sõ ñ@ (¨Ó-Ð Ù“fÐ Ø!$Ð Ø#%Ð  ð¨Cð °Dô ð M ð M¨ô Mð°Cð À%ð ÈDô ð, #ô ðQ˜sð Q tô Qð4 ð 4¨ô 4ð Cð ¸#ô ð —m’mÐ$DÀfÇnÂnÓFVÓW×^Ñ^Ð_fÓgÐ ð ô ð
˜dô 
ð$ Ð ð˜Gð ¨sô ð6'[ Gð '[°sð '[ÐUYô '[ñT	%�wð 	%¨#ð 	%°Dð 	%ÀSõ 	%ð ð °4ô ð¨ð °#ô ð& #Ð ØÐ ØÐ ñ) Cð )¨cð )¸cõ )ðD Cô Dòñ 6=¸V³_ñ W
˜gð W
¨7õ W
ñt ?FÀf»oñ  wð °Gõ ð4 #°'ô  #òFð,# #ð #¨7ð #°tô #ð )Ð Ø*Ð àÐ\ØÐnðÐ ð
 Ð4ØÐ6ðÐ ð	¨sð 	¸ô 	ð¨ð °ð ¸Tô ð9 #ð 9¨7ð 9°tô 9ð 3ð ¨Gð ¸ô ðI¨tô Ið	H°Cð 	H¸Dô 	HðA¨ð A°ð A¸Sô Að'¨7ð '°sô 'ð;¨ð ;°Tô ;ð	HÀð 	HÐY\ð 	HÐbið 	HÐnrô 	Hð¨wô ð˜Sô ð@9¨Cð 9°Wð 9Àô 9ð	;°ð 	;¸ô 	;ð CÐ Ø:Ð=oÑoÐ Ø3Ð6HÑHÐ òñ6 °ð  ÀSö  r<   