Files
zsglpt/static/app/assets/LoginPage-BtooAZsk.js
2026-05-27 20:39:46 +08:00

2 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{f as X,g as n,h as Ee,i as Le,j as l,k as s,l as u,n as ae,t as g,w,v as k,m as se,p as Re,q as oe,o as c}from"./vendor-vue-WbiK4TmU.js";import{S as Ve}from"./SocialLoginButtons-BlVSr6Mm.js";import{_ as Ne}from"./style-CEbARg1o.js";import"./base-xgxQQEpV.js";import"./el-overlay-hge8bsIn.js";import"./aria-DLpFpzDe.js";import"./http-BoPYlvwK.js";import"./vendor-axios-B9ygI19o.js";import"./index-CoYtSGUZ.js";import"./auth-B5cl_nsV.js";const Ie={class:"login-page"},$e={class:"login-container"},Be={class:"form-group"},Ke={class:"form-group"},De={key:1,class:"form-group"},ze={class:"captcha-row"},He=["src"],je=["disabled"],qe=["disabled"],Fe={key:2,class:"social-login-area"},Je={class:"action-links"},We={class:"modal-card"},Me={class:"modal-head"},Ge={key:0,class:"modal-tip warn"},Xe={key:1,class:"modal-tip error"},Qe={class:"form-group"},Ye={class:"form-group"},Ze={class:"captcha-row"},et=["src"],tt={class:"modal-actions"},at=["disabled"],st={class:"modal-card"},ot={class:"modal-head"},nt={key:0,class:"modal-tip error"},rt={class:"form-group"},it={class:"form-group"},lt={class:"captcha-row"},ct=["src"],ut={class:"modal-actions"},dt=["disabled"],pt={__name:"LoginPage",setup(mt){const i=X({username:"",password:"",captcha:""}),_=n(!1),A=n(""),H=n(""),U=n(!1),E=n(!1),C=n(!1),j=n(!1),q=n(""),L=n(""),S=n(!1),P=n(!1),p=X({username:"",captcha:""}),R=n(""),F=n(""),V=n(!1),T=n(""),y=n(""),m=X({email:"",captcha:""}),N=n(""),J=n(""),I=n(!1),h=n(""),ne=Ee(()=>!0),Q=n(!1),$=n({enabled:!1,providers:[]}),B=n(!1),K={token:"zsglpt_social_pending_bind_token",provider:"zsglpt_social_pending_bind_provider",nickname:"zsglpt_social_pending_bind_nickname",avatar:"zsglpt_social_pending_bind_avatar_url"};function re(t){const e=String(t).replace(/([.*+?^${}()|[\]\\])/g,"\\$1"),a=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return a?decodeURIComponent(a[1]):""}class ie extends Error{constructor(e,a,o){super(e||"请求失败"),this.name="ApiError",this.response={status:Number(a||0),data:o||{}}}}async function f(t,e={}){const a=String(e.method||"GET").toUpperCase(),o={...e.headers||{}},v=Object.prototype.hasOwnProperty.call(e,"body");if(v&&!o["Content-Type"]&&(o["Content-Type"]="application/json"),!["GET","HEAD","OPTIONS"].includes(a)){const te=re("csrf_token");te&&(o["X-CSRF-Token"]=te)}const b=await fetch(`/api${t}`,{method:a,headers:o,credentials:"include",body:v?JSON.stringify(e.body??{}):void 0});let d={};try{d=await b.json()}catch{d={}}if(!b.ok)throw new ie(d?.error||d?.message||`请求失败 (${b.status})`,b.status,d);return d}const le=()=>f("/email/verify-status"),W=()=>f("/generate_captcha",{method:"POST",body:{}}),ce=t=>f("/login",{method:"POST",body:t||{}}),ue=t=>f("/passkeys/login/options",{method:"POST",body:t||{}}),de=t=>f("/passkeys/login/verify",{method:"POST",body:t||{}}),pe=t=>f("/resend-verify-email",{method:"POST",body:t||{}}),me=t=>f("/forgot-password",{method:"POST",body:t||{}}),fe=()=>f("/auth/social/config"),ve=t=>f("/auth/social/callback",{method:"POST",body:t||{}});function Y(t){const e=String(t||""),a="=".repeat((4-e.length%4)%4),o=(e+a).replace(/-/g,"+").replace(/_/g,"/"),v=window.atob(o),b=new Uint8Array(v.length);for(let d=0;d<v.length;d+=1)b[d]=v.charCodeAt(d);return b}function O(t){const e=t instanceof ArrayBuffer?new Uint8Array(t):new Uint8Array(t||[]);let a="";for(let o=0;o<e.length;o+=1)a+=String.fromCharCode(e[o]);return window.btoa(a).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function ge(t){if(!t||typeof t!="object")throw new Error("Passkey参数无效");return t.publicKey&&typeof t.publicKey=="object"?t.publicKey:t}function ye(t){const e=ge(t),a={...e,challenge:Y(e.challenge)};return Array.isArray(e.allowCredentials)&&(a.allowCredentials=e.allowCredentials.map(o=>({...o,id:Y(o.id)}))),a}function he(t){const e=t?.response||{},a={id:t?.id,rawId:O(t?.rawId),type:t?.type,authenticatorAttachment:t?.authenticatorAttachment||void 0,response:{}};return e.clientDataJSON&&(a.response.clientDataJSON=O(e.clientDataJSON)),e.authenticatorData&&(a.response.authenticatorData=O(e.authenticatorData)),e.signature&&(a.response.signature=O(e.signature)),e.userHandle?a.response.userHandle=O(e.userHandle):a.response.userHandle=null,a}function be(){return typeof window<"u"&&window.isSecureContext&&!!window.PublicKeyCredential&&!!navigator.credentials}async function we(t){const e=ye(t),a=await navigator.credentials.get({publicKey:e});return he(a)}async function Z(){if(!Q.value)try{const t=await le();C.value=!!t?.email_enabled,j.value=!!t?.register_verify_enabled}catch{C.value=!1,j.value=!1}finally{Q.value=!0}}function r(t,e){q.value=String(t||""),L.value=String(e||"")}function ee(){q.value="",L.value=""}async function x(){try{const t=await W();H.value=t?.session_id||"",A.value=t?.captcha_image||"",i.captcha=""}catch{H.value="",A.value=""}}async function D(){try{const t=await W();F.value=t?.session_id||"",R.value=t?.captcha_image||"",p.captcha=""}catch{F.value="",R.value=""}}async function z(){try{const t=await W();J.value=t?.session_id||"",N.value=t?.captcha_image||"",m.captcha=""}catch{J.value="",N.value=""}}function M(){const t=new URLSearchParams(window.location.search||""),e=String(t.get("next")||"").trim(),a=e&&e.startsWith("/")&&!e.startsWith("//")&&!e.startsWith("/\\")?e:"";window.setTimeout(()=>{window.location.href=a||"/app"},300)}function ke(){const t=new URL(window.location.href);return t.pathname="/login",t.search="",t.hash="",t.toString()}async function _e(){try{const t=await fe();$.value={enabled:!!t?.enabled,providers:Array.isArray(t?.providers)?t.providers:[]}}catch{$.value={enabled:!1,providers:[]}}}function Ce(t){try{window.sessionStorage.setItem(K.token,t?.bind_token||""),window.sessionStorage.setItem(K.provider,t?.provider||""),window.sessionStorage.setItem(K.nickname,t?.nickname||""),window.sessionStorage.setItem(K.avatar,t?.avatar_url||"")}catch{}}async function Se(){const t=new URLSearchParams(window.location.search||""),e=String(t.get("provider")||t.get("type")||"").trim(),a=String(t.get("code")||"").trim();if(!e||!a)return!1;B.value=!0,r("success","正在完成快捷登录...");try{const o=await ve({provider:e,code:a,mode:"login"});if(o?.requires_register&&o?.bind_token)return Ce(o),r("success","请完成注册后继续"),window.setTimeout(()=>{window.location.href="/register"},500),!0;if(o?.success||o?.bound)return r("success","快捷登录成功,正在跳转..."),M(),!0;r("error","快捷登录失败")}catch(o){const v=o?.response?.data;r("error",v?.error||v?.message||"快捷登录失败")}finally{B.value=!1}return!0}async function G(){if(ee(),!i.username.trim()||!i.password.trim()){r("error","用户名和密码不能为空");return}if(_.value&&!i.captcha.trim()){r("error","请输入验证码");return}U.value=!0;try{const t=i.username.trim();await ce({username:t,password:i.password,captcha_session:H.value,captcha:i.captcha.trim(),need_captcha:_.value}),r("success","登录成功,正在跳转..."),M()}catch(t){const e=t?.response?.status,a=t?.response?.data,o=a?.error||a?.message||"登录失败";r("error",o),a?.need_captcha?(_.value=!0,await x()):_.value&&e===400&&await x()}finally{U.value=!1}}async function Pe(){ee();const t=i.username.trim();if(!be()){r("error","当前浏览器或环境不支持Passkey需 HTTPS");return}E.value=!0;try{const e=await ue(t?{username:t}:{}),a=await we(e?.publicKey||{});await de(t?{username:t,credential:a}:{credential:a}),r("success","Passkey 登录成功,正在跳转..."),M()}catch(e){const o=e?.response?.data?.error||(e?.name==="NotAllowedError"?"Passkey验证未完成可能取消、超时或设备未响应":e?.message||"Passkey登录失败");r("error",o)}finally{E.value=!1}}async function Te(){await Z(),S.value=!0,T.value="",y.value="",p.username="",p.captcha="",await D()}async function Oe(){if(y.value="",T.value="",!C.value){y.value="邮件功能未启用,请联系管理员重置密码。";return}const t=p.username.trim();if(!t){y.value="请输入用户名";return}if(!p.captcha.trim()){y.value="请输入验证码";return}V.value=!0;try{const e=await me({username:t,captcha_session:F.value,captcha:p.captcha.trim()});r("success",e?.message||"已发送重置邮件"),S.value=!1}catch(e){const a=e?.response?.data,o=a?.error||"发送失败";a?.code==="email_not_bound"?T.value=o:y.value=o,await D()}finally{V.value=!1}}async function xe(){if(await Z(),!j.value){r("error","当前未启用注册邮箱验证,无需重发验证邮件。");return}P.value=!0,m.email="",m.captcha="",h.value="",await z()}async function Ae(){h.value="";const t=m.email.trim();if(!t){h.value="请输入邮箱";return}if(!m.captcha.trim()){h.value="请输入验证码";return}I.value=!0;try{const e=await pe({email:t,captcha_session:J.value,captcha:m.captcha.trim()});r("success",e?.message||"验证邮件已发送,请查收"),P.value=!1}catch(e){const a=e?.response?.data;h.value=a?.error||"发送失败",await z()}finally{I.value=!1}}function Ue(){window.location.href="/register"}return Le(async()=>{await _e(),await Se(),_.value&&await x()}),(t,e)=>(c(),l("div",Ie,[s("div",$e,[e[19]||(e[19]=s("div",{class:"login-header"},[s("span",{class:"login-badge"},"用户登录"),s("h1",null,"用户登录系统"),s("p",null,"知识管理平台")],-1)),L.value?(c(),l("div",{key:0,class:ae(["notice",q.value==="success"?"is-success":"is-error"])},g(L.value),3)):u("",!0),s("div",Be,[e[14]||(e[14]=s("label",{for:"username"},"用户账号",-1)),w(s("input",{id:"username","onUpdate:modelValue":e[0]||(e[0]=a=>i.username=a),class:"text-input",placeholder:"请输入用户名",autocomplete:"username"},null,512),[[k,i.username]])]),s("div",Ke,[e[15]||(e[15]=s("label",{for:"password"},"密码",-1)),w(s("input",{id:"password","onUpdate:modelValue":e[1]||(e[1]=a=>i.password=a),class:"text-input",type:"password",placeholder:"请输入密码",autocomplete:"current-password",onKeyup:se(G,["enter"])},null,544),[[k,i.password]])]),_.value?(c(),l("div",De,[e[16]||(e[16]=s("label",{for:"captcha"},"验证码",-1)),s("div",ze,[w(s("input",{id:"captcha","onUpdate:modelValue":e[2]||(e[2]=a=>i.captcha=a),class:"text-input captcha-input",placeholder:"请输入验证码",onKeyup:se(G,["enter"])},null,544),[[k,i.captcha]]),A.value?(c(),l("img",{key:0,class:"captcha-img",src:A.value,alt:"验证码",title:"点击刷新",onClick:x},null,8,He)):u("",!0),s("button",{type:"button",class:"captcha-refresh",onClick:x},"刷新")])])):u("",!0),s("button",{type:"button",class:"btn-login",disabled:U.value||B.value,onClick:G},g(U.value||B.value?"登录中...":"登录系统"),9,je),s("button",{type:"button",class:"btn-passkey",disabled:E.value,onClick:Pe},g(E.value?"Passkey验证中...":"使用 Passkey 登录"),9,qe),$.value.enabled?(c(),l("div",Fe,[e[17]||(e[17]=s("div",{class:"divider"},[s("span",null,"快捷登录")],-1)),Re(Ve,{providers:$.value.providers,mode:"login","redirect-uri":ke(),block:"",onError:e[3]||(e[3]=a=>r("error",a))},null,8,["providers","redirect-uri"])])):u("",!0),s("div",Je,[s("button",{type:"button",class:"link-btn",onClick:Te},"忘记密码?"),ne.value?(c(),l("button",{key:0,type:"button",class:"link-btn",onClick:xe},"重发验证邮件")):u("",!0)]),s("div",{class:"register-row"},[e[18]||(e[18]=s("span",null,"还没有账号?",-1)),s("button",{type:"button",class:"link-btn",onClick:Ue},"立即注册")])]),S.value?(c(),l("div",{key:0,class:"modal-mask",onClick:e[8]||(e[8]=oe(a=>S.value=!1,["self"]))},[s("section",We,[s("div",Me,[e[20]||(e[20]=s("h3",null,"找回密码",-1)),s("button",{type:"button",class:"modal-close",onClick:e[4]||(e[4]=a=>S.value=!1)},"关闭")]),s("p",{class:ae(["modal-tip",{warn:!C.value}])},g(C.value?"输入用户名并完成验证码,我们将向该账号绑定的邮箱发送重置链接。":"邮件功能未启用,无法通过邮箱找回密码。"),3),T.value?(c(),l("p",Ge,g(T.value),1)):u("",!0),y.value?(c(),l("p",Xe,g(y.value),1)):u("",!0),s("div",Qe,[e[21]||(e[21]=s("label",{for:"forgot-username"},"用户名",-1)),w(s("input",{id:"forgot-username","onUpdate:modelValue":e[5]||(e[5]=a=>p.username=a),class:"text-input",placeholder:"请输入用户名"},null,512),[[k,p.username]])]),s("div",Ye,[e[22]||(e[22]=s("label",{for:"forgot-captcha"},"验证码",-1)),s("div",Ze,[w(s("input",{id:"forgot-captcha","onUpdate:modelValue":e[6]||(e[6]=a=>p.captcha=a),class:"text-input captcha-input",placeholder:"请输入验证码"},null,512),[[k,p.captcha]]),R.value?(c(),l("img",{key:0,class:"captcha-img",src:R.value,alt:"验证码",title:"点击刷新",onClick:D},null,8,et)):u("",!0),s("button",{type:"button",class:"captcha-refresh",onClick:D},"刷新")])]),s("div",tt,[s("button",{type:"button",class:"btn-ghost",onClick:e[7]||(e[7]=a=>S.value=!1)},"取消"),s("button",{type:"button",class:"btn-login",disabled:V.value||!C.value,onClick:Oe},g(V.value?"发送中...":"发送重置邮件"),9,at)])])])):u("",!0),P.value?(c(),l("div",{key:1,class:"modal-mask",onClick:e[13]||(e[13]=oe(a=>P.value=!1,["self"]))},[s("section",st,[s("div",ot,[e[23]||(e[23]=s("h3",null,"重发验证邮件",-1)),s("button",{type:"button",class:"modal-close",onClick:e[9]||(e[9]=a=>P.value=!1)},"关闭")]),e[26]||(e[26]=s("p",{class:"modal-tip"},"用于注册邮箱验证:请输入邮箱并完成验证码。",-1)),h.value?(c(),l("p",nt,g(h.value),1)):u("",!0),s("div",rt,[e[24]||(e[24]=s("label",{for:"resend-email"},"邮箱",-1)),w(s("input",{id:"resend-email","onUpdate:modelValue":e[10]||(e[10]=a=>m.email=a),class:"text-input",placeholder:"name@example.com"},null,512),[[k,m.email]])]),s("div",it,[e[25]||(e[25]=s("label",{for:"resend-captcha"},"验证码",-1)),s("div",lt,[w(s("input",{id:"resend-captcha","onUpdate:modelValue":e[11]||(e[11]=a=>m.captcha=a),class:"text-input captcha-input",placeholder:"请输入验证码"},null,512),[[k,m.captcha]]),N.value?(c(),l("img",{key:0,class:"captcha-img",src:N.value,alt:"验证码",title:"点击刷新",onClick:z},null,8,ct)):u("",!0),s("button",{type:"button",class:"captcha-refresh",onClick:z},"刷新")])]),s("div",ut,[s("button",{type:"button",class:"btn-ghost",onClick:e[12]||(e[12]=a=>P.value=!1)},"取消"),s("button",{type:"button",class:"btn-login",disabled:I.value,onClick:Ae},g(I.value?"发送中...":"发送"),9,dt)])])])):u("",!0)]))}},St=Ne(pt,[["__scopeId","data-v-870324c7"]]);export{St as default};