File: /www/server/panel/BTPanel/static/js/config6.js
import{k as m,M as c,X as I,da as J,o as L,R,w as j,cP as z,K as M}from"./utils-lib.js?v=1777008528";import{_ as $}from"./index118.js?v=1777008528";import{c as H,r as w,e as o,x as k,g as Q,ap as C,j as W,k as X,q as d,v as u,p as i,Q as G,F as Y,aV as Z,z as ee}from"./base-lib.js?v=1777008528";import{z as te,A as ae,B as se,C as re,D as ne}from"./config.js?v=1777008528";import{g as oe}from"./index3.js?v=1777008528";import{s as P}from"./useMethod2.js?v=1777008528";import{g as le}from"./useStore.js?v=1777008528";import{F as ie}from"./form-item.js?v=1777008528";import"./__commonjsHelpers__.js?v=1777008528";import"./index119.js?v=1777008528";import"./index116.js?v=1777008528";const ue=async(a,n)=>{await m({loading:"正在准备注册Passkey,请稍候...",request:te({origin:window.location.origin,name:a.name}),success:async e=>{if(e.data.hasOwnProperty("msg")){c.request(e);return}const s=await ce(e.data);s&&await de(s,e.data.challenge,n)}})},ce=async a=>{try{const n={rp:a.rp,user:{id:y(a.user.id),name:a.user.name,displayName:a.user.displayName},challenge:y(a.challenge),pubKeyCredParams:a.pubKeyCredParams,authenticatorSelection:a.authenticatorSelection||{userVerification:"preferred",authenticatorAttachment:"platform",residentKey:"preferred"},attestation:a.attestation||"none",timeout:a.timeout||6e4,excludeCredentials:a.excludeCredentials||[]};a.excludeCredentials&&a.excludeCredentials.length>0&&(n.excludeCredentials=a.excludeCredentials.map(s=>({...s,id:y(s.id)})));const e=await navigator.credentials.create({publicKey:n});if(!e)throw new Error("用户取消了操作");return{id:e.id,rawId:g(e.rawId),response:{clientDataJSON:g(e.response.clientDataJSON),attestationObject:g(e.response.attestationObject)},type:e.type}}catch(n){return n.name==="NotAllowedError"?c.error("验证失败,可能原因:<br>1、操作被取消<br>2、证书不匹配<br>3、设备不支持"):n.name==="InvalidStateError"?c.error("该用户已存在Passkey,请直接登录"):n.name==="SecurityError"?c.error("安全错误:请确保在安全的上下文中使用"):c.error("创建Passkey失败:"+n.message),null}},de=async(a,n,e)=>{try{await m({loading:"正在验证注册,请稍候...",request:ae({credential:JSON.stringify(a),challenge:JSON.stringify(n)}),success:s=>{c.request({msg:s.msg,status:s.status}),s.status&&e()}})}catch(s){}},y=a=>{const n=a.replace(/-/g,"+").replace(/_/g,"/"),e=window.atob(n),s=new Uint8Array(e.length);for(let l=0;l<e.length;l++)s[l]=e.charCodeAt(l);return s.buffer},g=a=>{const n=new Uint8Array(a);let e="";for(let s=0;s<n.byteLength;s++)e+=String.fromCharCode(n[s]);return window.btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")},me={class:"p-2rem"},pe={class:"py-1.2rem flex items-center"},fe={class:"flex items-center"},Ee=H({__name:"config",props:{compData:{default:()=>({isSwitch:!1})}},setup(a){const n=a,{refs:{panelConfig:e}}=le(),s=w(!0),l=w(!1),B=[{content:"开启时需要面板配置有效的域名证书,自签证书或域名不匹配时均无法使用"},{content:"开启此功能后,请在安全的设备上绑定凭证信息"},{content:"域名变更、修改面板端口或改用免端口访问,都会导致登录凭证暂时失效,必须用与凭证匹配的网址访问才能正常登录"},{content:o("span",{class:"text-danger"},[k("Passkey登录失败的常见原因:操作被取消、证书不匹配、当前设备中无可用凭证、设备不支持")])}],x=r=>P(r?1:0),E=Q(()=>[ie("名称","name",{attrs:{...{class:"!w-[280px]",clearable:!0},placeholder:"例如:我的MacBook / iPhone"},rules:[{required:!0,message:"名称不能为空",trigger:"blur"}]})]),{BtForm:v,submit:D,param:S}=I({data:()=>({}),options:E,submit:async(r,t,_)=>{try{await t(),await ue(r.value,()=>{l.value=!1,p()})}catch(b){}return!1}}),A=async(r,t)=>{await m({loading:"正在更新状态,请稍候...",request:ne({passkey_id:r.id,status:t}),message:!0,success:()=>{p()}})},{BtTable:F,BtPage:V,BtRefresh:O,BtSearch:N,refresh:p}=J({request:async r=>{const t=await se(r);return Array.isArray(t.data.data)?(e.value.passkey_status=t.data.is_enable,s.value&&n.compData.isSwitch&&(s.value=!1,t.data.data.length?P(1):h()),{data:t.data.data,total:L(t.data.page)}):{data:[],total:0}},columns:[{label:"凭证名称",prop:"name",showOverflowTooltip:!0,width:200},{label:"状态",prop:"status",width:100,render:r=>o(C,{size:"small",modelValue:r.status,"onUpdate:modelValue":t=>r.status=t,onChange:t=>A(r,Number(t))},null)},{label:"适配网址",prop:"origin",showOverflowTooltip:!0},{label:"创建时间",prop:"created_at",width:180,render:r=>R(r.created_at)},oe([{title:"删除",onClick:r=>q(r)}])],extension:[]}),h=()=>{if(/^[\d.]+$/.test(window.location.hostname))return c.error("当前访问地址非域名,无法使用Passkey登录,请使用绑定了有效证书的域名访问后再试。");S.value.name="",l.value=!0},q=async r=>{await j({title:"删除Passkey【".concat(r.name,"】"),content:"您确定要删除该Passkey吗?删除后将无法使用该Passkey登录。"}),m({loading:"正在删除Passkey,请稍候...",request:re({passkey_id:r.id}),message:!0,success:()=>{p()}})};return(r,t)=>{const _=Z,b=ee,T=$,U=z,K=M;return W(),X(Y,null,[d("div",me,[o(_,{type:"info","show-icon":"",closable:!1},{title:u(()=>[...t[2]||(t[2]=[d("div",{class:"leading-2rem text-small"},"基于 WebAuthn 技术的无密码登录方式,通过设备内置的生物识别或 PIN 码完成身份验证,更安全、更便捷。",-1)])]),_:1}),d("div",pe,[t[3]||(t[3]=d("span",{class:"mr-2rem"},"启用Passkey登录",-1)),o(i(C),{modelValue:i(e).passkey_status,"onUpdate:modelValue":t[0]||(t[0]=f=>i(e).passkey_status=f),onChange:x},null,8,["modelValue"])]),o(T,null,{"header-left":u(()=>[o(b,{type:"primary",onClick:h},{default:u(()=>[...t[4]||(t[4]=[k("添加Passkey",-1)])]),_:1})]),"header-right":u(()=>[d("div",fe,[o(i(N),{placeholder:"请输入关键词搜索",class:"!w-[270px] mr-[10px]"}),o(i(O))])]),content:u(()=>[o(i(F),{"max-height":300})]),"footer-right":u(()=>[o(i(V))]),_:1}),o(U,{class:"mt-2rem",options:B})]),o(K,{title:"添加Passkey",area:46,modelValue:i(l),"onUpdate:modelValue":t[1]||(t[1]=f=>G(l)?l.value=f:null),"show-footer":"",onConfirm:i(D)},{default:u(()=>[o(i(v),{class:"p-[2rem]"})]),_:1},8,["modelValue","onConfirm"])],64)}}});export{Ee as default};