bPxM%Z1M74wlUgQ>77Y7@0Y
zjkK#v55n1`$D!W!VIw`hDXom^cw1*z)GNG?b2O^{3=Gug{{|xJ(a)$??giAV^fBtj
z^rP$ubE7s_G-~toLUm{(>i+$xV|5<&9{2~az
zX}F16^S)#3$L8m#8Ttw}<#SQze+_k9N&j(7^*Uh2$p@;1Md_a}L)NY{0hc4F*1<;p(o%4RrcQr?N@yuFqZ
ze~<9exBe8iQwi>UTf^CnN>_-dVMMKnYudD_;)rt+O?ARi(*Iy9f-c_PzF*H4+oX9x
z`Y`pi6f0aF?=j!iNPqv))rD}KaF>d0T%q!(lhzdLdPZDV8*EBgOyE1IiNe-|`@}z|
z{AWU1;@!!+jk5{A5hf9IZNnv43d_6peFZw#9mq`2XbW+(uJ(iw7gw4$t;t3DEb+3$
z9};w3BlIBuU()+r-cy|K?mda+2-AJF*%!pG68DA@Ip8w0azg-(>pbf{U6J%`S9Zjy
zvtNUI^p`SS+Nk@8FU8Er9`t?pQ<+{guUx&<#HUiGYbSYgZQN__5?N^TeLw$jm6Z6J
zikl=sfAOkESr*i_hA@J7Ho`_<4$DCK0OFfnTBqeEc~=O@2^$@%aKM@-1{D0{l
z*dB8dI#ZB=if@R2M@S-^A?WJsRGd@lyZrdcJIHs1;}I9nN?rYrO1ku6Rsw5aJ>)x%
zNv3*Q|0+}}LqZ>|>E3BTFCV>#bOjLZQ701hK7XJ1Pt?`_F~xhz{7BeHSW8+jsr2|C
zM&mj1GqS9@>Ja9W4#V*TKXqWSXG+DWtlkFX>&k<*xlh+|JV1H^@#Mt+Av__BCh+1m
zkIB#C?)!pxX5uX{CFQ!lB)lekr3BY;SNCt?m8r9VbcC=Wa?x=6*sw
z(kWct1u7?J7Q@M3Pdt!tma=68edOoGw&dl*j|febM_Sh{(ldz9C%%i2f%F1GYvOOO
zo&||Lqf!aN?-bS|{OU^Ek*AOAzEgU(8}Yfs*AU+GmGDNR-ahTw+GM04q3al)CuFDMIP8xJ
zw#fH$9(mQsyGgi5j{X#`D~kLc_#5c};<*VK375&MrV8&|m&qUTzcdT=p-Y_qU#5*T
zry}1O%>t77(BCzt(#FJp!Lo$s#D5_4CVqlYmB2SJ-xrTLsOt@0piWo98kcug>c|Wu
za$L2z4pHGS=~&_y2^$FSUU8KDN2p7^k`&ZLT`!&cu_fiV$xDa1Nyoaf7%WNHLzqT+
z6Ux0w{LnRw%>M{Mr2PqF$xG?V^qa|NgwceBSc$s(7=ZODE
z$l>x1U_~l#NXGb=kmyKgL&jcQ>z>kU}3=@jvW
zgn8~E$5hE(PsywFHi1W}zmmM6nA_#2A)b!Tlydja#=e-p
ztDt9mLHgY*(IqlrdFpL{r?8`|8|w1fQGSNJ@%W?5o8am+#uxA08?W(?A)}Q554>JAeTxZIU
zst#cQVV0}hpE~+=w-?w
ziTFUm7o_*&L-IZ*1QUOIy+^zu<%0<6$^4r1_pY!Rc@+pZwEmZg6vqTA^d__*M3ATJ
z1b&CV`%>%&m%kn-ySOVdlezEh6-~T|EB7aJFzJ-8a2@%NU0teZ*L
z4!*t8QZ`EO|FL9#J9uWV8P@DV$ggbO6N6>ZO;`>>hpSj3?aobIG2wso8Y(r4N`PGOJZwCdzIm$83m
z#~H_ckzJ{SALA%&(#>&7P`(Xo;i>M9GbytZaI*DuoY7R6+1GLM^5D$RJI-R#h59>A
zCmPs<>oPlz$4g_}_lYYhnp(g~f0%X2Wrq
z3#VZooM(Lt%aY!TrSWUj^B!VW%rJp8Z8qee6dH4`&X16qXBaVfHbPK8O1qxPzz>NT9i`WGeAmJIbY8a3jVY{gl&;u5S*
z{yNkWT)=YpCzipIlg(5&$I_&IsOL>XjdTTSrZ%8v_%LcfUruKJT_WF*p*7Dm#c{e~
z6;#D>sD@v`2>cjB@dqrAPp}+@O*Ic}k9tl&48zH&0j)!IY&Vv|D;S*l0FlgOgiJG2
zoe$OH3aHIk7wh3*Y>bPo=dc;+f-iHl@HuRR^RYF4g>|qn^Iso3p`J4ho8exYA8=kV
z$Dsjo@|*;0fuG_A44GkW*o7Qj=P}mAE;G#xO+t-i7OLY*P*eRLY5@DO65dAbnL@9c
z8H~WX>_4Z4i8y0WYr7F^;BnLo$$5=sff5*kWl(EZ4Yd@_F&Fkk-5-seZ~|t*6F36T
z;z(>aix(K~!{)T_j-uA`3YN!WZysiE8+3%#OEg{(aQ3eu#m5M4p*rMp714&rL7>ZRA{GQkz7hx2Bi`s0oixNNS-*-WqjZS5!lBSOmwRM!pa=prxq#fe&nCCu(XxL5=hls^TB0
z4rS+?taP|F5;d}pm<@ZN?(2{0XgsO|)2+);dtx)HgZq&C1I{@jdhiw8gm+OrUHztc
z;Jc`q*^XMv&uscK>b_r4n=iu>Go@v)AnE#86g%7eVWdQ?B5>P#zgspHfHo+_S9F|;RzLFzxAnBv{ELL1;Hme`ifmg9OF2!QF6V=`sR7cCN
zV*WK1jaHc{X^)La_d)H>dDsV6qGseFYQz~=o0$kfJ*W^?$0|0zzs(hM?$;AxxR
zbB)h`
zQ{s8s?EY+6o^%1!{gDA8VMM&B8>XSw=snbkciHqIEKT|}s$;*S_Ck(#Oale5yob)9
zX0GMC<`i{C%~%i2jQvr^FdB7#Aeo5P>P2jhGtk9jSPk!>HcQF1=ElaTjE!{x8g?dh2KupT`Wi7wJgAIY2}ezObG{jo=z;CT?SPe1ck_uGhZy7if3RI+<;n|i>M{NiR$oe%#Y4C^Eaac
zsQQhO`T=Jc5xrnWqDDRs>)>)!hfbq9cpcTTyEgwJ)+e29yLoVPYaFV9*{J94L3Q{N
zYU+#bFiYAN8|wV~h}5QF1y;b*s404kZ876VW=cDtM(9J0Xau&ysn`Hdpk^e;PV+{L
zz#60npial@H~=@JmMq`Lw5#*qnusdCfLg=%QOEI1RD
zov3<;P#r&pYVZ_l$-Y5t<~z3hH|yiw%)fSjrak67=Es7htD!m&g?hkCs0U87&c|m+
zzlDu(8>)eOw)`(!o_()bx}sQ;@>-~+>W1p@%)J5gMw>@Q5i-`|N<4^~Qr|vvJV&8M
zJPnmU7ghglRKxpF9X)D2iP}?_u>gkdH%n3p!$@~R&6GbtL=|2{ZJybvk!?k-@h7Ow
z@)xS%st3#(HbpH(N7S14L5*lUYOhSU>DO%e0@R+^gL=+4sF@BtAfl-WIcN&Pu@&jY
z7>W}y3g@HN`VwjreUBQ!1Jq1B!U!yQ$mF+1Eo}#Ei~UgTyoH*nLr8}M&KE>Vka5ly
z{DvBt=Wy^J2%KD~8(N_n?2PJ2FI2rjSRCVR{&ZCRIhYxj+4LGLMS25<;}=*$=l>xQ
zO?i<|%!4YU8fs(hgj(aCsFC(ZH9QK{kx4fFDr&|SVRc-Ok$4%kgvE}SneBuPNzcJt
zwC@}zqTPKFGvSY@&2|^HHy&eS3_Z#h4!hz+JcF&U&!_yu6fQ&k4A}QG^X{MUFY_-U
z2e1w0c|SKFyFS=}^dt8dqp?Vlae&a9APsx)}OSJw==ATXA>>#5o?#I&j9p=WYUzv14%uKpI
zY7LuUE*yZtwMRW?I%dT;P&2t0Gvad8QmjUe{3`1Hq9>XEEJP}vG;3K6m2QCA6U|WX
z`mU(m9E;imBdxDvQPS&B4If5znTTp=G-||C@NJxf1u)R?j2U4U)D1q=
z2$E1UFxomDHS)!%2DhLZJc4=gf=%B>-RC)Lo|_N#imrg##L=jwU1w{X;F{l|Di&Joo&9D5m8EJ$y64k->sP{}i^x+FwO6UJ7k>>1D
z=R8L*13%YYV7+M};xfmJ^!RH`E9t}E@Jgm$;qRFN@;lt*?~U9x@CSB0{(#eP`j4C@
z>gD~3AM3EgZO3_&HCuXzX{Wrwul$vt`;XyUwC}|J&Ms!VhWx=l60-X$J>rK+D!i7#
zB*%$!A-dj1Ldgj3lXh(LDv)fD3rpor0ZfB_C>w%#-rA5CKkdsQF~xB
zhT{>eiuaLmIHgN_f}61-G67C?o34umNjE9Y?_cy$=t+jou^)9BW}_Ndk19WmTKjLY
z0%j`X3H~@;1$AF*EQ5nlYdr
zB+L`s-EFWE=|t2NFGQV+Ls%JaqdHue7r%~WJ=Dy#N4>BHqeh;BTFRHPCVqgUF>sBD
z*0yg2Pw-tIi_J;Djq2DdM~P8mT*t-S2a->NqQmb1#=p;
z>qDz}g1-srjIBt|!zOqh&11Cgyg1^B$gKDs6HM1#~pf=kM
z)aE*E^KW2n(iy6I^cxMQ9;#jeIe6fQZ(30qWT7N3G>i
zR6`eR`X|&o{BP8Z<*Mm%24iE?rd)yZ@LgPqO?X>rjjv)~>{Htl{MWQCs7;x>4(Gom
z5toS0XAJ5=!>}->pmzNX)bU!3>fmnF0}i3;pTP=v8MW!M)HQpfAnG``MCA`eovI|%
z3{9=e`EO5TH5t|M4yu7tyw=o#@~B))Un}}#_Z=$9=XJd0iIn?K}A!NvQkhqKjKld*U?eMRf`Fg1cvZf|~jq&GnoB=a7g-*ap?`^EN%%x)8IG|32zL
zTTz>BKWa0bLKh#RW~_J%vk4nwY0~Xc9g0WoH9ua$*D)LIJBcmLt9BG>#IsQk+K9U0
zIBMiSpx)h{R;FHU)Y5fF9lw#N`<9^^-i2EG%cueVYSYfHqSNBD%2!YHbFg
zi=$DycM+;%yHR`OB5DR6pk^jpl-ZPdtz}RhuZ3EI&e#}ZP#s!@>i7=*_ZOO)3uI_F
ze}nqy+(S)uNE>5e3?W?(^?(|v5w=0y7l)dm(byVip*ngRwbplV7#3-3Ht}TCF+9>X
zU?RVf(T0q$cIF$9fbpacU@TT^?{N}wKK8@R&jxp|GZ@wIeAF>sk2UZXj=*9a%&YxX
z)J$x*evUmzUkeb?4Akvt8fbz_uSZSoR@6D(gL=TH*bFbDj$5ftX2vR^zG^LT8m>pZ
zV(WA^9qonrJ)Q?zmQ6IGpsGlFcMm;ZcH}k5mjnw1&PedabkDAI?Q0ICjYS(^(`s$rW&CE@V
z_wX4-ZNmON%*QJkRc|Ef8!{QSXJ(*ga3Sh>tFbF?$Fe&A*?XEPt%~~CB%(IoT-3*8
z1?p66M0M;aR>j+>k5;i>9%l%4Kn-LICgUDdhpRnjI$95vZjYL&ZpzpBf1Zd&o``zD
z6x3SJQUzRt>d1D~jYqI0oXgjJ=WsJ>06F`ZwXcqW{$xZE
z$&G7JYquHIz;RRu^7S>lI}Ejnyr@m|CTeC*U>&@P`Z=QH^JWRkp*k3j8emgwj=fMF
zT=={_|LbhVCag%oA=HhxQ7;ltKQjX*Pz_c^jkGnYgS}8o7KfU_G}M3ssI`9$wc8h=
z_QnR(3vF9J&cCMQG#T36e_Uib>=0~(5
zs2OR88L=~}1Kq8C14Q%yFKVQ5s5jRX)E-!7)0=JjbJT;bp*s8>R>tfD&3UhlI=)@e
z#c`-jy&QG?4x^s?E2_Of_CaPBhoRody-*JxgL;81#TK{|_29>-Z$)LVnbNkXJuv{w
z<3iMP_F^-v=5y^NXgO;m#`P#xZenyKR$jt^0rwL+|U)7D3Ipf~o=`5#I|57>=*@JZC0>;`H^
ze#MTMaftcOcSXH`#$Yvk2el+;u`ND8ElHE1W=2M16zRFBfn2~ESTK(BuPJIvqziUJ
zt=)1|2M(Y{bOHzAP1F*!8)im01NFciSO@Q81*|mO6Z~CoSJZcZE2=~HQ4Lq+{aqIa
z#&iC4Ugwjc7s3kEly1UixE*!lAE;whGr^qODAWx2P%|(Gb!rZxX7VCxm)}DzZPr9H
zu>7c{sE67sZ4(3LO&3FkI`S^o!cC|fZ=h!4zAg78nR+=<=ePjsfyGhvs-li_BWp`k
zy=PG~*$s6{hM`W`>;RFDM7E;dR2h@a2y&xtC}-1=*p75JR0B&;FQzr9nfVy?M*9Nw
zg1Un`6`>>S>B1tUN1!(O4BUu;cWptR6!XAT)YQF#n#$$q;#Snh=L~B1UO|ocXVj*9
zjHNIt)x3~mt+P=xunU7rgxVt)kc0R8K|jUj(WgG)aKc4)3;FX
zjk~CsdxY8xS<_6tdZ-5Dury9Y&CD9q^FPJl-~TTW(NtC)=?VT9j;&B5TYx%#Z`t$~
z)OkLD_3;j>gB3;@>tibEc32a4qh|0fs-sy(n-1hd9rJn^s`KBTh^BA=>NviG8u5D6
zrrd&hz#i15`3%*uJE*02jJhw^7_(_ZQ7<4Dt7AtD!*QsO*c#NS+KT}-^d}Lmt@DCu
zFgt29g`)OCO;mXsR7bj?HfKN7lKHU{zK@ak5c^{N7tO%tpgMdJHDf=bI{fHG&cCKQ
z!%JqZp26OvE8!bB5ocq8v7X?+6TE{5NZ-Ti9yaAT^JDuBj`3jfBgUJK%*NKFucBtQ
z`~;JqgnA+ELA}TxP2fhoxtdHg75q4Y^g&dGI+M)L|D#ZAei@Hop~)U+242BRIDCr7
z`32|Uvp8+4*()beGyFGd#95}9{1B{4x_*F&rZ^ULEM7!aT#YWSMeWwlusmKy?TO4U
zn|gUrZ_EOi5sP9kEQ#GQ4Yfx;Mcwzc^&8ZZ1a1@2T0TOZ-~7`}hiYRO>2|1wldvMr
zN8Pv=wI_~a1fE50wk)rhH)uW7E+39MhT~8JT!0$+UL30Pf18MI>@~xj+i9o~e}sAk
zA44^G98Nq4rD
z_F?mM<;p&zKe!fY{dK)bg?JwH^jb%}0pTGTk0^^p4<3G6!J15+Ys7OhqG;keigARN
z#5vhcJHm0&4{~>-6dM9FaKk
zax>Zr+^lN|p^S|y&9}@cN%|b|2E^|YbbUieCI1QOBR20h46L#@pT#X
zE8?d%uMjunrE%^4K7^*Em)Npn*4p?i_e2qNX`>z?z7`82r#JY`P#Isxfb-Z^%tpq1
z3U%!#Z@G>Ch^tL@@Xw!Zz7qO1+74Vm_>g!P$_m-%eMsI^;zbDCiR+4{{6+jIn9?sW
zS^w|JyiUkO;9V5_w|XBH4ifY#on;?56iX1|$;(YW4>R!&>3)QB1YKjSit|DYUV8uY
z`VU@}@wkl_rta$jdqWK}t5c;tcEJS9Xe+j%PF>=9x#UXMz%!)vJ=did%}>;+fqEG=
zBz}mxp#(k|&Mv|Z!e-JrOUcaP^cen9U
z*oo)pI*Ff=ew}z`;tvTA2-69C9G&~*7qs{B1r0a_Na!t{2R)Bij6^vXt@l?`4G_;U{Fb<~+aJQ=SN8U{eaoKcqrj(%HAjF^;{Z#gUBpP
zWDub@nJ#HvH%TuhzLNNULLSnq3DGLFmmhzpPIba%$~qFhv}Lj6>9ak0PS<*c0vYY%
z)}Y1*lq{p9G)^P^EAeW?b!EdxCK~+nZOU5_o0cxG4|VuEgYy?8=*Ki8@^fHHmgW
zU5~6sQ5)wbc_CPebPHS71Zxov6XsL?9OZ%M^+2x4s>EK%PdX3b6_QzOSwZ5dgqI0x
z$kUI-x(*Tlj{8m#U!wc%Re*TCbm{ZNcM*!&yw9*Hb+=_;{A)=JC&ZBP32w3vi6yS9
zDvjh&+;&EJn+Zipzekuy*hTsdW~bhpgo?z|Uwdt06jq{aCE-u%{lQ-{oSwFDr5fQH
zhWbIhER}w?dCJ!helHQ`D#6v(HqsbRo2=kpfr@iaJbAYq8Hr-VE#&0W-0nEdg?ClX&v{0Z@wFo!+L?-2Ley1^Ux
zV>@{r2>&Af`_oL+{&PMfOyGw8c#}$Jh_4~6un+k{mF)E!dCi_C@C)j1Aa4?uwD~!R
z=b|&U?fpx!vW*X=O#ef1BhoX~el9W&5?-+t^o*IL(_h_eA|E!U-kx-Y!))COHg5>!
z=g8Cl0Q|Adn{Dg#!avj9+fw77PDV{zAqqdT9qCK_dCGd?Z&(~lq`P?^>C1%d>GBdu
zf1*6Q6x%5KlJt9c7;o|Hy2LvZ@1}M%|FuczdcisiC#v^^HRLA}z9(ejq2aa;$$zd&
zdJtE2Y>!u{bLxN8n?hM$%JN}V!Wqgp5CRb-nh@dd`A#a~bwVS;Ju1JCj|neRCo7Hb
z#t7278WO)k(6yVq8^ptidx;;ydA6)Co+Uk!{6ct^Imr#uO)2lx5o|Fd&A!IHj
zz0MXsPhL~PcUu2zM5y6s{+HXDj_grK^NV1YQ5a53m$rsWP~7
zl6RbtoqIkclqY1h_q&w$CFG}}<=CHkT`B8~Pp=TlUe^162AKoxjVfG3yr!+Vm~<_|
z4}>uCY{#8C#FNQeLfyf{$J+YC?Q;fGHi)3BG$DU5#vrIyj`(E4=c=pmm$x^!#~p+M
zwDPBY&}-jlCu7EA1FFPzhj<*JBl+bBKM>Mi^GF1`+MHpy
zk;=N#2>+sTIO%8c4g41O;0DTa5XOA!RH^E6f4@ta?f0c5GQPMN&6j_So1Bs~l0=GIF+Og%&wbW6
zCOSUJJG_e9CMju1yswIzl;Uc78~Wnoyp7ouX561N+?VLarX(e3eCbx0etVOXpLRGvk5hgA;4NOaO?=W|CL!1-)5i!ma&StM
zcCl_`sy`(uaY&Q&Ra*FBS+(Fa{Ck&0RoJ2>7KQ-w8TKfIe(8Tws~p))2$2quU*;f
zTV1wmMt1#zycInKGO;OYFKC|2Q#_Z~jrAUUhZ7N#l<1$c@Rw4B7@ObKW{74od~U+Q
zwc7YTEm66SNq#rR7u>5pvqS%5dv%zz_?Hra;6o0saN{d@**b1ag|tLBkp&>)kBg5>
zWzVLixIUhyl7#e+{pWaa5Tb`4T$^ed@+B~_5pK^!7AY-Wylt!Ns$k4xW@D!Bb;SO82;bPD-#WAt^B?
zjw9tA>1BhlG3={0*1nVfeOi2}e%BlAj~jV#Ez`uRvi)3T2G2|C(ZNn4|D?W`~ox(E{wPE6!7#$!cGF2mHiFBrd$Lo#JMK@3VHKA9zbVGaE_J8z#
L`@Qy_geLz5-v1`J
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index a8827b7..0d2e2bd 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2026-03-14 11:54-0300\n"
+"POT-Creation-Date: 2026-03-15 17:20-0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -38,12 +38,12 @@ msgstr "Retour"
#: templates/app_gateway/application_details.html:125
#: templates/firewall/manage_firewall_rule.html:382
#: templates/firewall/manage_redirect_rule.html:86
-#: templates/gatekeeper/gatekeeper_list.html:77
-#: templates/gatekeeper/gatekeeper_list.html:120
-#: templates/gatekeeper/gatekeeper_list.html:165
-#: templates/gatekeeper/gatekeeper_list.html:213
-#: templates/gatekeeper/gatekeeper_list.html:230
-#: templates/gatekeeper/gatekeeper_list.html:282
+#: templates/gatekeeper/gatekeeper_list.html:93
+#: templates/gatekeeper/gatekeeper_list.html:136
+#: templates/gatekeeper/gatekeeper_list.html:181
+#: templates/gatekeeper/gatekeeper_list.html:229
+#: templates/gatekeeper/gatekeeper_list.html:246
+#: templates/gatekeeper/gatekeeper_list.html:298
#: templates/scheduler/scheduleprofile_form.html:127
#: templates/scheduler/scheduleprofile_list.html:29
#: templates/wireguard/peer_list/peer_preview_modal.html:109
@@ -65,11 +65,11 @@ msgstr ""
"fonctionner immédiatement."
#: api_v2/forms.py:63 app_gateway/forms.py:40 app_gateway/forms.py:92
-#: app_gateway/forms.py:136 app_gateway/forms.py:154 app_gateway/forms.py:226
-#: app_gateway/forms.py:267 cluster/forms.py:67 cluster/forms.py:124
-#: dns/forms.py:37 dns/forms.py:84 dns/forms.py:153 gatekeeper/forms.py:41
-#: gatekeeper/forms.py:75 gatekeeper/forms.py:139 gatekeeper/forms.py:226
-#: gatekeeper/forms.py:256 gatekeeper/forms.py:287
+#: app_gateway/forms.py:136 app_gateway/forms.py:154 app_gateway/forms.py:237
+#: app_gateway/forms.py:278 cluster/forms.py:67 cluster/forms.py:124
+#: dns/forms.py:37 dns/forms.py:84 dns/forms.py:153 gatekeeper/forms.py:70
+#: gatekeeper/forms.py:150 gatekeeper/forms.py:212 gatekeeper/forms.py:299
+#: gatekeeper/forms.py:329 gatekeeper/forms.py:360
#: routing_templates/forms.py:71 scheduler/forms.py:102
#: templates/firewall/manage_firewall_rule.html:379
#: templates/firewall/manage_firewall_settings.html:59
@@ -83,13 +83,13 @@ msgid "Save"
msgstr "Enregistrer"
#: api_v2/models.py:10 app_gateway/forms.py:18 app_gateway/forms.py:106
-#: cluster/forms.py:18 dns/forms.py:130 gatekeeper/forms.py:99
+#: cluster/forms.py:18 dns/forms.py:130 gatekeeper/forms.py:174
#: routing_templates/forms.py:28 templates/api_v2/api_documentation.html:47
#: templates/api_v2/list.html:8 templates/app_gateway/app_gateway_list.html:58
#: templates/app_gateway/app_gateway_list.html:138
#: templates/app_gateway/application_details.html:26
#: templates/cluster/workers_list.html:8 templates/dns/static_host_list.html:68
-#: templates/gatekeeper/gatekeeper_list.html:149
+#: templates/gatekeeper/gatekeeper_list.html:165
#: templates/routing_templates/list.html:8
#: templates/scheduler/scheduleprofile_list.html:13
#: templates/user_manager/peer_group_list.html:8
@@ -133,10 +133,10 @@ msgstr "Activé"
#: app_gateway/views.py:293 app_gateway/views.py:328 app_gateway/views.py:354
#: app_gateway/views.py:404 app_gateway/views.py:432 cluster/views.py:18
#: cluster/views.py:45 cluster/views.py:114 gatekeeper/views.py:23
-#: gatekeeper/views.py:48 gatekeeper/views.py:78 gatekeeper/views.py:101
-#: gatekeeper/views.py:131 gatekeeper/views.py:154 gatekeeper/views.py:202
-#: gatekeeper/views.py:261 gatekeeper/views.py:291 gatekeeper/views.py:314
-#: gatekeeper/views.py:344 gatekeeper/views.py:367 gatekeeper/views.py:416
+#: gatekeeper/views.py:48 gatekeeper/views.py:98 gatekeeper/views.py:121
+#: gatekeeper/views.py:151 gatekeeper/views.py:174 gatekeeper/views.py:222
+#: gatekeeper/views.py:281 gatekeeper/views.py:311 gatekeeper/views.py:334
+#: gatekeeper/views.py:364 gatekeeper/views.py:387 gatekeeper/views.py:436
#: templates/access_denied.html:9
msgid "Access Denied"
msgstr "Accès refusé"
@@ -217,9 +217,9 @@ msgid "Upstream"
msgstr "Upstream"
#: app_gateway/forms.py:41 app_gateway/forms.py:93 app_gateway/forms.py:137
-#: app_gateway/forms.py:155 app_gateway/forms.py:227 app_gateway/forms.py:268
-#: gatekeeper/forms.py:42 gatekeeper/forms.py:76 gatekeeper/forms.py:140
-#: gatekeeper/forms.py:227 gatekeeper/forms.py:257 gatekeeper/forms.py:288
+#: app_gateway/forms.py:155 app_gateway/forms.py:238 app_gateway/forms.py:279
+#: gatekeeper/forms.py:71 gatekeeper/forms.py:151 gatekeeper/forms.py:213
+#: gatekeeper/forms.py:300 gatekeeper/forms.py:330 gatekeeper/forms.py:361
#: scheduler/forms.py:103
#: templates/app_gateway/access_policy_type_select.html:50
#: templates/generic_delete_confirmation.html:19
@@ -263,20 +263,28 @@ msgstr "Groupes autorisés"
msgid "Authentication Methods"
msgstr "Méthodes d'authentification"
-#: app_gateway/forms.py:185
+#: app_gateway/forms.py:188
msgid "Cannot select more than one Local Password authentication method."
msgstr ""
"Impossible de sélectionner plus d'une méthode d'authentification par mot de "
"passe local."
-#: app_gateway/forms.py:189
+#: app_gateway/forms.py:192
msgid ""
"Cannot select more than one OpenID Connect (OIDC) authentication method."
msgstr ""
"Impossible de sélectionner plus d'une méthode d'authentification OpenID "
"Connect (OIDC)."
-#: app_gateway/forms.py:193
+#: app_gateway/forms.py:196
+#, fuzzy
+#| msgid "Cannot select more than one Local Password authentication method."
+msgid "Cannot select more than one TOTP authentication method."
+msgstr ""
+"Impossible de sélectionner plus d'une méthode d'authentification par mot de "
+"passe local."
+
+#: app_gateway/forms.py:200
msgid ""
"Cannot select both Local Password and OpenID Connect (OIDC) authentication "
"methods."
@@ -284,7 +292,19 @@ msgstr ""
"Impossible de sélectionner à la fois les méthodes d'authentification par mot "
"de passe local et OpenID Connect (OIDC)."
-#: app_gateway/forms.py:197
+#: app_gateway/forms.py:204
+#, fuzzy
+#| msgid ""
+#| "Cannot select both Local Password and OpenID Connect (OIDC) "
+#| "authentication methods."
+msgid ""
+"TOTP must be combined with a Local Password or OpenID Connect authentication "
+"method."
+msgstr ""
+"Impossible de sélectionner à la fois les méthodes d'authentification par mot "
+"de passe local et OpenID Connect (OIDC)."
+
+#: app_gateway/forms.py:208
msgid ""
"At least one user group must be selected when using Local Password "
"authentication."
@@ -292,31 +312,31 @@ msgstr ""
"Au moins un groupe d'utilisateurs doit être sélectionné lors de "
"l'utilisation de l'authentification par mot de passe local."
-#: app_gateway/forms.py:201
+#: app_gateway/forms.py:212
msgid "User groups can only be used with Local Password authentication."
msgstr ""
"Les groupes d'utilisateurs ne peuvent être utilisés qu'avec "
"l'authentification par mot de passe local."
-#: app_gateway/forms.py:211 templates/app_gateway/app_gateway_list.html:62
+#: app_gateway/forms.py:222 templates/app_gateway/app_gateway_list.html:62
#: templates/app_gateway/application_details.html:31
#: templates/firewall/firewall_nav_tabs.html:15
msgid "Default Policy"
msgstr "Politique par défaut"
-#: app_gateway/forms.py:240 templates/app_gateway/application_details.html:105
+#: app_gateway/forms.py:251 templates/app_gateway/application_details.html:105
msgid "Route Name"
msgstr "Nom de la route"
-#: app_gateway/forms.py:241 templates/app_gateway/application_details.html:106
+#: app_gateway/forms.py:252 templates/app_gateway/application_details.html:106
msgid "Path Prefix"
msgstr "Préfixe de chemin"
-#: app_gateway/forms.py:242 templates/app_gateway/application_details.html:107
+#: app_gateway/forms.py:253 templates/app_gateway/application_details.html:107
msgid "Policy"
msgstr "Politique"
-#: app_gateway/forms.py:243 templates/app_gateway/application_details.html:108
+#: app_gateway/forms.py:254 templates/app_gateway/application_details.html:108
msgid "Order"
msgstr "Ordre"
@@ -334,9 +354,9 @@ msgstr "Public"
msgid "Protected"
msgstr "Protégé"
-#: app_gateway/models.py:45 gatekeeper/models.py:110
+#: app_gateway/models.py:45 gatekeeper/models.py:108
#: templates/app_gateway/access_policy_type_select.html:41
-#: templates/gatekeeper/gatekeeper_list.html:272
+#: templates/gatekeeper/gatekeeper_list.html:288
msgid "Deny"
msgstr "Refuser"
@@ -624,11 +644,11 @@ msgstr "Supprimer la route d'application"
msgid "Are you sure you want to delete the route \"%(name)s\" (%(path)s)?"
msgstr "Êtes-vous sûr de vouloir supprimer la route \"%(name)s\" (%(path)s) ?"
-#: app_gateway/views.py:444
+#: app_gateway/views.py:443
msgid "Configuration exported successfully."
msgstr "Configuration exportée avec succès."
-#: app_gateway/views.py:446
+#: app_gateway/views.py:445
msgid ""
"Caddy is not active. Configuration files were exported for debugging "
"purposes."
@@ -640,13 +660,13 @@ msgstr ""
msgid "IP Lock"
msgstr "Verrouillage IP"
-#: cluster/forms.py:21 dns/forms.py:67 gatekeeper/forms.py:198
+#: cluster/forms.py:21 dns/forms.py:67 gatekeeper/forms.py:271
#: templates/cluster/workers_list.html:10
#: templates/dns/static_host_list.html:18
#: templates/firewall/manage_redirect_rule.html:43
#: templates/firewall/manage_redirect_rule.html:67
#: templates/firewall/manage_redirect_rule.html:68
-#: templates/gatekeeper/gatekeeper_list.html:256
+#: templates/gatekeeper/gatekeeper_list.html:272
#: templates/wireguard/wireguard_status.html:45
msgid "IP Address"
msgstr "Adresse IP"
@@ -922,7 +942,7 @@ msgstr "DNS statique"
msgid "Invalid hostname."
msgstr "Nom d'hôte invalide."
-#: dns/forms.py:131 firewall/forms.py:111 gatekeeper/forms.py:201
+#: dns/forms.py:131 firewall/forms.py:111 gatekeeper/forms.py:274
#: templates/api_v2/api_documentation.html:51
#: templates/dns/static_host_list.html:69
#: templates/firewall/manage_redirect_rule.html:18
@@ -1256,43 +1276,29 @@ msgstr "Gérer les paramètres du pare‑feu"
msgid "Firewall settings saved successfully"
msgstr "Paramètres du pare‑feu enregistrés avec succès"
-#: gatekeeper/forms.py:17 templates/accounts/login.html:14
-#: templates/gatekeeper/gatekeeper_list.html:61
-#: templates/user_manager/list.html:8 user_manager/forms.py:13
-#: vpn_invite/forms.py:281
-msgid "Username"
-msgstr "Nom d’utilisateur"
-
-#: gatekeeper/forms.py:18 gatekeeper/forms.py:271
-#: templates/gatekeeper/gatekeeper_list.html:62
-#: templates/gatekeeper/gatekeeper_list.html:204
-#: templates/wireguard/peer_list/peer_preview_modal.html:103
-msgid "Email"
-msgstr "E‑mail"
-
-#: gatekeeper/forms.py:19 templates/accounts/login.html:23
+#: gatekeeper/forms.py:17 templates/accounts/login.html:23
#: templates/vpn_invite/invite_settings.html:19 user_manager/forms.py:14
#: vpn_invite/forms.py:282
msgid "Password"
msgstr "Mot de passe"
#: gatekeeper/forms.py:20
-msgid "TOTP Secret"
-msgstr "Secret TOTP"
+msgid ""
+"Minimum 8 characters, with at least one uppercase letter, one lowercase "
+"letter, and one number."
+msgstr ""
-#: gatekeeper/forms.py:55 templates/gatekeeper/gatekeeper_list.html:104
-msgid "Group Name"
-msgstr "Nom du groupe"
+#: gatekeeper/forms.py:23
+#, fuzzy
+#| msgid "Random Password"
+msgid "Confirm Password"
+msgstr "Mot de passe aléatoire"
-#: gatekeeper/forms.py:56 templates/gatekeeper/gatekeeper_list.html:105
-msgid "Members"
-msgstr "Membres"
-
-#: gatekeeper/forms.py:86
+#: gatekeeper/forms.py:28 gatekeeper/forms.py:161
msgid "TOTP Validation PIN"
msgstr "Code de validation TOTP"
-#: gatekeeper/forms.py:89
+#: gatekeeper/forms.py:31 gatekeeper/forms.py:164
msgid ""
"Enter a 6-digit PIN generated by your authenticator app to validate the "
"secret."
@@ -1300,97 +1306,153 @@ msgstr ""
"Saisissez un code à 6 chiffres généré par votre application "
"d'authentification pour valider le secret."
-#: gatekeeper/forms.py:100
+#: gatekeeper/forms.py:38 templates/accounts/login.html:14
+#: templates/gatekeeper/gatekeeper_list.html:61
+#: templates/user_manager/list.html:8 user_manager/forms.py:13
+#: vpn_invite/forms.py:281
+msgid "Username"
+msgstr "Nom d’utilisateur"
+
+#: gatekeeper/forms.py:39 gatekeeper/forms.py:344
+#: templates/gatekeeper/gatekeeper_list.html:62
+#: templates/gatekeeper/gatekeeper_list.html:220
+#: templates/wireguard/peer_list/peer_preview_modal.html:103
+msgid "Email"
+msgstr "E‑mail"
+
+#: gatekeeper/forms.py:40
+msgid "TOTP Secret"
+msgstr "Secret TOTP"
+
+#: gatekeeper/forms.py:87
+#, fuzzy
+#| msgid "Port is required."
+msgid "Password is required."
+msgstr "Le port est obligatoire."
+
+#: gatekeeper/forms.py:90 user_manager/forms.py:127
+msgid "Password must be at least 8 characters long."
+msgstr "Le mot de passe doit comporter au moins 8 caractères."
+
+#: gatekeeper/forms.py:92
+#, fuzzy
+#| msgid "Password must be at least 8 characters long."
+msgid "Password must contain at least one lowercase letter."
+msgstr "Le mot de passe doit comporter au moins 8 caractères."
+
+#: gatekeeper/forms.py:94
+#, fuzzy
+#| msgid "Password must be at least 8 characters long."
+msgid "Password must contain at least one uppercase letter."
+msgstr "Le mot de passe doit comporter au moins 8 caractères."
+
+#: gatekeeper/forms.py:96
+#, fuzzy
+#| msgid "Password must be at least 8 characters long."
+msgid "Password must contain at least one number."
+msgstr "Le mot de passe doit comporter au moins 8 caractères."
+
+#: gatekeeper/forms.py:98
+#, fuzzy
+#| msgid "Password Confirmation"
+msgid "Passwords do not match."
+msgstr "Confirmation du mot de passe"
+
+#: gatekeeper/forms.py:103 gatekeeper/forms.py:249
+msgid "Please provide a PIN to validate the TOTP secret."
+msgstr "Veuillez fournir un code pour valider le secret TOTP."
+
+#: gatekeeper/forms.py:108 gatekeeper/forms.py:254
+msgid "Invalid TOTP PIN."
+msgstr "Code TOTP invalide."
+
+#: gatekeeper/forms.py:110 gatekeeper/forms.py:256
+msgid "Invalid TOTP secret format. Must be a valid Base32 string."
+msgstr "Format du secret TOTP invalide. Doit être une chaîne Base32 valide."
+
+#: gatekeeper/forms.py:130 templates/gatekeeper/gatekeeper_list.html:120
+msgid "Group Name"
+msgstr "Nom du groupe"
+
+#: gatekeeper/forms.py:131 templates/gatekeeper/gatekeeper_list.html:121
+msgid "Members"
+msgstr "Membres"
+
+#: gatekeeper/forms.py:175
msgid "Authentication Type"
msgstr "Type d'authentification"
-#: gatekeeper/forms.py:101
+#: gatekeeper/forms.py:176
msgid "Global TOTP Secret"
msgstr "Secret TOTP mondial"
-#: gatekeeper/forms.py:102
-msgid "Global TOTP Before Authentication"
-msgstr "TOTP global avant l'authentification"
-
-#: gatekeeper/forms.py:103
+#: gatekeeper/forms.py:177
msgid "OIDC Provider URL"
msgstr "URL du fournisseur OIDC"
-#: gatekeeper/forms.py:104
+#: gatekeeper/forms.py:178
msgid "OIDC Client ID"
msgstr "ID client OIDC"
-#: gatekeeper/forms.py:105
+#: gatekeeper/forms.py:179
msgid "OIDC Client Secret"
msgstr "Secret client OIDC"
-#: gatekeeper/forms.py:157
+#: gatekeeper/forms.py:230
msgid "TOTP secret must be empty for Local Password authentication."
msgstr ""
"Le secret TOTP doit être vide pour l'authentification par mot de passe local."
-#: gatekeeper/forms.py:159
+#: gatekeeper/forms.py:232
msgid "TOTP validation PIN must be empty for Local Password authentication."
msgstr ""
"Le code de validation TOTP doit être vide pour l'authentification par mot de "
"passe local."
-#: gatekeeper/forms.py:161
+#: gatekeeper/forms.py:234
msgid "OIDC fields must be empty for Local Password authentication."
msgstr ""
"Les champs OIDC doivent être vides pour l'authentification par mot de passe "
"local."
-#: gatekeeper/forms.py:167
+#: gatekeeper/forms.py:240
msgid "Only one Local Password authentication method can be configured."
msgstr ""
"Un seul système d'authentification par mot de passe local peut être "
"configuré."
-#: gatekeeper/forms.py:170
+#: gatekeeper/forms.py:243
msgid "OIDC fields must be empty for TOTP authentication."
msgstr "Les champs OIDC doivent être vides pour l'authentification TOTP."
-#: gatekeeper/forms.py:172
+#: gatekeeper/forms.py:245
msgid "TOTP secret is required for TOTP authentication."
msgstr "Le secret TOTP est requis pour l'authentification TOTP."
-#: gatekeeper/forms.py:176
-msgid "Please provide a PIN to validate the TOTP secret."
-msgstr "Veuillez fournir un code pour valider le secret TOTP."
-
-#: gatekeeper/forms.py:181
-msgid "Invalid TOTP PIN."
-msgstr "Code TOTP invalide."
-
-#: gatekeeper/forms.py:183
-msgid "Invalid TOTP secret format. Must be a valid Base32 string."
-msgstr "Format du secret TOTP invalide. Doit être une chaîne Base32 valide."
-
-#: gatekeeper/forms.py:186
+#: gatekeeper/forms.py:259
msgid "TOTP secret must be empty for OIDC authentication."
msgstr "Le secret TOTP doit être vide pour l'authentification OIDC."
-#: gatekeeper/forms.py:188
+#: gatekeeper/forms.py:261
msgid "TOTP validation PIN must be empty for OIDC authentication."
msgstr ""
"Le code de validation TOTP doit être vide pour l'authentification OIDC."
-#: gatekeeper/forms.py:197 gatekeeper/forms.py:239 gatekeeper/forms.py:270
+#: gatekeeper/forms.py:270 gatekeeper/forms.py:312 gatekeeper/forms.py:343
msgid "Authentication Method"
msgstr "Méthode d'authentification"
-#: gatekeeper/forms.py:199 templates/gatekeeper/gatekeeper_list.html:257
+#: gatekeeper/forms.py:272 templates/gatekeeper/gatekeeper_list.html:273
msgid "Prefix Length"
msgstr "Longueur du préfixe"
-#: gatekeeper/forms.py:200 templates/firewall/firewall_rule_list.html:47
+#: gatekeeper/forms.py:273 templates/firewall/firewall_rule_list.html:47
#: templates/firewall/manage_firewall_rule.html:360
-#: templates/gatekeeper/gatekeeper_list.html:258
+#: templates/gatekeeper/gatekeeper_list.html:274
msgid "Action"
msgstr "Action"
-#: gatekeeper/forms.py:240 templates/gatekeeper/gatekeeper_list.html:221
+#: gatekeeper/forms.py:313 templates/gatekeeper/gatekeeper_list.html:237
msgid "Domain"
msgstr "Domaine"
@@ -1414,17 +1476,17 @@ msgstr "Liste d'adresses IP"
msgid "Shared/global TOTP secret key"
msgstr "Clé secrète TOTP partagée/globale"
-#: gatekeeper/models.py:69
+#: gatekeeper/models.py:68
msgid "Password for local authentication (leave blank if not using)"
msgstr ""
"Mot de passe pour l'authentification locale (laissez vide si vous ne "
"l'utilisez pas)"
-#: gatekeeper/models.py:71
+#: gatekeeper/models.py:69
msgid "Per-user TOTP secret key"
msgstr "Clé secrète TOTP par utilisateur"
-#: gatekeeper/models.py:110 templates/gatekeeper/gatekeeper_list.html:270
+#: gatekeeper/models.py:108 templates/gatekeeper/gatekeeper_list.html:286
msgid "Allow"
msgstr "Autoriser"
@@ -1440,57 +1502,102 @@ msgstr "Créer un utilisateur Gatekeeper"
msgid "Gatekeeper User saved successfully."
msgstr "Utilisateur Gatekeeper enregistré avec succès."
-#: gatekeeper/views.py:86
+#: gatekeeper/views.py:69
+msgid ""
+"\n"
+" Gatekeeper User
\n"
+" Gatekeeper users are used for authenticating against protected "
+"applications managed by this gateway.
\n"
+"\n"
+" Password
\n"
+" Required when creating a user. When editing, leave both password "
+"fields blank to keep the current password.\n"
+" Passwords are stored using Argon2id hashing.
\n"
+"\n"
+" TOTP Secret
\n"
+" Optional per-user TOTP secret. When set, this user will "
+"authenticate using their own secret instead of the\n"
+" global TOTP secret configured on the Authentication Method. Use the "
+"buttons below the field to generate a\n"
+" random secret and scan the QR code with your authenticator app. "
+"Validate the secret by entering the current\n"
+" 6-digit PIN before saving.
\n"
+" "
+msgstr ""
+
+#: gatekeeper/views.py:106
msgid "Gatekeeper User deleted successfully."
msgstr "Utilisateur Gatekeeper supprimé avec succès."
-#: gatekeeper/views.py:91
+#: gatekeeper/views.py:111
msgid "Delete Gatekeeper User"
msgstr "Supprimer l'utilisateur Gatekeeper"
-#: gatekeeper/views.py:93
+#: gatekeeper/views.py:113
#, python-format
msgid "Are you sure you want to delete the user \"%(username)s\"?"
msgstr "Êtes-vous sûr de vouloir supprimer l'utilisateur \"%(username)s\" ?"
-#: gatekeeper/views.py:107
+#: gatekeeper/views.py:127
msgid "Edit Gatekeeper Group"
msgstr "Modifier le groupe Gatekeeper"
-#: gatekeeper/views.py:110
+#: gatekeeper/views.py:130
msgid "Create Gatekeeper Group"
msgstr "Créer un groupe Gatekeeper"
-#: gatekeeper/views.py:117
+#: gatekeeper/views.py:137
msgid "Gatekeeper Group saved successfully."
msgstr "Groupe Gatekeeper enregistré avec succès."
-#: gatekeeper/views.py:139
+#: gatekeeper/views.py:159
msgid "Gatekeeper Group deleted successfully."
msgstr "Groupe Gatekeeper supprimé avec succès."
-#: gatekeeper/views.py:144
+#: gatekeeper/views.py:164
msgid "Delete Gatekeeper Group"
msgstr "Supprimer le groupe Gatekeeper"
-#: gatekeeper/views.py:146
+#: gatekeeper/views.py:166
#, python-format
msgid "Are you sure you want to delete the group \"%(name)s\"?"
msgstr "Êtes-vous sûr de vouloir supprimer le groupe \"%(name)s\" ?"
-#: gatekeeper/views.py:160
+#: gatekeeper/views.py:180
msgid "Edit Authentication Method"
msgstr "Modifier la méthode d'authentification"
-#: gatekeeper/views.py:163
+#: gatekeeper/views.py:183
msgid "Create Authentication Method"
msgstr "Créer une méthode d'authentification"
-#: gatekeeper/views.py:170
+#: gatekeeper/views.py:190
msgid "Authentication Method saved successfully."
msgstr "Méthode d'authentification enregistrée avec succès."
-#: gatekeeper/views.py:175
+#: gatekeeper/views.py:195
+#, fuzzy
+#| msgid ""
+#| "\n"
+#| " Authentication Types
\n"
+#| " Select how users will authenticate through this method.
\n"
+#| " \n"
+#| " Local Password
\n"
+#| " Users will authenticate using a standard username and password "
+#| "stored locally. Only one of this type can be created.
\n"
+#| " \n"
+#| " OIDC (OpenID Connect)
\n"
+#| " Users will authenticate via an external identity provider "
+#| "(like Keycloak, Google, or Authelia). Requires Provider URL, Client ID, "
+#| "and Client Secret.
\n"
+#| " \n"
+#| " TOTP (Time-Based One-Time Password)
\n"
+#| " Users will need to enter a rotating token from an "
+#| "authenticator app. Requires setting a Global TOTP Secret.
If "
+#| "Global TOTP Before Authentication is enabled, the PIN is "
+#| "required before the username and password to help combat bruteforce "
+#| "attacks.
\n"
+#| " "
msgid ""
"\n"
" Authentication Types
\n"
@@ -1507,9 +1614,8 @@ msgid ""
" \n"
" TOTP (Time-Based One-Time Password)
\n"
" Users will need to enter a rotating token from an authenticator "
-"app. Requires setting a Global TOTP Secret.
If Global TOTP "
-"Before Authentication is enabled, the PIN is required before the "
-"username and password to help combat bruteforce attacks.
\n"
+"app. If a user does not have a personal TOTP configured, the Global "
+"TOTP Secret will be used instead.
\n"
" "
msgstr ""
"\n"
@@ -1535,86 +1641,86 @@ msgstr ""
"pour aider à lutter contre les attaques par force brute.