diff --git a/chfs-ng/internal/api/web/index.html b/chfs-ng/internal/api/web/index.html index 9a2a3b2..8b32c75 100644 --- a/chfs-ng/internal/api/web/index.html +++ b/chfs-ng/internal/api/web/index.html @@ -66,10 +66,12 @@ $("modal").addEventListener("click",e=>{if(e.target.id==="modal")closeModal()}) async function showUsers(){try{const d=await api("/chfs/users");let html='

用户管理

';for(const u of d.users)html+='
'+esc(u.username)+' · '+(u.enabled?"启用":"已禁用")+' · '+esc(u.home||"")+(u.managed&&!u.admin?' ':"")+"
";html+='
';show(html)}catch(e){alert(e.message)}} async function createUser(){try{await api("/chfs/users",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:$("nu").value,password:$("np").value})});showUsers()}catch(e){alert(e.message)}} async function resetUser(u){const p=prompt("为 "+u+" 设置新密码");if(!p)return;try{await api("/chfs/users",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:u,password:p})});alert("密码已更新")}catch(e){alert(e.message)}} -async function editUser(name){const d=await api("/chfs/users");const u=d.users.find(x=>x.username===name);if(!u)return;window._editUser=u;window._editRules=[...(u.rules||[])];show('

'+esc(u.username)+'

主目录:'+esc(u.home)+'
主目录固定为 RWD;额外规则用于开放其他目录或显式拒绝访问。
');renderEditRules()} -function addRule(){const dir=$("rp").value.trim().replace(/^\/+|\/+$/g,"");if(!dir)return;const rule={dir,mask:$("rm").value};if($("rd").checked)rule.deny=true;if($("rc").checked)rule.childrenOnly=true;window._editRules.push(rule);$("rp").value="";renderEditRules()} -function removeRule(i){window._editRules.splice(i,1);renderEditRules()} -function renderEditRules(){$("rules").innerHTML=window._editRules.map((r,i)=>{const flags=(r.deny?"拒绝":"允许")+(r.childrenOnly?" · 仅子项":"");return '
'+esc(r.dir)+' · '+esc(r.mask||"禁止")+' · '+flags+'
'}).join("")} +async function editUser(name){const d=await api("/chfs/users");const u=d.users.find(x=>x.username===name);if(!u)return;window._editUser=u;window._editRules=[...(u.rules||[])];show('

'+esc(u.username)+'

主目录:'+esc(u.home)+'
主目录始终保留 RWD;下面的“共享目录”用于给用户开放其他位置,也可以单独设置拒绝规则。

共享目录

高级规则
可对已授权目录增加更细的拒绝规则,例如禁止访问 public/private。
');renderEditRules()} +function isHomeRule(r){return String(r.dir||"").replace(/^\/+|\/+$/g,"")===String(window._editUser.home||"").replace(/^\/+|\/+$/g,"")} +function setRulePreset(level){const mask=["","r","rw","rwd"][level];$("rd").checked=level===0;$("rm").value=mask;$("rp").focus()} +function addRule(){const dir=$("rp").value.trim().replace(/^\/+|\/+$/g,"");if(!dir)return;const rule={dir,mask:$("rm").value};if($("rd").checked)rule.deny=true;if($("rc").checked)rule.childrenOnly=true;window._editRules=window._editRules.filter(r=>!(String(r.dir||"").replace(/^\/+|\/+$/g,"")===dir&&!isHomeRule(r)));window._editRules.push(rule);$("rp").value="";$("rd").checked=false;$("rc").checked=false;renderEditRules()} +function removeRule(i){if(i<0||isHomeRule(window._editRules[i]))return;window._editRules.splice(i,1);renderEditRules()} +function renderEditRules(){const shared=window._editRules.filter(r=>!isHomeRule(r));$("sharedRules").innerHTML=shared.length?shared.map(r=>{const i=window._editRules.indexOf(r);const flags=(r.deny?"禁止":"允许")+" · "+(r.mask||"无权限")+(r.childrenOnly?" · 仅子项":"");return '
'+esc(r.dir)+'
'+esc(flags)+'
'}).join(""):'
还没有共享目录权限
';$("rules").innerHTML=window._editRules.map((r,i)=>isHomeRule(r)?'':'
'+esc(r.dir)+' · '+esc((r.deny?"拒绝":"允许")+" · "+(r.mask||"禁止")+(r.childrenOnly?" · 仅子项":""))+'
').join("")} async function saveUser(u){try{await api("/chfs/users",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:u,enabled:$("ue").checked,rules:window._editRules})});showUsers()}catch(e){alert(e.message)}} async function deleteUser(u){if(!confirm("删除用户 "+u+"?用户目录不会自动删除。"))return;try{await api("/chfs/users?username="+encodeURIComponent(u),{method:"DELETE"});showUsers()}catch(e){alert(e.message)}} init();