1import{r as i,s as p,o as W,j as e,N as Y,H as Z,q as ee,I as S,m as L}from"./shield-check-B4bOhH5m.js";import{bf as te,u as se,bg as M,bh as q,bi as B,bj as re}from"./entry-standard-CSk4ffYh.js";import{C as ae,b as ie,c as ne,d as oe,a as F,e as T}from"./card-CTsF48jq.js";import{L as N}from"./label-BEZOS6j-.js";import{l as ce}from"./useRecaptcha-CdDwmr-_.js";import{L as le}from"./lock-DM2S7p74.js";import{S as de}from"./smartphone-DuvCWACa.js";import{K as ue}from"./key-round-CFBXKVzR.js";import"./main-Dww2uteL.js";function me(r){const a="admin_login",u=i.useCallback(async()=>{const f="6LcnY1wtAAAAAMvE8lwk8Ex1SPIt8Mwd97gF1VQg";return await ce(),await new Promise(l=>window.grecaptcha.ready(l)),window.grecaptcha.execute(f,{action:a})},[a]),x=i.useCallback(async f=>{const l=await u(),{data:c,error:w}=await p.functions.invoke("check-auth-rate-limit",{body:{op:"check",kind:r,email:f,action:a,recaptchaToken:l}});return w?{ok:!1,reason:w.message}:c!=null&&c.blocked?{ok:!1,blocked:!0,waitSeconds:c.waitSeconds,retryAt:c.retryAt,reason:c.reason}:{ok:!0}},[r,a,u]),b=i.useCallback(async(f,l)=>{try{await p.functions.invoke("check-auth-rate-limit",{body:{op:"record",kind:r,email:f,success:l}})}catch(c){console.warn("[rate-limit] record failed",c)}},[r]);return{checkBeforeLogin:x,recordAttempt:b}}function P(r){if(r<60)return`${r} s`;const a=Math.ceil(r/60);if(a<60)return`${a} min`;const u=Math.floor(a/60),x=a%60;return x?`${u} h ${x} min`:`${u} h`}const ge=()=>{const[r,a]=i.useState("password"),[u,x]=i.useState(""),[b,f]=i.useState(""),[l,c]=i.useState(""),[w,R]=i.useState(""),[k,U]=i.useState(null),[m,v]=i.useState(!1),[j,$]=i.useState(0),[H,A]=i.useState(!1),{loginAdmin:K,isAdmin:X,adminUser:g}=te(),{toast:h}=se(),C=W(),{checkBeforeLogin:G,recordAttempt:z}=me("admin");if(i.useEffect(()=>{let s=!1;if(!X||!g||!M(g.id)){A(!1);return}return(async()=>{try{const t=await q(g.id);if(s)return;t||B(),A(t)}catch(t){if(s)return;console.error("Impossible de vérifier le niveau MFA administrateur:",t),B(),A(!1)}})(),()=>{s=!0}},[g,X]),H)return e.jsx(Y,{to:"/admin",replace:!0});const O=async s=>{var o;s.preventDefault(),v(!0);const t=u.trim().toLowerCase();try{const n=await G(t);if(!n.ok){n.blocked&&n.waitSeconds?($(n.waitSeconds),h({title:"Trop de tentatives",description:`Compte temporairement bloqué. Réessayez dans ${P(n.waitSeconds)}.`,variant:"destructive"})):h({title:"Vérification échouée",description:n.reason||"Impossible de vérifier la requête.",variant:"destructive"});return}try{await K(t,b),await z(t,!0);const{data:d,error:y}=await p.auth.mfa.listFactors();if(y)throw y;const I=((d==null?void 0:d.all)??[]).find(V=>V.factor_type==="totp"&&V.status==="verified");if(!I){C("/admin-connexion/mfa-setup",{replace:!0});return}const{data:Q,error:D}=await p.auth.getUser(),E=(o=Q.user)==null?void 0:o.id;if(D||!E)throw D||new Error("Session administrateur introuvable.");if(M(E)&&await q(E)){C("/admin",{replace:!0});return}U(I.id),a("mfa")}catch(d){const y=d instanceof Error?d.message:"";(y==="Email ou mot de passe incorrect."||y==="Ce compte ne dispose pas des droits administrateur.")&&await z(t,!1),h({title:"Ãchec de connexion",description:y||"La connexion administrateur a échoué. Veuillez réessayer.",variant:"destructive"})}}catch(n){h({title:"Erreur",description:n instanceof Error?n.message:"Erreur inattendue",variant:"destructive"})}finally{v(!1)}},_=async s=>{if(s.preventDefault(),!k)return;v(!0);let t=!1;try{const{data:o,error:n}=await p.auth.mfa.challenge({factorId:k});if(n||!o)throw n||new Error("Défi impossible");const{error:d}=await p.auth.mfa.verify({factorId:k,challengeId:o.id,code:l.trim()});if(d)throw d;t=!0,await re(),C("/admin",{replace:!0})}catch(o){h({title:t?"Connexion non mémorisée":"Code invalide",description:o instanceof Error?o.message:t?"Veuillez réessayer.":"Code TOTP refusé",variant:"destructive"})}finally{v(!1)}},J=async s=>{s.preventDefault(),v(!0);try{const{data:t,error:o}=await p.functions.invoke("admin-mfa-backup",{body:{action:"consume",code:w.trim()}});if(o)throw o;if(!(t!=null&&t.ok))throw new Error((t==null?void 0:t.error)||"Code refusé");h({title:"Code accepté",description:"Votre authentificateur a été réinitialisé. Configurez-en un nouveau."}),C("/admin-connexion/mfa-setup",{replace:!0})}catch(t){h({title:"Code invalide",description:t instanceof Error?t.message:"Code refusé",variant:"destructive"})}finally{v(!1)}};return e.jsxs("div",{className:"min-h-screen flex items-center justify-center bg-gray-100",children:[e.jsxs(Z,{children:[e.jsx("title",{children:"Connexion administrateur â Bien-être Connect"}),e.jsx("meta",{name:"robots",content:"noindex, nofollow"})]}),e.jsx("div",{className:"w-full max-w-md p-4",children:e.jsxs(ae,{className:"shadow-lg",children:[e.jsxs(ie,{className:"space-y-1 flex flex-col items-center",children:[e.jsx("div",{className:"bg-primary w-12 h-12 rounded-full flex items-center justify-center mb-2",children:e.jsx(ee,{className:"w-6 h-6 text-white"})}),e.jsx(ne,{className:"text-2xl text-center",children:"Connexion administrateur"}),e.jsxs(oe,{className:"text-center",children:[r==="password"&&"Accès sécurisé réservé aux administrateurs",r==="mfa"&&"Saisissez le code de Google Authenticator",r==="backup"&&"Utilisez un code de secours"]})]}),r==="password"&&e.jsxs("form",{onSubmit:O,children:[e.jsxs(F,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"email",children:"Email"}),e.jsx(S,{id:"email",type:"email",autoComplete:"username",value:u,onChange:s=>x(s.target.value),required:!0,disabled:m||j>0})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"password",children:"Mot de passe"}),e.jsx(S,{id:"password",type:"password",autoComplete:"current-password",value:b,onChange:s=>
1f(s.target.value),required:!0,disabled:m||j>0})]}),j>0&&e.jsxs("p",{className:"text-sm text-destructive text-center",children:["Trop de tentatives â réessayez dans ",P(j),"."]}),e.jsx("p",{className:"text-xs text-muted-foreground text-center",children:"Protégé par reCAPTCHA et double authentification."})]}),e.jsx(T,{children:e.jsx(L,{type:"submit",className:"w-full",disabled:m||j>0,children:m?"Connexion en coursâ¦":e.jsxs("span",{className:"flex items-center",children:[e.jsx(le,{className:"mr-2 h-4 w-4"})," Se connecter"]})})})]}),r==="mfa"&&e.jsxs("form",{onSubmit:_,children:[e.jsxs(F,{className:"space-y-4",children:[e.jsx("div",{className:"flex justify-center",children:e.jsx(de,{className:"w-10 h-10 text-primary"})}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"otp",children:"Code à 6 chiffres"}),e.jsx(S,{id:"otp",inputMode:"numeric",pattern:"[0-9]*",maxLength:6,autoComplete:"one-time-code",autoFocus:!0,value:l,onChange:s=>c(s.target.value.replace(/\D/g,"")),required:!0})]}),e.jsx("button",{type:"button",onClick:()=>a("backup"),className:"text-xs text-primary underline w-full text-center",children:"J'ai perdu mon téléphone â utiliser un code de secours"})]}),e.jsx(T,{children:e.jsx(L,{type:"submit",className:"w-full",disabled:m||l.length!==6,children:m?"Vérificationâ¦":"Valider"})})]}),r==="backup"&&e.jsxs("form",{onSubmit:J,children:[e.jsxs(F,{className:"space-y-4",children:[e.jsx("div",{className:"flex justify-center",children:e.jsx(ue,{className:"w-10 h-10 text-primary"})}),e.jsx("p",{className:"text-xs text-muted-foreground text-center",children:"Utiliser un code de secours réinitialisera votre authentificateur. Vous devrez ensuite en configurer un nouveau."}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(N,{htmlFor:"bc",children:"Code de secours"}),e.jsx(S,{id:"bc",autoFocus:!0,value:w,onChange:s=>R(s.target.value.toUpperCase()),placeholder:"XXXXX-XXXXX",required:!0})]}),e.jsx("button",{type:"button",onClick:()=>a("mfa"),className:"text-xs text-primary underline w-full text-center",children:"Retour au code Google Authenticator"})]}),e.jsx(T,{children:e.jsx(L,{type:"submit",className:"w-full",disabled:m||w.length<10,children:m?"Vérificationâ¦":"Valider le code de secours"})})]})]})})]})};export{ge as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.