1import{d as me,C as xe,Z as fe,b as be,Y as ye,o as we,w as W,c as ge,k as r,h as t,j as s,v as a,l as w,I as d,i as X,f as he,g as c,t as b,q as Z,L as ke,r as l,x as Ce,J as _e,p as Ae,e as n,am as Fe,E as N,G as ee,H as te,F as se,y as ae,D as oe,ae as Te}from"./CxtYSI8p.js";import{_ as Se}from"./DCsG_pTt.js";import{u as Ee}from"./C7XnKuu5.js";import"./DbnxMNFr.js";import"./BoIYZ6dm.js";const Be={key:0,class:"mb-6 bg-yellow-500/10 border border-yellow-500/40 rounded-xl p-4"},Pe={class:"flex items-start gap-3"},Ve={class:"space-y-6"},Ue={class:"bg-card p-6 rounded-xl shadow-card border border-card-text/10"},Me={class:"flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4"},Ne={class:"flex-1"},De={key:0,class:"flex items-center gap-2 text-sm text-card-text-secondary"},Re={key:1,class:"flex items-center gap-2"},qe={key:2,class:"flex items-center gap-2"},je={key:0,class:"font-bold"},Ye={key:0,class:"shrink-0"},Le={key:1,class:"flex flex-col sm:flex-row gap-2"},Oe={key:0,class:"mt-4 bg-destructive/10 border border-destructive/20 text-destructive px-4 py-3 rounded-lg text-sm"},$e={key:1,class:"mt-4 bg-green-500/10 border border-green-500/30 text-card-text px-4 py-3 rounded-lg text-sm"},Ie={class:"bg-card p-6 rounded-xl shadow-card border border-card-text/10"},Ge={class:"bg-card rounded-xl shadow-xl max-w-md w-full p-6 my-auto",role:"dialog","aria-modal":"true","aria-label":"Set up two-factor authentication"},He={key:0},Qe={class:"mb-6"},Ke={key:0,class:"mb-4 bg-destructive/10 border border-destructive/20 text-destructive px-4 py-3 rounded-lg text-sm"},ze={class:"flex gap-3"},Je={key:1},We={class:"flex justify-center mb-4 bg-white p-3 sm:p-4 rounded-lg"},Xe=["src"],Ze={class:"text-xs text-card-text-secondary text-center mb-6"},et=["href"],tt={class:"mb-6"},st={key:0,class:"mb-4 bg-destructive/10 border border-destructive/20 text-destructive px-4 py-3 rounded-lg text-sm"},at={class:"flex gap-3"},ot={key:2},lt={class:"text-center"},nt={class:"flex justify-center mb-4"},rt={class:"mb-6 bg-yellow-500/10 border border-yellow-500/30 rounded-lg p-4 text-left"},dt={class:"text-sm font-semibold text-card-text mb-2 flex items-center gap-2"},it={class:"grid grid-cols-2 gap-2 font-mono text-xs bg-card-text/10 p-3 rounded"},ut={class:"text-center"},ct={class:"bg-card rounded-xl shadow-xl max-w-md w-full p-6 my-auto",role:"dialog","aria-modal":"true","aria-labelledby":"regenerate-codes-title"},pt={key:0},vt={class:"mb-4"},mt={class:"mb-6"},xt={key:0,class:"mb-4 bg-destructive/10 border border-destructive/20 text-destructive px-4 py-3 rounded-lg text-sm"},ft={class:"flex gap-3"},bt={key:1},yt={class:"grid grid-cols-2 gap-2 font-mono text-xs bg-card-text/10 p-3 rounded mb-3"},wt={class:"bg-card rounded-xl shadow-xl max-w-md w-full p-6 my-auto",role:"dialog","aria-modal":"true","aria-labelledby":"disable-2fa-title"},gt={class:"space-y-4 mb-6"},ht={class:"flex gap-3"},K=6,St=me({__name:"security",setup(kt){const E=Ee(),le=xe(),ne=fe(),re=Z(()=>ne.siteName.value),de=be(),O=ke(),g=Z(()=>de.query.require2fa==="admin");ye({title:"Security Settings",description:`Manage your account security settings including two-factor authentication on ${re.value}.`,minimal:!0});const D=l(!1),i=l(""),_=l(""),h=l(!1),B=l(!1),v=l(!1),y=l(""),P=l(""),V=l([]),U=l(!1),x=l(""),f=l(""),A=l(!1),R=l(!1),F=l(!1),k=l(""),C=l(""),T=l(""),M=l([]),q=l(!1),j=l(!1),Y=l(!1),S=l("");we(async()=>{await $(),g.value&&O.warning("Two-factor authentication is required for admin access. Please enable 2FA to continue.",8e3)});const $=async()=>{D.value=!0,i.value="";try{await E.fetchCurrentUser(),h.value=le.user?.twoFactorEnabled||!1}catch(o){i.value=o.data?.message||"Failed to load 2FA status"}finally{D.value=!1}},z=async()=>{if(!v.value){if(!x.value){i.value="Please enter your password";return}v.value=!0,i.value="";try{const o=await E.setup2FA(x.value);y.value=o.data.qrCodeUrl,P.value=o.data.otpauthUrl}catch(o){i.value=o.data?.message||"Failed to initiate 2FA setup"}finally{v.value=!1}}},J=async()=>{if(v.value=!0,i.value="",!x.value){i.value="Your setup session expired. Please start again.",y.value="",v.value=!1;return}if(!f.value||f.value.length!==K){i.value="Please enter a valid 6-digit code",v.value=!1;return}try{const e=(await E.verify2FASetup(f.value,x.value)).data?.backupCodes??[];if(!e.length){i.value='Two-factor authentication was enabled, but we could not show your backup codes. Use "New backup codes" on this page to generate a set.',h.value=!0,ve(),await $();return}V.value=e,U.value=!1,x.value="",A.value=!0,h.value=!0,_.value="Two-factor authentication has been enabled successfully!",g.value||setTimeout(()=>{_.value=""},5e3)}catch(o){i.value=o.data?.message||"Invalid verification code",o.data?.code==="TWO_FACTOR_SETUP_EXPIRED"&&(y.value="",P.value="",f.value="")}finally{v.value=!1}},ie=async()=>{try{await navigator.clipboard.writeText(V.value.join(` 2`)),U.value=!0}catch{O.error("Could not copy to clipboard. Please write the codes down instead.")}},ue=async()=>
2{if(!F.value){F.value=!0,T.value="";try{const e=(await E.regenerateBackupCodes(k.value,C.value)).data?.backupCodes??[];if(!e.length){T.value="Your previous codes were replaced, but we could not show the new ones. Please try again.";return}M.value=e,q.value=!1,k.value="",C.value=""}catch(o){T.value=o.data?.message||"Could not generate new backup codes"}finally{F.value=!1}}},ce=async()=>{try{await navigator.clipboard.writeText(M.value.join(` 3`)),q.value=!0}catch{O.error("Could not copy to clipboard. Please write the codes down instead.")}},I=()=>{F.value||(R.value=!1,k.value="",C.value="",T.value="",M.value=[],q.value=!1)},pe=async()=>{Y.value=!0,i.value="";try{const o=await E.disable2FA(S.value);h.value=!1,_.value="Two-factor authentication has been disabled.",G();try{await $()}catch{}setTimeout(()=>{_.value=""},5e3)}catch(o){i.value=o.data?.message||"Failed to disable 2FA"}finally{Y.value=!1}},ve=()=>{B.value=!1,y.value="",P.value="",V.value=[],U.value=!1,x.value="",f.value="",A.value=!1},L=()=>{if(v.value)return;const o=A.value;B.value=!1,y.value="",P.value="",V.value=[],U.value=!1,x.value="",f.value="",A.value=!1,v.value=!1,i.value="",o&&g.value&&Te("/admin")},G=()=>{j.value=!1,S.value="",Y.value=!1};return W(f,o=>{const e=o.length===K&&/^\d+$/.test(o);y.value&&!A.value&&e&&!v.value&&J()}),W([B,j,R],([o,e,m])=>{o||e||m?document.body.style.overflow="hidden":document.body.style.overflow=""}),ge(()=>{document.body.style.overflow=""}),(o,e)=>{const m=Ce,p=_e,H=Se,Q=Ae;return n(),r("div",null,[e[53]||(e[53]=t("h2",{class:"h2 text-card-text mb-6"},"Security Settings",-1)),s(g)&&!s(h)?(n(),r("div",Be,[t("div",Pe,[a(m,{name:"heroicons:shield-exclamation",class:"h-6 w-6 text-yellow-500 shrink-0 mt-0.5"}),e[9]||(e[9]=t("div",null,[t("h3",{class:"text-lg font-semibold text-card-text"},"Two-Factor Authentication Required"),t("p",{class:"text-sm text-card-text-secondary mt-1"}," As an administrator, you must enable two-factor authentication to access admin features. This helps protect sensitive competition data and user information. ")],-1))])])):w("",!0),t("div",Ve,[t("div",Ue,[t("div",Me,[t("div",Ne,[e[13]||(e[13]=t("h3",{class:"h4 text-card-text mb-2"},"Two-Factor Authentication",-1)),e[14]||(e[14]=t("p",{class:"text-sm text-card-text-secondary mb-4"}," Add an extra layer of security to your account by requiring a verification code from your authenticator app when signing in. ",-1)),s(D)?(n(),r("div",De,[a(m,{name:"heroicons:arrow-path",class:"animate-spin h-4 w-4"}),e[10]||(e[10]=d(" Loading 2FA status... ",-1))])):s(h)?(n(),r("div",Re,[a(m,{name:"heroicons:shield-check",class:"h-5 w-5 text-green-400"}),e[11]||(e[11]=t("span",{class:"text-sm font-medium text-green-400"}," Two-factor authentication is enabled ",-1))])):(n(),r("div",qe,[a(m,{name:"heroicons:exclamation-triangle",class:X(["h-5 w-5",s(g)?"text-red-400":"text-yellow-400"])},null,8,["class"]),t("span",{class:X(["text-sm font-medium",s(g)?"text-red-400":"text-yellow-400"])},[e[12]||(e[12]=d(" Two-factor authentication is not enabled ",-1)),s(g)?(n(),r("span",je," â Required for admin access")):w("",!0)],2)]))]),s(D)?w("",!0):(n(),r("div",Ye,[s(h)?(n(),r("div",Le,[a(p,{variant:"outline",onClick:e[1]||(e[1]=u=>R.value=!0),class:"inline-flex items-center gap-2 w-full sm:w-auto justify-center"},{default:c(()=>[a(m,{name:"heroicons:arrow-path",class:"h-4 w-4"}),e[16]||(e[16]=d(" New backup codes ",-1))]),_:1}),a(p,{variant:"destructive",onClick:e[2]||(e[2]=u=>j.value=!0),class:"inline-flex items-center gap-2 w-full sm:w-auto justify-center"},{default:c(()=>[a(m,{name:"heroicons:x-mark",class:"h-4 w-4"}),e[17]||(e[17]=d(" Disable 2FA ",-1))]),_:1})])):(n(),he(p,{key:0,onClick:e[0]||(e[0]=u=>B.value=!0),class:"inline-flex items-center gap-2 w-full sm:w-auto justify-center"},{default:c(()=>[a(m,{name:"heroicons:lock-closed",class:"h-4 w-4"}),e[15]||(e[15]=d(" Enable 2FA ",-1))]),_:1}))]))]),s(i)?(n(),r("div",Oe,b(s(i)),1)):w("",!0),s(_)?(n(),r("div",$e,b(s(_)),1)):w("",!0)]),t("div",Ie,[e[19]||(e[19]=t("h3",{class:"h4 text-card-text mb-2"},"Password",-1)),e[20]||(e[20]=t("p",{class:"text-sm text-card-text-secondary mb-4"}," Change your password to keep your account secure. ",-1)),a(p,{to:"/account/change-password",class:"inline-flex items-center gap-2"},{default:c(()=>[a(m,{name:"heroicons:key",class:"h-5 w-5"}),e[18]||(e[18]=d(" Change Password ",-1))]),_:1})])]),a(Q,{"model-value":s(B),onBackdropClick:L},{default:c(()=>[t("div",Ge,[s(y)?s(A)?(n(),r("div",ot,[t("div",lt,[t("div",nt,[a(m,{name:"heroicons:check-circle",class:"h-16 w-16 text-green-400"})]),e[33]||(e[33]=t("h3",{class:"h4 text-card-text mb-2"},"2FA Enabled Successfully!",-1)),e[34]||(e[34]=t("p",{class:"text-sm text-card-text-secondary mb-6"}," Your account is now protected with two-factor authentication. ",-1))]),t("div",rt,[t("h4",dt,[a(m,{name:"heroicons:exclamation-triangle",class:"h-5 w-5 text-yellow-500"}),e[35]||(e[35]=d(" Save Your Backup Codes ",-1))]),e[36]||(e[36]=t("p",{class:"text-xs text-card-text-secondary mb-3"}," Store these somewhere safe. They are the only way back into your account if you lose your authenticator app, and this is the only time we will show them. ",-1)),t("div",it,[(n(!0),r(se,null,ae(s(V),u=>(n(),r("div",{key:u,class:"text-card-text"},b(u),1))),128))]),a(p,{variant:"outline",class:"w-full mt-3 text-xs",onClick:ie},{default:c(()=>[d(b(s(U)?"Copied":"Copy codes"),1)]),_:1})]),t("div",ut,[e[38]||(e[38]=t("p",{class:"text-xs text-card-text-secondary mb-3"}," Other devices have been signed out. ",-1)),a(p,{onClick:L,class:"w-full"},{default:c(()=>
3[...e[37]||(e[37]=[d(" Done ",-1)])]),_:1})])])):(n(),r("div",Je,[e[31]||(e[31]=t("h3",{class:"h4 text-card-text mb-4"},"Scan QR Code",-1)),e[32]||(e[32]=t("p",{class:"text-sm text-card-text-secondary mb-4"}," Scan this QR code with your authenticator app: ",-1)),t("div",We,[t("img",{src:s(y),alt:"2FA QR Code",class:"w-48 h-48 sm:w-64 sm:h-64"},null,8,Xe)]),t("p",Ze,[e[27]||(e[27]=d(" On mobile? ",-1)),t("a",{href:s(P),class:"text-primary hover:text-primary/80 underline"}," Tap here to open your authenticator app ",8,et)]),t("div",tt,[e[28]||(e[28]=t("label",{for:"verify-token",class:"label"},"Enter verification code",-1)),ee(t("input",{id:"verify-token","onUpdate:modelValue":e[5]||(e[5]=u=>N(f)?f.value=u:null),type:"text",inputmode:"numeric",pattern:"[0-9]{6}",maxlength:"6",class:"input text-center text-xl tracking-widest",placeholder:"000000"},null,512),[[te,s(f)]])]),s(i)?(n(),r("div",st,b(s(i)),1)):w("",!0),t("div",at,[a(p,{onClick:J,loading:s(v),disabled:s(f).length!==6,class:"flex-1"},{default:c(()=>[...e[29]||(e[29]=[d(" Verify & Enable ",-1)])]),_:1},8,["loading","disabled"]),a(p,{variant:"outline",disabled:s(v),onClick:L},{default:c(()=>[...e[30]||(e[30]=[d(" Cancel ",-1)])]),_:1},8,["disabled"])])])):(n(),r("div",He,[e[24]||(e[24]=t("h3",{class:"h4 text-card-text mb-4"},"Enable Two-Factor Authentication",-1)),e[25]||(e[25]=t("p",{class:"text-sm text-card-text-secondary mb-4"}," To enable 2FA, you'll need an authenticator app like Google Authenticator, Authy, or 1Password. ",-1)),e[26]||(e[26]=t("p",{class:"text-sm text-card-text-secondary mb-4"}," Turning 2FA on will sign you out on every other device. ",-1)),t("div",Qe,[e[21]||(e[21]=t("label",{for:"setup-password",class:"label"},"Confirm your password",-1)),a(H,{id:"setup-password",modelValue:s(x),"onUpdate:modelValue":e[3]||(e[3]=u=>N(x)?x.value=u:null),class:"input",autocomplete:"current-password","data-1p-ignore":"","data-lpignore":"true","data-form-type":"other",onKeyup:e[4]||(e[4]=Fe(u=>z(),["enter"]))},null,8,["modelValue"])]),s(i)?(n(),r("div",Ke,b(s(i)),1)):w("",!0),t("div",ze,[a(p,{onClick:z,loading:s(v),disabled:!s(x),class:"flex-1"},{default:c(()=>[...e[22]||(e[22]=[d(" Continue ",-1)])]),_:1},8,["loading","disabled"]),a(p,{variant:"outline",disabled:s(v),onClick:L},{default:c(()=>[...e[23]||(e[23]=[d(" Cancel ",-1)])]),_:1},8,["disabled"])])]))])]),_:1},8,["model-value"]),a(Q,{"model-value":s(R),onBackdropClick:I},{default:c(()=>[t("div",ct,[s(M).length?(n(),r("div",bt,[e[46]||(e[46]=t("h3",{id:"regenerate-codes-title",class:"h4 text-card-text mb-2"},"Your New Backup Codes",-1)),e[47]||(e[47]=t("p",{class:"text-xs text-card-text-secondary mb-3"}," Store these somewhere safe. Your previous codes no longer work, and this is the only time we will show these. ",-1)),t("div",yt,[(n(!0),r(se,null,ae(s(M),u=>(n(),r("div",{key:u,class:"text-card-text"},b(u),1))),128))]),a(p,{variant:"outline",class:"w-full mb-3 text-xs",onClick:ce},{default:c(()=>[d(b(s(q)?"Copied":"Copy codes"),1)]),_:1}),a(p,{class:"w-full",onClick:I},{default:c(()=>[...e[45]||(e[45]=[d(" Done ",-1)])]),_:1})])):(n(),r("div",pt,[e[43]||(e[43]=t("h3",{id:"regenerate-codes-title",class:"h4 text-card-text mb-4"},"New Backup Codes",-1)),e[44]||(e[44]=t("p",{class:"text-sm text-card-text-secondary mb-4"}," This replaces your existing backup codes. Any codes you still have will stop working. ",-1)),t("div",vt,[e[39]||(e[39]=t("label",{for:"regen-password",class:"label"},"Confirm your password",-1)),a(H,{id:"regen-password",modelValue:s(k),"onUpdate:modelValue":e[6]||(e[6]=u=>N(k)?k.value=u:null),class:"input",autocomplete:"current-password","data-1p-ignore":"","data-lpignore":"true","data-form-type":"other"},null,8,["modelValue"])]),t("div",mt,[e[40]||(e[40]=t("label",{for:"regen-token",class:"label"},"Authenticator code",-1)),ee(t("input",{id:"regen-token","onUpdate:modelValue":e[7]||(e[7]=u=>N(C)?C.value=u:null),type:"text",inputmode:"numeric",pattern:"[0-9]{6}",maxlength:"6",class:"input text-center text-xl tracking-widest",placeholder:"000000"},null,512),[[te,s(C)]])]),s(T)?(n(),r("div",xt,b(s(T)),1)):w("",!0),t("div",ft,[a(p,{loading:s(F),disabled:!s(k)||s(C).length!==K,class:"flex-1",onClick:ue},{default:c(()=>[...e[41]||(e[41]=[d(" Generate new codes ",-1)])]),_:1},8,["loading","disabled"]),a(p,{variant:"outline",disabled:s(F),onClick:I},{default:c(()=>[...e[42]||(e[42]=[d(" Cancel ",-1)])]),_:1},8,["disabled"])])]))])]),_:1},8,["model-value"]),a(Q,{"model-value":s(j),onBackdropClick:G},{default:c(()=>[t("div",wt,[e[51]||(e[51]=t("h3",{id:"disable-2fa-title",class:"h4 text-card-text mb-4"},"Disable Two-Factor Authentication",-1)),e[52]||(e[52]=t("p",{class:"text-sm text-card-text-secondary mb-6"}," Are you sure you want to disable 2FA? Your account will be less secure without it. ",-1)),t("div",gt,[t("div",null,[e[48]||(e[48]=t("label",{for:"disable-password",class:"label"},"Confirm your password",-1)),a(H,{id:"disable-password",modelValue:s(S),"onUpdate:modelValue":e[8]||(e[8]=u=>N(S)?S.value=u:null),class:"input",placeholder:"Enter your password",autocomplete:"off","data-1p-ignore":"","data-lpignore":"true","data-form-type":"other"},null,8,["modelValue"])])]),t("div",ht,[a(p,{variant:"destructive",onClick:oe(pe,["stop"]),loading:s(Y),disabled:!s(S),class:"flex-1"},{default:c(()=>[...e[49]||(e[49]=[d(" Disable 2FA ",-1)])]),_:1},8,["loading","disabled"]),a(p,{variant:"outline",onClick:oe(G,["stop"])},{default:c(()=>[...e[50]||(e[50]=[d(" Cancel ",-1)])]),_:1})])])]),_:1},8,["model-value"])])}}});
3export{St 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.