Files
zsglpt/static/app/assets/ResetPasswordPage--Vqm02p7.js
yuyx 89f3fd9759 feat: 安全增强 + 删除密码重置申请功能 + 登录提醒开关
安全增强:
- 新增 SSRF、XXE、模板注入、敏感路径探测检测规则
- security/constants.py: 添加新的威胁类型和检测模式
- security/threat_detector.py: 实现新检测逻辑

删除密码重置申请功能:
- 移除 /api/password_resets 相关API
- 删除 password_reset_requests 数据库表
- 前端移除密码重置申请页面和菜单
- 用户只能通过邮��找回密码,未绑定邮箱需联系管理员

登录提醒全局开关:
- email_service.py: 添加 login_alert_enabled 字段
- routes/api_auth.py: 检查开关状态再发送登录提醒
- EmailPage.vue: 添加新设备登录提醒开关

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 12:08:36 +08:00

2 lines
3.6 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{_ as M,a as n,l as U,r as j,c as F,o as K,m as z,b as g,d as o,w as t,e as l,u as D,f,g as w,F as A,k as I,h as Z,i as B,j as q,t as G,E as y}from"./index-CEOd73lG.js";import{c as H}from"./auth-WsWSY0rn.js";function J(S){const r=String(S||"");return r.length<8?{ok:!1,message:"密码长度至少8位"}:!/[a-zA-Z]/.test(r)||!/\d/.test(r)?{ok:!1,message:"密码必须包含字母和数字"}:{ok:!0,message:""}}const O={class:"auth-wrap"},Q={class:"actions"},W={class:"actions"},X={key:0,class:"app-muted"},Y={__name:"ResetPasswordPage",setup(S){const r=U(),C=D(),i=n(String(r.params.token||"")),d=n(!0),b=n(""),a=j({newPassword:"",confirmPassword:""}),k=n(!1),_=n(""),u=n(0);let c=null;function N(){if(typeof window>"u")return null;const s=window.__APP_INITIAL_STATE__;return!s||typeof s!="object"?null:(window.__APP_INITIAL_STATE__=null,s)}const h=F(()=>!!(d.value&&i.value&&!_.value));function V(){C.push("/login")}function R(){u.value=3,c=window.setInterval(()=>{u.value-=1,u.value<=0&&(window.clearInterval(c),c=null,window.location.href="/login")},1e3)}async function T(){if(!h.value)return;const s=a.newPassword,e=a.confirmPassword,p=J(s);if(!p.ok){y.error(p.message);return}if(s!==e){y.error("两次输入的密码不一致");return}k.value=!0;try{await H({token:i.value,new_password:s}),_.value="密码重置成功3秒后跳转到登录页面...",y.success("密码重置成功"),R()}catch(m){const v=m?.response?.data;y.error(v?.error||"重置失败")}finally{k.value=!1}}return K(()=>{const s=N();s?.page==="reset_password"?(i.value=String(s?.token||i.value||""),d.value=!!s?.valid,b.value=s?.error_message||(d.value?"":"重置链接无效或已过期,请重新申请密码重置")):i.value||(d.value=!1,b.value="重置链接无效或已过期,请重新申请密码重置")}),z(()=>{c&&window.clearInterval(c)}),(s,e)=>{const p=l("el-alert"),m=l("el-button"),v=l("el-input"),x=l("el-form-item"),E=l("el-form"),L=l("el-card");return f(),g("div",O,[o(L,{shadow:"never",class:"auth-card","body-style":{padding:"22px"}},{default:t(()=>[e[5]||(e[5]=w("div",{class:"brand"},[w("div",{class:"brand-title"},"知识管理平台"),w("div",{class:"brand-sub app-muted"},"重置密码")],-1)),d.value?(f(),g(A,{key:1},[_.value?(f(),Z(p,{key:0,type:"success",closable:!1,title:"重置成功",description:_.value,"show-icon":"",class:"alert"},null,8,["description"])):B("",!0),o(E,{"label-position":"top"},{default:t(()=>[o(x,{label:"新密码至少8位且包含字母和数字"},{default:t(()=>[o(v,{modelValue:a.newPassword,"onUpdate:modelValue":e[0]||(e[0]=P=>a.newPassword=P),type:"password","show-password":"",placeholder:"请输入新密码",autocomplete:"new-password"},null,8,["modelValue"])]),_:1}),o(x,{label:"确认密码"},{default:t(()=>[o(v,{modelValue:a.confirmPassword,"onUpdate:modelValue":e[1]||(e[1]=P=>a.confirmPassword=P),type:"password","show-password":"",placeholder:"请再次输入新密码",autocomplete:"new-password",onKeyup:q(T,["enter"])},null,8,["modelValue"])]),_:1})]),_:1}),o(m,{type:"primary",class:"submit-btn",loading:k.value,disabled:!h.value,onClick:T},{default:t(()=>[...e[3]||(e[3]=[I(" 确认重置 ",-1)])]),_:1},8,["loading","disabled"]),w("div",W,[o(m,{link:"",type:"primary",onClick:V},{default:t(()=>[...e[4]||(e[4]=[I("返回登录",-1)])]),_:1}),u.value>0?(f(),g("span",X,G(u.value)+" 秒后自动跳转…",1)):B("",!0)])],64)):(f(),g(A,{key:0},[o(p,{type:"error",closable:!1,title:"链接已失效",description:b.value,"show-icon":""},null,8,["description"]),w("div",Q,[o(m,{type:"primary",onClick:V},{default:t(()=>[...e[2]||(e[2]=[I("返回登录",-1)])]),_:1})])],64))]),_:1})])}}},se=M(Y,[["__scopeId","data-v-0bbb511c"]]);export{se as default};